久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3011|回復: 0
打印 上一主題 下一主題
收起左側

LIN總線MC9S12XS128發送與接收源程序

[復制鏈接]
跳轉到指定樓層
樓主
ID:381982 發表于 2018-8-2 09:10 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
文件在附件
LIN接收.rar (243.82 KB, 下載次數: 40)
LIN發送.rar (362.66 KB, 下載次數: 30)

單片機源程序如下:
  1. /*---------------------------------------------------------*/
  2. /************************************************************
  3. 飛翔科技MC9S12XS128汽車電子開發板
  4. ************************************************************/
  5. /*---------------------------------------------------------*/
  6. #include <hidef.h>      /* common defines and macros */
  7. #include "derivative.h"      /* derivative-specific definitions */

  8. #define BUZZ PORTK_PK5
  9. #define BUZZ_dir DDRK_DDRK5
  10. #define LEDCPU PORTK_PK4
  11. #define LEDCPU_dir DDRK_DDRK4
  12. #define  BUS_CLOCK                   32000000           //總線頻率
  13. #define  OSC_CLOCK                   16000000           //晶振頻率
  14. #define  BAUD 9600                   //串口波特率

  15. #define BIT(A,B)      ((A>>B)&0x01)   // A 為變量
  16.                                       // B 表示A中的第幾位
  17. #define     ID         0x30           // ID場值為0x30
  18. #define     EN         PTM_PTM6     //LIN使能
  19. #define     EN_dir     DDRM_DDRM6

  20. unsigned int x=0;
  21. Bool a;
  22.                                       
  23. struct message {
  24.   unsigned char identifier;
  25.   unsigned char data[8];
  26. };

  27. struct message msg_send;
  28. struct message msg_get;

  29. // 定義LIN狀態
  30. enum lin_state { IDLE, _BREAK, SYNCH, PROTECTED_IDENTIFIER, DATA0, DATA1,
  31.                  DATA2, DATA3, DATA4, DATA5, DATA6, DATA7, CHECKSUM };

  32. // 定義幀結構體
  33. struct frame {
  34.   unsigned char protected_id;
  35.   unsigned char data[8];
  36.   unsigned char check;
  37.   enum lin_state state;
  38.   unsigned char error;
  39. };

  40. struct frame frame_send,frame_receive;

  41. /*************************************************************/
  42. /*                      初始化鎖相環                         */
  43. /*************************************************************/
  44. void INIT_PLL(void)
  45. {
  46.     CLKSEL &= 0x7f;       //set OSCCLK as sysclk
  47.     PLLCTL &= 0x8F;       //Disable PLL circuit
  48.     CRGINT &= 0xDF;
  49.    
  50.     #if(BUS_CLOCK == 40000000)
  51.       SYNR = 0x44;
  52.     #elif(BUS_CLOCK == 32000000)
  53.       SYNR = 0x43;     
  54.     #elif(BUS_CLOCK == 24000000)
  55.       SYNR = 0x42;
  56.     #endif

  57.     REFDV = 0x81;         //PLLCLK=2×OSCCLK×(SYNDIV+1)/(REFDIV+1)=64MHz ,fbus=32M
  58.     PLLCTL =PLLCTL|0x70;  //Enable PLL circuit
  59.     asm NOP;
  60.     asm NOP;
  61.     while(!(CRGFLG&0x08)); //PLLCLK is Locked already
  62.     CLKSEL |= 0x80;        //set PLLCLK as sysclk
  63. }

  64. /************************************************************/
  65. /*                    初始化ECT模塊                         */
  66. /************************************************************/
  67. void initialize_ect(void){
  68.   TSCR1_TFFCA = 1;  // 定時器標志位快速清除
  69.   TSCR1_TEN = 1;    // 定時器使能位. 1=允許定時器正常工作; 0=使主定時器不起作用(包括計數器)
  70.   TIOS  = 0xff;      //指定所有通道為輸出比較方式
  71.   TCTL1 = 0x00;            // 后四個通道設置為定時器與輸出引腳斷開
  72.   TCTL2 = 0x00;     // 前四個通道設置為定時器與輸出引腳斷開
  73.   TIE   = 0x00;     // 禁止所有通道定時中斷
  74.   TSCR2 = 0x07;            // 預分頻系數pr2-pr0:111,,時鐘周期為4us,
  75.   TFLG1 = 0xff;            // 清除各IC/OC中斷標志位
  76.   TFLG2 = 0xff;     // 清除自由定時器中斷標志位
  77. }

  78. /*************************************************************/
  79. /*                        初始化LIN                          */
  80. /*************************************************************/
  81. void INIT_LIN(void)
  82. {
  83.   unsigned char i;
  84.   SCI0BD = BUS_CLOCK/16/BAUD;   //設置SCI0波特率為9600  
  85.   SCI0CR1 = 0x00;        //設置SCI0為正常模式,八位數據位,無奇偶校驗
  86.   SCI0CR2 = 0x2c;        //允許接收和發送數據,允許接收中斷功能
  87.   SCI0SR2_BRK13 = 1;  
  88.   frame_send.protected_id=0;
  89.   frame_send.state=IDLE;
  90.   frame_send.error=0;
  91.   frame_send.check=0;
  92.   for (i=0;i<8;i++)
  93.     frame_send.data[i]=0;
  94.   EN_dir=1;
  95.   EN=1;
  96. }



  97. /*************************************************************/
  98. /*                     計算奇偶校驗位                        */
  99. /*************************************************************/
  100. unsigned char LINCalcParity(unsigned char id)
  101. {
  102.   unsigned char parity, p0,p1;
  103.   parity=id;
  104.   p0=(BIT(parity,0)^BIT(parity,1)^BIT(parity,2)^BIT(parity,4))<<6;     //偶校驗位
  105.   p1=(!(BIT(parity,1)^BIT(parity,3)^BIT(parity,4)^BIT(parity,5)))<<7;  //奇校驗位
  106.   parity|=(p0|p1);
  107.   return parity;
  108. }

  109. /*************************************************************/
  110. /*                       計算和校驗位                        */
  111. /*************************************************************/
  112. unsigned char LINCalcChecksum(unsigned char *data)         
  113. {
  114.   unsigned int sum = 0;
  115.   unsigned char i;

  116.   for(i = 0; i < 8; i++)
  117.   {
  118.     sum += data[i];
  119.     if(sum&0xFF00)
  120.       sum = (sum&0x00FF) + 1;
  121.   }
  122.   sum ^= 0x00FF;         
  123.   return (unsigned char)sum;
  124. }

  125. /*************************************************************/
  126. /*                       發送檢測函數                        */
  127. /*************************************************************/
  128. Bool LINCheckSend(enum lin_state status, unsigned char val)
  129. {
  130.   // 等待串口數據接收到為止  
  131.   while(frame_send.state < status)
  132.      if(frame_send.error)
  133.      return(FALSE);
  134.    
  135.   switch(status)
  136.   {
  137.     case _BREAK:
  138.     case SYNCH:
  139.       break;
  140.       
  141.     case PROTECTED_IDENTIFIER:
  142.       if(frame_send.protected_id != val)
  143.         return(FALSE);
  144.       break;
  145.         
  146.     case DATA0:
  147.     case DATA1:
  148.     case DATA2:
  149.     case DATA3:
  150.     case DATA4:
  151.     case DATA5:
  152.     case DATA6:
  153.     case DATA7:
  154.       if(frame_send.data[status-DATA0] != val)
  155.         return(FALSE);
  156.       break;
  157.         
  158.     case CHECKSUM:
  159.       if(frame_send.check != val)
  160.         return(FALSE);
  161.       break;
  162.   }
  163.   return(TRUE);
  164. }

  165. /*************************************************************/
  166. /*                     LIN發送字節函數                       */
  167. /*************************************************************/
  168. Bool LINSendChar(unsigned char ch)
  169. {
  170.   while(!SCI0SR1_TDRE);         //等待發送數據寄存器(緩沖器)為空
  171.   SCI0DRL = ch;
  172.   return(TRUE);
  173. }

  174. /*************************************************************/
  175. /*                      LIN發送間隔場                        */
  176. /*************************************************************/
  177. Bool LINSendbreak(void)
  178. {
  179.   while(!SCI0SR1_TDRE);         //等待發送數據寄存器(緩沖器)為空
  180.   SCI0CR2_SBK = 1;           //隊列待發送的中止字符
  181.   SCI0CR2_SBK = 0;           //返回正常發送操作
  182.   return(TRUE);
  183. }

  184. /*************************************************************/
  185. /*                     LIN發送信息函數                       */
  186. /*************************************************************/
  187. Bool LINSendMsg(void)
  188. {
  189.   unsigned char check_sum, parity_id, i;
  190.   
  191.   frame_send.error = 0;
  192.   
  193.     // 發送間隔場
  194.     if(!LINSendbreak())
  195.       return(FALSE);
  196.     // 檢查間隔場發送
  197.     if(!LINCheckSend(_BREAK,0x00))
  198.       return(FALSE);      
  199.     // 發送同步場
  200.     if(!LINSendChar(0x55))
  201.       return(FALSE);
  202.     // 檢查同步場發送
  203.     if(!LINCheckSend(SYNCH,0x55))
  204.       return(FALSE);
  205.     // 計算奇偶校驗
  206.     parity_id=LINCalcParity(msg_send.identifier);
  207.     // 發送標識符場
  208.     if(!LINSendChar(parity_id))
  209.       return(FALSE);
  210.     // 檢查標識符場發送
  211.     if(!LINCheckSend(PROTECTED_IDENTIFIER, parity_id))
  212.       return(FALSE);  
  213.    
  214.     for(i=0; i < 8; i++)
  215.     {
  216.       // 發送數據場
  217.       if(!LINSendChar(msg_send.data[i]))
  218.         return(FALSE);
  219.       // 檢查數據場發送
  220.       if(!LINCheckSend(DATA0+i, msg_send.data[i]))
  221.         return(FALSE);
  222.     }
  223.     check_sum = LINCalcChecksum(msg_send.data);
  224.     // 發送校驗和場
  225.     if(!LINSendChar(check_sum))
  226.       return(FALSE);
  227.     // 檢查校驗和場發送
  228.     if(!LINCheckSend(CHECKSUM, check_sum))
  229.      return(FALSE);  
  230.     frame_send.state = IDLE;
  231.   return(TRUE);
  232. }

  233. /*************************************************************/
  234. /*                     LIN接收字節函數                       */
  235. /*************************************************************/
  236. Bool LINGetChar(void)
  237. {
  238.   unsigned volatile char ch;
  239.   
  240.   // LIN接收通道狀態
  241.   switch(frame_send.state)
  242.   {
  243.     case IDLE:
  244.       if(!(SCI0SR1&0x22))
  245.         return(FALSE);  
  246.       if(SCI0DRL)
  247.         return(FALSE);
  248.       break;
  249.     case _BREAK:
  250.       if(!(SCI0SR1&0x20))
  251.         return(FALSE);
  252.       if(SCI0DRL != 0x55)
  253.         return(FALSE);   
  254.       break;  
  255.     case SYNCH:
  256.       if(!(SCI0SR1&0x20))
  257.         return(FALSE);
  258.       ch = SCI0DRL;
  259.       frame_send.protected_id = ch;
  260.       break;   
  261.     case PROTECTED_IDENTIFIER:
  262.     case DATA0:
  263.     case DATA1:
  264.     case DATA2:
  265.     case DATA3:
  266.     case DATA4:
  267.     case DATA5:
  268.     case DATA6:
  269.       if(!(SCI0SR1&0x20))
  270.         return(FALSE);
  271.       ch = SCI0DRL;
  272.       frame_send.data[frame_send.state-PROTECTED_IDENTIFIER] = ch;
  273.       break;
  274.     case DATA7:
  275.       if(!(SCI0SR1&0x20))
  276.         return(FALSE);
  277.       ch = SCI0DRL;
  278.       frame_send.check = ch;
  279.       break;
  280.     case CHECKSUM:
  281.       return(FALSE);  
  282.   }
  283.   frame_send.state+=1;
  284.   return(TRUE);
  285. }

  286. /*************************************************************/
  287. /*                         延時函數                          */
  288. /*************************************************************/
  289. void delay1ms(unsigned int n)
  290. {
  291.     unsigned int i;
  292.     for(i=0;i<n;i++)
  293.     {
  294.         TFLG1_C0F = 1;              //清除標志位
  295.         TC0 = TCNT + 250;             //設置輸出比較時間為1ms
  296.         while(TFLG1_C0F == 0);      //等待,直到發生輸出比較事件
  297.     }
  298. }


  299. /*************************************************************/
  300. /*                    LIN檢查發送的數據                      */
  301. /*************************************************************/
  302. #pragma CODE_SEG __NEAR_SEG NON_BANKED
  303. interrupt void LINreceive(void)
  304. {
  305.   if(!LINGetChar())
  306.   {
  307.     BUZZ=1;
  308.     frame_send.error = 1;
  309.     frame_send.state = IDLE;
  310.   }
  311. }
  312. #pragma CODE_SEG DEFAULT


  313. /*************************************************************/
  314. /*                           主函數                          */
  315. /*************************************************************/
  316. void main(void) {
  317.   DisableInterrupts;
  318.   INIT_PLL();
  319.   initialize_ect();
  320.   INIT_LIN();
  321.   LEDCPU_dir=1;
  322.   LEDCPU=0;
  323.   BUZZ_dir=1;
  324.   BUZZ=0;
  325.         EnableInterrupts;

  326.   msg_send.identifier = ID;    // 標識符
  327.   msg_send.data[0] = 'F';      // 數據  
  328.   msg_send.data[1] = 'R';
  329.   msg_send.data[2] = 'E';
  330.   msg_send.data[3] = 'E';
  331.   msg_send.data[4] = 'F';
  332.   msg_send.data[5] = 'L';
  333.   msg_send.data[6] = 'Y';
  334.   msg_send.data[7] = '!';
  335.   frame_send.state = IDLE;

  336.   for(;;)
  337.   {
  338.       delay1ms(500);
  339.       a = LINSendMsg();      //LIN發送數據
  340.       if(a)
  341.          LEDCPU=~LEDCPU;
  342.       else
  343.          BUZZ=1;
  344.   }
  345. }
