1511|1

20

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

[N32L43X评测] 4.模拟SPI驱动OLED [复制链接]

 

前两篇[N32L43X评测] 2.模拟I2C驱动OLED [N32L43X评测] 3.硬件I2C驱动OLED介绍了I2C总线驱动OLED显示屏,此篇介绍SPI串行总线驱动OLED显示屏。

SPI是一种高速、全双工、同步串行总线,SPI与I2C对比:

    SPI是全双工,I2C是半双工

    SPI只能有一个主机,I2C支持多主机多从机

    I2C占用更少的GPIO,更节省资源
    SPI的数据位宽更灵活,可以根据需要选择多位数数据宽度
    SPI协议没有响应机制,主机无法得知从机是否接收到所发的数据,需采用一些方法来防止数据丢帧
    SPI协议可以做到非常高的速率,每一个SCLK都可以进行数据的传输,通过引入CRC等校验方法,可以即高速传输数据,又能保持数据的准确度
    I2C通过器件地址来选择从机,从机数量的增加不会导致GPIO的增加,而SPI通过CS片选信号选择从机,每增加一个从机就要多占用一个GPIO;也可以通过加入译码器来实现多从机控制
    SPI、I2C都应用于板内器件短距离通讯

SPI总线详解可参考:

SPI Block Guide V04.01.pdf (428.89 KB, 下载次数: 1)

此篇主要介绍GPIO软件模拟实现SPI来驱动0.96寸OLED显示屏

硬件连接

GND ——  GND

VCC ——  3.3V

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

软件代码

SPI代码:

  • //SPI初始化
  • void SPI_Initial(void)
  • {
  • GPIO_InitType GPIO_InitStructure;
  • //根据GPIO组初始化GPIO时钟
  • RCC_EnableAPB2PeriphClk( RCC_SPI_CS | RCC_SPI_SCK | RCC_SPI_MOSI | RCC_SPI_MISO, ENABLE);
  • //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);
  • //GPIO_SCK初始化设置
  • GPIO_InitStruct(&GPIO_InitStructure);
  • GPIO_InitStructure.Pin = PIN_SPI_SCK;
  • 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_SCK, &GPIO_InitStructure);
  • //GPIO_MISO初始化设置
  • GPIO_InitStruct(&GPIO_InitStructure);
  • GPIO_InitStructure.Pin = PIN_SPI_MISO;
  • 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_Input;
  • GPIO_InitPeripheral(PORT_SPI_MISO, &GPIO_InitStructure);
  • //GPIO_MOSI初始化设置
  • GPIO_InitStruct(&GPIO_InitStructure);
  • GPIO_InitStructure.Pin = PIN_SPI_MOSI;
  • 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_MOSI, &GPIO_InitStructure);
  • SPI_CS_DISABLE;
  • SPI_SCK_HIGH;
  • SPI_MOSI_HIGH;
  • }
  • //SPI写一字节数据,TxData --- 发送的字节数据
  • void SPI_WriteByte(unsigned char TxData)
  • {
  • unsigned char cnt;
  • for(cnt = 0; cnt < 8; cnt++)
  • {
  • SPI_SCK_LOW; //时钟 - 低
  • Delay_Us(1);
  • if(TxData & 0x80) //发送数据
  • SPI_MOSI_HIGH;
  • else
  • SPI_MOSI_LOW;
  • TxData <<= 1;
  • Delay_Us(1);
  • SPI_SCK_HIGH; //时钟 - 高
  • Delay_Us(1);
  • }
  • }
  • //SPI读一字节数据,读回来的字节数据
  • unsigned char SPI_ReadByte(void)
  • {
  • unsigned char cnt;
  • unsigned char RxData = 0;
  • for(cnt = 0; cnt < 8; cnt++)
  • {
  • SPI_SCK_LOW; //时钟 - 低
  • Delay_Us(1);
  • RxData <<= 1;
  • if(SPI_MISO_READ) //读取数据
  • {
  • RxData |= 0x01;
  • }
  • SPI_SCK_HIGH; //时钟 - 高
  • Delay_Us(1);
  • }
  • return RxData;
  • }

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
  • }
  • //向设备写数据
  • 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
  • }
  • //OLED初始化
  • void OLED_Init(void)
  • {
  • #ifdef SW_I2C
  • I2C_Initial();
  • #endif
  • #ifdef SW_SPI
  • SPI_Initial();
  • OLED_SPI_GPIO_Init();
  • #endif
  • Delay_Ms(200);
  • OLED_Write_CMD(0xAE); //display off
  • OLED_Write_CMD(0x00); //set low column address
  • OLED_Write_CMD(0x10); //set high column address
  • OLED_Write_CMD(0x40); //set start line address
  • OLED_Write_CMD(0xB0); //set page address
  • OLED_Write_CMD(0x81); //contract control
  • OLED_Write_CMD(0xFF); //128
  • OLED_Write_CMD(0xA1); //set segment remap
  • OLED_Write_CMD(0xA6); //normal / reverse
  • OLED_Write_CMD(0xA8); //set multiplex ratio(1 to 64)
  • OLED_Write_CMD(0x3F); //1/32 duty
  • OLED_Write_CMD(0xC8); //Com scan direction
  • OLED_Write_CMD(0xD3); //set display offset
  • OLED_Write_CMD(0x00); //
  • OLED_Write_CMD(0xD5); //set osc division
  • OLED_Write_CMD(0x80); //
  • OLED_Write_CMD(0xD8); //set area color mode off
  • OLED_Write_CMD(0x05); //
  • OLED_Write_CMD(0xD9); //Set Pre-Charge Period
  • OLED_Write_CMD(0xF1); //
  • OLED_Write_CMD(0xDA); //set com pin configuartion
  • OLED_Write_CMD(0x12); //
  • OLED_Write_CMD(0xDB); //set Vcomh
  • OLED_Write_CMD(0x30); //
  • OLED_Write_CMD(0x8D); //set charge pump enable
  • OLED_Write_CMD(0x14); //
  • OLED_Write_CMD(0xAF); //turn on oled panel
  • }

运行测试

播放器加载失败: 未检测到Flash Player,请到安装
SW_SPI_OLED

测试代码

N32L43x_SW_SPI_OLED.zip (518.73 KB, 下载次数: 6)

 

最新回复

谢谢分享,期待后续。   详情 回复 发表于 2022-7-27 18:43
点赞 关注
 
 

回复
举报

7793

帖子

18

TA的资源

五彩晶圆(高级)

沙发
 

谢谢分享,期待后续。

个人签名

默认摸鱼,再摸鱼。2022、9、28

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

猜你喜欢
随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
有奖直播:当AI遇见仿真,会有什么样的电子行业革新之路?
首场直播:Simcenter AI 赋能电子行业研发创新
直播时间:04月15日14:00-14:50

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网 1

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表