市面上的开发板很少接有SPI设备,但是SPI协议在工作中经常用到。我们开发了SPI模块,上面有SPI Flash和SPI OLED。OLED就是一块显示器。
我们裸板程序会涉及两部分:
- 用GPIO模拟SPI
- 用S3C2440的SPI控制器
我们先介绍下SPI协议,硬件框架如下:
- SCK:提供时钟
- DO:作为数据输出
- DI:作为数据输入
- CS0/CS1:作为片选
同一时刻只能有一个SPI设备处于工作状态。
假设现在2440传输一个0x56数据给SPI Flash,时序如下: 首先CS0先拉低选中SPI Flash,0x56的二进制就是0b0101 0110,因此在每个SCK时钟周期,DO输出对应的电平。 SPI Flash会在每个时钟周期的上升沿读取D0上的电平。
在SPI协议中,有两个值来确定SPI的模式。 CPOL:表示SPICLK的初始电平,0为电平,1为高电平 CPHA:表示相位,即第一个还是第二个时钟沿采样数据,0为第一个时钟沿,1为第二个时钟沿
CPOLCPHA模式含义000初始电平为低电平,在第一个时钟沿采样数据011初始电平为低电平,在第二个时钟沿采样数据102初始电平为高电平,在第一个时钟沿采样数据113初始电平为高电平,在第二个时钟沿采样数据我们常用的是模式0和模式3,因为它们都是在上升沿采样数据,不用去在乎时钟的初始电平是什么,只要在上升沿采集数据就行。
极性选什么?格式选什么?通常去参考外接的模块的芯片手册。比如对于OLED,查看它的芯片手册时序部分:
SCLK的初始电平我们并不需要关心,只要保证在上升沿采样数据就行。
第002节_使用GPIO实现SPI协议操作OLED现在开始写代码,使用GPIO实现SPI协议操作。
我们现在想要操作OLED,通过三条线(SCK、DO、CS)与OLED相连,这里没有DI是因为2440只会向OLED传数据而不用接收数据。
我们要用GPIO来实现SOC向OLED写数据,这一层用gpio_spi.c来实现,负责发送数据。
对于OLED,有专门的指令和数据格式,要传输的数据内容,在oled.c这一层来实现,负责组织数据。
因此,我们需要实现以上两个文件。
需要实现的函数:先SPI初始化SPIInt(),再初始化OLEDOLEDInit(),最后再显示OLEDPrint()。
新建一个gpio_spi.c文件,实现SPI初始化SPIInt()
void SPIInit(void)
{
/* 初始化引脚 */
SPI_GPIO_Init();
}
再具体实现SPI_GPIO_Init()。这里使用GPIO实现SPI协议,电路图如下:
GPF1作为OLED片选引脚,设置为输出;
GPG2作为FLASH片选引脚,设置为输出;
GPG4作为OLED的数据(Data)/命令(Command)选择引脚,设置为输出;
GPG5作为SPI的MISO,设置为输入;
GPG6作为SPI的MOSI,设置为输出;
GPG7作为SPI的时钟CLK,设置为输出;
/* 用GPIO模拟SPI */
static void SPI_GPIO_Init(void)
{
/* GPF1 OLED_CSn output */
GPFCON &= ~(3
关注
打赏
- 韦东山freeRTOS系列教程:入门文档教程+进阶视频教程(全部免费的freeRTOS系列教程、freeRTOS学习路线)
- 韦东山嵌入式Linux三大学习路线
- 新人怎样学习嵌入式Linux?
- 【RTOS训练营】作业讲解、队列和环形缓冲区、队列——传输数据、队列——同步任务和晚课提问
- 【RTOS训练营】任务调度(续)、任务礼让、调度总结、队列和晚课提问
- 【RTOS训练营】上节回顾、空闲任务、定时器任务、执行顺序、调度策略和晚课提问
- 【RTOS训练营】设备子系统、晚课学员提问
- 【RTOS训练营】继续程序框架、tick中断补充、预习、课后作业和晚课提问
- 【RTOS训练营】程序框架、预习、课后作业和晚课提问
- 【RTOS训练营】环形缓冲区、AT指令、预习安排和晚课提问