感谢EEWORLD和ST公司提供开发板 板子资料地址
手头上有一块SSD1306控制芯片的OLED SPI 液晶。利用这块SSD1306 OLED板子测试一下STM32G431芯片的SPI操作。因为板子上没有专门的SSD1306的液晶接口,虽然主要的引脚只要两个SPI_SCK和SPI_MOSI就可以操作。但是比较麻烦的是SPI1的接口两个挨着的引脚PA5和PB3其中的PA5被用于LED的驱动。没有办法就使用杜邦线'跳接'一下。也就是做做实验也没什么关系了。
引脚设置:SPI_MOSI->PA7,SPI_SCK->PB3,CD->PA10,RST->PC4。CS引脚默认为低也就是'使能',CS不接任何引脚。电源为3.3V。按照设计接好引线。
STM32G431的SPI接口参数如下:
因为不需要接收SSD1306的数据,所以选择 Mode:Transmit Only Master;
也不需要NSS信号选择Disable,
数据长度为 8-Bit,其它默认。
注意:通讯速率的分频系数,我这里使用的是Prescaler(for Baud Rate):32,这个参数和你的时钟有关系,设置好了软件自动计算出速率。SPI通讯不像UART速率严格,所以大致差不多就可以。
生成程序,加入SSD1306的驱动。
SSD1306芯片驱动比较复杂,但是使用非常的灵活。所以没有自己全写,也是参考了网上的一些代码。
我的驱动主要的项目介绍一下:
SSD1306的命令和数据是由CD信号线的电平选择的;CD=1数据,CD=0命令;
主要的驱动函数介绍:
/*写数据和命令*/
void OLED_Write_Data(uint8_t dat)
{
HAL_GPIO_WritePin(CDS_GPIO_Port, CDS_Pin, GPIO_PIN_SET);//0
HAL_SPI_Transmit(&hspi1,&dat,1,100);
}
void OLED_Write_Cmd(uint8_t cmd)
{
HAL_GPIO_WritePin(CDS_GPIO_Port, CDS_Pin, GPIO_PIN_RESET);//1
HAL_SPI_Transmit(&hspi1,&cmd,1,100);
}
初始化过程比较复杂,也没有深究,照别人的代码写的。
/* 初始化*/
void OLED_Init(void)
{
.
.
.
}
/*填充数据*/
void OLED_Clear(uint8_t cmd)
{
unsigned char y,x;
OLED_Write_Cmd(0x20);//-Set Page Addressing Mode (0x00/0x01/0x02)
OLED_Write_Cmd(0x00);//
OLED_Write_Cmd(0x21);//-Set Column Address
OLED_Write_Cmd(0x00);
OLED_Write_Cmd(0x7f);
OLED_Write_Cmd(0x22);//-Set Page Address
OLED_Write_Cmd(0x00);
OLED_Write_Cmd(0x07);
HAL_Delay(1);
for(y=0;y<PAGE;y++)
{
for(x=0;x<X_WIDTH;x++)
{
OLED_Write_Data(dat);
}
}
}
SSD1306有三种模式,本列中使用'页'模式。GRAM中数据一个bit对应屏幕中的一个'像素点',但是SSD1306的GRAM数据只能以字节为单位操作。一个字节也就是一列8个像素。也就是一次就可以画一列,8个像素行。页模式就是一个页有8行128列。64行也就是8页。SSD1306中没有字库,字库需要自己构造。当然我也没有自己写了,也是从别人的代码中拷贝了一份。使用的是6x8的字库。其实操作GRAM最好的方法就是在MCU中构造一个8x128的图像缓冲区,先在缓冲区中操作,然后刷新到SSD1306的GRAM中。虽然这样效果又好又方便。但是这样需要占用MCU中的内存。单片机的应用一般没有太复杂的画面,也就是简单的显示一些文字。也没必要搞得很复杂。目前看屏幕显示正常,测试完成。
此内容由EEWORLD论坛网友bigbat原创,如需转载或用于商业用途需征得作者同意并注明出处