【CW32L052测评】 (学习笔记1)IIC驱动OLED。
[复制链接]
最近公司在搞新项目,在了解一块adi的dsp,非常抱歉晚了。
一开始了解了一下lcd的数码管,我的数码管似乎第一个数字有几道线无法点亮(可能是我配置的问题,后面再看看),因此我把我室友的OLED屏拿来用用。
工程模板用的厂商自带样例,时钟初始化,串口重定向,系统定时器已经完成了(ps: 嵌入式软件工程师的事怎么能叫偷呢!那叫移植。)
而我的室友已经有了OLED的上层驱动以及字库(ps: 继续移植qaq)
你说巧不巧厂商测试样例里刚好又有一个IIC读写EEPROM的底层配置。(ps: 三次移植)
那么接下来,就是我应该要做的事了,我只需要把例程里的iic初始化和oled的iic初始化接起来,胶合一下,应该就没什么大问题啦。(是的,那就是我要做的全部了,认真脸)
所以首先,IIC的硬件连接方式,OLED屏有四根线,vcc,GND,clk,sda。CLK和SDA直接把EEPROM跳帽拔了,鸠占鹊巢(理直气壮)。GND到处都是,VCC需要留意一下,我尝试以下几种情况,都是可以的。
1.调试器上的3.3V供电,我用的是usb给开发板供电,那么调试器上的3.3V排针就空出来了,因此我直接用电脑给OLED屏供电,测试没有问题(家电不如野电香啊)
2.调试器上的5.5v供电,同上。
3.CN6上的VDDIN,由原理图可知,CN6的VDDIN是供电出口,而CN24的DCIN是供电入口,所以CN6的IN在任何时候都有电,而CN24只在用IN作为供电时,另一个CN24IN才有电。
4.j1上的1,3,5排针,也可以作为供电。
ps:在为oled选择供电时,研究了一下power模块,发现我的LD1117AS33TR芯片是坏的,VDDLDO并没有3.3v输出,暴风哭泣啊。
接下来就是软件部分了。先复习一下iic的协议规则,
主机发开始信号和从机地址(包含读写操作,默认为写操作,因为OLED屏不需要读)
从机应答
主机发送机寄存器地址
从机应答
主机发送写入寄存器的值
从机应答
iic的时钟为100K或者400K,1M。例程配置的是1M,高速IIC,而OLED呢,网上找了几十分钟没找到时钟频率,好嘛,一个一个试呗。我先给IIC的时钟配置成了100k试试。
查看例程,用户手册得到配置方式为:
SCL 时钟频率计算公式:
fSCL = fPCLK / 8 / ( BRR + 1 )
其中,BRR 通过波特率计数器配置寄存器 I2Cx_BRR 配置,BRR 有效范围为 1 ~ 255。
I2C_InitStruct.I2C_Baud = 0x1d;//1MHz=(24000000/(8*(2+1))
例程里外设时钟为24MHZ,我需要100K,那么BRR= 24000 000/8/100 000 - 1 =29 = 0x1d
其他的都直接用例程就完事了。(报错再改qaq)
IIC初始化就完了,那么IIC发送数据呢,例程用的是I2C_MasterWriteEepromData(TEST_I2C,(WRITEADDRESS+j*8),&u8Senddata[j*8],8);但是OLED库的底层是一个数据一个数据发的,因此我需要为OLED库自己写三个函数:
void OLED_WriteCommand(uint8_t Command)
void OLED_WriteData(uint8_t Data)
int OLED_I2C_SendByte(uint8_t data)
前两个调用第三个来传输。
void OLED_WriteCommand(uint8_t Command)
{
OLED_I2C_SendByte(0x78); //从机地址
OLED_I2C_SendByte(0x00); //写命令
OLED_I2C_SendByte(Command);
}
void OLED_WriteData(uint8_t Data)
{
OLED_I2C_SendByte(0x78); //从机地址
OLED_I2C_SendByte(0x40); //写数据
OLED_I2C_SendByte(Data);
}
int OLED_I2C_SendByte(uint8_t data)
{
I2C_SendData(); //我只需要把硬件IIC发送字节放到里面去就行了
}
然后嘎了,倒弄了一段时间。没找到原因,然后跑到论坛偷瞄了一眼大兄弟们驱动IIC的代码。果然是开始信号没发,加上就ok了。(嵌入式软件工程师的事怎么能叫偷呢!那叫移植。)
屏已经成功点亮了,最后把图附上。
|