上一篇04的记录里面说了,更新SDK手欠把之前的测试代码都删除了,更悲催的是W801的开发板找不着了,不知道仍哪个夹缝里吃灰去了。好在W800还在,我的记录也才能继续记录下去,感谢W800竟然还在吧。
这次要点亮的是个0.96的OLED,之前不知道买什么配件时顺便带的,也是我在翻找W801时无意间发现的,全新都没拆封,就折腾他吧。根据屏幕防静电袋内的一个小纸条找到手册下载地址,先把手册和DEMO程序都下载下来,简单看了一下DEMO是用keil写的,先直接把DEMO复制到我的MYCODE文件夹下(后来发现没啥大用,除了字库文件其它都没用,因为根本编译不了,几乎全重新改,不过读代码还是很方便的)。
经过分析,发现其实点亮屏幕很简单,先是初始化,然后清屏把所有点都熄灭,然后就设置个位置输出你想要的内容就行了,当然输出汉字时需要先查点阵字库,至于指令内容到底是0XA0还是0X1B就无所谓了,直接从DEMO里复制就行了。
再有就是IIC通信,DEMO里是自己写了一个IIC通讯的过程,之前看W800的SDK里是有IIC通讯的,咱就不用再单独写这块了直接用SDK吧,简单读了sdk里iic的DEMO,发现很简单,大致用到的几个函数:
tls_i2c_write_byte(0xA0,1);
tls_i2c_wait_ack();
temp=tls_i2c_read_byte(0,1);
tls_i2c_stop();
tls_os_time_delay(1);
写,等,读,停,延时大概就这样了,IIC的通讯开始(就是两条线的电平变化,让IIC上设备准备接收的功能),被集成到tls_i2c_write_byte中,就不用自己操心了。其实驱动屏幕好像不用读这个操作。
查看W800的手册,IIC是用PA1+PA4,或者PB19+PB20,不过PB19和20还是串口,那就先用PA1+4吧,感觉这个IIC通讯也不是什么高频率,也不需要多大驱动电流,按理来说只要是个IO就行,等有空在测测用别的非手册上指定的IIC的IO行不行。
再看看IIC端口初始化
wm_i2c_scl_config(WM_IO_PA_01);//时钟
wm_i2c_sda_config(WM_IO_PA_04);//数据
tls_i2c_init(I2C_FREQ);//啥玩意???
大概这三行就行,I2C_FREQ这个应该是IIC总线频率,DEMO中默认是20000,就先用这个数值了。
好了,有了这些基本就够了,准备开整。
先定义两个IO,这个方法其实不错,可以随时改不同管脚,甚至可以做成软件自定义
enum tls_io_name gpio_pin_CLK;//IIC的CLK时钟
enum tls_io_name gpio_pin_SDA;//IIC的SDA数据
再根据显示屏的DEMO定义几个能用得上的
#define OLED091_I2C_FREQ (400000) //IIC的频率
#define OLED091_I2C_delay (1)//一个I体现IC写命令执行后等待延迟
#define OLED091_DISP_X (128)//显示屏横轴点数
#define OLED091_DISP_Y (32)//显示屏纵轴点数
#define OLED091_CMD 0 //写命令
#define OLED091_DATA 1 //写数据
#define OLED091_MODE 0 //0正常显示/1反白显示
写IIC通讯函数
//写IIC函数,一个字节
void OLED091_WriteByte(u8 dat,u8 cmd)
{
tls_i2c_write_byte(0x78,1); //D/C#=0; R/W#=0 //Slave address,SA0=0
tls_i2c_wait_ack();
if(cmd)
{
tls_i2c_write_byte(0x40,0); //write data
}
else
{
tls_i2c_write_byte(0x00,0); //write command
}
tls_i2c_wait_ack();
tls_i2c_write_byte(dat,0);
tls_i2c_wait_ack();
tls_i2c_stop();
tls_os_time_delay(OLED091_I2C_delay);
}
初始化屏幕,按demo的指令顺序,用上面的写IIC函数一套,万事大吉,这种干翻译活的程序员真的应该很开心。
void OLED091_Init(enum tls_io_name CLK,enum tls_io_name SDA){
//初始化端口
gpio_pin_CLK = CLK;
gpio_pin_SDA = SDA;
//配置IIC
//WM_IO_PA_01
//WM_IO_PA_04
wm_i2c_scl_config(gpio_pin_CLK);
wm_i2c_sda_config(gpio_pin_SDA);
tls_i2c_init(OLED091_I2C_FREQ); //这个是IIC的频率吗?DEMO里给的200000,先按DEMO来做
tls_os_time_delay(10);
OLED091_WriteByte(0xAE,OLED091_CMD);//关闭显示
OLED091_WriteByte(0x40,OLED091_CMD);//---set low column address
OLED091_WriteByte(0xB0,OLED091_CMD);//---set high column address
OLED091_WriteByte(0xC8,OLED091_CMD);//-not offset
OLED091_WriteByte(0x81,OLED091_CMD);//设置对比度
OLED091_WriteByte(0xff,OLED091_CMD);
OLED091_WriteByte(0xa1,OLED091_CMD);//段重定向设置
OLED091_WriteByte(0xa6,OLED091_CMD);//
OLED091_WriteByte(0xa8,OLED091_CMD);//设置驱动路数
OLED091_WriteByte(0x1f,OLED091_CMD);
OLED091_WriteByte(0xd3,OLED091_CMD);
OLED091_WriteByte(0x00,OLED091_CMD);
OLED091_WriteByte(0xd5,OLED091_CMD);
OLED091_WriteByte(0xf0,OLED091_CMD);
OLED091_WriteByte(0xd9,OLED091_CMD);
OLED091_WriteByte(0x22,OLED091_CMD);
OLED091_WriteByte(0xda,OLED091_CMD);
OLED091_WriteByte(0x02,OLED091_CMD);
OLED091_WriteByte(0xdb,OLED091_CMD);
OLED091_WriteByte(0x49,OLED091_CMD);
OLED091_WriteByte(0x8d,OLED091_CMD);//SET DCDC命令
OLED091_WriteByte(0x14,OLED091_CMD);//DCDC ON
OLED091_WriteByte(0xAF,OLED091_CMD);//打开显示
//OLED091_Clear();
}
开启和关闭显示,这个没什么说的,都是照搬DEMO
//开启OLED显示
void OLED091_Display_On(void)
{
OLED091_WriteByte(0X8D,OLED091_CMD); //SET DCDC命令
OLED091_WriteByte(0X14,OLED091_CMD); //DCDC ON
OLED091_WriteByte(0XAF,OLED091_CMD); //DISPLAY ON
}
//关闭OLED显示
void OLED091_Display_Off(void)
{
OLED091_WriteByte(0X8D,OLED091_CMD); //SET DCDC命令
OLED091_WriteByte(0X10,OLED091_CMD); //DCDC OFF
OLED091_WriteByte(0XAE,OLED091_CMD); //DISPLAY OFF
}
清屏和全部点亮函数,也是照搬,重新套函数名穿马甲,但是原来DEMO的全部点亮函数是有bug的,只点亮了每列的第一个点,这里修改了一下。
//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!
void OLED091_Clear(void)
{
u8 i,n,t;
t=OLED091_DISP_Y/8;
for(i=0;i<t;i++)
{
OLED091_WriteByte (0xb0+i,OLED091_CMD); //设置页地址(0~7)
OLED091_WriteByte (0x00,OLED091_CMD); //设置显示位置—列低地址
OLED091_WriteByte (0x10,OLED091_CMD); //设置显示位置—列高地址
for(n=0;n<OLED091_DISP_X;n++)OLED091_WriteByte(0,OLED091_DATA);
} //更新显示
}
//全部点亮
void OLED091_On(void)
{
u8 i,n;
for(i=0;i<4;i++)
{
OLED091_WriteByte (0xb0+i,OLED091_CMD); //设置页地址(0~7)
OLED091_WriteByte (0x00,OLED091_CMD); //设置显示位置—列低地址
OLED091_WriteByte (0x10,OLED091_CMD); //设置显示位置—列高地址
//for(n=0;n<128;n++)OLED091_WriteByte(0XFF,OLED091_DATA);
for(n=0;n<OLED091_DISP_X;n++)OLED091_WriteByte(0XFF,OLED091_DATA);
} //更新显示
}
好了,迫不及待了,先测试一下能不能亮吧,其它的字符输出什么的一会再写
先写个循环,初始化后点亮和清屏
int DispToOLED091_main(void)
{
OLED091_Init(WM_IO_PA_01,WM_IO_PA_04);
while (1){
OLED091_Display_On();
OLED091_Clear();
OLED091_On();
OLED091_Display_Off();
tls_os_time_delay(1000);
}
}
怀着激动的心情,接线,编译,下载,通电,哈哈,好用了。不错不错,给直接赞一个。
全部程序我下次贴出吧,毕竟这次也就是测试了一下屏幕是不是能点亮。