復制代碼

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产精品毛片一区二区三区 | 秋霞av国产精品一区 | 午夜在线小视频 | 可以在线观看av的网站 | 日韩免费毛片视频 | 一区二区三区国产视频 | 噜噜噜色网 | 久久综合狠狠综合久久综合88 | 色爱综合网| 午夜国产一级 | 日韩在线精品视频 | 麻豆av在线| 欧美日本一区 | 91精品久久 | 日韩精品在线一区 | 国户精品久久久久久久久久久不卡 | 久久久91精品国产一区二区三区 | 中文字幕av色 | 新疆少妇videos高潮 | 99精品视频免费在线观看 | 97久久精品 | 欧美精品一区二区免费视频 | 亚洲理论在线观看电影 | 国内精品久久久久 | 久久久久久一区 | 中文字幕日韩一区 | 久久一区二区三区四区 | 日韩中文字幕免费 | 青青草社区 | caoporn国产精品免费公开 | 久久久久久九九九九九九 | 亚洲电影专区 | 免费中文字幕 | 综合色导航 | 伊人久久伊人 | 91精品国产综合久久婷婷香蕉 | 欧美日韩在线一区二区 | 精品欧美一区二区久久久伦 | 黄色成人免费在线观看 | 日本精品一区二区三区视频 | 成人在线一区二区 |