Victorlsx · 2 天前

【Mini-F5375-OB开发板评测】软件I2C驱动OLED显示屏实践

本文介绍了使用Mini-F5375-OB开发板通过GPIO引脚模拟I2C协议,驱动0.96寸的OLED显示屏。为后续PID调参以及MPU6050驱动提供可视化功能。

一、硬件平台

  1. 开发板: Mini-F5375-OB
  2. 主控MCU: MM32F5375G8PV

    • SYSCLK Frequency : 150.000 MHz
    • HCLK Frequency : 150.000 MHz
    • PCLK1 Frequency : 150.000 MHz
    • PCLK2 Frequency : 150.000 MHz
  3. OLED模块:

    • 尺寸: 0.96英寸
    • 分辨率: 128x64
    • 驱动IC: SSD1306
    • 接口: I2C
  4. 硬件连接:

    • OLED VCC -> 开发板 3.3V
    • OLED GND -> 开发板 GND
    • OLED SCL -> 开发板 B8
    • OLED SDA -> 开发板 B9

二、软件环境

  • IDE: Keil MDK-ARM V5.41.0.0
  • 固件库: LibSamples_MM32F5370_V0.10.3

三、核心实现: 软件模拟I2C

老规矩,先上核心代码(Talk is cheap. Show me the code.)

oled.h

#ifndef __OLED_H
#define __OLED_H

#ifdef __cplusplus
extern "C" {
#endif

/* Files include */
#include "hal_conf.h"

/**
  * @addtogroup OLED_Driver
  * @{
  */

/* Exported types *****************************************************************************************************/

/* Exported constants *************************************************************************************************/

/* OLED I2C Pin Configuration */
#define OLED_SCL_GPIO_PORT         GPIOB
#define OLED_SCL_GPIO_PIN          GPIO_Pin_8
#define OLED_SCL_GPIO_CLK()        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE)

#define OLED_SDA_GPIO_PORT         GPIOB  
#define OLED_SDA_GPIO_PIN          GPIO_Pin_9
#define OLED_SDA_GPIO_CLK()        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE)

/* OLED I2C Pin Control Macros */
#define OLED_W_SCL(x)              GPIO_WriteBit(OLED_SCL_GPIO_PORT, OLED_SCL_GPIO_PIN, (BitAction)(x))
#define OLED_W_SDA(x)              GPIO_WriteBit(OLED_SDA_GPIO_PORT, OLED_SDA_GPIO_PIN, (BitAction)(x))

/* OLED Device Address */
#define OLED_ADDRESS               0x78    /* OLED I2C address (8-bit format) */

/* Exported macro *****************************************************************************************************/

/* Exported variables *************************************************************************************************/

/* Exported functions *************************************************************************************************/

/* OLED Basic Functions */
void OLED_Init(void);
void OLED_Clear(void);

/* OLED Display Functions */
void OLED_ShowChar(uint8_t Line, uint8_t Column, char Char);
void OLED_ShowString(uint8_t Line, uint8_t Column, char *String);
void OLED_ShowNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length);
void OLED_ShowSignedNum(uint8_t Line, uint8_t Column, int32_t Number, uint8_t Length);
void OLED_ShowHexNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length);
void OLED_ShowBinNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length);

/* OLED Low Level Functions */
void OLED_I2C_Init(void);
void OLED_I2C_Start(void);
void OLED_I2C_Stop(void);
void OLED_I2C_SendByte(uint8_t Byte);
void OLED_WriteCommand(uint8_t Command);
void OLED_WriteData(uint8_t Data);
void OLED_SetCursor(uint8_t Y, uint8_t X);

#ifdef __cplusplus
}
#endif

#endif /* __OLED_H */

oled.c

#include "oled.h"
#include "oled_font.h"

/***********************************************************************************************************************
  * @brief  Initialize OLED I2C GPIO pins
  * @note   Configure GPIO pins for software I2C communication
  * @param  None
  * @retval None
  *********************************************************************************************************************/
