【原创】LaunchPad的USCI实战--硬件I2C连接24LC02+MFRC522

[复制链接]
 楼主| yirongfu 发表于 2012-6-15 00:38 | 显示全部楼层 |阅读模式
    这回拿到LaunchPad,除了感谢档、感谢蒸俯和CCAVTI就不用特别感谢了,用实际产品应用来回报,还得感谢21IC,特别是小跑堂的辛勤劳动!!!
    这回来点儿实用的吧,分享些自己的实际项目资料。之前曾用过2系列,最近也抽空看了看LaunchPad的资料,其实ValueLine可以当作2系列来看,再其实反正都是430,所以有些部分的移植还是比较快的。这些天使用LaunchPad做的试验,是通过MSP430G2553的硬件I2C访问挂在同一I2C接口上的EEPROMMFRC522EEPROM使用模拟I2C接口、MFRC522使用模拟SPI接口的资料网上不难得到,针对430的硬件I2C接口的可能稍微少些,至少我看TI官网上的例程好像就没有跟EEPROM连接的,MFRC522就更别说了。这回测试的难度可能在于两个器件并联挂在一个I2C接口上时的通讯,以及430USCI模块的使用。
      I2C协议就不用在这里赘述了,EEPROM选用Microchip24LC02BMFRC522接成I2C接口形式,MSP430G2553I2C口配置在USCI_B0UCB0SCLUCB0SDA)上,接线示意图如下,图中只画出I2C接口相关接线,其他接线略去,MFRC52224LC02B的用法详见芯片数据手册:

       MSP430G2553使用DCO作为CPU时钟,1MHzUSCI_B0时钟取自SMCLK11分频,SMCLK=DCOCLK。这里需要注意器件的地址,USCII2C模块有一个专门的从设备地址寄存器UCBxI2CSA,用来设置从设备的地址,这个地址可别写错,一个器件一个唯一的地址,比如24LC02B,其地址寻址控制如下所示:

MSP430G2553UCBxI2CSA寄存器构成如下所示:

在前面的电路图中,24LC02BA0A2接地,因为是7-bit寻址模式,所以其地址slave address0x50,如果A0A2不是这么接,则需要把这个地址修改为对应的值。MFRC522类似,高地址由EA固定为0101,低3位我接成010,所以地址为0x2A。这个地址的设置与模拟I2C程序中常用的一个写地址和一个读地址的方式编程方法有所不同,需要注意。
    程序思路是:采用查询相关标志位的方式,而不是中断方式,实现单个字节的收发,在此基础上接着实现若干个字节的收发,然后实现与实际器件相关的读写操作,比如24LC02B的读写,MFRC522寄存器的读、写、修改,等等。花了不少时间和眼神研究USCI模块的用法,最终还是调试出来了,感觉还不算太复杂,不像硬件SPI还有多种时序形式,没有示波器实在费劲。根据I2C器件地址和器件各自的寄存器或存储单元操作规范,分别进行访问、控制,不会冲突。这里,建议初次使用的朋友一定要好好读一下MSP430G2553User’s Guide,特别是其中的Master发送和接收模式的流程图,调试的过程需要吃透这个图,比如停止信号在何时发出、各标志位在什么时候产生、是否需要软件人为复位或置位等,要是没弄清这些细节,可能还不如使用模拟I2C方式。
    主要调试经验小结:
