3772|2

20

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

MSP430 硬件I2C 中断法始终调不通,求助!!! [复制链接]

MSP430F5x单片机硬件I2C通过中断的方式对AT24C02进行读写
代码如下:
  1. #include "msp430.h"

  2. typedef unsigned char uint8;

  3. uint8 test_buf1[10] = {'H','E','L','L','O','Y','O','U',0,0};
  4. uint8 test_buf2[10] = {0,0,0,0,0,0,0,0,0};
  5. uint8 test_byte1 = 0x0c;
  6. uint8 test_byte2 = 0x00;

  7. //UCB0---I2C
  8. uint8 I2C_Tx_Size = 0;         //left data to be sent
  9. uint8 I2C_Rx_Size = 0;         //left data to be received
  10. uint8 *I2C_Tx_Buffer;         //pointer of data to be sent
  11. uint8 *I2C_Rx_Buffer;         //pointer of data to be received
  12. uint8 I2C_State = 0;         //flag of I2C tranmit or receive state
  13. uint8 I2C_Read_Data_Address = 0;
  14. uint8 I2C_Write_Data_Address = 0;
  15. uint8 UCB0_Rx_Or_Tx = 0; // 0--Receive only; 1--Transmit only; 2--Receive and transmit
  16. uint8 Flag_ACK=1;
  17. uint8 Flag_I2C_Address_Transmitted=0;

  18. #define EEPROM_SCL                        BIT2        //P1.2
  19. #define EEPROM_SDA                        BIT3        //P1.3
  20. #define ADG841_IN1                        BIT7        //P3.7
  21. #define LED                                    BIT1        //P3.1
  22. #define I2C_SLAVE_ADDR                        0x50

  23. //Delay
  24. #define         CPU_F                          ((double)26000000)        //XT2CLK--26MHz
  25. #define         delay_us(x)                  __delay_cycles((long)(CPU_F*(double)x/1000000.0))
  26. #define         delay_ms(x)                  __delay_cycles((long)(CPU_F*(double)x/1000.0))

  27. void UCB0_Interrupt_Sel(uint8);


  28. void CLK_Init()
  29. {
  30.         UCSCTL6 &= ~(XT2OFF+XT1OFF);                      // Enable XT2--26MHz XT1--32.768kHz

  31.         UCSCTL4 = SELA_0 + SELS_5 + SELM_5;

  32.         UCSCTL5 = DIVM_0 | DIVS_0 | DIVA_0;

  33.         do
  34.         {
  35.                   UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
  36.                                                         // Clear XT2,DCO fault flags
  37.                   SFRIFG1 &= ~OFIFG;                        // Clear fault flags
  38.         }while (SFRIFG1&OFIFG);                           // Test oscillator fault flag

  39.         UCSCTL4 = SELA_0 + SELS_5 + SELM_5;
  40. }
  41. void GPIO_Init()
  42. {
  43.         P3DIR |= LED + ADG841_IN1;

  44.         P5SEL |= BIT0 + BIT1; //Port select XT1
  45. }

  46. void LED_ON()
  47. {
  48.         P3OUT |= LED;
  49. }

  50. void LED_OFF()
  51. {
  52.         P3OUT &= ~LED;
  53. }

  54. void UCB0_I2C_Init()
  55. {
  56.         P1SEL |= EEPROM_SCL + EEPROM_SDA;
  57.         /* Disable USCI */
  58.         UCB0CTL1 |= UCSWRST;

  59.         //UCB0CTL0 &= ~UCSLA10;////
  60.         UCB0CTL0 = UCMST | UCMODE_3 | UCSYNC; //I2C, Mater mode, Synchronous mode

  61.         UCB0CTL1 = UCSSEL_2 | UCSWRST;

  62.         /* I2C Slave Address Register */
  63.         UCB0I2CSA = I2C_SLAVE_ADDR;

  64.         /* Bit Rate Control Register 0 */
  65.         UCB0BR0 = 4;   //  26MHz/260=100KHz
  66.         UCB0BR1 = 1;
  67.         /* Enable USCI */
  68.         UCB0CTL1 &= ~UCSWRST;

  69.         P3OUT |= ADG841_IN1;
  70. }

  71. uint8 I2C_Write_Page(uint8 Data_Address, uint8 *pBuffer, uint8 size)
  72. {
  73.         if(size==0)
  74.                 return 0;
  75.         if(UCB0STAT & UCBUSY)         //If I2C is busy
  76.                 return 0;

  77.         Flag_I2C_Address_Transmitted=0;

  78.         I2C_Write_Data_Address=Data_Address;
  79.         I2C_Tx_Buffer=pBuffer;
  80.         //I2C_Tx_Size=size-1;
  81.         I2C_Tx_Size=size;

  82.         //_EINT();
  83.         UCB0IFG &= ~UCTXIFG;
  84.         UCB0_Rx_Or_Tx = 1;                                         //transmit interrupt only
  85.         UCB0_Interrupt_Sel(UCB0_Rx_Or_Tx);
  86.         _EINT();

  87.         while( UCB0CTL1& UCTXSTP );
  88.         UCB0CTL1 |= UCTR+UCTXSTT;           //write mode, send start bit

  89.         __bis_SR_register(LPM0_bits);     // Enter LPM0

  90.         return 1;
  91. }

  92. uint8 I2C_Read_Page(uint8 Read_Data_Address, uint8 *pbuffer, uint8 size)
  93. {
  94.         _DINT();
  95.         if(size==0)
  96.                 return 0;
  97.         if(UCB0STAT & UCBUSY)        //If I2C is busy
  98.                 return 0;

  99.         I2C_Read_Data_Address=Read_Data_Address; // set address
  100.         Flag_I2C_Address_Transmitted=0;
  101.         I2C_Tx_Size=0;
  102. /*
  103.         UCB0_Rx_Or_Tx = 1;                //enable transmit interrupt bit only
  104.         _EINT();
  105.         UCB0_Interrupt_Sel(UCB0_Rx_Or_Tx);
  106. */

  107.         while( UCB0CTL1& UCTXSTP );
  108.         UCB0CTL1 |= UCTR;                //write mode
  109.         UCB0CTL1 |= UCTXSTT;    //send start bit
  110.         //UCB0TXBUF = E2PROM_WRITE_CMD;

  111.         if(Flag_I2C_Address_Transmitted==0)
  112.         {
  113.                 Flag_I2C_Address_Transmitted=1;
  114.                 UCB0TXBUF = I2C_Read_Data_Address;           //write data address
  115.         }

  116.         I2C_Rx_Buffer = pbuffer;
  117.         //I2C_Rx_Size = size-1;         //Number of data to be received
  118.         I2C_Rx_Size = size;

  119.         UCB0IFG &= ~UCRXIFG;
  120.         UCB0_Rx_Or_Tx=0;
  121.         UCB0_Interrupt_Sel(UCB0_Rx_Or_Tx);
  122.         _EINT();
  123.         while( UCB0CTL1& UCTXSTP );
  124.         //delay_ms(5);
  125.         UCB0CTL1 &= ~UCTR;                //read mode
  126.         //UCB0IFG &= ~UCRXIFG;                          // clear interrupt flag

  127.         UCB0CTL1 |= UCTXSTT;              //send start bit

  128.         __bis_SR_register(LPM0_bits);     // Enter LPM0, enable interrupts

  129.         return 0;
  130. }

  131. void UCB0_Interrupt_Sel(uint8 onOff)
  132. {

  133.         if(onOff == 0)                 //Only receive interrupt enabled
  134.         {
  135.                 UCB0IE &=~UCTXIE;                         // Disable USCI_B0 TX interrupt
  136.                 UCB0IE |= UCRXIE;                         // Enable USCI_B0 RX interrupt
  137.         }
  138.         else if(onOff==1)        //Only transmit interrupt enabled
  139.         {
  140.                 UCB0IE &=~UCRXIE;                         // Disable USCI_B0 RX interrupt
  141.                 UCB0IE |= UCTXIE;                         // Enable USCI_B0 TX interrupt
  142.         }
  143.         else               //Both receive and transmit interrupt enabled
  144.         {
  145.                 UCB0IE |= UCTXIE;                         // Enable USCI_B0 TX interrupt
  146.                 UCB0IE |= UCRXIE;                         // Enable USCI_B0 RX interrupt
  147.         }
  148. }

  149. void I2C_Write_Byte(uint8 data_addr, uint8 data_value)
  150. {
  151.         while(UCB0STAT & UCBUSY);         //If I2C is busy

  152.         Flag_I2C_Address_Transmitted=0;

  153.         I2C_Write_Data_Address=data_addr;
  154.         I2C_Tx_Buffer=&data_value;

  155.     //UCB0IFG &= ~UCTXIFG;
  156.         UCB0_Rx_Or_Tx = 1;                                         //transmit interrupt only

  157.         while( UCB0CTL1& UCTXSTP );
  158.         UCB0CTL1 |= UCTR+UCTXSTT;           //write mode, send start bit

  159.         UCB0_Interrupt_Sel(UCB0_Rx_Or_Tx);
  160.         _EINT();
  161.         __bis_SR_register(LPM0_bits);     // Enter LPM0
  162. }
  163. void I2C_Read_Byte(uint8 data_addr, uint8 * data_value)
  164. {
  165.     //_DINT();
  166.         I2C_State=1;
  167.         while(UCB0STAT & UCBUSY);        //If I2C is busy

  168.         I2C_Read_Data_Address=data_addr; // set address
  169.         Flag_I2C_Address_Transmitted=0;
  170.         I2C_Rx_Buffer = data_value;

  171.         while( UCB0CTL1& UCTXSTP );
  172.         UCB0CTL1 |= UCTR;                //write mode
  173.         UCB0CTL1 |= UCTXSTT;    //send start bit

  174.         UCB0IE |= UCTXIE;

  175.         UCB0_Rx_Or_Tx=0;
  176.         UCB0_Interrupt_Sel(UCB0_Rx_Or_Tx);
  177. /*
  178.         if(Flag_I2C_Address_Transmitted==0)
  179.         {
  180.                 Flag_I2C_Address_Transmitted=1;
  181.                 UCB0TXBUF = I2C_Read_Data_Address;           //write data address
  182.         }
  183. */
  184.         UCB0IFG &= ~UCTXIFG;

  185.         _EINT();
  186.         while( UCB0CTL1& UCTXSTP );

  187.         UCB0CTL1 &= ~UCTR;                //read mode

  188.         UCB0CTL1 |= UCTXSTT;              //send start bit

  189.         __bis_SR_register(LPM0_bits);     // Enter LPM0, enable interrupts

  190. }

  191. #pragma vector = USCI_B0_VECTOR
  192. __interrupt void USCI_B0_ISR(void)
  193. {
  194.         //_DINT();
  195.         switch(__even_in_range(UCB0IV,12))
  196.         {
  197.                 case 0:                                 // no interrupt
  198.                         break;
  199.                 case 2:                                        // ALIFG
  200.                         break;
  201.                 case 4:                                        // NACKIFG
  202.                         break;
  203.                 case 6:                                        // STTIFG
  204.                         break;
  205.                 case 8:                                        // STPIFG
  206.                         break;
  207.                 case 10:                                // RXIFG

  208.                         UCB0CTL1 |= UCTXSTP;                    // Generate I2C stop condition

  209.                         *I2C_Rx_Buffer = UCB0RXBUF;                 // Move final RX data to PRxData
  210.                         __bic_SR_register_on_exit(LPM0_bits);       // Exit active CPU
  211.                         break;
  212.                 case 12:                                // TXIFG

  213.                         if(Flag_I2C_Address_Transmitted==0)
  214.                         {
  215.                                 UCB0TXBUF = I2C_Write_Data_Address;           //write data address
  216.                                 Flag_I2C_Address_Transmitted=1;
  217.                                 while(!(UCB0IFG & UCTXIFG));
  218.                         }
  219.                         if(I2C_State==0)
  220.                         {
  221.                                 UCB0TXBUF = *I2C_Tx_Buffer;           // Load TX buffer
  222.                                 while(!(UCB0IFG & UCTXIFG));          // wait UCTXIFG=1
  223.                                 UCB0IE &= ~UCTXIE;
  224.                                 UCB0CTL1 |= UCTXSTP;                  // I2C stop condition
  225.                                 __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
  226.                         }
  227.                         // Clear USCI_B0 TX int flag
  228.                         __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0

  229.                         break;
  230.                 default:
  231.                         break;
  232.         }
  233. }

  234. void main()
  235. {
  236.         uint8 I2C_SUCCESS_FLAG=0;
  237.         WDTCTL = WDTPW | WDTHOLD;        // Stop watchdog timer

  238.         GPIO_Init();

  239.         LED_ON();
  240.         CLK_Init();
  241.         UCB0_I2C_Init();

  242.         delay_ms(20);

  243.         I2C_Write_Byte(0x00,test_byte1);

  244.         I2C_Read_Byte(0x00,&test_byte2);
  245.         if((test_buf1[0]==test_buf2[0])&&(test_buf1[1]==test_buf2[1]))
  246.                 I2C_SUCCESS_FLAG=1;
  247. }
复制代码

等待法已经调试成功了,说明AT24C02没有问题,求助各位帮忙看看这个程序有什么问题,谢谢!

最新回复

用示波器截一下信号波形对不对。  详情 回复 发表于 2015-4-19 22:01
 
点赞 关注

回复
举报

396

帖子

5

TA的资源

纯净的硅(中级)

沙发
 
用示波器截一下信号波形对不对。

点评

单步的时候,发送的波形是正确的,但是接收的波形我没有去截。谢谢  详情 回复 发表于 2015-4-19 22:08
 
个人签名一别四五年,变化万千。https://home.eeworld.com.cn/static/image/smiley/comcom/5.gif[/img]
 

回复

20

帖子

0

TA的资源

一粒金砂(中级)

板凳
 
jqh_111 发表于 2015-4-19 22:01
用示波器截一下信号波形对不对。

单步的时候,发送的波形是正确的,但是接收的波形我没有去截。谢谢
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表