void OLED_I2C_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;

    /* Enable GPIO clocks */
    OLED_SCL_GPIO_CLK();
    OLED_SDA_GPIO_CLK();

    /* Configure SCL pin as open-drain output */
    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_Out_OD;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
    GPIO_InitStruct.GPIO_Pin   = OLED_SCL_GPIO_PIN;
    GPIO_Init(OLED_SCL_GPIO_PORT, &GPIO_InitStruct);

    /* Configure SDA pin as open-drain output */
    GPIO_InitStruct.GPIO_Pin = OLED_SDA_GPIO_PIN;
    GPIO_Init(OLED_SDA_GPIO_PORT, &GPIO_InitStruct);

    /* Set both pins to high (idle state) */
    OLED_W_SCL(1);
    OLED_W_SDA(1);
}

/***********************************************************************************************************************
  * @brief  Generate I2C start condition
  * @note   SDA transitions from high to low while SCL is high
  * @param  None
  * @retval None
  *********************************************************************************************************************/
void OLED_I2C_Start(void)
{
    OLED_W_SDA(1);
    OLED_W_SCL(1);
    OLED_W_SDA(0);
    OLED_W_SCL(0);
}

/***********************************************************************************************************************
  * @brief  Generate I2C stop condition
  * @note   SDA transitions from low to high while SCL is high
  * @param  None
  * @retval None
  *********************************************************************************************************************/
void OLED_I2C_Stop(void)
{
    OLED_W_SDA(0);
    OLED_W_SCL(1);
    OLED_W_SDA(1);
}

/***********************************************************************************************************************
  * @brief  Send one byte via I2C
  * @note   Send 8 bits of data, MSB first
  * @param  Byte: The byte to send
  * @retval None
  *********************************************************************************************************************/
void OLED_I2C_SendByte(uint8_t Byte)
{
    uint8_t i;
    
    for (i = 0; i < 8; i++)
    {
        OLED_W_SDA(Byte & (0x80 >> i));
        OLED_W_SCL(1);
        OLED_W_SCL(0);
    }
    
    /* Extra clock for ACK (not handled) */
    OLED_W_SCL(1);
    OLED_W_SCL(0);
}

/***********************************************************************************************************************
  * @brief  Write command to OLED
  * @note   Send command byte to OLED controller
  * @param  Command: Command byte to send
  * @retval None
  *********************************************************************************************************************/
void OLED_WriteCommand(uint8_t Command)
{
    OLED_I2C_Start();
    OLED_I2C_SendByte(OLED_ADDRESS);    /* Device address */
    OLED_I2C_SendByte(0x00);            /* Command mode */
    OLED_I2C_SendByte(Command);         /* Command byte */
    OLED_I2C_Stop();
}

/***********************************************************************************************************************
  * @brief  Write data to OLED
  * @note   Send data byte to OLED display RAM
  * @param  Data: Data byte to send
  * @retval None
  *********************************************************************************************************************/
void OLED_WriteData(uint8_t Data)
{
    OLED_I2C_Start();
    OLED_I2C_SendByte(OLED_ADDRESS);    /* Device address */
    OLED_I2C_SendByte(0x40);            /* Data mode */
    OLED_I2C_SendByte(Data);            /* Data byte */
    OLED_I2C_Stop();
}

/***********************************************************************************************************************
  * @brief  Set cursor position on OLED
  * @note   Set the current position for subsequent write operations
  * @param  Y: Page address (0-7)
  * @param  X: Column address (0-127)
  * @retval None
  *********************************************************************************************************************/
void OLED_SetCursor(uint8_t Y, uint8_t X)
{
    X += 2;  /* Adjust for display offset */
    OLED_WriteCommand(0xB0 | Y);                        /* Set page address */
    OLED_WriteCommand(0x10 | ((X & 0xF0) >> 4));        /* Set column high 4 bits */
    OLED_WriteCommand(0x02 | (X & 0x0F));               /* Set column low 4 bits */
}

/***********************************************************************************************************************
  * @brief  Clear OLED display
  * @note   Fill entire display with zeros (black)
  * @param  None
  * @retval None
  *********************************************************************************************************************/