1. 在调试中曾遇到一个问题,写完24LC02B的一个Page后,需要做适当的延时再接着下一个Page的写,否则有可能出错或进行不下去。一般停在循环判断某个标志位的地方,后面所附的源代码中也可以看到,等待标志位的过程我是采用一直while查询的方式,没有作超时退出处理,这种处理方式当然最好进行改进,目前之所以这么处理,是因为一般调试好后成品的线路板只要器件不坏,不会在这里出问题,因此简化处理了。
2. 硬件I2C的操作采用了查询的方式,而不是中断的方式,这是基于保证通讯优先级最高的考虑,在通讯期间不处理其他事件,因为我的应用中通讯的数据很重要。采用查询的方式,也便于编程。当然,具体情况具体分析,大家可以根据自己的情况进行选择。我个人认为查询稳妥些,并且在操作期间将中断暂时关闭,确保时序不出错。
3. 多个I2C器件挂同一总线上,是为了节约I/O口的开支,这也体现Value的精神,目前来看,硬件USCI使用起来还是不难的。多年以前曾经尝试将PCF856324LC02挂同一总线进行操作,模拟I2C方式,结果不行,后来的解决措施是共用SCL,但分开SDA,这也是种思路。
4. 调试MFRC522时,可以对照上面的MSP430G2553的流程图和MFRC522的寄存器读、写流程进行,使程序符合MFRC522的要求,再结合下面的NXP示例代码,一般都能成功,除非硬件有问题。
    因为涉及正在使用的产品,不便完全分享,只摘出与MSP430G2553硬件相关的代码和公用的底层代码供大家参考,请见谅。不过,这样也有好处,因为照搬源代码不利于自己的进步:)。好在而分享的这些代码都是接口的关键代码,已经节约了这部分的调试过程。MFRC522的接口协议程序我附上NXP的一个示例代码供大家参考,它的单片机使用的是NXPLPC9401,其中RC522的硬件初始化函数SysInit(void)的开头部分需要对芯片进行复位操作,涉及MSP430G2553I/O口对MFRC522NRSTPD引脚的操作,大家在实际应用编程时注意不要遗忘。基本上,这些资料对于使用24LC02BMFRC522的软件开发和原理图设计已经够用了。

    最后,2楼上代码,因为网站提示字数超限了。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×

评分

参与人数 2威望 +6 收起 理由
永远的不知 + 4 原创好文
tianm + 2

查看全部评分

 楼主| yirongfu 发表于 2012-6-15 00:45 | 显示全部楼层
首先是NXP的示例代码:

