[MCU] [N32L43X评测] 5.硬件SPI驱动OLED

805721366   2022-7-27 00:19 楼主

前面[N32L43X评测] 2.模拟I2C驱动OLED  [N32L43X评测] 3.硬件I2C驱动OLED [N32L43X评测] 4.模拟SPI驱动OLED介绍了模拟I2C、硬件I2C、模拟SPI来驱动OLED显示屏,

此篇介绍使用N32L43x硬件SPI2轮询模式来实现驱动OLED显示屏。

硬件连接

GND ——  GND

VCC ——  3.3V

DO  ——  PB13
DI  ——  PB15
RES ——  PC7
DC  ——  PC6
CS  ——  PB12

软件代码

SPI2配置参考官方例程:

配置时需注意驱动OLED,SPI模式需配置为模式3,

即空闲时SCK时钟高电平 SPI_InitStructure.CLKPOL = SPI_CLKPOL_HIGH;

采样时刻为偶数边沿采样 SPI_InitStructure.CLKPHA = SPI_CLKPHA_SECOND_EDGE;

数据传输设置为MSB最高有效位先行 SPI_InitStructure.FirstBit = SPI_FB_MSB;

如果SPI SCK时钟频率过高或过低,可设置时钟频率 SPI_InitStructure.BaudRatePres = SPI_BR_PRESCALER_256;(如果时钟频率仍过高,可设置APB2总线频率RCC_ConfigPclk2(RCC_HCLK_DIV4);)

#ifdef HW_SPI
//SPI初始化
void SPI_Initial(void)
{
    SPI_InitType SPI_InitStructure;
    GPIO_InitType GPIO_InitStructure;

    /* PCLK2 = HCLK/2 */
    RCC_ConfigPclk2(RCC_HCLK_DIV4);
    /* Enable GPIO clock for SPI_MASTER */
    RCC_EnableAPB2PeriphClk(SPI_MASTER_GPIO_CLK | RCC_APB2_PERIPH_AFIO | RCC_SPI_CS, ENABLE);
    /* Enable SPI_MASTER Periph clock */
    RCC_EnableAPB2PeriphClk(SPI_MASTER_CLK, ENABLE);

    GPIO_InitStruct(&GPIO_InitStructure);
    //GPIO_CS初始化设置
    GPIO_InitStruct(&GPIO_InitStructure);
    GPIO_InitStructure.Pin = PIN_SPI_CS;
    GPIO_InitStructure.GPIO_Slew_Rate = GPIO_Slew_Rate_High;
    GPIO_InitStructure.GPIO_Current = GPIO_DC_4mA;
    GPIO_InitStructure.GPIO_Pull = GPIO_Pull_Up;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitPeripheral(PORT_SPI_CS, &GPIO_InitStructure);
    SPI_CS_DISABLE;
    /* Configure SPI_MASTER pins: SCK and MOSI ---------------------------------*/
    /* Configure SCK and MOSI pins as Alternate Function Push Pull */
    GPIO_InitStructure.Pin        = SPI_MASTER_PIN_SCK | SPI_MASTER_PIN_MOSI;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Alternate = GPIO_AF0_SPI2;
    GPIO_InitPeripheral(SPI_MASTER_GPIO, &GPIO_InitStructure);
    /* Configure MISO pin as Input Floating  */
    GPIO_InitStructure.Pin = SPI_MASTER_PIN_MISO;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Input;
    GPIO_InitPeripheral(SPI_MASTER_GPIO, &GPIO_InitStructure);

    /* SPI_MASTER configuration ------------------------------------------------*/
    SPI_InitStructure.DataDirection = SPI_DIR_DOUBLELINE_FULLDUPLEX;
    SPI_InitStructure.SpiMode       = SPI_MODE_MASTER;
    SPI_InitStructure.DataLen       = SPI_DATA_SIZE_8BITS;
    SPI_InitStructure.CLKPOL        = SPI_CLKPOL_HIGH;
    SPI_InitStructure.CLKPHA        = SPI_CLKPHA_SECOND_EDGE;
    SPI_InitStructure.NSS           = SPI_NSS_SOFT;
    SPI_InitStructure.BaudRatePres  = SPI_BR_PRESCALER_256;
    SPI_InitStructure.FirstBit      = SPI_FB_MSB;
    SPI_InitStructure.CRCPoly       = 7;
    SPI_Init(SPI_MASTER, &SPI_InitStructure);

    /* Enable SPI_MASTER */
    SPI_Enable(SPI_MASTER, ENABLE);

}
#endif

