文件在附件
LIN接收.rar
(243.82 KB, 下載次數: 40)
2018-8-2 09:09 上傳
點擊文件名下載附件
LIN接 下載積分: 黑幣 -5
LIN發送.rar
(362.66 KB, 下載次數: 30)
2018-8-2 09:09 上傳
點擊文件名下載附件
LIN發 下載積分: 黑幣 -5
單片機源程序如下:
- /*---------------------------------------------------------*/
- /************************************************************
- 飛翔科技MC9S12XS128汽車電子開發板
- ************************************************************/
- /*---------------------------------------------------------*/
- #include <hidef.h> /* common defines and macros */
- #include "derivative.h" /* derivative-specific definitions */
- #define BUZZ PORTK_PK5
- #define BUZZ_dir DDRK_DDRK5
- #define LEDCPU PORTK_PK4
- #define LEDCPU_dir DDRK_DDRK4
- #define BUS_CLOCK 32000000 //總線頻率
- #define OSC_CLOCK 16000000 //晶振頻率
- #define BAUD 9600 //串口波特率
- #define BIT(A,B) ((A>>B)&0x01) // A 為變量
- // B 表示A中的第幾位
- #define ID 0x30 // ID場值為0x30
- #define EN PTM_PTM6 //LIN使能
- #define EN_dir DDRM_DDRM6
- unsigned int x=0;
- Bool a;
-
- struct message {
- unsigned char identifier;
- unsigned char data[8];
- };
- struct message msg_send;
- struct message msg_get;
- // 定義LIN狀態
- enum lin_state { IDLE, _BREAK, SYNCH, PROTECTED_IDENTIFIER, DATA0, DATA1,
- DATA2, DATA3, DATA4, DATA5, DATA6, DATA7, CHECKSUM };
- // 定義幀結構體
- struct frame {
- unsigned char protected_id;
- unsigned char data[8];
- unsigned char check;
- enum lin_state state;
- unsigned char error;
- };
- struct frame frame_send,frame_receive;
- /*************************************************************/
- /* 初始化鎖相環 */
- /*************************************************************/
- void INIT_PLL(void)
- {
- CLKSEL &= 0x7f; //set OSCCLK as sysclk
- PLLCTL &= 0x8F; //Disable PLL circuit
- CRGINT &= 0xDF;
-
- #if(BUS_CLOCK == 40000000)
- SYNR = 0x44;
- #elif(BUS_CLOCK == 32000000)
- SYNR = 0x43;
- #elif(BUS_CLOCK == 24000000)
- SYNR = 0x42;
- #endif
- REFDV = 0x81; //PLLCLK=2×OSCCLK×(SYNDIV+1)/(REFDIV+1)=64MHz ,fbus=32M
- PLLCTL =PLLCTL|0x70; //Enable PLL circuit
- asm NOP;
- asm NOP;
- while(!(CRGFLG&0x08)); //PLLCLK is Locked already
- CLKSEL |= 0x80; //set PLLCLK as sysclk
- }
- /************************************************************/
- /* 初始化ECT模塊 */
- /************************************************************/
- void initialize_ect(void){
- TSCR1_TFFCA = 1; // 定時器標志位快速清除
- TSCR1_TEN = 1; // 定時器使能位. 1=允許定時器正常工作; 0=使主定時器不起作用(包括計數器)
- TIOS = 0xff; //指定所有通道為輸出比較方式
- TCTL1 = 0x00; // 后四個通道設置為定時器與輸出引腳斷開
- TCTL2 = 0x00; // 前四個通道設置為定時器與輸出引腳斷開
- TIE = 0x00; // 禁止所有通道定時中斷
- TSCR2 = 0x07; // 預分頻系數pr2-pr0:111,,時鐘周期為4us,
- TFLG1 = 0xff; // 清除各IC/OC中斷標志位
- TFLG2 = 0xff; // 清除自由定時器中斷標志位
- }
- /*************************************************************/
- /* 初始化LIN */
- /*************************************************************/
- void INIT_LIN(void)
- {
- unsigned char i;
- SCI0BD = BUS_CLOCK/16/BAUD; //設置SCI0波特率為9600
- SCI0CR1 = 0x00; //設置SCI0為正常模式,八位數據位,無奇偶校驗
- SCI0CR2 = 0x2c; //允許接收和發送數據,允許接收中斷功能
- SCI0SR2_BRK13 = 1;
- frame_send.protected_id=0;
- frame_send.state=IDLE;
- frame_send.error=0;
- frame_send.check=0;
- for (i=0;i<8;i++)
- frame_send.data[i]=0;
- EN_dir=1;
- EN=1;
- }
- /*************************************************************/
- /* 計算奇偶校驗位 */
- /*************************************************************/
- unsigned char LINCalcParity(unsigned char id)
- {
- unsigned char parity, p0,p1;
- parity=id;
- p0=(BIT(parity,0)^BIT(parity,1)^BIT(parity,2)^BIT(parity,4))<<6; //偶校驗位
- p1=(!(BIT(parity,1)^BIT(parity,3)^BIT(parity,4)^BIT(parity,5)))<<7; //奇校驗位
- parity|=(p0|p1);
- return parity;
- }
- /*************************************************************/
- /* 計算和校驗位 */
- /*************************************************************/
- unsigned char LINCalcChecksum(unsigned char *data)
- {
- unsigned int sum = 0;
- unsigned char i;
- for(i = 0; i < 8; i++)
- {
- sum += data[i];
- if(sum&0xFF00)
- sum = (sum&0x00FF) + 1;
- }
- sum ^= 0x00FF;
- return (unsigned char)sum;
- }
- /*************************************************************/
- /* 發送檢測函數 */
- /*************************************************************/
- Bool LINCheckSend(enum lin_state status, unsigned char val)
- {
- // 等待串口數據接收到為止
- while(frame_send.state < status)
- if(frame_send.error)
- return(FALSE);
-
- switch(status)
- {
- case _BREAK:
- case SYNCH:
- break;
-
- case PROTECTED_IDENTIFIER:
- if(frame_send.protected_id != val)
- return(FALSE);
- break;
-
- case DATA0:
- case DATA1:
- case DATA2:
- case DATA3:
- case DATA4:
- case DATA5:
- case DATA6:
- case DATA7:
- if(frame_send.data[status-DATA0] != val)
- return(FALSE);
- break;
-
- case CHECKSUM:
- if(frame_send.check != val)
- return(FALSE);
- break;
- }
- return(TRUE);
- }
- /*************************************************************/
- /* LIN發送字節函數 */
- /*************************************************************/
- Bool LINSendChar(unsigned char ch)
- {
- while(!SCI0SR1_TDRE); //等待發送數據寄存器(緩沖器)為空
- SCI0DRL = ch;
- return(TRUE);
- }
- /*************************************************************/
- /* LIN發送間隔場 */
- /*************************************************************/
- Bool LINSendbreak(void)
- {
- while(!SCI0SR1_TDRE); //等待發送數據寄存器(緩沖器)為空
- SCI0CR2_SBK = 1; //隊列待發送的中止字符
- SCI0CR2_SBK = 0; //返回正常發送操作
- return(TRUE);
- }
- /*************************************************************/
- /* LIN發送信息函數 */
- /*************************************************************/
- Bool LINSendMsg(void)
- {
- unsigned char check_sum, parity_id, i;
-
- frame_send.error = 0;
-
- // 發送間隔場
- if(!LINSendbreak())
- return(FALSE);
- // 檢查間隔場發送
- if(!LINCheckSend(_BREAK,0x00))
- return(FALSE);
- // 發送同步場
- if(!LINSendChar(0x55))
- return(FALSE);
- // 檢查同步場發送
- if(!LINCheckSend(SYNCH,0x55))
- return(FALSE);
- // 計算奇偶校驗
- parity_id=LINCalcParity(msg_send.identifier);
- // 發送標識符場
- if(!LINSendChar(parity_id))
- return(FALSE);
- // 檢查標識符場發送
- if(!LINCheckSend(PROTECTED_IDENTIFIER, parity_id))
- return(FALSE);
-
- for(i=0; i < 8; i++)
- {
- // 發送數據場
- if(!LINSendChar(msg_send.data[i]))
- return(FALSE);
- // 檢查數據場發送
- if(!LINCheckSend(DATA0+i, msg_send.data[i]))
- return(FALSE);
- }
- check_sum = LINCalcChecksum(msg_send.data);
- // 發送校驗和場
- if(!LINSendChar(check_sum))
- return(FALSE);
- // 檢查校驗和場發送
- if(!LINCheckSend(CHECKSUM, check_sum))
- return(FALSE);
- frame_send.state = IDLE;
- return(TRUE);
- }
- /*************************************************************/
- /* LIN接收字節函數 */
- /*************************************************************/
- Bool LINGetChar(void)
- {
- unsigned volatile char ch;
-
- // LIN接收通道狀態
- switch(frame_send.state)
- {
- case IDLE:
- if(!(SCI0SR1&0x22))
- return(FALSE);
- if(SCI0DRL)
- return(FALSE);
- break;
- case _BREAK:
- if(!(SCI0SR1&0x20))
- return(FALSE);
- if(SCI0DRL != 0x55)
- return(FALSE);
- break;
- case SYNCH:
- if(!(SCI0SR1&0x20))
- return(FALSE);
- ch = SCI0DRL;
- frame_send.protected_id = ch;
- break;
- case PROTECTED_IDENTIFIER:
- case DATA0:
- case DATA1:
- case DATA2:
- case DATA3:
- case DATA4:
- case DATA5:
- case DATA6:
- if(!(SCI0SR1&0x20))
- return(FALSE);
- ch = SCI0DRL;
- frame_send.data[frame_send.state-PROTECTED_IDENTIFIER] = ch;
- break;
- case DATA7:
- if(!(SCI0SR1&0x20))
- return(FALSE);
- ch = SCI0DRL;
- frame_send.check = ch;
- break;
- case CHECKSUM:
- return(FALSE);
- }
- frame_send.state+=1;
- return(TRUE);
- }
- /*************************************************************/
- /* 延時函數 */
- /*************************************************************/
- void delay1ms(unsigned int n)
- {
- unsigned int i;
- for(i=0;i<n;i++)
- {
- TFLG1_C0F = 1; //清除標志位
- TC0 = TCNT + 250; //設置輸出比較時間為1ms
- while(TFLG1_C0F == 0); //等待,直到發生輸出比較事件
- }
- }
- /*************************************************************/
- /* LIN檢查發送的數據 */
- /*************************************************************/
- #pragma CODE_SEG __NEAR_SEG NON_BANKED
- interrupt void LINreceive(void)
- {
- if(!LINGetChar())
- {
- BUZZ=1;
- frame_send.error = 1;
- frame_send.state = IDLE;
- }
- }
- #pragma CODE_SEG DEFAULT
- /*************************************************************/
- /* 主函數 */
- /*************************************************************/
- void main(void) {
- DisableInterrupts;
- INIT_PLL();
- initialize_ect();
- INIT_LIN();
- LEDCPU_dir=1;
- LEDCPU=0;
- BUZZ_dir=1;
- BUZZ=0;
- EnableInterrupts;
- msg_send.identifier = ID; // 標識符
- msg_send.data[0] = 'F'; // 數據
- msg_send.data[1] = 'R';
- msg_send.data[2] = 'E';
- msg_send.data[3] = 'E';
- msg_send.data[4] = 'F';
- msg_send.data[5] = 'L';
- msg_send.data[6] = 'Y';
- msg_send.data[7] = '!';
- frame_send.state = IDLE;
- for(;;)
- {
- delay1ms(500);
- a = LINSendMsg(); //LIN發送數據
- if(a)
- LEDCPU=~LEDCPU;
- else
- BUZZ=1;
- }
- }
復制代碼
|