最后,上酸菜:

  1. #include "msp430g2553.h"
  2. #include <intrinsics.h>
  3. #include "Rc522Reg.h"                        //见NXP的代码
  4. #include "ErrCode.h"                            //见NXP的代码
  5. #include "OpCtrl.h"                                //见NXP的代码
  6. #include "Mifare.h"                                //见NXP的代码

  7. #define txbeforerx 0x01                 //bitflag
  8. #define i2ctxend 0x02                   //bitflag
  9. #define i2crxend 0x04                   //bitflag
  10. #define tx1byte 0x08                    //bitflag

  11. #define epr24_addr  0x50                //24LC02B器件地址
  12. #define rc522_addr  0x2A                //MFRC522器件地址

  13. unsigned char TxData[9];
  14. unsigned char RxBuffer[8];
  15. unsigned char cachedata[40];
  16. unsigned char *PTxData,*PRxData;
  17. unsigned char bitflag;


  18. /*----------------------------------------------------------------------------
  19. 功能:USCI_B0的I2C功能初始化
  20. 输入:
  21. 输出:
  22. 说明:SMCLK=DCOCLK
  23. ----------------------------------------------------------------------------*/
  24. void I2C_init(void)
  25. {
  26.   UCB0CTL1 |= UCSWRST;                                      // Enable SW reset
  27.   UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;        // I2C Master, synchronous mode
  28.   UCB0CTL1 = UCSSEL_2 + UCSWRST;                    // Use SMCLK, keep SW reset, receiver
  29.   UCB0BR0 = 11;                                                     // fSCL = SMCLK/11
  30.   UCB0BR1 = 0;

  31.   UCB0CTL1 &= ~UCSWRST;                                 // Clear SW reset, resume operation
  32.   bitflag &= 0xF0;
  33. }

  34. /*----------------------------------------------------------------------------
  35. 功能:从I2C接口接收n个字节数据
  36. 输入:待接收字节个数 num,7-bit从机地址slave_addr
  37. 输出:接收的数据存放在RxBuffer数组
  38. 说明:接收之前需要发送的数据放在TxData[0],比如源数据内存地址;适合接收2个以上字节
  39. ----------------------------------------------------------------------------*/
  40. void I2CRxnbyte(unsigned char slave_addr, unsigned char num)
  41. {
  42.   UCB0I2CSA = slave_addr;
  43.   IE2 |= UCB0TXIE + UCB0RXIE;                 // Enable TX RX interrupt
  44.   
  45.   PRxData = (unsigned char *)RxBuffer;        // Start of RX buffer
  46.   PTxData = (unsigned char *)TxData;          // TX array start address

  47.   TxByteCount = 1;
  48.   RxByteCount = num;                                 // Load RX byte counter
  49.   bitflag |= txbeforerx;
  50.   UCB0CTL1 |= UCTR + UCTXSTT;             // I2C TX, start condition

  51.   __bis_SR_register( GIE );                           // Enable general interrupt
  52.   while( bitflag & txbeforerx )                       //TxByteCount != 1
  53.   {
  54.     __no_operation();
  55.   }
  56.   IFG2 &= ~UCB0TXIFG;

  57.   IE2 &= ~UCB0TXIE;

  58.   while( !(bitflag & i2crxend) )                    // Wait until all data is RX'd
  59.   {
  60.     __no_operation();
  61.   }
  62.   IE2 &= ~UCB0RXIE;                                    // Disable RX interrupt
  63.   bitflag &= ~i2crxend;
  64. }

  65. /*----------------------------------------------------------------------------
  66. 功能:从I2C接口的当前地址接收1个字节数据
  67. 输入:7-bit从机地址slave_addr
  68. 输出:接收的数据存放在RxBuffer数组
  69. 说明:在接收第1个字节过程中需要置位停止位,接收数据放在RxBuffer[0]
  70. ----------------------------------------------------------------------------*/
  71. void I2CRx1byte(unsigned char slave_addr)
  72. {
  73.   UCB0I2CSA = slave_addr;
  74.   IE2 |= UCB0RXIE;                                         // Enable TX RX interrupt
  75.   
  76.   PRxData = (unsigned char *)RxBuffer;            // Start of RX buffer

  77.   RxByteCount = 1;                                          // Load RX byte counter

  78.   UCB0CTL1 &= ~UCTR;                                    // I2C RX
  79.   UCB0CTL1 |= UCTXSTT;


  80.   while( UCB0CTL1 & UCTXSTT )
  81.   {
  82.     __no_operation();
  83.   }
  84.   __no_operation();
  85.   UCB0CTL1 |= UCTXSTP;
  86.   while( !(bitflag & i2crxend) )                        // Wait until all data is RX'd
  87.   {
  88.     __no_operation();
  89.   }
  90.   IE2 &= ~UCB0RXIE;                                        // Disable RX interrupt
  91.   bitflag &= ~i2crxend;
  92.   __no_operation();
  93. }

  94. /*----------------------------------------------------------------------------
  95. 功能:向I2C接口发送n个字节数据
  96. 输入:待发送字节个数 num,7-bit从机地址slave_addr
  97. 输出:
  98. 说明:待发送数据存放在TxData数组中;适合发送2个以上字节
  99. ----------------------------------------------------------------------------*/
  100. void I2CTxnbyte(unsigned char slave_addr, unsigned char num)
  101. {

  102.   UCB0I2CSA = slave_addr;                         // 24C02 Write Address is 0a0h

  103.   IE2 |= UCB0TXIE;                                      // Enable TX interrupt

  104.   PTxData = (unsigned char *)TxData;              // TX array start address
  105.   TxByteCount = num;                                      // Load TX byte counter
  106.   UCB0CTL1 |= UCTR + UCTXSTT;                 // I2C TX, start condition
  107.   __bis_SR_register( GIE );                                // Enter LPM0 w/ interrupts

  108.   while( !(bitflag & i2ctxend) )                        // Wait until all data is RX'd
  109.   {
  110.     __no_operation();
  111.   }
  112.   
  113.   IE2 &= ~UCB0TXIE;                                      // Disable TX interrupt
  114.   IFG2 &= ~UCB0TXIFG;
  115.   bitflag &= ~i2ctxend;
  116. }

  117. /*----------------------------------------------------------------------------
  118. 功能:向I2C接口发送1个字节数据
  119. 输入:待发送字节个数 num,7-bit从机地址slave_addr
  120. 输出:
  121. 说明:在发送第1个字节过程中需要置位停止位,待发送数据放在TxData[0]
  122. ----------------------------------------------------------------------------*/
  123. void I2CTx1byte(unsigned char slave_addr)
  124. {
  125.   UCB0I2CSA = slave_addr;                         // 24C02 Write Address is 0a0h
  126.   bitflag |= tx1byte;

  127.   IE2 |= UCB0TXIE;                                      // Enable TX interrupt

  128.   PTxData = (unsigned char *)TxData;              // TX array start address
  129.   TxByteCount = 1;                                          // Load TX byte counter
  130.   UCB0CTL1 |= UCTR + UCTXSTT;                 // I2C TX, start condition
  131.   __bis_SR_register( GIE );                                // Enter LPM0 w/ interrupts

  132.   while( UCB0CTL1 & UCTXSTT )
  133.   {
  134.     __no_operation();
  135.   }
  136.   __no_operation();
  137.   UCB0CTL1 |= UCTXSTP;
  138.   while( !(bitflag & i2ctxend) )                        // Wait until all data is RX'd
  139.   {
  140.     __no_operation();
  141.   }
  142.   
  143.   IE2 &= ~UCB0TXIE;                                      // Disable TX interrupt
  144.   bitflag &= ~tx1byte;
  145.   IFG2 &= ~UCB0TXIFG;
  146.   bitflag &= ~i2ctxend;
  147.   __no_operation();
  148. }

  149. /*----------------------------------------------------------------------------
  150. 功能:软件延时
  151. 输入:u16Val,延时长度,ms
  152. 输出:
  153. 说明:参数范围0-65535,延时单位约为1ms@1MHz MCLK
  154. ----------------------------------------------------------------------------*/
  155. void soft_delay_ms(unsigned int u16Val)
  156. {
  157.   unsigned int i;
  158.   while(u16Val--)
  159.   {
  160.     i = 1000;
  161.     while(i--)
  162.     {
  163.       __no_operation();
  164. //      _nop_();
  165. //      _nop_();
  166.     }
  167.   }
  168. }

  169. /*----------------------------------------------------------------------------
  170. 功能:向24LC02B发送n个字节数据
  171. 输入:待发送字节个数 num(包括地址字节),写入的目的地址d_addr
  172. 输出:
  173. 说明:待发送数据存放在TxData数组中,地址存放TxData[0],数据从TxData[1]开始存放
  174. ----------------------------------------------------------------------------*/
  175. void Write_24c02_nbyte(unsigned char num,unsigned char d_addr)
  176. {
  177.   TxData[0] = d_addr;
  178.   I2CTxnbyte(epr24_addr, num);
  179. }

  180. /*----------------------------------------------------------------------------
  181. 功能:从24LC02B接收n个字节数据
  182. 输入:待接收字节个数 num,待读取的源数据地址s_addr
  183. 输出:接收的数据存放在RxBuffer数组
  184. 说明:接收之前需要发送的数据放在TxData[0],比如源数据内存地址,待接收字节数应大于2
  185. ----------------------------------------------------------------------------*/
  186. void Read_24c02_nbyte(unsigned char num,unsigned char s_addr)
  187. {
  188.   TxData[0] = s_addr;
  189.   I2CRxnbyte(epr24_addr,num);
  190. }

  191. /*----------------------------------------------------------------------------
  192. 功能:向24LC02B更新所有数据
  193. 输入:
  194. 输出:
  195. 说明:cachedata[]是被保存的数据,只是个示例
  196. ----------------------------------------------------------------------------*/
  197. void renew_24c02(void)
  198. {
  199.   TxData[1] = cachedata[0];
  200.   TxData[2] = cachedata[1];
  201.   TxData[3] = cachedata[2];
  202.   TxData[4] = cachedata[3];
  203.   TxData[5] = cachedata[4];
  204.   TxData[6] = cachedata[5];
  205.   TxData[7] = cachedata[6];
  206.   TxData[8] = cachedata[7];
  207.   Write_24c02_nbyte(9,0);     //page1
  208.   
  209.   soft_delay_ms(2);

  210.   TxData[1] = cachedata[8];
  211.   TxData[2] = cachedata[9];
  212.   TxData[3] = cachedata[10];
  213.   TxData[4] = cachedata[11];
  214.   TxData[5] = cachedata[12];
  215.   TxData[6] = cachedata[13];
  216.   TxData[7] = cachedata[14];
  217.   TxData[8] = cachedata[15];
  218.   Write_24c02_nbyte(9,8);     //page2
  219.   
  220.   soft_delay_ms(2);
  221.   
  222.   TxData[1] = cachedata[16];
  223.   TxData[2] = cachedata[17];
  224.   TxData[3] = cachedata[18];
  225.   TxData[4] = cachedata[19];
  226.   TxData[5] = cachedata[20];
  227.   TxData[6] = cachedata[21];
  228.   TxData[7] = cachedata[22];
  229.   TxData[8] = cachedata[23];
  230.   Write_24c02_nbyte(9,0x10);     //page3
  231.   
  232.   soft_delay_ms(2);
  233.   
  234.   TxData[1] = cachedata[24];
  235.   TxData[2] = cachedata[25];
  236.   TxData[3] = cachedata[26];
  237.   TxData[4] = cachedata[27];
  238.   TxData[5] = cachedata[28];
  239.   TxData[6] = cachedata[29];
  240.   TxData[7] = cachedata[30];
  241.   TxData[8] = cachedata[31];
  242.   Write_24c02_nbyte(9,0x18);     //page4
  243.   
  244.   soft_delay_ms(2);
  245.   
  246.   TxData[1] = cachedata[32];
  247.   TxData[2] = cachedata[33];
  248.   TxData[3] = cachedata[34];
  249.   TxData[4] = cachedata[35];
  250.   TxData[5] = cachedata[36];
  251.   TxData[6] = cachedata[37];
  252.   TxData[7] = cachedata[38];
  253.   TxData[8] = cachedata[39];
  254.   Write_24c02_nbyte(9,0x20);     //page5
  255. }

  256. /*----------------------------------------------------------------------------
  257. 功能:从24LC02B还原所有数据
  258. 输入:
  259. 输出:
  260. 说明:cachedata[]是被还原的数据,只是个示例
  261. ----------------------------------------------------------------------------*/
  262. void recover_24c02(void)
  263. {
  264.   Read_24c02_nbyte(8,0);
  265.   cachedata[0] = RxBuffer[0];
  266.   cachedata[1] = RxBuffer[1];
  267.   cachedata[2] = RxBuffer[2];
  268.   cachedata[3] = RxBuffer[3];
  269.   cachedata[4] = RxBuffer[4];
  270.   cachedata[5] = RxBuffer[5];
  271.   cachedata[6] = RxBuffer[6];
  272.   cachedata[7] = RxBuffer[7];
  273.   
  274.   Read_24c02_nbyte(8,8);
  275.   cachedata[8] = RxBuffer[0];
  276.   cachedata[9] = RxBuffer[1];
  277.   cachedata[10] = RxBuffer[2];
  278.   cachedata[11] = RxBuffer[3];
  279.   cachedata[12] = RxBuffer[4];
  280.   cachedata[13] = RxBuffer[5];
  281.   cachedata[14] = RxBuffer[6];
  282.   cachedata[15] = RxBuffer[7];
  283.   
  284.   Read_24c02_nbyte(8,0x10);
  285.   cachedata[16] = RxBuffer[0];
  286.   cachedata[17] = RxBuffer[1];
  287.   cachedata[18] = RxBuffer[2];
  288.   cachedata[19] = RxBuffer[3];
  289.   cachedata[20] = RxBuffer[4];
  290.   cachedata[21] = RxBuffer[5];
  291.   cachedata[22] = RxBuffer[6];
  292.   cachedata[23] = RxBuffer[7];
  293.   
  294.   Read_24c02_nbyte(8,0x18);
  295.   cachedata[24] = RxBuffer[0];
  296.   cachedata[25] = RxBuffer[1];
  297.   cachedata[26] = RxBuffer[2];
  298.   cachedata[27] = RxBuffer[3];
  299.   cachedata[28] = RxBuffer[4];
  300.   cachedata[29] = RxBuffer[5];
  301.   cachedata[30] = RxBuffer[6];
  302.   cachedata[31] = RxBuffer[7];
  303.   
  304.   Read_24c02_nbyte(8,0x20);
  305.   cachedata[32] = RxBuffer[0];
  306.   cachedata[33] = RxBuffer[1];
  307.   cachedata[34] = RxBuffer[2];
  308.   cachedata[35] = RxBuffer[3];
  309.   cachedata[36] = RxBuffer[4];
  310.   cachedata[37] = RxBuffer[5];
  311.   cachedata[38] = RxBuffer[6];
  312.   cachedata[39] = RxBuffer[7];
  313. }

  314. /*----------------------------------------------------------------------------
  315. 功能:Write data to register of RC522
  316. 输入:RegAddr-The address of the register;RegVal-The value to be written
  317. 输出:
  318. 说明:
  319. ----------------------------------------------------------------------------*/
  320. void RcSetReg(unsigned char RegAddr, unsigned char RegVal)
  321. {
  322.   TxData[0] = RegAddr;

  323.   TxData[1] = RegVal;
  324.   I2CTxnbyte(rc522_addr, 2);
  325. }

  326. /*----------------------------------------------------------------------------
  327. 功能:read data from register of RC522
  328. 输入:RegAddr-The address of the register to be read
  329. 输出:The value of the specified register
  330. 说明:
  331. ----------------------------------------------------------------------------*/
  332. unsigned char RcGetReg(unsigned char RegAddr)
  333. {
  334.   unsigned char RegVal;
  335.   short status;

  336.   TxData[0] = RegAddr;

  337.   I2CTx1byte(rc522_addr);

  338.   I2CRx1byte(rc522_addr);
  339.   status = STATUS_SUCCESS;                //实际调试已经成功
  340.   RegVal = RxBuffer[0];

  341.   return RegVal;
  342. }

  343. /*----------------------------------------------------------------------------
  344. 功能:Change some bits of the register
  345. 输入:RegAddr-The address of the register;ModifyVal-The value to change to, set or clr;MaskByte-Only the corresponding bit '1' is valid
  346. 输出:
  347. 说明:
  348. ----------------------------------------------------------------------------*/
  349. void RcModifyReg(unsigned char RegAddr, unsigned char ModifyVal, unsigned char MaskByte)
  350. {
  351.     unsigned char RegVal;
  352.     RegVal = RcGetReg(RegAddr);
  353.     if(ModifyVal)
  354.     {
  355.         RegVal |= MaskByte;
  356.     }
  357.     else
  358.     {
  359.         RegVal &= (~MaskByte);
  360.     }
  361.     RcSetReg(RegAddr, RegVal);
  362. }

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×