void OLED_Clear(void)
{
    uint8_t i, j;
    
    for (j = 0; j < 8; j++)
    {
        OLED_SetCursor(j, 0);
        for (i = 0; i < 132; i++)
        {
            OLED_WriteData(0x00);
        }
    }
}

/***********************************************************************************************************************
  * @brief  Display single character on OLED
  * @note   Display one character using 8x16 font
  * @param  Line: Line position (1-4)
  * @param  Column: Column position (1-16)
  * @param  Char: Character to display
  * @retval None
  *********************************************************************************************************************/
void OLED_ShowChar(uint8_t Line, uint8_t Column, char Char)
{
    uint8_t i;
    
    /* Display upper half of character */
    OLED_SetCursor((Line - 1) * 2, (Column - 1) * 8);
    for (i = 0; i < 8; i++)
    {
        OLED_WriteData(OLED_F8x16[Char - ' '][i]);
    }
    
    /* Display lower half of character */
    OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 8);
    for (i = 0; i < 8; i++)
    {
        OLED_WriteData(OLED_F8x16[Char - ' '][i + 8]);
    }
}

/***********************************************************************************************************************
  * @brief  Display string on OLED
  * @note   Display multiple characters starting from specified position
  * @param  Line: Starting line position (1-4)
  * @param  Column: Starting column position (1-16)
  * @param  String: String to display
  * @retval None
  *********************************************************************************************************************/
void OLED_ShowString(uint8_t Line, uint8_t Column, char *String)
{
    uint8_t i;
    
    for (i = 0; String[i] != '\0'; i++)
    {
        OLED_ShowChar(Line, Column + i, String[i]);
    }
}

/***********************************************************************************************************************
  * @brief  Power function for number display
  * @note   Calculate X to the power of Y
  * @param  X: Base number
  * @param  Y: Exponent
  * @retval Result of X^Y
  *********************************************************************************************************************/
uint32_t OLED_Pow(uint32_t X, uint32_t Y)
{
    uint32_t Result = 1;
    
    while (Y--)
    {
        Result *= X;
    }
    
    return Result;
}

/***********************************************************************************************************************
  * @brief  Display decimal number on OLED
  * @note   Display positive decimal number with specified length
  * @param  Line: Line position (1-4)
  * @param  Column: Starting column position (1-16)
  * @param  Number: Number to display (0-4294967295)
  * @param  Length: Number of digits to display (1-10)
  * @retval None
  *********************************************************************************************************************/
void OLED_ShowNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
{
    uint8_t i;
    
    for (i = 0; i < Length; i++)
    {
        OLED_ShowChar(Line, Column + i, Number / OLED_Pow(10, Length - i - 1) % 10 + '0');
    }
}

/***********************************************************************************************************************
  * @brief  Display signed decimal number on OLED
  * @note   Display signed decimal number with specified length
  * @param  Line: Line position (1-4)
  * @param  Column: Starting column position (1-16)
  * @param  Number: Number to display (-2147483648 to 2147483647)
  * @param  Length: Number of digits to display (1-10)
  * @retval None
  *********************************************************************************************************************/
void OLED_ShowSignedNum(uint8_t Line, uint8_t Column, int32_t Number, uint8_t Length)
{
    uint8_t i;
    uint32_t Number1;
    
    if (Number >= 0)
    {
        OLED_ShowChar(Line, Column, '+');
        Number1 = Number;
    }
    else
    {
        OLED_ShowChar(Line, Column, '-');
        Number1 = -Number;
    }
    
    for (i = 0; i < Length; i++)
    {
        OLED_ShowChar(Line, Column + i + 1, Number1 / OLED_Pow(10, Length - i - 1) % 10 + '0');
    }
}

/***********************************************************************************************************************
  * @brief  Display hexadecimal number on OLED
  * @note   Display positive hexadecimal number with specified length
  * @param  Line: Line position (1-4)
  * @param  Column: Starting column position (1-16)
  * @param  Number: Number to display (0-0xFFFFFFFF)
  * @param  Length: Number of digits to display (1-8)
  * @retval None
  *********************************************************************************************************************/