OLED代码变更部分:

//向设备写控制命令
static void OLED_Write_CMD(unsigned char cmd)
{
    #ifdef SW_I2C
    I2C_Start();
    I2C_Send_Byte(0x78);
    I2C_Wait_Ack();
    I2C_Send_Byte(0x00);
    I2C_Wait_Ack();
    I2C_Send_Byte(cmd);
    I2C_Wait_Ack();
    I2C_Stop();
    #endif
    #ifdef HW_I2C
    unsigned char tx_buf[BUF_SIZE] = {0x00, cmd};
    i2c_master_send(tx_buf, BUF_SIZE);
    #endif
    #ifdef SW_SPI
    OLED_CS_LOW;
    OLED_DC_LOW;
    SPI_WriteByte(cmd);
    OLED_CS_HIGH;
    #endif
    #ifdef HW_SPI
    OLED_CS_LOW;
    OLED_DC_LOW;
    while (SPI_I2S_GetStatus(SPI_MASTER, SPI_I2S_TE_FLAG) == RESET);
    SPI_I2S_TransmitData(SPI_MASTER, cmd);
    while (SPI_I2S_GetStatus(SPI_MASTER, SPI_I2S_RNE_FLAG) == RESET);
    SPI_I2S_ReceiveData(SPI_MASTER);
    OLED_CS_HIGH;
    #endif
}

//向设备写数据
static void OLED_Write_Date(unsigned char date)
{
    #ifdef SW_I2C
    I2C_Start();
    I2C_Send_Byte(0x78);
    I2C_Wait_Ack();
    I2C_Send_Byte(0x40);
    I2C_Wait_Ack();
    I2C_Send_Byte(date);
    I2C_Wait_Ack();
    I2C_Stop();
    #endif
    #ifdef HW_I2C
    unsigned char tx_buf[BUF_SIZE] = {0x40, date};
    i2c_master_send(tx_buf, BUF_SIZE);
    #endif
    #ifdef SW_SPI
    OLED_CS_LOW;
    OLED_DC_HIGH;
    SPI_WriteByte(date);
    OLED_CS_HIGH;
    #endif
    #ifdef HW_SPI
    OLED_CS_LOW;
    OLED_DC_HIGH;
    while (SPI_I2S_GetStatus(SPI_MASTER, SPI_I2S_TE_FLAG) == RESET);
    SPI_I2S_TransmitData(SPI_MASTER, date);
    while (SPI_I2S_GetStatus(SPI_MASTER, SPI_I2S_RNE_FLAG) == RESET);
    SPI_I2S_ReceiveData(SPI_MASTER);
    OLED_CS_HIGH;
    #endif
}

运行测试

HW_SPI_OLED

测试代码

N32L43x_HW_SPI_OLED.zip (520.48 KB)
(下载次数: 10, 2022-7-27 00:00 上传)

 

回复评论 (6)

谢谢分享,期待后续。

默认摸鱼,再摸鱼。2022、9、28
点赞  2022-7-27 18:43
看来刷新率还是挺好的。
点赞  2022-7-29 07:13

N32L43X的主频是多少?我和国民科技无缘,总是擦肩而过

在爱好的道路上不断前进,在生活的迷雾中播撒光引
点赞  2022-7-30 20:12
引用: 秦天qintian0303 发表于 2022-7-30 20:12 N32L43X的主频是多少?我和国民科技无缘,总是擦肩而过

最高工作主频可达108MHz,很奶思的一款芯片

点赞  2022-7-30 22:35
引用: 805721366 发表于 2022-7-30 22:35 最高工作主频可达108MHz,很奶思的一款芯片

还是很不错的,不过有USB的话基本上用96M比较方便

在爱好的道路上不断前进,在生活的迷雾中播撒光引
点赞  2022-7-30 23:39

请问,那个OS_SYSTEM.c,是自己写的任务调度吗

点赞  2023-10-10 15:44
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复