主题中讨论的其他器件: MSP430G2230
我使用 TFP410连接外部 HDMI 监视器、该监视器设置为在上电时由 MSP430G2230微控制器通过 I2C 连接进行配置(请参阅原理图片段)。 我当前遇到的问题是、TFP410不会 ACK 任何命令(请参阅示波器屏幕截图)。 我的 SCL 以大约11kHz 的频率运行、我对 I2C 引脚进行了位拆裂。 我的代码如下:
main.c:
/* * main.c * *创建日期:2019年9月26日 * / #include #include /* TFP410的子地址*/ #define CTL_1_MODE 0x08 #define CTL_2_MODE 0x09 #define CTL_3_MODE 0x0A #define DE_DLY 0x32 #define DE_CTL 0x33 #define DE_TOP 0x34 #define DE_CNT_L 0x36 #define DE_CNT_MODE 0x37 #define 0x39 #define ADDR_CL_CL_#define 0x37 #define 0x39 #define 0x37 #define 0x39 #define ADDR_CL_CL_CL_CL_IN_CL_CL_#define 0x //写入地址 unsigned char sData = 0; //要写入从 器件的数据 int main (void){ WDTCTL = WDTPW | WDTHOLD; //停止看门狗 /*初始化时钟*/ BCSCTL3 |= LFXT1S_2; //选择 VLO 作为低频率时钟 if (CALBC1_1MHz == 0xFF){ //如果校准常数被擦除 while (1); //不加载,陷阱 CPU!! } DCOCTL = 0; //选择最低 DCOx 和 MODx 设置 BCSCTL1 = CALBC1_1MHz; //设置 DCO DCOCTL = CALDCO_1MHz; //等待 FPGA 初始化 _delay_cycles (10000); /*配置 TFP410数字发送器*/ // 0x37、T.M.D.S.使能状态由 PD 确定 sData = 0x37; I2C_WriteData (&sData、SLV_ADDR、CTL_1_MODE、1); // 0x39、MSEN 输出被禁用、来自 HTPLG 的 MDI、MDI 逻辑电平保持不变 sData = 0x39; I2C_WriteData (&sData、SLV_ADDR、CTL_2_MODE、1); // 0x80、sData 去偏斜被禁用 sData = 0x80; I2C_WriteData (&sData、SLV_ADDR、CTL_3_MODE、1); // 0xD8、216像素(HSYNC +后沿) sData = 0xD8; I2C_WriteData (&sData、SLV_ADDR、DE_DLY、1); // 0x70、DE 发生器启用、VSYNC 和 HSYNC 高电平有效 sData = 0x70; I2C_WriteData (&sData、SLV_ADDR、DE_CTL、1); // 0x1B、27像素(VSYNC +后沿) sData = 0x1B; I2C_WriteData (&sData、SLV_ADDR、DE_TOP、1); // 0x20、0x03、800像素宽 sData = 0x20; I2C_WriteData (&sData、SLV_ADDR、DE_CNT_L、1); sData = 0x03; I2C_WriteData (&sData、SLV_ADDR、DE_CNT_H、1); // 0xE0、0x01 480行高 sData = 0xE0; I2C_WriteData (&sData、SLV_ADDR、DE_LIN_L、1); sData = 0x01; I2C_WriteData (&sData、SLV_ADDR、DE_LIN_H、1); //_delay_cycles (10000); /*配置后的陷阱*/; while (1); }
I2C_SW.c:
/* i2c_sw.c * *创建时间:2019年10月1日 * */ #include "msp430.h" #include "i2c_sw.h" unsigned char read_scl (void); unsigned char read_SDA (void); void clear_scl (void); void clear_SDA (void); void I2C_Init (void); void I2C_Start (void); void I2C_Stop (void); void I2C_Writebit (unsigned char bit); unsigned char I2C_ReadByte (unsigned char Data); unsigned char I2C_ReadByte (void I2C_WriteData);unsigned char Addr * Data、unsigned char Addr、unsigned char DeviceRegister Addr、unsigned char DeviceRegister、unsigned char DeviceRegister、unsigned char DeviceLength (unsigned char Data、unsigned char Devicechar DeviceRegister、unsigned、unsigned char Devicechar DeviceRegister、Devicechar DeviceData)-- --------------/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/ 函数:READ_SCL 用途 :将 SCL 设置为 SCL 的输入和返回电流逻辑电平(0或1) NORMAL 为1,因为它由电阻器上拉 参数:无 返回 :SCL 引脚的逻辑电平------------------------------------------------------- */ unsigned char read_scl (void) { I2C_PxDIR &=~SCL; return ((I2C_PxIN & SCL)!= 0); } /*--------------- 函数:READ_SDA 用途 :将 SDA 设置为 SDA 的输入和返回电流逻辑电平(0或1), NORMAL 为1,因为它由电阻器上拉 参数:无 返回 :SDA 管脚的逻辑电平 --------------------------- */ unsigned char read_SDA (void) { I2C_PxDIR &=~SDA; return ((I2C_PxIN & SDA)!= 0); } /*--------------- 函数:CLEAR_SCL 用途 :将 SCL 设置为输出,逻辑低 电平参数:无 返回 无:无 ------------------------------------------------------------ */ void clear_SCL (void) { I2C_PxDIR |= SCL; I2C_PxOUT &=~SCL; }/*--------------- 函数:clear_SDA 用途 :将 SDA 设置为输出,逻辑低 电平参数:无 返回 无:无 ------------------------------------------------------------ */ void clear_SDA (void) { I2C_PxDIR |= SDA; I2C_PxOUT &=~SDA; }/*--------------- 函数:I2C_Init 用途 :初始化 I2C 块 参数: 无返回 无:无 ------------------------------------------------------------ */ void I2C_Init (void) { //将 SCL 和 SDA 配置为 GPIO I2C_PxSEL &=~(SCL + SDA); //将 SCL 和 SDA 设置为输入、通过电阻器将逻辑高电平拉高 I2C_PxDIR &=~(SCL + SDA); I2C_PxOUT &=~(SCL + SDA); }/*--------------- 函数:I2C_Start 用途 :发送启动信号 参数:无 返回 无:无 ------------------------------------------------------------ */ void I2C_Start (void) { READ_SDA(); //将 SDA 设置为1 I2C_DELAY (); CLEAR_SDA(); //将 SDA 设置为0、当前 SCL 为1 I2C_DELAY (); CLEAR_SCL (); //set SCL to 0 }/*--><!--kadov_tag{</spaces>}}-->将 SCL 设置为0 }/--><!--kadov_tag{</spaces>}--><!--kadov_tag{</spaces>}--><!--kadov_tag{</spaces>}}--> 函数:I2C_Stop 用途 :发送停止信号 参数:无 返回 无:无 ------------------------------------------------------------ */ void I2C_Stop (void) { CLEAR_SDA(); //将 SDA 设置为0 I2C_DELAY (); READ_SCL (); //将 SCL 设置为1 I2C_DELAY (); READ_SDA(); //set SDA to 1 }/*--><!--kadov_tag{</spaces>}}-->将 SDA 设置为1 }/*--><!--kadov_tag{</spaces>}--><!--kadov_tag{</spaces>}--><!--kadov_tag{</spaces>}--><!--kadov_tag{</spaces>}}--> 函数:I2C_Writebit 用途 :将位写入 I2C 总线 参数:要写入 的位返回 无:无 ------------------------------------------------------------ */ void I2C_Writebit (unsigned char bit) { if (位) READ_SDA(); 其他 CLEAR_SDA(); I2C_DELAY (); READ_SCL (); I2C_DELAY (); CLEAR_SCL ();}/*--><!--kadov_tag{</spaces>}}--> 函数:I2C_Readbit 用途 :I2C 总线 参数上的读取位:无 返回 :无符号字符 ------------------------------------------------------- */ unsigned char I2C_Readbit (void) { unsigned char 位; //让从器件驱动数据 READ_SDA(); I2C_DELAY (); READ_SCL (); 位= READ_SDA (); I2C_DELAY (); CLEAR_SCL (); 返回位;}/*--><!--kadov_tag{{</spaces>}--><!--kadov_tag{</spaces>}}--> 函数:I2C_WriteByte 用途 :将一个字节写入 I2C 总线 参数:unsigned char 数据 返回 无:无 ------------------------------------------------------------ */ void I2C_WriteByte (unsigned char Data) { unsigned char nBit; 对于(nBit = 0;nBit < 8;nBit++) { I2C_Writebit ((Data & 0x80)!= 0); 数据<<= 1; } I2C_Readbit();// Write NACK } /*-->--------------- 函数:I2C_ReadByte 用途 :读取 I2C 总线 参数上的字节:无 返回 :无符号字符 ------------------------------------------------------- */ unsigned char I2C_ReadByte (void) { unsigned char buff = 0; unsigned char nBit; 对于(nBit = 0;nBit < 8;nBit++) { buff =(buff << 1)| I2C_Readbit(); } 返回缓冲区;}/*--><!--kadov_tag{{</spaces>}--><!--kadov_tag{</spaces>}}--> 函数:I2C_WriteData 用途 :将 n 个字节写入 I2C 总线 参数:数据 -要写入的数据的指针 DeviceAddr -器件地址 寄存器 -寄存器地址 n 长度 - 要写入的字节数返回值 无:无 ------------------------------------------------------------ // void I2C_WriteData (unsigned char *数据、unsigned char DeviceAddr、unsigned char 寄存器、unsigned char nLength) { unsigned char nIndex; I2C_Start(); I2C_WriteByte (DeviceAddr << 1);// DeviceAddr 为7位且命令为写入 I2C_WriteByte (寄存器); for (nIndex = 0;nIndex < nLength;nIndex++) { I2C_WriteByte (*(数据+ nIndex)); } I2C_Readbit(); I2C_Stop();}/*--><!--kadov_tag{</spaces>}}--> 函数:I2C_ReadData 用途 :从 I2C 总线 参数中读取 n 个字节:buff -用于存储值的缓冲区指针 视频地址-器件地址 寄存器 -寄存器地址 n 长度 - 要读取的字节数返回值 无:无 ------------------------------------------------------------ // 空 I2C_ReadData (unsigned char *缓冲区、unsigned char DeviceAddr、unsigned char 寄存器、unsigned char nLength) { unsigned char nIndex; I2C_Start(); I2C_WriteByte (DeviceAddr << 1); I2C_WriteByte (寄存器); I2C_Stop (); _NOP(); //短延迟 I2C_Start(); _NOP(); //短延迟 I2C_WriteByte ((DeviceAddr << 1)| 1); for (nIndex = 0;nIndex < nLength;nIndex++) { *(buff + nIndex)= I2C_ReadByte (); if (nIndex > 0) I2C_Writebit (ACK); } I2C_Writebit (NACK); I2C_Stop(); }
原理图片段:
示波器屏幕截图: