• 【MM32F5270开发板试用】快速移植STM32应用到MM32F5270(以OLED为例)


    本篇文章来自极术社区与灵动组织的MM32F5270开发板评测活动,更多开发板试用活动请关注极术社区网站。作者:@#@

    本篇文章来自极术社区与灵动组织的MM32F5270开发板评测活动,更多开发板试用活动请关注极术社区网站。作者:@#@

    最近在做几个嵌入式项目,一直使用的是STM32F429作为主控制芯片。从去年开始,ST的芯片全系涨价,价格高到离谱,并且市场上充斥着翻新芯片,有时候有钱都不一定能买到靠谱的原装芯片。考虑到项目最终落地需要考虑到芯片供应问题,所以一直在寻找国产替代。正好看到极术社区的MM32F5270适用活动,初步看芯片性能以及外设接口能满足现在的项目需求,所以申请一个板子来看下从STM32移植到MM32F5270的工作量。

    一 项目简介

    最近做的项目是一个气体分析仪,基本原理框图如下。

    用STM32跑PID算法,控制比例阀开度,将输入气流稳定到设置值,然后由气体检测器进行采样并处理。这个项目目前已经开始小批量出货,这里就不过多说明技术细节。

    由于项目客制化需求比较多,要求能够通过键盘选择不同功能,涉及到多级菜单。所以大量的工作都在自定义的菜单设计和实现上,这里就先试试移植OLED驱动代码到MM32F5270看看工作量。

    二 环境准备

    请参考https://aijishu.com/a/1060000…准备开发环境。记住,一定要下载MDK5.37版本才能使用灵动微电子的MM32 pack包。

    因为我习惯用JLINK调试器做开发,所以这里我就直接使用JLINK作为调试工具。JLINK的插头直接插上去就可以,有防呆设计,不用担心会插错,下面是JLINK连接特写。

    插上JLINK后,在魔术棒页面DEBUG tab里选择JLINK/J-TRACE Cortex

    点击setting,在setting页面选择SW

    接下来就可以愉快的使用JLINK进行MM32F5270开发板的调试了。

    三 代码移植

    初步看了下Mind SDK的文件结构,对所有的外设,都有对应的驱动代码,驱动代码对底层的硬件操作做了很好的封装。看了下对应的driver_example以及demo_apps,提供的都是类似于如下的代码文件组织结构

    对于简单的应用来说,这种结构可以满足需求。但是对于一些外设较多的项目,这种组织形式在逻辑上不是很清晰,且代码复用性不高。所以这里按照项目的需求,设计了按hardware和module分类的方法,项目部分文件结构如下:

    其中hardware目录是用到的外设driver,module目录里会放跟硬件无关的功能模块,比如流量控制功能,气体采样功能(当然目前为空,但是因为这是硬件无关逻辑,所以基本上可以不做改动直接移到MM32F5270)等。这里以tim_basic例程为基础,来移植OLED驱动。

    1. 拆分clock_init.c/clock_init.h文件,这里将所有外设的clokc外设移除,只留下主时钟的初始化。
      void BOARD_InitBootClocks(void)
      {
      CLOCK_ResetToDefault();
      CLOCK_BootToHSE120MHz();
      }

    2.将uart拆分到单独文件,以后在不同项目可以进行复用
    demo_uart.h

    #ifndef _UART_H_
    #define _UART_H_

    #include “clock_init.h”

    /* DEBUG UART. */
    #define BOARD_DEBUG_UART_PORT UART1
    #define BOARD_DEBUG_UART_BAUDRATE 9600u
    #define BOARD_DEBUG_UART_FREQ CLOCK_APB2_FREQ

    void uart1_init(void);
    #endif

    demo_uart.c
    #include “demo_uart.h”
    #include

    #include “hal_common.h”
    #include “hal_gpio.h”
    #include “hal_uart.h”
    #include “hal_rcc.h”

    static void uart1_gpio_init(void)
    {
    /* PB6 - UART1_TX. */
    GPIO_Init_Type gpio_init;
    gpio_init.Pins = GPIO_PIN_6;
    gpio_init.PinMode = GPIO_PinMode_AF_PushPull;
    gpio_init.Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &gpio_init);
    GPIO_PinAFConf(GPIOB, gpio_init.Pins, GPIO_AF_7);

    /* PB7 - UART1_RX. */
    gpio_init.Pins = GPIO_PIN_7;
    gpio_init.PinMode = GPIO_PinMode_In_Floating;
    gpio_init.Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &gpio_init);
    GPIO_PinAFConf(GPIOB, gpio_init.Pins, GPIO_AF_7);

    }

    static void uart1_port_init(void)
    {
    UART_Init_Type uart_init;

    uart_init.ClockFreqHz = BOARD_DEBUG_UART_FREQ;
    uart_init.BaudRate = BOARD_DEBUG_UART_BAUDRATE;
    uart_init.WordLength = UART_WordLength_8b;
    uart_init.StopBits = UART_StopBits_1;
    uart_init.Parity = UART_Parity_None;
    uart_init.XferMode = UART_XferMode_RxTx;
    uart_init.HwFlowControl = UART_HwFlowControl_None;
    UART_Init(BOARD_DEBUG_UART_PORT, &uart_init);
    UART_Enable(BOARD_DEBUG_UART_PORT, true);

    }

    void uart1_init(void)
    {
    /* UART1. */
    RCC_EnableAPB2Periphs(RCC_APB2_PERIPH_UART1, true);
    RCC_ResetAPB2Periphs(RCC_APB2_PERIPH_UART1);

    /* GPIOB. */
    RCC_EnableAHB1Periphs(RCC_AHB1_PERIPH_GPIOB, true);
    RCC_ResetAHB1Periphs(RCC_AHB1_PERIPH_GPIOB);

    uart1_gpio_init();

    uart1_port_init();
    }

    #if defined(__ARMCC_VERSION)
    int fputc(int c, FILE *f)
    {
    (void)(f);
    while ( 0u == (UART_STATUS_TX_EMPTY & UART_GetStatus(BOARD_DEBUG_UART_PORT)) )
    {}
    UART_PutData(BOARD_DEBUG_UART_PORT, (uint8_t)©);
    return c;
    }

    int fgetc(FILE *f)
    {
    (void)(f);
    while ( 0u == (UART_STATUS_RX_DONE & UART_GetStatus(BOARD_DEBUG_UART_PORT)) )
    {}
    return UART_GetData(BOARD_DEBUG_UART_PORT);
    }

    #elif defined(__GNUC__)

    /*
    * Called by libc stdio fwrite functions
    */
    int _write(int fd, char *ptr, int len)
    {
    int i = 0;

    /*
    * write “len” of char from “ptr” to file id “fd”
    * Return number of char written.
    *
    * Only work for STDOUT, STDIN, and STDERR
    */
    if (fd > 2)
    {
    return -1;
    }

    while (*ptr && (i < len))
    {
    while ( 0u == (UART_STATUS_TX_EMPTY & UART_GetStatus(BOARD_DEBUG_UART_PORT)) )
    {}
    UART_PutData(BOARD_DEBUG_UART_PORT, (uint8_t)(*ptr));
    i++;
    ptr++;
    }

    return i;
    }

    /*
    * Called by the libc stdio fread fucntions
    *
    * Implements a buffered read with line editing.
    */
    int _read(int fd, char *ptr, int len)
    {
    int my_len;

    if (fd > 2)
    {
    return -1;
    }

    my_len = 0;
    while (len > 0)
    {
    while ( 0u == (UART_STATUS_RX_DONE & UART_GetStatus(BOARD_DEBUG_UART_PORT)) )
    {}
    *ptr = UART_GetData(BOARD_DEBUG_UART_PORT);
    len–;
    my_len++;

    if ( (*ptr == ‘\r’) || (*ptr == ‘\n’) || (*ptr == ‘\0’) )
    {
    break;
    }

    ptr++;
    }

    return my_len; /* return the length we got */
    }

    int putchar(int c)
    {
    while ( 0u == (UART_STATUS_TX_EMPTY & UART_GetStatus(BOARD_DEBUG_UART_PORT)) )
    {}
    UART_PutData(BOARD_DEBUG_UART_PORT, (uint8_t)©);
    return c;
    }

    int getchar(void)
    {
    while ( 0u == (UART_STATUS_RX_DONE & UART_GetStatus(BOARD_DEBUG_UART_PORT)) )
    {}
    return UART_GetData(BOARD_DEBUG_UART_PORT);
    }

    #elif (defined(__ICCARM__))
    /* These function __write and __read is used to support IAR toolchain to printf and scanf. */

    int fputc(int ch, FILE *f)
    {
    while ( 0u == (UART_STATUS_TX_EMPTY & UART_GetStatus(BOARD_DEBUG_UART_PORT)) )
    {}
    UART_PutData(BOARD_DEBUG_UART_PORT, (uint8_t)(ch));
    return ch;
    }

    int fgetc(FILE *f)
    {
    while ( 0u == (UART_STATUS_RX_DONE & UART_GetStatus(BOARD_DEBUG_UART_PORT)) )
    {}
    return UART_GetData(BOARD_DEBUG_UART_PORT);
    }

    #endif

    1. OLED会用到SPI,这里用SPI3作为控制接口
      demo_spi.h

      #ifndef _DEMO_SPI_H_
      #define _DEMO_SPI_H_
      #include “hal_common.h”
      #include “clock_init.h”

      #define BOARD_LOOP_SPI_PORT SPI3
      //#define BOARD_LOOP_SPI_BAUDRATE 1000000u /* 400khz. /
      #define BOARD_LOOP_SPI_BAUDRATE 400000u /
      400khz. */

      #define BOARD_LOOP_SPI_FREQ CLOCK_APB1_FREQ

      void spi3_init(void);

      /* SPI tx. */
      void spi3_putbyte(uint8_t c);

      /* SPI rx. */
      uint8_t spi3_getbyte(void);
      #endif

    2. demo_spi.c

      #include “demo_spi.h”
      #include “hal_rcc.h”
      #include “hal_spi.h”
      #include “hal_gpio.h”

      static void spi3_gpio_init(void)
      {
      GPIO_Init_Type gpio_init;

      /* SPI3_NSS - PA15. /
      /

      gpio_init.Pins = GPIO_PIN_15;
      gpio_init.PinMode = GPIO_PinMode_AF_PushPull;
      gpio_init.Speed = GPIO_Speed_50MHz;
      GPIO_Init(GPIOA, &gpio_init);
      GPIO_PinAFConf(GPIOA, GPIO_PIN_15, GPIO_AF_6);
      */

      /* SPI3_MOSI - PC12. */
      gpio_init.Pins = GPIO_PIN_12;
      gpio_init.PinMode = GPIO_PinMode_AF_PushPull;
      gpio_init.Speed = GPIO_Speed_50MHz;
      GPIO_Init(GPIOC, &gpio_init);
      GPIO_PinAFConf(GPIOC, GPIO_PIN_12, GPIO_AF_6);

      /* SPI3_MISO - PC11. */
      gpio_init.Pins = GPIO_PIN_11;
      gpio_init.PinMode = GPIO_PinMode_In_Floating;
      gpio_init.Speed = GPIO_Speed_50MHz;
      GPIO_Init(GPIOC, &gpio_init);
      GPIO_PinAFConf(GPIOC, GPIO_PIN_11, GPIO_AF_6);

      /* SPI3_SCK - PC10. */
      gpio_init.Pins = GPIO_PIN_10;
      gpio_init.PinMode = GPIO_PinMode_AF_PushPull;
      gpio_init.Speed = GPIO_Speed_50MHz;
      GPIO_Init(GPIOC, &gpio_init);
      GPIO_PinAFConf(GPIOC, GPIO_PIN_10, GPIO_AF_6);

      }

      static void spi3_port_init(void)
      {
      /* Setup SPI module. */
      SPI_Master_Init_Type spi_init;
      spi_init.ClockFreqHz = BOARD_LOOP_SPI_FREQ;
      spi_init.BaudRate = BOARD_LOOP_SPI_BAUDRATE;
      spi_init.XferMode = SPI_XferMode_TxRx;
      spi_init.PolarityPhase = SPI_PolarityPhase_Alt0;
      spi_init.DataWidth = SPI_DataWidth_8b;
      spi_init.LSB = false;
      spi_init.CSMode = SPI_CSMode_NonAuto;
      SPI_InitMaster(BOARD_LOOP_SPI_PORT, &spi_init);

      /* Enable SPI. */
      SPI_Enable(BOARD_LOOP_SPI_PORT, true);

      }

      void spi3_init(void)
      {
      /* GPIOA. /
      /

      RCC_EnableAHB1Periphs(RCC_AHB1_PERIPH_GPIOA, true);
      RCC_ResetAHB1Periphs(RCC_AHB1_PERIPH_GPIOA);
      */

      /* GPIOC. */
      RCC_EnableAHB1Periphs(RCC_AHB1_PERIPH_GPIOC, true);
      RCC_ResetAHB1Periphs(RCC_AHB1_PERIPH_GPIOC);

      /* SPI3. */
      RCC_EnableAPB1Periphs(RCC_APB1_PERIPH_SPI3, true);
      RCC_ResetAPB1Periphs(RCC_APB1_PERIPH_SPI3);

      spi3_gpio_init();
      spi3_port_init();
      }

      /* SPI tx. */
      void spi3_putbyte(uint8_t c)
      {
      /* Polling for tx empty. */
      while ( SPI_STATUS_TX_FULL & SPI_GetStatus(BOARD_LOOP_SPI_PORT) )
      {}
      SPI_PutData(BOARD_LOOP_SPI_PORT, c);
      }

      /* SPI rx. */
      uint8_t spi3_getbyte(void)
      {
      /* Polling for rx done. */
      while (0u == (SPI_STATUS_RX_DONE & SPI_GetStatus(BOARD_LOOP_SPI_PORT)) )
      {}
      return SPI_GetData(BOARD_LOOP_SPI_PORT);
      }

    3. 顺便将LED4, LED5的控制单独拉出,可以作为debug的辅助手段
      led.h
      #ifndef _LED_H_
      #define _LED_H_

      #include “type_def.h”

      enum LED_NUM {
      LED4,
      LED5,
      };

      void led_init(void);

      void led_on(u8 led);

      void led_off(u8 led);
      #endif

    4. led.c
      #include “led.h”
      #include “hal_rcc.h”
      #include “hal_gpio.h”

      static void led_gpio_init(void)
      {
      GPIO_Init_Type gpio_init;

      /* LED4. */
      gpio_init.Pins = GPIO_PIN_0;
      gpio_init.PinMode = GPIO_PinMode_Out_PushPull;
      gpio_init.Speed = GPIO_Speed_50MHz;
      GPIO_Init(GPIOI, &gpio_init);

      /* LED5. */
      gpio_init.Pins = GPIO_PIN_2;
      gpio_init.PinMode = GPIO_PinMode_Out_PushPull;
      gpio_init.Speed = GPIO_Speed_50MHz;
      GPIO_Init(GPIOD, &gpio_init);

      }

      void led_init(void)
      {
      /* GPIOD. */
      RCC_EnableAHB1Periphs(RCC_AHB1_PERIPH_GPIOD, true);
      RCC_ResetAHB1Periphs(RCC_AHB1_PERIPH_GPIOD);

      /* GPIOI. */
      RCC_EnableAHB1Periphs(RCC_AHB1_PERIPH_GPIOI, true);
      RCC_ResetAHB1Periphs(RCC_AHB1_PERIPH_GPIOI);

      led_gpio_init();

      }

      void led_on(u8 led)
      {
      switch (led) {
      case LED4:
      GPIO_WriteBit(GPIOI, GPIO_PIN_0, 0u);
      break;
      case LED5:
      GPIO_WriteBit(GPIOD, GPIO_PIN_2, 0u);
      break;
      default:
      break;
      }
      }

      void led_off(u8 led)
      {
      switch (led) {
      case LED4:
      GPIO_WriteBit(GPIOI, GPIO_PIN_0, 1u);
      break;
      case LED5:
      GPIO_WriteBit(GPIOD, GPIO_PIN_2, 1u);
      break;
      default:
      break;
      }
      }

    5. 以上完成后,OLED驱动移植的前期准备工作已经完成,现在开始将STM32上的OLED控制代码移到MM32F5270上来。OLED使用的是中景园的3.12寸 256X64 单色OLED屏幕,淘宝连接https://item.taobao.com/item…
      控制引脚如图所示

    原始STM32控制代码如下所示:
    stm32的oled.h

    #ifndef __OLED_H
    #define __OLED_H 
    
    #include "sys.h"
    
    #define OLED_USE_SOFT_SPI 0
    
    
    #define OLED_CS_Pin GPIO_PIN_12
    #define OLED_CS_GPIO_Port GPIOH
    #define OLED_DC_Pin GPIO_PIN_12
    #define OLED_DC_GPIO_Port GPIOB
    #define OLED_RES_Pin GPIO_PIN_11
    #define OLED_RES_GPIO_Port GPIOH
    
    #if OLED_USE_SOFT_SPI
    #define SOFT_SPI_MOSI_Pin GPIO_PIN_7
    #define SOFT_SPI_MOSI_GPIO_Port GPIOF
    #define SOFT_SPI_MISO_Pin GPIO_PIN_8
    #define SOFT_SPI_MISO_GPIO_Port GPIOF
    #define SOFT_SPI_SCK_Pin GPIO_PIN_9
    #define SOFT_SPI_SCK_GPIO_Port GPIOF
    #endif
    
    #define USE_HORIZONTAL 1  //设置显示方向 0:正向显示;1:旋转180度显示
    
    #ifndef PIN_RESET
    #define PIN_RESET 0
    #define PIN_SET 1
    #endif
    
    void OLED_WR_REG(u8 reg);
    void OLED_WR_Byte(u8 dat);
    void Column_Address(u8 a,u8 b);
    void Row_Address(u8 a,u8 b);
    void OLED_Fill(u16 xstr,u8 ystr,u16 xend,u8 yend,u8 color);
    void OLED_ShowChinese(u8 x,u8 y,u8 *s,u8 sizey,u8 mode);
    void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 sizey,u8 mode);
    void OLED_ShowString(u8 x,u8 y,u8 *dp,u8 sizey,u8 mode);
    u32 oled_pow(u8 m,u8 n);
    void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 sizey,u8 mode);
    void OLED_DrawBMP(u8 x,u8 y,u16 length,u8 width,const u8 BMP[],u8 mode);
    void OLED_DrawSingleBMP(u8 x,u8 y,u16 length,u8 width,const u8 BMP[],u8 mode);
    void OLED_Init(void);
    
    void OLED_GPIO_Init(void);
    
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    stm32的oled.c

    #include "oledfont.h"
    #include "delay.h"
    #include "oled.h"
    #include "osal.h"
    #include "spi.h"
    
    #if OLED_USE_SOFT_SPI
    static void OLED_SCL_Clr()
    {
        HAL_GPIO_WritePin(SOFT_SPI_SCK_GPIO_Port, SOFT_SPI_SCK_Pin, GPIO_PIN_RESET); //SCL
    }
    
    static void OLED_SCL_Set()
    {
        HAL_GPIO_WritePin(SOFT_SPI_SCK_GPIO_Port, SOFT_SPI_SCK_Pin, GPIO_PIN_SET);
    }
    
    static void OLED_SDA_Clr()
    {
        HAL_GPIO_WritePin(SOFT_SPI_MOSI_GPIO_Port, SOFT_SPI_MOSI_Pin, GPIO_PIN_RESET); //SDA
    }
    
    static void OLED_SDA_Set()
    {
        HAL_GPIO_WritePin(SOFT_SPI_MOSI_GPIO_Port, SOFT_SPI_MOSI_Pin, GPIO_PIN_SET);
    }
    #endif
    
    static void OLED_RES_Clr()
    {
        HAL_GPIO_WritePin(OLED_RES_GPIO_Port, OLED_RES_Pin, GPIO_PIN_RESET); //RES
    }
    
    static void OLED_RES_Set()
    {
        HAL_GPIO_WritePin(OLED_RES_GPIO_Port, OLED_RES_Pin, GPIO_PIN_SET);
    }
    
    static void OLED_DC_Clr()
    {
        HAL_GPIO_WritePin(OLED_DC_GPIO_Port, OLED_DC_Pin, GPIO_PIN_RESET); //DC
    }
    
    static void OLED_DC_Set()
    {
        HAL_GPIO_WritePin(OLED_DC_GPIO_Port, OLED_DC_Pin, GPIO_PIN_SET);
    }
    
    static void OLED_CS_Clr()
    {
        HAL_GPIO_WritePin(OLED_CS_GPIO_Port, OLED_CS_Pin, GPIO_PIN_RESET); //CS
    }
    
    static void OLED_CS_Set()
    {
        HAL_GPIO_WritePin(OLED_CS_GPIO_Port, OLED_CS_Pin, GPIO_PIN_SET);
    }
    
    static void OLED_Write_Byte(u8 dat)
    {
    #if OLED_USE_SOFT_SPI
        u8 i;
        for(i=0;i<8;i++)
        {              
            OLED_SCL_Clr();
            //delay_us(200);
            if(dat&0x80)
            {
               OLED_SDA_Set();
            }
            else 
            {
               OLED_SDA_Clr();
            }
            //delay_us(20);
            OLED_SCL_Set();
            //delay_us(200);
            dat<<=1;   
        }
    #else
        SPI_Write_Byte(2, dat);             
    #endif
    }
    
    void OLED_WR_Bus(u8 dat)
    {
        OLED_CS_Clr();
        OLED_Write_Byte(dat);          
        OLED_CS_Set();
    }
    
    void OLED_WR_REG(u8 reg)
    {      
        OLED_DC_Clr();          
      OLED_WR_Bus(reg);
      OLED_DC_Set();    
    }
    
    void OLED_WR_Byte(u8 dat)
    {      
      OLED_WR_Bus(dat);
    }
    
    void Column_Address(u8 a,u8 b)
    {
        OLED_WR_REG(0x15);       // Set Column Address
        OLED_WR_Byte(0x1c+a);
        OLED_WR_Byte(0x1c+b);
    }
    
    void Row_Address(u8 a,u8 b)
    {
        OLED_WR_REG(0x75);       // Row Column Address
        OLED_WR_Byte(a);
        OLED_WR_Byte(b);
        OLED_WR_REG(0x5C);    //写RAM命令
    }
    
    void OLED_Fill(u16 xstr,u8 ystr,u16 xend,u8 yend,u8 color)
    {
        u8 x,y;
        xstr/=4;
        xend/=4;
        Column_Address(xstr,xend-1);
        Row_Address(ystr,yend-1);
        for(x=xstr;x
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    • 385
    • 386
    • 387
    • 388
    • 389
    • 390
    • 391
    • 392
    • 393
    • 394
    • 395
    • 396
    • 397
    • 398
    • 399
    • 400
    • 401
    • 402
    • 403
    • 404

    分析OLED的LOG,发现只需要更改RES, DC, CS的GPIO控制即可。将OLED的GPIO控制由STM32 HAL库控制更改为MM32F5270 HAL控制,修改代码如下:
    MM32F5270的oled.h

    #ifndef __OLED_H
    #define __OLED_H 
    
    #include "type_def.h"
    
    #define USE_HORIZONTAL 1  //设置显示方向 0:正向显示;1:旋转180度显示
    
    #define OLED_USE_SOFT_SPI 0
    
    
    void OLED_control_gpio_init(void);
    
    void OLED_WR_REG(u8 reg);
    void OLED_WR_Byte(u8 dat);
    void Column_Address(u8 a,u8 b);
    void Row_Address(u8 a,u8 b);
    void OLED_Fill(u16 xstr,u8 ystr,u16 xend,u8 yend,u8 color);
    void OLED_ShowChinese(u8 x,u8 y,u8 *s,u8 sizey,u8 mode);
    void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 sizey,u8 mode);
    void OLED_ShowString(u8 x,u8 y,u8 *dp,u8 sizey,u8 mode);
    u32 oled_pow(u8 m,u8 n);
    void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 sizey,u8 mode);
    void OLED_DrawBMP(u8 x,u8 y,u16 length,u8 width,const u8 BMP[],u8 mode);
    void OLED_DrawSingleBMP(u8 x,u8 y,u16 length,u8 width,const u8 BMP[],u8 mode);
    void OLED_Init(void);
    
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    MM32F5270的oled.c

    #include "oledfont.h"
    #include "delay.h"
    #include "oled.h"
    #include "demo_spi.h"
    #include "hal_rcc.h"
    #include "hal_gpio.h"
    #include "stdio.h"
    
    ~~*void OLEDcontrolgpioinit(void)
    {
        //GPIOA
        RCCEnableAHB1Periphs(RCCAHB1PERIPHGPIOA, true);
        RCCResetAHB1Periphs(RCCAHB1PERIPHGPIOA);
    #if OLEDUSESOFTSPI
        RCCEnableAHB1Periphs(RCCAHB1PERIPHGPIOC, true);
        RCCResetAHB1Periphs(RCCAHB1PERIPHGPIOC);
    #endif
    
        GPIOInitType gpioinit;
    
        //RES PA10
        gpioinit.Pins  = GPIOPIN10;
        gpioinit.PinMode  = GPIOPinModeOutPushPull;
        gpioinit.Speed = GPIOSpeed50MHz;
        GPIOInit(GPIOA, &gpioinit);
    
        //DC PA12
        gpioinit.Pins  = GPIOPIN12;
        gpioinit.PinMode  = GPIOPinModeOutPushPull;
        gpioinit.Speed = GPIOSpeed50MHz;
        GPIOInit(GPIOA, &gpioinit);
    
        //CS PA15
        gpioinit.Pins  = GPIOPIN15;
        gpioinit.PinMode  = GPIOPinModeOutPushPull;
        gpioinit.Speed = GPIOSpeed50MHz;
        GPIOInit(GPIOA, &gpioinit);
    
    #if OLEDUSESOFTSPI
        //soft SCL PC10
        gpioinit.Pins  = GPIOPIN10;
        gpioinit.PinMode  = GPIOPinModeOutPushPull;
        gpioinit.Speed = GPIOSpeed50MHz;
        GPIOInit(GPIOC, &gpioinit);
    
        //soft MOSI PC12
        gpioinit.Pins  = GPIOPIN12;
        gpioinit.PinMode  = GPIOPinModeOutPushPull;
        gpioinit.Speed = GPIOSpeed50MHz;
        GPIOInit(GPIOC, &gpioinit);
    #endif
    
    }
    
    #if OLEDUSESOFTSPI
    static void OLEDSOFTSPISCKClr()
    {
        GPIOWriteBit(GPIOC, GPIOPIN10, 0u); //RES
    }
    
    static void OLEDSOFTSPISCKSet()
    {
        GPIOWriteBit(GPIOC, GPIOPIN10, 1u); //RES
    }
    
    static void OLEDSOFTSPISDAClr()
    {
        GPIOWriteBit(GPIOC, GPIOPIN12, 0u); //RES
    }
    
    
    static void OLEDSOFTSPISDASet()
    {
        GPIOWriteBit(GPIOC, GPIOPIN12, 1u); //RES
    }
    
    #endif
    static void OLEDRESClr()
    {
        GPIOWriteBit(GPIOA, GPIOPIN10, 0u); //RES
    }
    
    static void OLEDRESSet()
    {
        GPIOWriteBit(GPIOA, GPIOPIN10, 1u); //RES
    }
    
    static void OLEDDCClr()
    {
        GPIOWriteBit(GPIOA, GPIOPIN12, 0u); //RES
    }
    
    static void OLEDDCSet()
    {
        GPIOWriteBit(GPIOA, GPIOPIN12, 1u); //RES
    }
    
    static void OLEDCSClr()
    {
        GPIOWriteBit(GPIOA, GPIOPIN15, 0u); //RES
    }*~~
    
    static void OLED_CS_Set()
    {
        GPIO_WriteBit(GPIOA, GPIO_PIN_15, 1u); //RES
    }
    
    static void OLED_Write_Byte(u8 dat)
    {
    #if OLED_USE_SOFT_SPI
        u8 i;
        for(i=0;i<8;i++)
        {              
            OLED_SOFT_SPI_SCK_Clr();
            //delay_us(20);
            if(dat&0x80)
            {
               OLED_SOFT_SPI_SDA_Set();
            }
            else 
            {
               OLED_SOFT_SPI_SDA_Clr();
            }
            //delay_us(20);
            OLED_SOFT_SPI_SCK_Set();
            //delay_us(200);
            dat<<=1;   
        }
    #else
        spi3_putbyte(dat);
    #endif
    }
    
    void OLED_WR_Bus(u8 dat)
    {
        OLED_CS_Clr();
        OLED_Write_Byte(dat);
        OLED_CS_Set();
    }
    
    void OLED_WR_REG(u8 reg)
    {      
        OLED_DC_Clr();          
        OLED_WR_Bus(reg);
        OLED_DC_Set();    
    }
    
    void OLED_WR_Byte(u8 dat)
    {      
      OLED_WR_Bus(dat);
    }
    
    void Column_Address(u8 a,u8 b)
    {
        OLED_WR_REG(0x15);       // Set Column Address
        OLED_WR_Byte(0x1c+a);
        OLED_WR_Byte(0x1c+b);
    }
    
    void Row_Address(u8 a,u8 b)
    {
        OLED_WR_REG(0x75);       // Row Column Address
        OLED_WR_Byte(a);
        OLED_WR_Byte(b);
        OLED_WR_REG(0x5C);    //写RAM命令
    }
    
    void OLED_Fill(u16 xstr,u8 ystr,u16 xend,u8 yend,u8 color)
    {
        u8 x,y;
        xstr/=4;
        xend/=4;
        Column_Address(xstr,xend-1);
        Row_Address(ystr,yend-1);
        for(x=xstr;x
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    • 385
    • 386
    • 387
    • 388
    • 389
    • 390
    • 391
    • 392
    • 393
    • 394
    • 395
    • 396
    • 397
    • 398

    对应只需要改动几个控制GPIO的具体实现,可以非常快速的进行移植

    1. 最后放上main函数,在main函数里要对用到的各个硬件做初始化,代码如下:

      /*
      * Copyright 2021 MindMotion Microelectronics Co., Ltd.
      * All rights reserved.
      *
      * SPDX-License-Identifier: BSD-3-Clause
      */

      #include
      #include
      #include “clock_init.h”
      #include “demo_uart.h”
      #include “conv_timer.h”
      #include “demo_spi.h”
      #include “led.h”
      #include “delay.h”
      #include “oled.h”
      /*
      * Functions.
      */

      int main(void)
      {
      BOARD_InitBootClocks();
      timer1_init();
      uart1_init();
      #if !OLED_USE_SOFT_SPI
      spi3_init();
      #endif
      led_init();

      OLED_control_gpio_init();
      OLED_Init();
      //OLED_ShowString(0, 0, “hello world”, 16, 0);
      printf(“\r\ntim_basic example.\r\n”);

      timer1_start();
      led_off(LED4);
      led_off(LED5);

      while (1)
      {
      //spi3_putbyte(0xaa);
      led_on(LED4);
      delay_1ms();
      led_off(LED4);
      delay_1ms();
      OLED_ShowString(0, 0, " ARM STAR-MC1 MM32F5270", 16, 0);
      OLED_ShowString(0, 16, " aijishu", 16, 0);
      OLED_ShowString(0, 32, “https://aijishu.com”, 16, 0);

      }
      }

      /* EOF. */

      显示效果如图所示:

    四 总结

    MindSDK已经提供了封装良好的驱动代码,能够非常方便的做开发,对于STM32平台的应用,能够非常快速的进行移植,所需要的工作量非常小。
    STM32CubeMX只是提供了一个可视化的配置界面,但是其生成的代码对于一些比较大型的项目来说,其组织形式和代码复用性相比MindSDK并不会有优势。

    MindSDK目前提供的轮子,已经能够应付一些基本需求。但是目前,MindSDK缺乏对FreeRTOS,RTThread等RTOS的支持。如果官方能够解决RTOS的问题,相信我们能够基于MindSDK用MM32F5230作出更多有趣的应用。

    五 参考链接

    【灵动官网】PLUS-F5270开发板介绍(含资料链接):https://www.mindmotion.com.cn…
    【灵动官网】MM32F5270芯片介绍(含资料链接):https://www.mindmotion.com.cn…
    【极术社区】基于灵动MM32F5系列芯片的PLUS-F5270开发板资料(包含逐飞科技网盘链接):https://aijishu.com/a/1060000…
    【极术社区】[MM32F5270开发板试用] 基本开发环境搭建篇:https://aijishu.com/a/1060000…
    【极术社区】带灵动微MM32F5的Plus-F5270开发板怎么玩?https://aijishu.com/a/1060000…

  • 相关阅读:
    GitHub 披露宕机原因;谷歌前 AI 研究员被解雇后成立独立研究所;常用 Linux 桌面版排行榜出炉 | 开源日报
    改变滚动条样式
    [vue] element的表格fixed悬浮固定列错乱的官方解决办法
    数字花园的指南针:微信小程序排名的提升之道
    g2o的hessian矩阵、b怎么存储
    记录一次阿里云ECS服务器系统盘扩容
    从壹开始前后端开发【.Net6+Vue3】
    java计算机毕业设计高校科研信息管理系统MyBatis+系统+LW文档+源码+调试部署
    Scala技术与架构-1
    每日五道java面试题之spring篇(九)
  • 原文地址:https://blog.csdn.net/weixin_47569031/article/details/127366610