原创MSP430中继通讯协议(源代码)

来源:互联网 发布:哇魔力作文模板知乎 编辑:程序博客网 时间:2024/05/16 03:52
Code:
  1. //===========================================================================//  
  2. //                MSP430接收中继端协议——徐方鑫                             //  
  3. //                通讯协议格式为:16进制发送                                 //  
  4. //                53 09 AA AA AA AA AA AA 45                                 //  
  5. //                53为数据包打头,字符's'                                    //  
  6. //                09为字符串长度,char类型                                   //  
  7. //                其后AA AA AA 等为数据内容                                  //  
  8. //                45为数据包结尾,字符'E'                                    //  
  9. //===========================================================================//  
  10.   
  11. #include "msp430x54x.h"  
  12. #include <stdlib.h>  
  13. #include <stdio.h>  
  14. #include <string.h>  
  15. #include "PIN_DEF.H"  
  16.   
  17. #define uchar unsigned char  
  18. #define uint unsigned int  
  19.   
  20. #define  FLL_FACTOR     749                // FLL_FACTOR: DCO倍频系数      
  21. #define DATA_BAG_ERROR_MAX 0x5000         //最大数据包长度,int类型,串口所用8位基本都支持  
  22.   
  23. char event;     //待机模式事件  
  24. uint Data_Bag_Length,Data_Length;   //Data_Bag_Leangth接收数据包的长度  
  25. char RXBuffer[20]; // 接收缓存  
  26.   
  27.   
  28. //***************************************************************************//  
  29. //                                                                           //  
  30. //                 初始化主时钟: MCLK = XT1×(FLL_FACTOR+1)                  //  
  31. //                                                                           //  
  32. //***************************************************************************//  
  33. void Init_CLK(void)  
  34. {  
  35.   WDTCTL     = WDTPW + WDTHOLD                            ; // 关看门狗  
  36.   P7SEL     |= 0x03                                       ; // 端口选择外部低频晶振XT1  
  37.   UCSCTL6   &=~XT1OFF                                     ; // 使能外部晶振   
  38.   UCSCTL6   |= XCAP_3                                     ; // 设置内部负载电容  
  39.   UCSCTL3   |= SELREF_2                                   ; // DCOref = REFO  
  40.   UCSCTL4   |= SELA_0                                     ; // ACLK   = XT1    
  41.   __bis_SR_register(SCG0)                                 ; // 关闭FLL控制回路  
  42.   UCSCTL0    = 0x0000                                     ; // 设置DCOx, MODx  
  43.   UCSCTL1    = DCORSEL_7                                  ; // 设置DCO振荡范围  
  44.   UCSCTL2    = FLLD__1 + FLL_FACTOR                       ; // Fdco = ( FLL_FACTOR + 1)×FLLRef = (649 + 1) * 32768 = 21.2992MHz  
  45.   __bic_SR_register(SCG0)                                 ; // 打开FLL控制回路                                                              
  46.   __delay_cycles(1024000)                                 ;   
  47.   do  
  48.   {  
  49.     UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG); // 清除 XT2,XT1,DCO 错误标志                                                              
  50.     SFRIFG1 &= ~OFIFG                                     ;   
  51.   }while(SFRIFG1&OFIFG)                                   ; // 检测振荡器错误标志   
  52. }  
  53. //***************************************************************************//  
  54. //                                                                           //  
  55. //  Init_Port(void): 设置IO端口                                              //  
  56. //                                                                           //  
  57. //***************************************************************************//  
  58. void Init_Port(void)  
  59. {  
  60.   P5DIR  |= POWER                                                  ; // 主电源  
  61.   MAIN_POWER_ON                                                    ;  
  62.   P7DIR  |= LED_PWR                                                ; // 发光二极管电源  
  63.   P7OUT  &=~LED_PWR                                                ;  
  64.   INTERNAL_PULL_UP                                                 ; // 使能键盘端口内部上拉电阻   
  65.   ROW_IN_COL_OUT                                                   ; // 设置行输入,列输出0  
  66. }  
  67. //***************************************************************************//  
  68. //                                                                           //  
  69. //  Init_UART(void): 初始化USB端口                                           //  
  70. //                                                                           //  
  71. //***************************************************************************//  
  72. void Init_UART(void)  
  73. {   
  74.   USB_PORT_SEL   |= TXD_U + RXD_U                                  ; // 选择引脚功能  
  75.   USB_PORT_DIR   |= TXD_U                                          ; // 选择引脚功能  
  76.   UCA1CTL1        = UCSWRST                                        ; // 状态机复位  
  77.   UCA1CTL1       |= UCSSEL_1                                       ; // CLK = ACLK  
  78.   UCA1BR0         = 0x03                                           ; // 32kHz/9600=3.41   
  79.   UCA1BR1         = 0x00                                           ;   
  80.   UCA1MCTL        = UCBRS_3 + UCBRF_0                              ; // UCBRSx=3, UCBRFx=0  
  81.   UCA1CTL1       &= ~UCSWRST                                       ; // 启动状态机  
  82.   UCA1IE         |= UCRXIE                                         ; // 允许接收中断  
  83. }  
  84.   
  85. //***************************************************************************//  
  86. //                                                                           //  
  87. //  UTX_PROC(void): USB端口发送程序                                          //  
  88. //                                                                           //  
  89. //***************************************************************************//  
  90. void UTX_PROC(char *tx_buf)  
  91. {  
  92.   unsigned char i,length;  
  93.   length = strlen(tx_buf);  
  94.   for(i=0;i<length;i++)  
  95.   {  
  96.     UCA1TXBUF = *tx_buf++;   
  97. //    __delay_cycles(5000);  
  98.     while (!(UCA1IFG&UCTXIFG));   
  99.   }  
  100. }  
  101. //***************************************************************************//  
  102. //                                                                           //  
  103. //  UTX_PROC(void): USB端口发送程序                                          //  
  104. //                                                                           //  
  105. //***************************************************************************//  
  106. void Data_Bag_Send(char *tx_buf)  
  107. {  
  108.   unsigned char i,length_all,length;      //声明数据总长度,length_all为转发数据包,length为不带转发数据包  
  109.   length_all = strlen(tx_buf)+Data_Length;    //转发数据包为待发送数据长度+转发数据长度  
  110.   length = strlen(tx_buf);      //length为本身数据长度,当无转发数据时从串口发送  
  111.   UCA1TXBUF = 'S';          //发送启始指令'S',八进制为0x53  
  112.     while(!(UCA1IFG&UCTXIFG));   //等待发送完成  
  113.       
  114.   if(Data_Length<DATA_BAG_ERROR_MAX)    //如果有待转发数据  
  115.   {  
  116.     UCA1TXBUF = length_all+3;     //发送数据总长度  
  117.     while(!(UCA1IFG&UCTXIFG));    //等待发送完成  
  118.     for(i=2;i<2+Data_Length;i++)    //发送转发数据包  
  119.     {  
  120.       UCA1TXBUF = RXBuffer[i];  
  121.       while(!(UCA1IFG&UCTXIFG));  
  122.     }  
  123.   }  
  124.   else  
  125.   {  
  126.     UCA1TXBUF = length+3;       //没有中继数据的时候,直接发送数据包  
  127.     while(!(UCA1IFG&UCTXIFG));  
  128.   }  
  129.     
  130.   for(i=0;i<length;i++)  
  131.   {  
  132.     UCA1TXBUF = *tx_buf++;    //发送本地数据包  
  133. //    __delay_cycles(5000);  
  134.     while (!(UCA1IFG&UCTXIFG));   
  135.   }  
  136.     
  137.   UCA1TXBUF = 'E';        //发送包尾'E'  
  138. }  
  139. //***************************************************************************//  
  140. //                                                                           //  
  141. //                              主函数                                       //  
  142. //                                                                           //  
  143. //***************************************************************************//  
  144. void main( void )  
  145. {  
  146.   int i;  
  147.   WDTCTL = WDTPW + WDTHOLD;     //看门狗关闭  
  148.   Init_CLK();       //时钟初始化  
  149.   Init_Port();      //IO端口初始化  
  150.   Init_UART();      //串口初始化  
  151.   _EINT();    //启动中断  
  152.   for(;;)  
  153.   {  
  154.     if(event)  
  155.     {  
  156.       event   = 0x00;  
  157.       UTX_PROC(RXBuffer);  
  158.     }  
  159.       
  160.     if((P6IN&0x0F)!=0x0F)            // 检测按键按下  
  161.     {  
  162.       //UTX_PROC(Data_Bag);  
  163.       //UTX_PROC(RXBuffer);  
  164.       //UTX_PROC(&Data_Length);  
  165.       Data_Bag_Send("123");       //本地数据包为123  
  166.       __delay_cycles(5000000);  
  167.     }      
  168.   }  
  169. }  
  170. //***************************************************************************//  
  171. //                                                                           //  
  172. //  USB接收中断服务程序                                                      //  
  173. //                                                                           //  
  174. //***************************************************************************//  
  175. #pragma vector=USCI_A1_VECTOR  
  176. __interrupt void USCI_A1_ISR(void)  
  177. {  
  178.   static char rx_byte = 0x00;   //接收字段初始化  
  179.   unsigned char temp,event = 0x00;    //BUFFER空间,还有待机模式初始化  
  180.   switch(__even_in_range(UCA1IV,4))  
  181.   {  
  182.   case 0:break// Vector 0 - no interrupt  
  183.   case 2:            // Vector 2 - RXIFG  
  184.       temp = UCA1RXBUF;  
  185.       if(rx_byte==0)  
  186.       {  
  187.         if(temp=='S')  
  188.         {  
  189.           RXBuffer[0] = UCA1RXBUF;    //如果首位为's’接收数据  
  190.           rx_byte++;      //计数  
  191.         }  
  192.       }  
  193.       else  
  194.       {  
  195.         RXBuffer[rx_byte++] = temp;  
  196.         if(rx_byte>=RXBuffer[1])      //若数据还在接收范围内部,接收数据  
  197.         {  
  198.           Data_Bag_Length = RXBuffer[1];    //数据总长赋值  
  199.           Data_Length=Data_Bag_Length-3;    //数据长赋值  
  200.           if(RXBuffer[rx_byte-1] == 'E')      //如果数据尾巴为E,保存数据  
  201.           {  
  202.             rx_byte = 0x00;  
  203.             event |= 0x01;  
  204.           }  
  205.           else        //否则,在数据总长不对或者数据尾不对的情况下,删除数据  
  206.           {  
  207.             rx_byte = 0x00;    
  208.             for(temp=0;temp<20;temp++)  
  209.               RXBuffer[temp] = 0x00; // 通讯有误,清除缓冲区  
  210.           }  
  211.         }          
  212.       }  
  213.       break;  
  214.   case 4:break;  // Vector 4 - TXIFG  
  215.   defaultbreak;    
  216.   }    
  217.   if(event)    
  218.     LPM3_EXIT;      //唤醒待机模式  
  219. }  

 

 

原创粉丝点击