void OLED_ShowHexNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
{
    uint8_t i, SingleNumber;
    
    for (i = 0; i < Length; i++)
    {
        SingleNumber = Number / OLED_Pow(16, Length - i - 1) % 16;
        if (SingleNumber < 10)
        {
            OLED_ShowChar(Line, Column + i, SingleNumber + '0');
        }
        else
        {
            OLED_ShowChar(Line, Column + i, SingleNumber - 10 + 'A');
        }
    }
}

/***********************************************************************************************************************
  * @brief  Display binary number on OLED
  * @note   Display positive binary number with specified length
  * @param  Line: Line position (1-4)
  * @param  Column: Starting column position (1-16)
  * @param  Number: Number to display (0-65535)
  * @param  Length: Number of bits to display (1-16)
  * @retval None
  *********************************************************************************************************************/
void OLED_ShowBinNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
{
    uint8_t i;
    
    for (i = 0; i < Length; i++)
    {
        OLED_ShowChar(Line, Column + i, Number / OLED_Pow(2, Length - i - 1) % 2 + '0');
    }
}

/***********************************************************************************************************************
  * @brief  Initialize OLED display
  * @note   Initialize OLED controller and clear display
  * @param  None
  * @retval None
  *********************************************************************************************************************/
void OLED_Init(void)
{
    uint32_t i, j;

    /* Power-on delay */
    for (i = 0; i < 1000; i++)
    {
        for (j = 0; j < 1000; j++);
    }

    /* Initialize I2C GPIO */
    OLED_I2C_Init();

    /* OLED initialization sequence */
    OLED_WriteCommand(0xAE);    /* Display off */

    OLED_WriteCommand(0x02);    /* Set display start column */
    OLED_WriteCommand(0x10);

    OLED_WriteCommand(0xD5);    /* Set display clock divide ratio/oscillator frequency */
    OLED_WriteCommand(0x80);

    OLED_WriteCommand(0xA8);    /* Set multiplex ratio */
    OLED_WriteCommand(0x3F);

    OLED_WriteCommand(0xD3);    /* Set display offset */
    OLED_WriteCommand(0x00);

    OLED_WriteCommand(0x40);    /* Set display start line */

    OLED_WriteCommand(0xA1);    /* Set segment re-map (0xA1 normal, 0xA0 reversed) */

    OLED_WriteCommand(0xC8);    /* Set COM output scan direction (0xC8 normal, 0xC0 reversed) */

    OLED_WriteCommand(0xDA);    /* Set COM pins hardware configuration */
    OLED_WriteCommand(0x12);

    OLED_WriteCommand(0x81);    /* Set contrast control */
    OLED_WriteCommand(0xCF);

    OLED_WriteCommand(0xD9);    /* Set pre-charge period */
    OLED_WriteCommand(0xF1);

    OLED_WriteCommand(0xDB);    /* Set VCOMH deselect level */
    OLED_WriteCommand(0x30);

    OLED_WriteCommand(0xA4);    /* Set entire display on/off */

    OLED_WriteCommand(0xA6);    /* Set normal/inverse display */

    OLED_WriteCommand(0x8D);    /* Set charge pump */
    OLED_WriteCommand(0x14);

    OLED_WriteCommand(0xAF);    /* Display on */

    OLED_Clear();               /* Clear display */
}

这里应该就能看出是参考的江协的OLED驱动,所以接下来的oled_font.h文件就参考江协的同名文件,这里不贴出了。

main.c

main.c文件这里就给出核心的几个测试代码,用于测试OLED的显示功能。每个测试单元都写了相关注释,而且烧录进开发板后能直观的看到效果,所以就不进行逐行解释了。

/* Private functions **************************************************************************************************/
static void Test_OLED_Basic(void);
static void Test_OLED_Numbers(void);
static void Test_OLED_Animation(void);
static void Test_OLED_RealTime(void);
static void Print_Welcome_Info(void);
static void Delay_Ms(uint32_t ms);

