我打算使用TI F28335开发板读取一个湿度传感器的数据,通过I2C 通信。 我附上修改后的程序(基于TI官方的给F28335写的I2C的一个例子程序),发现这个例子程序并不可以运行。每次都是卡在 while(I2caRegs.I2CSTR.bit.XRDY == 0); // wait until first byte is out 这条语句无线循环,并不能继续执行下去。这个问题困扰我很久,是因为这个例子程序本身就有问题吗?还是因为其他原因? 这个传感器我目前使用的datasheet的PDF文件链接如下:https://www.pololu.com/file/0J721/HTU21D(F).pdf 方便您参考。 通信中使用的register还有地址我都严格按照datasheet上面所说应该都没有问题,build这个程序过程中也并没有报错,所以完全不知道我这个程序问题出在哪里。 传感器我使用的是adafruit家已经做好的breakout board,应该已经包括pull up resistor。 这个硬件链接在这里:https://learn.adafruit.com/adafruit-htu21d-f-temperature-humidity-sensor/overview
// //Lab12_2: TMS320F28335 //(C) Frank Bormann // //########################################################################### // // FILE: Lab12_2.c // // TITLE: DSP28335 I2C test //Temperature Sensor TMP100 connected to GPIO33 (SCL) and GPIO32(SDA) // LED GPIO34 as life indicator 100 ms toggle // 12 bit mode of TMP100, 1/16 degree celcius resolution // use watch window for variable "temperature" (type int; qvalue:8) //########################################################################### // // Ver | dd mmm yyyy | Who | Description of changes // =====|=============|======|=============================================== // 3.0 | 24 Jul 2009 | F.B. | Lab12_1 F28335; Header-files Version 1.20 // 3.1 | 15 Nov 2009 | F.B | Lab12_1 for F28335 @30MHz and PE revision 5 //########################################################################### #include "DSP2833x_Device.h" #define SLAVE_Address 0x40 #define SLAVE_Write0x80 #define SLAVE_READ0x81 #define SLAVE_Write_humidity0xE5 // external function prototypes extern void InitSysCtrl(void); extern void InitPieCtrl(void); extern void InitPieVectTable(void); extern void InitCpuTimers(void); extern void ConfigCpuTimer(struct CPUTIMER_VARS *, float, float); // Prototype statements for functions found within this file. void Gpio_select(void); void I2CA_Init(void); interrupt void cpu_timer0_isr(void); int Value_Read; //########################################################################### // main code //########################################################################### void main(void) { InitSysCtrl(); // Basic Core Init from DSP2833x_SysCtrl.c EALLOW; SysCtrlRegs.WDCR= 0x00AF; // Re-enable the watchdog EDIS; // 0x00AF to NOT disable the Watchdog, Prescaler = 64 DINT; // Disable all interrupts Gpio_select(); // GPI031-LED2, GPIO34-LED3 as output // to 2 LEDs on F28335 control-card I2CA_Init(); // Initialize I2C device slave address is issued in I2CA_Init() 0x29 // step 1 : do the configuration: //----------------------------------------------------// // Send START, set pointer to Configuration register and set resolution to 12 bit //hence it is master-transmitter mode to write register to the sensor //step 1.1 set integration time to address 0x01+0xFF (2.4ms) //step 1.2 set gain to address 0x0F + 0x00 (1*gain) //step 1.3 Enable Device to address 0x00+0x03 I2caRegs.I2CCNT = 2; // means the DXR includes 2 byte including POINTER_CONFIGURATION and 0x60 for data bit setting I2caRegs.I2CDXR = SLAVE_Write;// address for writing I2caRegs.I2CMDR.all = 0x6E20; //0x6E20 convert to binary is 0110111000100000 /*Bit15 = 0; no NACK in receiver mode Bit14 = 1; FREE on emulation halt Bit13 = 1; STT generate START Bit12 = 0; reserved Bit11 = 1; STP generate STOP Bit10 = 1; MST master mode Bit9 = 1; TRX ****master - transmitter mode**** Bit8 = 0; XA7 bit address mode Bit7 = 0; RMnonrepeat mode, I2CCNT determines # of bytes Bit6 = 1; DLB no loopback mode.it should be '0', from slide 12-12 corrected by Alex.J. Bit5 = 1; IRS I2C module enabled Bit4 = 0; STB no start byte mode Bit3 = 0; FDF no free data format Bit2-0: 0; BC **** 8 bit per data byte**** */ while(I2caRegs.I2CSTR.bit.XRDY == 0); // wait until first byte is out I2caRegs.I2CDXR = SLAVE_Write_humidity ;/*0xE5 read humidity*/ while(I2caRegs.I2CSTR.bit.SCD == 0); // wait for STOP condition I2caRegs.I2CSTR.bit.SCD = 1; //clear stop condition flag InitPieCtrl(); // basic setup of PIE table; from DSP2833x_PieCtrl.c InitPieVectTable(); // default ISR's in PIE EALLOW; PieVectTable.TINT0 = &cpu_timer0_isr; EDIS; InitCpuTimers(); // basic setup CPU Timer0, 1 and 2 ConfigCpuTimer(&CpuTimer0,150,100000); PieCtrlRegs.PIEIER1.bit.INTx7 = 1; IER |=1; EINT; ERTM; CpuTimer0Regs.TCR.bit.TSS = 0; // start timer0 //step 2 : start read the sensor data including 1 byte pointer register==>2 byte sensor data (upper 8bit) + (lower 8bit) while(1) {while(CpuTimer0.InterruptCount == 0);CpuTimer0.InterruptCount = 0; EALLOW; SysCtrlRegs.WDKEY = 0x55; // service WD #1 EDIS; // Send START and set pointer to temperature - register I2caRegs.I2CCNT = 1; // pointer to temperature register, count 1 bit only I2caRegs.I2CDXR = SLAVE_READ;// address for reading // Send start as master transmitter I2caRegs.I2CMDR.all = 0x6620; //only change stop to '0', do not generate stop. all others are the same as 6E20 /* Bit15 = 0; no NACK in receiver mode Bit14 = 1; FREE on emulation halt Bit13 = 1; STT generate START Bit12 = 0; reserved Bit11 = 0; STP not generate STOP Bit10 = 1; MST master mode Bit9 = 1; TRX master - transmitter mode Bit8 = 0; XA7 bit address mode Bit7 = 0; RMnonrepeat mode, I2CCNT determines # of bytes Bit6 = 1; DLB no loopback mode ,it should be '0', corrected by alex.J Bit5 = 1; IRS I2C module enabled Bit4 = 0; STB no start byte mode Bit3 = 0; FDF no free data format Bit2-0: 0; BC8 bit per data byte,000 */ while(I2caRegs.I2CSTR.bit.ARDY == 0); // 0=previous cycle has not completed, wait for access ready condition I2caRegs.I2CCNT = 1; // read 2 byte temperature I2caRegs.I2CMDR.all = 0x6C20; //only change bit9 to 0, means master-receiver mode /* Bit15 = 0; no NACK in receiver mode Bit14 = 1; FREE on emulation halt Bit13 = 1; STT generate START Bit12 = 0; reserved Bit11 = 1; STP generate STOP Bit10 = 1; MST master mode Bit9 = 0; TRX master - receiver mode Bit8 = 0; XA7 bit address mode Bit7 = 0; RMnonrepeat mode, I2CCNT determines # of bytes Bit6 = 0; DLB no loopback mode Bit5 = 1; IRS I2C module enabled Bit4 = 0; STB no start byte mode Bit3 = 0; FDF no free data format Bit2-0: 0; BC8 bit per data byte */ while(I2caRegs.I2CSTR.bit.RRDY == 0); //0 means receive data NOT available in 12CDRR, wait for 1st byte Value_Read = I2caRegs.I2CDRR; // read 8 Bit (integers) // RRDY is automatically cleared by read of I2CDRR GpioDataRegs.GPBTOGGLE.bit.GPIO34 = 1; // toggle red LED LD3 @ 28335CC GpioDataRegs.GPATOGGLE.bit.GPIO31 = 1; } } void Gpio_select(void) { EALLOW; GpioCtrlRegs.GPAMUX1.all = 0; // GPIO15 ... GPIO0 = General Puropse I/O GpioCtrlRegs.GPAMUX2.all = 0; // GPIO31 ... GPIO16 = General Purpose I/O GpioCtrlRegs.GPBMUX1.all = 0; // GPIO47 ... GPIO32 = General Purpose I/O GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 1; // GPIO32 = I2C - SDA GpioCtrlRegs.GPBMUX1.bit.GPIO33 = 1; // GPIO33 = I2C - SCL GpioCtrlRegs.GPBPUD.bit.GPIO32 = 0;// Enable pull-up for GPIO32 (SDAA) GpioCtrlRegs.GPBPUD.bit.GPIO33 = 0;// Enable pull-up for GPIO33 (SCLA) GpioCtrlRegs.GPBQSEL1.bit.GPIO32 = 3; // Asynch input GPIO32 (SDAA)GpioCtrlRegs.GPBQSEL1.bit.GPIO33 = 3; // Asynch input GPIO33 (SCLA) GpioCtrlRegs.GPBMUX2.all = 0; // GPIO63 ... GPIO48 = General Purpose I/O GpioCtrlRegs.GPCMUX1.all = 0; // GPIO79 ... GPIO64 = General Purpose I/O GpioCtrlRegs.GPCMUX2.all = 0; // GPIO87 ... GPIO80 = General Purpose I/O GpioCtrlRegs.GPADIR.all = 0; // GPIO0 to 31 as inputs // GpioCtrlRegs.GPADIR.bit.GPIO9 = 1; // GPIO9 = LED LD1 GpioCtrlRegs.GPADIR.bit.GPIO31 = 1; // GpIO11 = LED LD2 GpioCtrlRegs.GPBDIR.all = 0; // GPIO63-32 as inputs GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1; // peripheral explorer: LED LD3 at GPIO34 //GpioCtrlRegs.GPBDIR.bit.GPIO49 = 1; // peripheral explorer: LED LD4 at GPIO49 GpioCtrlRegs.GPCDIR.all = 0; // GPIO87-64 as inputs EDIS; } void I2CA_Init(void) { I2caRegs.I2CMDR.bit.IRS = 0; // Reset the I2C module // I2C slave address register I2caRegs.I2CSAR = SLAVE_Address; // I2C Prescale Register I2caRegs.I2CPSC.all = 14; // Internal I2C module clock = SYSCLK/(PSC +1)// = 10 MHzI2caRegs.I2CCLKL = 95; // Tmaster = (PSC +1)[ICCL + 5 + ICCH + 5] / 150MHz I2caRegs.I2CCLKH = 95; // Tmaster = 10 [ICCL + ICCH + 10] / 150 MHz // d = 5 for IPSC >1 // for I2C 50 kHz: // Tmaster = 20 µs *150 MHz / 10 = 200 = (ICCL + ICCH +10) // ICCL + ICCH = 190 // ICCL = ICH = 190/2 = 95 // I2caRegs.I2CCLKL = 45; // I2caRegs.I2CCLKH = 45; // for I2C 100 kHz: // Tmaster = 10 µs *150 MHz / 10 = 100 = (ICCL + ICCH + 10) // ICCL + ICCH = 90 // ICCL = ICH = 90/2 = 45 I2caRegs.I2CMDR.bit.IRS = 1; // Take I2C out of reset } interrupt void cpu_timer0_isr(void) { CpuTimer0.InterruptCount++; EALLOW; SysCtrlRegs.WDKEY = 0xAA; // service WD #2 EDIS; PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; } //=========================================================================== // End of SourceCode. //===========================================================================
Johnson Chen1:
TI的官方例程是没有问题的。应该是你修改后出的问题。
应该是你的数据没有发出去,你可以通过示波器测量SDA, CLK确认一下。
我打算使用TI F28335开发板读取一个湿度传感器的数据,通过I2C 通信。 我附上修改后的程序(基于TI官方的给F28335写的I2C的一个例子程序),发现这个例子程序并不可以运行。每次都是卡在 while(I2caRegs.I2CSTR.bit.XRDY == 0); // wait until first byte is out 这条语句无线循环,并不能继续执行下去。这个问题困扰我很久,是因为这个例子程序本身就有问题吗?还是因为其他原因? 这个传感器我目前使用的datasheet的PDF文件链接如下:https://www.pololu.com/file/0J721/HTU21D(F).pdf 方便您参考。 通信中使用的register还有地址我都严格按照datasheet上面所说应该都没有问题,build这个程序过程中也并没有报错,所以完全不知道我这个程序问题出在哪里。 传感器我使用的是adafruit家已经做好的breakout board,应该已经包括pull up resistor。 这个硬件链接在这里:https://learn.adafruit.com/adafruit-htu21d-f-temperature-humidity-sensor/overview
// //Lab12_2: TMS320F28335 //(C) Frank Bormann // //########################################################################### // // FILE: Lab12_2.c // // TITLE: DSP28335 I2C test //Temperature Sensor TMP100 connected to GPIO33 (SCL) and GPIO32(SDA) // LED GPIO34 as life indicator 100 ms toggle // 12 bit mode of TMP100, 1/16 degree celcius resolution // use watch window for variable "temperature" (type int; qvalue:8) //########################################################################### // // Ver | dd mmm yyyy | Who | Description of changes // =====|=============|======|=============================================== // 3.0 | 24 Jul 2009 | F.B. | Lab12_1 F28335; Header-files Version 1.20 // 3.1 | 15 Nov 2009 | F.B | Lab12_1 for F28335 @30MHz and PE revision 5 //########################################################################### #include "DSP2833x_Device.h" #define SLAVE_Address 0x40 #define SLAVE_Write0x80 #define SLAVE_READ0x81 #define SLAVE_Write_humidity0xE5 // external function prototypes extern void InitSysCtrl(void); extern void InitPieCtrl(void); extern void InitPieVectTable(void); extern void InitCpuTimers(void); extern void ConfigCpuTimer(struct CPUTIMER_VARS *, float, float); // Prototype statements for functions found within this file. void Gpio_select(void); void I2CA_Init(void); interrupt void cpu_timer0_isr(void); int Value_Read; //########################################################################### // main code //########################################################################### void main(void) { InitSysCtrl(); // Basic Core Init from DSP2833x_SysCtrl.c EALLOW; SysCtrlRegs.WDCR= 0x00AF; // Re-enable the watchdog EDIS; // 0x00AF to NOT disable the Watchdog, Prescaler = 64 DINT; // Disable all interrupts Gpio_select(); // GPI031-LED2, GPIO34-LED3 as output // to 2 LEDs on F28335 control-card I2CA_Init(); // Initialize I2C device slave address is issued in I2CA_Init() 0x29 // step 1 : do the configuration: //----------------------------------------------------// // Send START, set pointer to Configuration register and set resolution to 12 bit //hence it is master-transmitter mode to write register to the sensor //step 1.1 set integration time to address 0x01+0xFF (2.4ms) //step 1.2 set gain to address 0x0F + 0x00 (1*gain) //step 1.3 Enable Device to address 0x00+0x03 I2caRegs.I2CCNT = 2; // means the DXR includes 2 byte including POINTER_CONFIGURATION and 0x60 for data bit setting I2caRegs.I2CDXR = SLAVE_Write;// address for writing I2caRegs.I2CMDR.all = 0x6E20; //0x6E20 convert to binary is 0110111000100000 /*Bit15 = 0; no NACK in receiver mode Bit14 = 1; FREE on emulation halt Bit13 = 1; STT generate START Bit12 = 0; reserved Bit11 = 1; STP generate STOP Bit10 = 1; MST master mode Bit9 = 1; TRX ****master - transmitter mode**** Bit8 = 0; XA7 bit address mode Bit7 = 0; RMnonrepeat mode, I2CCNT determines # of bytes Bit6 = 1; DLB no loopback mode.it should be '0', from slide 12-12 corrected by Alex.J. Bit5 = 1; IRS I2C module enabled Bit4 = 0; STB no start byte mode Bit3 = 0; FDF no free data format Bit2-0: 0; BC **** 8 bit per data byte**** */ while(I2caRegs.I2CSTR.bit.XRDY == 0); // wait until first byte is out I2caRegs.I2CDXR = SLAVE_Write_humidity ;/*0xE5 read humidity*/ while(I2caRegs.I2CSTR.bit.SCD == 0); // wait for STOP condition I2caRegs.I2CSTR.bit.SCD = 1; //clear stop condition flag InitPieCtrl(); // basic setup of PIE table; from DSP2833x_PieCtrl.c InitPieVectTable(); // default ISR's in PIE EALLOW; PieVectTable.TINT0 = &cpu_timer0_isr; EDIS; InitCpuTimers(); // basic setup CPU Timer0, 1 and 2 ConfigCpuTimer(&CpuTimer0,150,100000); PieCtrlRegs.PIEIER1.bit.INTx7 = 1; IER |=1; EINT; ERTM; CpuTimer0Regs.TCR.bit.TSS = 0; // start timer0 //step 2 : start read the sensor data including 1 byte pointer register==>2 byte sensor data (upper 8bit) + (lower 8bit) while(1) {while(CpuTimer0.InterruptCount == 0);CpuTimer0.InterruptCount = 0; EALLOW; SysCtrlRegs.WDKEY = 0x55; // service WD #1 EDIS; // Send START and set pointer to temperature - register I2caRegs.I2CCNT = 1; // pointer to temperature register, count 1 bit only I2caRegs.I2CDXR = SLAVE_READ;// address for reading // Send start as master transmitter I2caRegs.I2CMDR.all = 0x6620; //only change stop to '0', do not generate stop. all others are the same as 6E20 /* Bit15 = 0; no NACK in receiver mode Bit14 = 1; FREE on emulation halt Bit13 = 1; STT generate START Bit12 = 0; reserved Bit11 = 0; STP not generate STOP Bit10 = 1; MST master mode Bit9 = 1; TRX master - transmitter mode Bit8 = 0; XA7 bit address mode Bit7 = 0; RMnonrepeat mode, I2CCNT determines # of bytes Bit6 = 1; DLB no loopback mode ,it should be '0', corrected by alex.J Bit5 = 1; IRS I2C module enabled Bit4 = 0; STB no start byte mode Bit3 = 0; FDF no free data format Bit2-0: 0; BC8 bit per data byte,000 */ while(I2caRegs.I2CSTR.bit.ARDY == 0); // 0=previous cycle has not completed, wait for access ready condition I2caRegs.I2CCNT = 1; // read 2 byte temperature I2caRegs.I2CMDR.all = 0x6C20; //only change bit9 to 0, means master-receiver mode /* Bit15 = 0; no NACK in receiver mode Bit14 = 1; FREE on emulation halt Bit13 = 1; STT generate START Bit12 = 0; reserved Bit11 = 1; STP generate STOP Bit10 = 1; MST master mode Bit9 = 0; TRX master - receiver mode Bit8 = 0; XA7 bit address mode Bit7 = 0; RMnonrepeat mode, I2CCNT determines # of bytes Bit6 = 0; DLB no loopback mode Bit5 = 1; IRS I2C module enabled Bit4 = 0; STB no start byte mode Bit3 = 0; FDF no free data format Bit2-0: 0; BC8 bit per data byte */ while(I2caRegs.I2CSTR.bit.RRDY == 0); //0 means receive data NOT available in 12CDRR, wait for 1st byte Value_Read = I2caRegs.I2CDRR; // read 8 Bit (integers) // RRDY is automatically cleared by read of I2CDRR GpioDataRegs.GPBTOGGLE.bit.GPIO34 = 1; // toggle red LED LD3 @ 28335CC GpioDataRegs.GPATOGGLE.bit.GPIO31 = 1; } } void Gpio_select(void) { EALLOW; GpioCtrlRegs.GPAMUX1.all = 0; // GPIO15 ... GPIO0 = General Puropse I/O GpioCtrlRegs.GPAMUX2.all = 0; // GPIO31 ... GPIO16 = General Purpose I/O GpioCtrlRegs.GPBMUX1.all = 0; // GPIO47 ... GPIO32 = General Purpose I/O GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 1; // GPIO32 = I2C - SDA GpioCtrlRegs.GPBMUX1.bit.GPIO33 = 1; // GPIO33 = I2C - SCL GpioCtrlRegs.GPBPUD.bit.GPIO32 = 0;// Enable pull-up for GPIO32 (SDAA) GpioCtrlRegs.GPBPUD.bit.GPIO33 = 0;// Enable pull-up for GPIO33 (SCLA) GpioCtrlRegs.GPBQSEL1.bit.GPIO32 = 3; // Asynch input GPIO32 (SDAA)GpioCtrlRegs.GPBQSEL1.bit.GPIO33 = 3; // Asynch input GPIO33 (SCLA) GpioCtrlRegs.GPBMUX2.all = 0; // GPIO63 ... GPIO48 = General Purpose I/O GpioCtrlRegs.GPCMUX1.all = 0; // GPIO79 ... GPIO64 = General Purpose I/O GpioCtrlRegs.GPCMUX2.all = 0; // GPIO87 ... GPIO80 = General Purpose I/O GpioCtrlRegs.GPADIR.all = 0; // GPIO0 to 31 as inputs // GpioCtrlRegs.GPADIR.bit.GPIO9 = 1; // GPIO9 = LED LD1 GpioCtrlRegs.GPADIR.bit.GPIO31 = 1; // GpIO11 = LED LD2 GpioCtrlRegs.GPBDIR.all = 0; // GPIO63-32 as inputs GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1; // peripheral explorer: LED LD3 at GPIO34 //GpioCtrlRegs.GPBDIR.bit.GPIO49 = 1; // peripheral explorer: LED LD4 at GPIO49 GpioCtrlRegs.GPCDIR.all = 0; // GPIO87-64 as inputs EDIS; } void I2CA_Init(void) { I2caRegs.I2CMDR.bit.IRS = 0; // Reset the I2C module // I2C slave address register I2caRegs.I2CSAR = SLAVE_Address; // I2C Prescale Register I2caRegs.I2CPSC.all = 14; // Internal I2C module clock = SYSCLK/(PSC +1)// = 10 MHzI2caRegs.I2CCLKL = 95; // Tmaster = (PSC +1)[ICCL + 5 + ICCH + 5] / 150MHz I2caRegs.I2CCLKH = 95; // Tmaster = 10 [ICCL + ICCH + 10] / 150 MHz // d = 5 for IPSC >1 // for I2C 50 kHz: // Tmaster = 20 µs *150 MHz / 10 = 200 = (ICCL + ICCH +10) // ICCL + ICCH = 190 // ICCL = ICH = 190/2 = 95 // I2caRegs.I2CCLKL = 45; // I2caRegs.I2CCLKH = 45; // for I2C 100 kHz: // Tmaster = 10 µs *150 MHz / 10 = 100 = (ICCL + ICCH + 10) // ICCL + ICCH = 90 // ICCL = ICH = 90/2 = 45 I2caRegs.I2CMDR.bit.IRS = 1; // Take I2C out of reset } interrupt void cpu_timer0_isr(void) { CpuTimer0.InterruptCount++; EALLOW; SysCtrlRegs.WDKEY = 0xAA; // service WD #2 EDIS; PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; } //=========================================================================== // End of SourceCode. //===========================================================================
pan zheng:
你好!我也遇到同样的问题,请问你的问题解决了吗?怎么解决的?