主题中讨论的其他器件: SysConfig、 C2000WARE
大家好、我正在尝试让 I2C 在我嵌入到输出板上的 TMS320F2838处理器上工作。
请不要给出硬件建议、因为我已经验证了我的硬件设置、我能够让 USB 到在电路板上工作的 UART、并从我的笔记本电脑的 CMD 终端从电路板上读写文本。
我想我配置的一些软件不正确。 我的目标是简单地从 VNCL4040距离传感器提取数据。 不过在我的 beginTransmission ()函数中,我被卡在 while 循环中,该循环检查是否 设置了 I2C_STS_REG_ACCESS_RDY。 我还被困在 while 环路中、以检查总线是否处于繁忙状态。
更多信息:
-我在 TMS320F2837xd LaunchPad 上具有完全相同的代码,可以与我使用的相同传感器完美配合使用
-我在 TMS320F28384D 的定制分线板上对 I2C 线路使用 GIPO 0和1。
我正在使用以下路径中的示例 sysconfig 文件: C:\ti\c2000\c2000\C2000Ware_5_01_00_00\driverlib\f2838x\examples\C28x\empty_projects。
-我在主代码中编写的所有代码粘贴到下面,后面是从 SysConfig 生成的配置文件。 我还要运行一个简单的中断使 LED 闪烁、这是运行正常的。
-我以黄色突出显示了我的代码所处的函数。
-我以橙色突出显示了我所停留的特定行。
当我为 I2C 总线调用"get status"时、得到的值为0x00001411
//##########################################################################出################################出
//
//文件:empty_driverlib_main.c
//
//! \addtogroup driver_example_list
//!
空项目示例
//!
//! 此示例是用于 Driverlib 开发的空项目设置。
//!
//
//##########################################################################出################################出
//------------------
//
//全局变量
//
//------------------
uint32_t 状态;
uint16_t AvailableI2C_slaves [20];
uint16_t * Devices = AvailableI2C_slaves;//指向阵列的指针
uint8_t data[2];
uint16_t * k =数据;
//------------------
////
////I2C 帮助程序函数
////
//------------------
void releaseI2CBusFromBusyState(){
//禁用 I2C 模块
I2C_disableModule (VNCL_40_BASE);
//切换 SCL 线路(时钟)以释放总线
GPIO_togglePin (GPIO_PIN_I2CA_SDA);
//切换 SDA 线(数据)以释放总线
GPIO_togglePin (GPIO_PIN_I2CA_SCL);
//支持 Re 的 I2C 模块
I2C_enableModule (VNCL_40_BASE);
}
void I2CBUS_scan (uint16_t * AvailableDevices)
{
//禁用中断
I2C_disableInterrupt (I2CA_BASE、(I2C_INT_ADDR_SLAVE | I2C_INT_STOP_Condition | I2C_INT_ARB_LOSS| I2C_INT_NO_ACK));
uint16_t Slave_Address、I;
I = 0;
//最多可连接128个 I2C 设备,承载7位地址
对于(Slave_Address = 1;Slave_Address < 128;Slave_Address +)
{
//检查总线状态,成功时,它将返回0。 如果不等于0、则停止程序。
while (I2C_isBusy (I2CA_BASE);
//配置 I2C
I2C_setConfig (I2CA_BASE、I2C_MASTER_SEND_MODE | I2C_REPEATE_MODE);
I2C_setAddressMode (I2CA_BASE、I2C_ADDR_MODE_7BITS);
I2C_setSlaveAddress (I2CA_BASE、Slave_Address);
I2C_sendStartCondition (I2CA_BASE);
//等待传输完成
//状态应为"register-access-ready"以继续
while (! (I2C_getStatus (I2CA_BASE)和 I2C_STS_REG_ACCESS_RDY);
I2C_sendStopCondition (I2CA_BASE);
//等待停止位被清零
while (I2C_getStopConditionStatus (I2CA_BASE));
///等待 BUSY 位被清零 总线不应处于忙状态
while (I2C_isBusy (I2CA_BASE));
//获取 I2C 状态以查看它是否已得到从机应答
状态= I2C_getStatus (I2CA_BASE);
如果(!(STATUS 和 I2C_STS_NO_ACK))
{
AvailableDevices[i]= Slave_Address;
I++;
}
I2C_clearStatus (I2CA_BASE、I2C_STS_NO_ACK | I2C_STS_ARB_LOST | I2C_STS_REG_ACCESS_RDY| I2C_STS_STOP_Condition);
}
I2C_setConfig (I2CA_BASE、(I2C_MASTER_SEND_MODE));
I2C_enableInterrupt (I2CA_BASE、(I2C_INT_ADDR_SLAVE | I2C_INT_STOP_Condition | I2C_INT_ARB_LOSS| I2C_INT_NO_ACK));
}
//用于显示 I2C 上连接的设备的功能
void printAvailable_I2C_Devices (){
uint8_t I = 0;
I2CBUS_SCAN (设备)
//只想密钥存储阵列的非空地址
for (i = 0;i <= 19;i++){//AvailbleDevices[]数组只有20个大容量,但可以在需要时进行扩展
//检查数组中的值是否为空
if (AvailableI2C_slaves [i]!= 0){
newline();//在屏幕上打印新行
sendMsg ((uint16_t*)"I2C Detected! 目标地址为:"、33);
printByte (AvailableI2C_slaves [i]);
newline();
}
}
}
空开始传输(uint16_t slaveAddr)
{
//检查地址是否有效
bool IsValid = I2C_isBaseValid (I2CA_BASE);
//检查总线是否繁忙,这可能是我们的问题
while (I2C_isBusy (I2CA_BASE));
while (I2C_getStopConditionStatus (I2CA_BASE));
I2C_setConfig (I2CA_BASE、(I2C_MASTER_SEND_MODE|I2C_REPEATE_MODE));
I2C_setSlaveAddress (I2CA_BASE、slaveAddr);
I2C_sendStartCondition (I2CA_BASE);
Status = I2C_getStatus (I2CA_BASE);//不断返回0x00001411
while (! (I2C_getStatus (I2CA_BASE)和 I2C_STS_REG_ACCESS_RDY);
}
空写入(uint16_t DATA)
{
while (! (I2C_getStatus (I2CA_BASE)和 I2C_STS_TX_DATA_RDY);
I2C_putData (I2CA_BASE、DATA);
// I2C_clearStatus (I2CA_BASE、I2C_STS_TX_DATA_RDY);
}
空 endTransmission ()
{
// while (! (I2C_getStatus (I2CA_BASE)和 I2C_STS_TX_DATA_RDY);
I2C_sendStopCondition (I2CA_BASE);
}
void read (uint16_t *数据、uint16_t count)
{
uint8_t I = 0;
对于(I = 0;I < count;I++)
{
while (! (I2C_getStatus (I2CA_BASE)和 I2C_STS_RX_DATA_RDY);
data[i]= I2C_getData (I2CA_BASE);
如果(i == count - 1){
//如果是最后一个数据字节,则清除接收标志
I2C_clearStatus (I2CA_BASE、I2C_STS_RX_DATA_RDY);
}
}
}
void requestFrom (uint16_t slaveAddr、uint16_t regAddr、uint16_t count)
{
while (I2C_getStopConditionStatus (I2CA_BASE));
I2C_setSlaveAddress (I2CA_BASE、slaveAddr);
I2C_setConfig (I2CA_BASE、(I2C_MASTER_SEND_MODE | I2C_REPEATE_MODE));
I2C_sendStartCondition (I2CA_BASE);
while (! (I2C_getStatus (I2CA_BASE)和 I2C_STS_REG_ACCESS_RDY);
I2C_putData (I2CA_BASE、regAddr);
while (! (I2C_getStatus (I2CA_BASE)和 I2C_STS_TX_DATA_RDY);
I2C_setSlaveAddress (I2CA_BASE、slaveAddr);
//设置要接收的字节数的数据计数
I2C_setDataCount (I2CA_BASE、count);
//设置接收模式的 I2C 配置
I2C_setConfig (I2CA_BASE、(I2C_MASTER_RECEIVE_MODE | I2C_REPEATE_MODE));
//发送重复启动条件
I2C_sendStartCondition (I2CA_BASE);
}
//------------------
//测试功能
//------------------
//进行实验以确保 I2C 正常工作
void prox_init()
开始传输(0x60);
写入(0x03);
写入(0xCE);
写入(0x08);
endTransmission ();
DEVICE_DELAY_US (300000);
开始传输(0x60);
写入(0x04);
写入(0x47);
写入(0x10);
endTransmission ();
DEVICE_DELAY_US (300000);
}
uint16_t read_proximity (){
uint16_t data_ret;
requestFrom (0x60、0x08、2);
读(k、2);
endTransmission ();
data_ret = data[0]<< 8;
data_ret +=数据[1];
返回 data_ret;
}
空 printPressure (){
uint16_t proxyData;
while (1){
proxyData = Read_Proximity ();
print_word (proxyData);
newline();
device_delay_us (500);
}
}
//------------------
//
//主要功能
//
//------------------
// MainMenu 将供用户选择要选择的选项
//这可以实现模块化测试功能,快速添加测试和使用其他
//测试以加快开发速度!
空 MainMenu()
{
//变量用于存储用户选择的内容。
uint8_t userChoice[1];
while (1)
{
// prox_init ();
// printPressure ();
newline();
sendMsg ("欢迎管理、到 WHSIP001 TMS320F28384D 测试板。"、52);
newline();
sendMsg ("请查看下面的菜单选项:"、34);
newline();
sendMsg ("1)向屏幕打印大气压力",42);
newline();
sendMsg ("2)将简单的消息打印到文本文件并保存在 SD 卡上"、60);
newline();
sendMsg ("3)扫描 I2C 总线以查找器件地址"、37);
newline();
DEVICE_DELAY_US (10000);
userChoice[0]= getChar();
if (userChoice[0]=='1'){
printPressure ();
}
if (userChoice[0]=='2'){
}
if (userChoice[0]=='3'){
printAvailable_I2C_Devices ();
}
}
}
//
//主菜单
//
空 main (void)
{
//
//初始化设备时钟和外设
//
device_init();
//
//禁用引脚锁定并启用内部上拉。
//
device_initGPIO();
//
//初始化 PIE 和清除 PIE 寄存器。 禁用 CPU 中断。
//
interrupt_initModule();
//
//使用指向 shell 中断的指针初始化 PIE 矢量表
//服务例程(ISR)。
//
interrupt_initVectorTable();
//
// PinMux 和外设初始化
//
Board_init();
//
// C2000Ware 库初始化
//
// C2000Ware_libraries_init ();
//
//启用全局中断(INTM)和实时中断(DBGM)
//
EINT;
ERTM;
while (1)
{
prox_init();
MainMenu();
}
}
配置代码:
//*****
//
// I2C 配置
//
//*****
void I2C_init()
VNCL_4040_init ();
}
void VNCL_4040_init (){
I2C_disableModule (VNCL_40_BASE);
I2C_initController (VNCL_4040_BASE、DEVICE_SYSCLK_FREQ、200000、I2C_DUTYCYCLE_50);
I2C_setConfig (VNCL_4040_BASE、I2C_CONTROL_SEND_MODE);
I2C_setTargetAddress (VNCL_4040_BASE、96);
I2C_disableLoopback (VNCL_4040_BASE);
I2C_setBitCount (VNCL_4040_BASE、I2C_BITCOUNT_8);
I2C_setDataCount (VNCL_4040_BASE、1);
I2C_setAddressMode (VNCL_4040_BASE、I2C_ADDR_MODE_7BITS);
I2C_disableFIFO (VNCL_40_BASE);
I2C_clearInterruptStatus (VNCL_4040_BASE、I2C_INT_REG_ACCESS_RDY | I2C_INT_RX_DATA_RDY | I2C_INT_STOP_Condition | I2C_INT_TX_DATA_RDY);
I2C_enableInterrupt (VNCL_40_BASE、I2C_INT_REG_ACCESS_RDY | I2C_INT_RX_DATA_RDY | I2C_INT_STOP_Condition | I2C_INT_TX_DATA_RDY);
I2C_setEmulationMode (VNCL_4040_BASE、I2C_emulation_free_run);
I2C_enableModule (VNCL_40_BASE);
}
//*****
//
// PinMux 配置
//
//*****
//
// GPIO167 - GPIO 设置
//
#define myBoardLED0_GPIO_PIN_CONFIG GPIO_167_GPIO167
//
// I2CA -> VNCL_4040引脚多路复用
//
//
// I2CA_SDA - GPIO 设置
//
#define GPIO_PIN_I2CA_SDA 0
#define VNCL_4040_I2CSDA_GPIO 0
#define VNCL_4040_I2CSDA_PIN_CONFIG GPIO_0_I2CA_SDA
//
// I2CA_SCL - GPIO 设置
//
#define GPIO_PIN_I2CA_SCL 1
#define VNCL_4040_I2CSCL_GPIO 1
#define VNCL_4040_I2CSCL_PIN_CONFIG GPIO_1_I2CA_SCL
//
// SCIA -> mySCI0引脚多路复用
//
//
// SCIA_RX - GPIO 设置
//
#define GPIO_PIN_SCIA_RX 43
#define mySCI0_SCIRX_GPIO 43
#define mySCI0_SCIRX_PIN_CONFIG GPIO_43_SCIA_RX
//
// SCIA_TX - GPIO 设置
//
#define GPIO_PIN_SCIA_TX 42
#define mySCI0_SCITX_GPIO 42
#define mySCI0_SCITX_PIN_CONFIG GPIO_42_SCIA_TX
//*****
//
// CPUTIMER 配置
//
//*****
#define Led_Toggle_Timer_ CPUTIMER0_BASE
void Led_Toggle_Timer_();
//*****
//
// GPIO 配置
//
//*****
#define myBoardLED0_GPIO 167
void myBoardLED0_GPIO_init ();
//*****
//
// I2C 配置
//
//*****
#define VNCL_4040_BASE I2CA_BASE
#define VNCL_4040_bitrate 200000
#define VNCL_4040_TARGET_ADDRESS 96
#define VNCL_4040_own_target_address 0
void VNCL_4040_init ();
//*****
//
//中断配置
//
//*****
// Led_Toggle_Timer 的中断设置
#define INT_TIMER0 INT_TIMER0 Led_Toggle_Timer
#define INT_RUPT_ACK_GROUP Led_Toggle_Timer_ INTERRUPT_ACK_GROUP1
extern _interrupt void INT_402 Led_Toggle_Timer_(void);
//*****
//
// SCI 配置
//
//*****
#define mySCI0_BASE SCIA_BASE
#define mySCI0_BAUDRATE 115200
#define mySCI0_CONFIG_WLEN SCI_CONFIG_WLEN_8
#define mySCI0_CONFIG_STOP SCI_CONFIG_STOP_ONE
#define mySCI0_CONFIG_PAR SCI_CONFIG_PAR_NONE
void mySCI0_init ();
//*****
//
//板配置
//
//*****
void Board_init();
void CPUTIME_INIT();
void GPIO_init();
void I2C_init();
void interrupt_init();
void sci_init();
void PinMux_init ();