/***********************************************************************************************************************
  * @brief  Simple millisecond delay
  * @param  ms: Delay time in milliseconds
  * @retval None
  *********************************************************************************************************************/
static void Delay_Ms(uint32_t ms)
{
    PLATFORM_DelayMS(ms);
}

/***********************************************************************************************************************
  * @brief  Print welcome information
  * @param  None
  * @retval None
  *********************************************************************************************************************/
static void Print_Welcome_Info(void)
{
    printf("\r\n");
    printf("==============================================\r\n");
    printf("    MM32F5370 软件I2C OLED 测试程序\r\n");
    printf("==============================================\r\n");
    printf("硬件连接:\r\n");
    printf("  OLED SCL -> PB8\r\n");
    printf("  OLED SDA -> PB9\r\n");
    printf("  OLED VCC -> 3.3V\r\n");
    printf("  OLED GND -> GND\r\n");
    printf("==============================================\r\n");
}

/***********************************************************************************************************************
  * @brief  Test OLED basic display functions
  * @param  None
  * @retval None
  *********************************************************************************************************************/
static void Test_OLED_Basic(void)
{
    printf("测试1: OLED基础显示功能\r\n");
    
    /* 清屏并显示标题 */
    OLED_Clear();
    OLED_ShowString(1, 1, "OLED Basic Test");
    Delay_Ms(1000);
    
    /* 字符串显示测试 */
    OLED_Clear();
    OLED_ShowString(1, 1, "String Test:");
    OLED_ShowString(2, 1, "Hello World!");
    OLED_ShowString(3, 1, "MM32F5370");
    OLED_ShowString(4, 1, "Software I2C");
    Delay_Ms(2000);
    
    /* 字符显示测试 */
    OLED_Clear();
    OLED_ShowString(1, 1, "Char Test:");
    OLED_ShowString(2, 1, "!@#$%^&*()");
    OLED_ShowString(3, 1, "0123456789");
    OLED_ShowString(4, 1, "ABCDEFGHIJ");
    Delay_Ms(2000);
    
    printf("测试1完成\r\n");
}

/***********************************************************************************************************************
  * @brief  Test OLED number display functions
  * @param  None
  * @retval None
  *********************************************************************************************************************/
static void Test_OLED_Numbers(void)
{
    printf("测试2: OLED数字显示功能\r\n");
    
    /* 数字显示测试 */
    OLED_Clear();
    OLED_ShowString(1, 1, "Number Test:");
    OLED_ShowString(2, 1, "Dec: ");
    OLED_ShowNum(2, 6, 12345, 5);
    OLED_ShowString(3, 1, "Hex: ");
    OLED_ShowHexNum(3, 6, 0xABCD, 4);
    OLED_ShowString(4, 1, "Bin: ");
    OLED_ShowBinNum(4, 6, 0b11010110, 8);
    Delay_Ms(2000);
    
    /* 有符号数测试 */
    OLED_Clear();
    OLED_ShowString(1, 1, "Signed Test:");
    OLED_ShowString(2, 1, "Positive: ");
    OLED_ShowSignedNum(2, 11, 123, 3);
    OLED_ShowString(3, 1, "Negative: ");
    OLED_ShowSignedNum(3, 11, -456, 3);
    OLED_ShowString(4, 1, "Zero:     ");
    OLED_ShowSignedNum(4, 11, 0, 1);
    Delay_Ms(2000);
    
    printf("测试2完成\r\n");
}

/***********************************************************************************************************************
  * @brief  Test OLED animation effects
  * @param  None
  * @retval None
  *********************************************************************************************************************/