评分

参与人数 1威望 +3 收起 理由
21小跑堂 + 3

查看全部评分

杰式4231 发表于 2012-6-15 07:48 | 显示全部楼层
坐沙发
QQ3986 发表于 2012-6-15 08:23 | 显示全部楼层
坐板凳。学习学习。。。。。。
tianm 发表于 2012-6-15 11:51 | 显示全部楼层
谢谢LZ分享  希望能看到更多更精彩的设计
 楼主| yirongfu 发表于 2012-6-15 18:26 | 显示全部楼层
:handshake
wudayongnb 发表于 2012-7-7 21:25 | 显示全部楼层
我怎么看不懂你的程序是怎么实现发送和接收的呢,连UCB0TXBUF和UCB0RXBUF寄存器也没用到
Rancho13502 发表于 2012-7-8 08:14 | 显示全部楼层
正在搞IIC的,学习
u880 发表于 2012-7-8 08:47 | 显示全部楼层
大牛,向你学习
huigoushang 发表于 2012-7-8 09:04 | 显示全部楼层
太详细了
G21372 发表于 2012-7-8 09:24 | 显示全部楼层
好棒的资料 顶
yangguangaisha 发表于 2012-7-8 09:36 | 显示全部楼层
强帖留名
gexingyouxian 发表于 2012-7-8 09:45 | 显示全部楼层
很有参考价值
acer4736 发表于 2012-7-8 09:51 | 显示全部楼层
果然和厉害啊
xiaojian1227 发表于 2012-7-13 21:49 | 显示全部楼层
楼主的数据时如何进行收发的呢?没有写中断函数啊,或者是根本没有看到UCB0RXBUF或者UCB0TXBUF,不通过这两个寄存器,怎么进行数据的收发呢?希望耐心赐教!
 楼主| yirongfu 发表于 2012-7-13 23:02 | 显示全部楼层
