一、iML7991
7991是应用在TFT-LCD领域的P-GAMMA芯片,利用IIC对其内部的GAMMA值(共14个)进行设定。7991地址表参考图1.1。
可以看到两个GAMMA值共用3个地址,补充一点,gamma值是画面显示的参考绑点值,相关LCD等方面的知识不做介绍。7991写操作示意图,iic规则与通用的iic并无区别。
7991的读操作稍微有点差异,但是问题不大,需要重新产生start条件。
二、stm32f10x端的iic配置
将stm32作为主机,选取GPIOB6(SCL)与 GPIOB7(SDA)作为iic传输线,采用stm32f10x函数库里的函数编写代码。
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle =I2C_DutyCycle_2;//Tlow/Thight=2
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;//应答
I2C_InitStructure.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 400000;//400K
stm32f10x的函数库非常丰富,可以直接利用库函数进行编写。事件的判断是主要的难点。
/*写操作*/
void WriteByte(u8 addr,u8 data)
{
while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));//判断是否繁忙
I2C_GenerateSTART(I2C1, ENABLE);//产生START 条件
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));//检查最近一次事件是否是EV5事件
I2C_Send7bitAddress(I2C1,Slave_address,I2C_Direction_Transmitter);//Slave_address为从机器件地址
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//检查最近一次事件是否是EV6事件
I2C_SendData(I2C1, addr);//addr为器件内部的寄存器地址
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));//检查最近一次事件是否是EV8事件
I2C_SendData(I2C1, data);//发送数据
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));//检查最近一次事件是否是EV8事件
I2C_GenerateSTOP(I2C1, ENABLE);//产生STOP 条件
}
主机变为接收模式的时候,读取数据前要先将DR寄存器清楚(我在重新产生start条件后选择了事件6,结果不对,于是发现了在读数据之前要先清)
/*从 寄存器地址 读取一个byte的数据*/
u8 I2C_ReadByte(uint8_t addr)
{
u8 ReadData;
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));//判断是否繁忙
I2C_GenerateSTART(I2C1, ENABLE);//产生 START 条件
/*先写*/
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));//检查最近一次 事件是否是EV5
I2C_Send7bitAddress(I2C1, Slave_address, I2C_Direction_Transmitter);//Slave_address从机地址
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//检查最近一次 事件是否是EV6事件
I2C_SendData(I2C1, addr);//寄存器地址
I2C_GenerateSTART(I2C1, ENABLE);//重新产生START 条件
/*再读*/
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));//检查最近一次 事件是否是EV5
I2C_Send7bitAddress(I2C1, Slave_address, I2C_Direction_Receiver);//此时主机变为接收模式
/*检查最近一次 I2C 事件是否是EV7事件!!!这里很重要*/
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED ));
ReadData=I2C_ReceiveData(I2C1);//读取数据
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));//检查事件是否为EV7读DR寄存器清除该事件
I2C_GenerateSTOP(I2C1, ENABLE);//产生STOP 条件
return ReadData;
}
三、验证
我在验证的时候加了个OLED的显示屏来显示读到的字。
先向7991中某个地址发送一个值,然后再将其读出来,最后用OLED显示出来。
将7991中的GAMMA值全部设定后放到tcon板上,显示画面正常。
四、总结
老拿公司的芯片玩确实不太好,还是买块FPGA方便点。