static void Test_OLED_Animation(void)
{
    uint8_t i, j;
    uint8_t percent;
    
    printf("测试3: OLED动画效果\r\n");
    
    /* 计数器动画 */
    OLED_Clear();
    OLED_ShowString(1, 1, "Counter Test:");
    OLED_ShowString(2, 1, "Count: ");
    OLED_ShowString(3, 1, "Time:  ");
    
    for (i = 0; i < 30; i++)
    {
        OLED_ShowNum(2, 8, i, 2);
        OLED_ShowNum(3, 8, i, 2);
        OLED_ShowChar(3, 10, '.');
        OLED_ShowNum(3, 11, (i * 10) % 10, 1);
        OLED_ShowChar(3, 12, 's');
        
        /* LED指示 */
        PLATFORM_LED_Toggle(LED2);
        Delay_Ms(200);
    }
    
    /* 进度条动画 */
    OLED_Clear();
    OLED_ShowString(1, 1, "Progress Bar:");
    OLED_ShowString(2, 1, "Loading...");
    OLED_ShowString(3, 1, "[          ]");
    OLED_ShowString(4, 1, "0%");
    
    for (i = 0; i <= 10; i++)
    {
        /* 更新进度条 */
        for (j = 0; j < i; j++)
        {
            OLED_ShowChar(3, 2 + j, '#');
        }
        
        /* 更新百分比 */
        percent = i * 10;
        if (percent == 100)
        {
            OLED_ShowString(4, 1, "100%");
        }
        else
        {
            OLED_ShowNum(4, 1, percent, 2);
            OLED_ShowChar(4, 3, '%');
        }
        
        Delay_Ms(300);
    }
    
    OLED_ShowString(2, 1, "Complete! ");
    Delay_Ms(1000);
    
    printf("测试3完成\r\n");
}

/***********************************************************************************************************************
  * @brief  Test OLED real-time display
  * @param  None
  * @retval None
  *********************************************************************************************************************/
static void Test_OLED_RealTime(void)
{
    uint32_t counter;
    uint32_t loop_count;
    char anim_chars[] = {'|', '/', '-', '\\'};
    
    printf("测试4: OLED实时显示(40次循环)\r\n");
    
    counter = 0;
    loop_count = 40; /* 循环40次 */
    
    while (counter < loop_count)
    {
        OLED_Clear();
        OLED_ShowString(1, 1, "Real-Time Test");
        
        /* 显示循环次数 */
        OLED_ShowString(2, 1, "Loop: ");
        OLED_ShowNum(2, 7, counter + 1, 2);
        OLED_ShowChar(2, 9, '/');
        OLED_ShowNum(2, 10, loop_count, 2);
        
        /* 显示计数器 */
        OLED_ShowString(3, 1, "Count: ");
        OLED_ShowNum(3, 8, counter, 3);
        
        /* 显示动画字符 */
        OLED_ShowString(4, 1, "Status: ");
        OLED_ShowChar(4, 9, anim_chars[counter % 4]);
        OLED_ShowString(4, 11, " OK");
        
        counter++;
        PLATFORM_LED_Toggle(LED1);
        Delay_Ms(250);
    }
    
    printf("测试4完成\r\n");
}

/***********************************************************************************************************************
  * @brief  Main function
  * @param  None
  * @retval int
  *********************************************************************************************************************/
int main(void)
{
    uint8_t init_progress;
    
    /* 系统初始化 */
    PLATFORM_Init();
    
    /* 打印欢迎信息 */
    Print_Welcome_Info();
    
    /* 初始化OLED */
    printf("正在初始化OLED...\r\n");
    OLED_Init();
    printf("OLED初始化完成!\r\n");
    
    /* 显示欢迎界面 */
    OLED_Clear();
    OLED_ShowString(1, 1, "MM32F5370 OLED");
    OLED_ShowString(2, 1, "Test Program");
    OLED_ShowString(3, 1, "Initializing");
    OLED_ShowString(4, 1, "Please wait...");
    Delay_Ms(2000);
    
    /* 显示初始化进度 */
    OLED_ShowString(4, 1, "Loading:    %");
    for (init_progress = 0; init_progress <= 100; init_progress += 20)
    {
        OLED_ShowNum(4, 9, init_progress, 3);
        Delay_Ms(500);
    }
    Delay_Ms(500);
    
    printf("\r\n开始OLED功能测试...\r\n");
    
    /* 执行OLED测试 */
    Test_OLED_Basic();      /* 基础显示测试 */
    Test_OLED_Numbers();    /* 数字显示测试 */
    Test_OLED_Animation();  /* 动画效果测试 */
    Test_OLED_RealTime();   /* 实时显示测试 */
    
    /* 测试完成 */
    printf("\r\n所有测试完成!\r\n");
    OLED_Clear();
    OLED_ShowString(1, 1, "All Tests");
    OLED_ShowString(2, 1, "Completed!");
    OLED_ShowString(3, 1, "OLED Working");
    OLED_ShowString(4, 1, "Successfully!");
    
    printf("程序进入主循环,LED1闪烁表示正常运行\r\n");
    printf("==============================================\r\n");
    
    /* 主循环 */
    while (1)
    {
        PLATFORM_LED_Toggle(LED1);
        Delay_Ms(1000);
    }
}