感谢7楼和15楼朋友的格外关注:handshake

再进一步说明一下,帖子里提到的查询相关标志位的方式是指在处理具体的应用层面的通讯时的方式,而不是最底层的单个字节bit流传输的处理方式,最底层的bit流传输方式正是上面两位朋友关注的,采用的是中断方式,现将这部分代码也贡献出来,这部分代码大家还可以参考官方例程:


  1. /*----------------------------------------------------------------------------
  2. The USCIAB0TX_ISR is structured such that it can be used to transmit any
  3. number of bytes by pre-loading TXByteCtr with the byte count. Also, TXData points to the next byte to transmit.
  4. ----------------------------------------------------------------------------*/
  5. #pragma vector = USCIAB0TX_VECTOR
  6. __interrupt void USCIAB0TX_ISR(void)
  7. {
  8.   if ( IFG2 & UCB0RXIFG )
  9.   {
  10.     RxByteCount--;                            // Decrement RX byte counter
  11.     if ( RxByteCount )
  12.     {
  13.       *PRxData++ = UCB0RXBUF;                 // Move RX data to address PRxData
  14.       if ( RxByteCount == 1 )                   // Only one byte left?
  15.         UCB0CTL1 |= UCTXSTP;   // Generate I2C stop condition before the final byte has been Rx'd
  16.     }
  17.     else
  18.     {
  19.       *PRxData = UCB0RXBUF;                   // Move final RX data to PRxData
  20.       bitflag |= i2crxend;
  21.     }
  22.   }
  23.   if ( IFG2 & UCB0TXIFG )
  24.   {
  25.     if (TxByteCount)                            // Check TX byte counter
  26.     {
  27.       UCB0TXBUF = *PTxData++;                 // Load TX buffer
  28.       TxByteCount--;                            // Decrement TX byte counter
  29.       if((TxByteCount == 0) && (bitflag & tx1byte))
  30.         bitflag |= i2ctxend;
  31.     }
  32.     else
  33.     {
  34.       if ( bitflag & txbeforerx )
  35.       {
  36.         UCB0CTL1 &= ~UCTR;            //set as RX
  37.         UCB0CTL1 |= UCTXSTT;          //generate Start
  38.         IFG2 &= ~UCB0TXIFG;
  39.         bitflag &= ~txbeforerx;
  40.       }
  41.       else
  42.       {
  43.         UCB0CTL1 |= UCTXSTP;                    // I2C stop condition
  44.         IFG2 &= ~UCB0TXIFG;                     // Clear USCI_B0 TX int flag
  45.         bitflag |= i2ctxend;
  46.       }
  47.     }
  48.   }
  49. }
whzy3j 发表于 2012-8-1 16:34 | 显示全部楼层
:handshake
hnhdzzc 发表于 2012-8-2 10:30 | 显示全部楼层
感谢楼主
冰岛海盗 发表于 2012-8-6 21:04 | 显示全部楼层
楼主给力啊
yuyishifeng 发表于 2012-8-7 11:39 | 显示全部楼层
楼主,看不太懂,能给我讲解一下吗,QQ977594253
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:生活将我们磨圆,是为了让我们滚得更远。。。 我来到这个世上就没打算活着回去!

99

主题

918

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部