因为之后的工程需要用到ADC采集,这里我先将OLED驱动先写好,搭建好人机交互界面,一边后续对参数的显示。
这里我使用的是0.96寸的I2C屏(4 Pins)/SPI屏(7-Pins),实物图如下:
我主要是用了条件编译的写法,来整合两个协议的驱动。
准备工作
这里我准备将I2C和SPI协议的屏幕整合到同一文件OLED.C中。所以我准备了一下两份OLED驱动(写STM32时用过)的源码,以下分别是
I2C协议
SPI协议
(以上两个驱动整合到最后的OLED整合包中)
整合工作
1.整合不兼容函数
代码如下:
#elif OLED_MODE == 1 //仅I2C可用函数
/*************************************************************************/
/*函数功能: I2C 启动 */
/*************************************************************************/
void IIC_Start(void)
{
OLED_SCLK_Set() ;
OLED_SDIN_Set();
OLED_SDIN_Clr();
OLED_SCLK_Clr();
}
/*************************************************************************/
/*函数功能: I2C 停止 */
/*************************************************************************/
void IIC_Stop(void)
{
OLED_SCLK_Set() ;
// OLED_SCLK_Clr();
OLED_SDIN_Clr();
OLED_SDIN_Set();
}
/*************************************************************************/
/*函数功能: I2C 等待响应 */
/*************************************************************************/
void IIC_Wait_Ack(void)
{
OLED_SCLK_Set() ;
OLED_SCLK_Clr();
}
/**********************************************/
// IIC Write byte */
**********************************************/
void Write_IIC_Byte(unsigned char IIC_Byte)
{
unsigned char i;
unsigned char m,da;
da=IIC_Byte;
OLED_SCLK_Clr();
for(i=0;i<8;i++)
{
m=da;
OLED_SCLK_Clr();
m=m&0x80;
if(m==0x80)
{OLED_SDIN_Set();}
else OLED_SDIN_Clr();
da=da<<1;
OLED_SCLK_Set();
OLED_SCLK_Clr();
}
}
/*************************************************************************/
/*函数功能: 设置坐标 */
/*入口参数: x:横坐标 0~127 */
/* y:纵坐标 0~63 */
/*************************************************************************/
void OLED_Set_Pos(unsigned char x, unsigned char y)
{ OLED_WR_Byte(0xb0+y,OLED_CMD);
OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);
OLED_WR_Byte((x&0x0f),OLED_CMD);
}
/*************************************************************************/
/*函数功能: 显示汉字 */
/*入口参数: x:横坐标 0~127 */
/* y:纵坐标 0~63 */
/* n0: 第n号字 */
/*************************************************************************/
void OLED_ShowCHinese(u8 x,u8 y,u8 no)
{
u8 t,adder=0;
OLED_Set_Pos(x,y);
for(t=0;t<16;t++)
{
OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);
adder+=1;
}
OLED_Set_Pos(x,y+1);
for(t=0;t<16;t++)
{
OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);
adder+=1;
}
}
/*************************************************************************/
/*函数功能: 功能描述:显示显示BMP图片128×64起始点坐标(x,y) */
/*入口参数: x的范围0~127,y为页的范围0~7 */ */
/* x:0~127 */
/* y:0~63 */ */
/* bmp[]:图库中的数组地址 */
/*************************************************************************/
void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[])
{
unsigned int j=0;
unsigned char x,y;
if(y1%8==0) y=y1/8;
else y=y1/8+1;
for(y=y0;y OLED_Set_Pos(x0,y); for(x=x0;x OLED_WR_Byte(BMP[j++],OLED_DATA); } } } #endif 2.OLED函数 代码如下: //OLED的显存 //存放格式如下. //[0]0 1 2 3 ... 127 //[1]0 1 2 3 ... 127 //[2]0 1 2 3 ... 127 //[3]0 1 2 3 ... 127 //[4]0 1 2 3 ... 127 //[5]0 1 2 3 ... 127 //[6]0 1 2 3 ... 127 //[7]0 1 2 3 ... 127 u8 OLED_GRAM[128][8]; //m^n函数 u32 mypow(u8 m,u8 n) { u32 result=1; while(n--)result*=m; return result; } /*************************************************************************/ /*函数功能: 通过软件模拟SPI/I2C通信协议,向模块(SSD1306)写入一个字节 */ /*入口参数: */ /* data:要写入的数据/命令 */ /* cmd :数据/命令标志 0,表示命令;1,表示数据; */ /*************************************************************************/ void OLED_WR_Byte(unsigned data,unsigned cmd) { #if OLED_MODE == 0 //SPI unsigned char i=0; if(cmd&0x01) OLED_DC_Set(); else OLED_DC_Clr(); OLED_SCLK_Clr(); for(i=0;i<8;i++) { OLED_SCLK_Clr(); if(data&0x80)OLED_SDIN_Set(); //从高位到低位 else OLED_SDIN_Clr(); OLED_SCLK_Set(); data<<=1; } OLED_SCLK_Set(); OLED_DC_Set(); #elif OLED_MODE == 1 //I2C if(cmd) { WriteData(data); } else { WriteCmd(data); } #endif } /*************************************************************************/ /*函数功能: 写命令 */ /*************************************************************************/ void WriteCmd(unsigned char cmd) { #if OLED_MODE == 0 //SPI OLED_WR_Byte(cmd,OLED_CMD); #elif OLED_MODE == 1 //I2C IIC_Start(); Write_IIC_Byte(0x78); //Slave address,SA0=0 IIC_Wait_Ack(); Write_IIC_Byte(0x00); //write command IIC_Wait_Ack(); Write_IIC_Byte(cmd); IIC_Wait_Ack(); IIC_Stop(); #endif } /*************************************************************************/ /*函数功能: 写数据 */ /*************************************************************************/ void WriteData(unsigned char data) { #if OLED_MODE == 0 //SPI OLED_WR_Byte(data,OLED_DATA); #elif OLED_MODE == 1 //I2C IIC_Start(); Write_IIC_Byte(0x78);//D/C#=0; R/W#=0 IIC_Wait_Ack(); Write_IIC_Byte(0x40);//write data IIC_Wait_Ack(); Write_IIC_Byte(data); IIC_Wait_Ack(); IIC_Stop(); #endif } /*************************************************************************/ /*函数功能: 初始化OLED模块 */ /*************************************************************************/ void OLED_Init(void) { #if OLED_MODE == 0 //SPI /*GPIO Init*/ GPIO_Init(OLED1_PORT,OLED_SDIN|OLED_SCL|OLED_DC|OLED_RST,GPIO_Mode_Out_PP_Low_Slow); GPIO_Init(OLED2_PORT,OLED_CS, GPIO_Mode_Out_PP_Low_Slow); OLED_CS_Clr(); OLED_SCLK_Set(); OLED_RST_Clr(); Delay_ms(100); OLED_RST_Set(); //从上电到下面开始初始化要有足够的时间,即等待RC复位完毕 WriteCmd(0xAE); // Display Off (0x00)
上一篇:STM8L151C8学习笔记4:ADC驱动
下一篇:STM8L151C8学习笔记1:LED驱动
推荐阅读最新更新时间:2024-11-17 00:51