注意我这里在主循环中调用了LED1的闪烁功能,开发板上的LED1LED2所接引脚为PB15PB14,所以需要修改官方提供的平台化文件里关于LED的定义

platform.h

/* Exported types *****************************************************************************************************/
typedef enum
{
    LED1,
    LED2
} LEDn_TypeDef;

platform.c

/***********************************************************************************************************************
  * @brief  LED on or off
  * @note   none
  * @param  LEDn : LED index
  * @arg    LED1, LED2
  * @param  State
  * @arg    ENABLE, DISABLE
  * @retval none
  *********************************************************************************************************************/
void PLATFORM_LED_Enable(LEDn_TypeDef LEDn, FunctionalState State)
{
    switch (LEDn)
    {
        case LED1:
            GPIO_WriteBit(GPIOB, GPIO_Pin_15, (ENABLE == State) ? Bit_RESET : Bit_SET);
            break;

        case LED2:
            GPIO_WriteBit(GPIOB, GPIO_Pin_14, (ENABLE == State) ? Bit_RESET : Bit_SET);
            break;
        default:
            break;
    }
}

/***********************************************************************************************************************
  * @brief  Initialize LED GPIO pin
  * @note   none
  * @param  none
  * @retval none
  *********************************************************************************************************************/
void PLATFORM_InitLED(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);

    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_14 | GPIO_Pin_15;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
    GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOB, &GPIO_InitStruct);

    PLATFORM_LED_Enable(LED1, ENABLE);
    PLATFORM_LED_Enable(LED2, ENABLE);
}

/***********************************************************************************************************************
  * @brief  LED toggle display
  * @note   none
  * @param  LEDn : LED index
  * @arg    LED1, LED2
  * @retval none
  *********************************************************************************************************************/
void PLATFORM_LED_Toggle(LEDn_TypeDef LEDn)
{
    switch (LEDn)
    {
        case LED1:
            GPIO_WriteBit(GPIOB, GPIO_Pin_15, GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_15) ? Bit_RESET : Bit_SET);
            break;

        case LED2:
            GPIO_WriteBit(GPIOB, GPIO_Pin_14, GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_14) ? Bit_RESET : Bit_SET);
            break;
        
        default:
            break;
    }
}

驱动效果

测试功能包含了基础显示测试数字显示测试动画效果测试实时显示测试,具体效果展示时间过长,后续将发布在B站上。

评测总结

最近项目Deadline将至,这两篇文章是抽时间出来写的,难免会有些纰漏。并且没有测试最主要的MindPWM功能,后续会深入使用这款板子的电机控制功能。
在使用这块板子的时候发现官方封装的库函数还挺多,但具体使用需要花时间去看例程和以及源代码实现,可能是没找到库函数的文档,导致做了些重复的工作;并且开发板的引脚有很多复用功能,合理分配的话可以作为复杂工程的主控板。
这篇文章最开始是想测试硬件I2C的极限,移植U8G2或者LVGL库做几个界面,后续实现多个功能之间的切换,并且无刷电机和驱动板都准备好了,步进电机和驱动板也购买了,为了对比电机控制的功能,也购买了STM32G431CBU6开发板,但时间紧张先立个flag在这吧。

推荐阅读
关注数
711
内容数
29
搭载安谋科技自研“星辰”STAR-MC1处理器,基于Armv8-M架构,专为电机控制、数字能源等实时控制应用打造
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息