MSP430 LIN总线编程
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?MSP430 LIN總線編程
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Lis, 2021-2-3
? ? ?時隔接近20年,CSDN我回來了...以下為本人原創. 如轉載,請注明出處!
? ? ? LIN總線在汽車領域應用十分的廣泛。汽車上的油泵,自動折疊反光鏡,大燈,鎖等等慢速通信都會有LIN總線的應用身影。但網絡上你幾乎找不到MSP430在這方面的應用,就算去TI的官方網站上去找,去問客服,也找不到,MSP430似乎沒有車規級型號,新能源汽車上幾乎清一色的使用TI的DSP車規級芯片,所以也基本沒有人在MSP430上使用LIN總線。但是掌握LIN總線的應用,會給我們在一些項目里帶來很大的幫助。至于什么是LIN,什么CAN這些的術語,大家自己百度應該可以找到很詳細介紹,這里不做過多的說明。
? ? ?以下是我做的一些筆記,為了避免重復勞動,浪費時間,就直接截圖上來了。
[1] LIN總線特點
[二]物理層連接
[三]接口電路
? ?這里我選擇了最小封裝的TJA1027,8腳芯片,以下為LIN master模式的配置電路。 詳細關于TJA1027請自行網上找它的datasheet
[四]LIN-BUS的幀格式
Break長度一般為為13位,我們稱之為:間隔場.(參考網上的一張比較不錯的圖)
示波下的真實waveform:
邏輯分析儀下的 讀某品牌油泵的時序:
[五]MSP430F24X下的LIN BUS配置
?這里我使用MSP430F249為例,UART模塊,需支持SCI功能。才可以支持LIN,所以不是所有的MSP430系列都支持LIN總線,查看Datasheet是最有效的方式。
[六]代碼部分
? 1.PID部分:ID只是高6個位,后兩個位為奇偶效驗碼.
//---------------------------------------------------------------------------// // uchar LIN_GetPID(uchar id) // //Description: calculate odd and even parity for ID Frame // // ? Parity: // // ? ? ? ? ? ? P0= id0^id1^id2^id4 ? ==>Even ?bit6 // // ? ? ? ? ? ? p1=~(id1^id3^id4^id5) ? ?==>Odd ? bit7 // //---------------------------------------------------------------------------// uchar LIN_GetPID(uchar id) {uchar parity=0, p0,p1;p0 =id;p0^=id>>1;p0^=id>>2;p0^=id>>4;p0&=0x01;p1 =id>>1;p1^=id>>3;p1^=id>>4;p1^=id>>5;p1=~p1;p1&=0x01;parity=id|(p0<<6)|(p1<<7);return parity; }2.checksum
LIN總線中的checksum算法為帶進位的累加。 在LIN總線里,有兩種校驗方式,一種稱為標準驗校,和增強型校驗。 代碼中我做了相關的說明。
//---------------------------------------------------------------------------// // calculate checksum // //paremeters: uchar id: slaver id // // uchar *data array of data,maximum:8 bytes // // uchar len length of the data array // //---------------------------------------------------------------------------// uchar LIN_Checksum(uchar id,uchar *data,uchar len) {uint16 sum = 0;uchar i;//if it's not a diagnostic package | id==0x3c using normal checksum,otherwise using enhance checksum if (id!=0x3c) {sum=LIN_GetPID(id);}for(i = 0; i < len; i++){sum +=data[i];if(sum&0xff00){sum&=0x00ff;sum+=1;} }sum=~sum;return (uchar)sum; }3.添加發送間隔場和同步場
我在代碼中加了宏代碼,以方便我配置LIN端口使用UART0 或UART1
//----------------------------------------------------------------------------// // void USART_UCA0_Send_Byte(uchar data) //----------------------------------------------------------------------------// void USART_UCA0_Send_Byte(uchar data) {UCA0TXBUF = data;while(!Get_Bit(UC0IFG,UCA0TXIFG)); }//---------------------------------------------------------------------------// // LIN_Send_Break_Sync(void) // //---------------------------------------------------------------------------// void LIN_Send_Break_Sync(void) {UCA0CTL0_bit.UCMODE0=1;UCA0CTL0_bit.UCMODE1=1;//4bit stopUCA0ABCTL_bit.UCDELIM0=1;UCA0ABCTL_bit.UCDELIM1=1;UCA0CTL1_bit.UCTXBRK=1;USART_UCA0_Send_Byte(0x55);UCA0CTL1_bit.UCTXBRK=0; } 4.一個完整幀的發送: //---------------------------------------------------------------------------// // LIN_Sendbuf // // // //paremeters: uchar id: slaver id // // uchar *data array of data,maximum:8 bytes // // uchar len length of the data array // //---------------------------------------------------------------------------// void LIN_Sendbuf(uchar id,uchar *data,uchar len) {uchar check_sum, parity_id;uint16 i;LIN_Send_Break_Sync();parity_id=LIN_GetPID(id);USART_UCA0_Send_Byte(parity_id);for(i=0;i<len;i++){ USART_UCA0_Send_Byte(data[i]);} check_sum=LIN_Checksum(id,data,len);USART_UCA0_Send_Byte(check_sum); }5.發送讀操作幀
//---------------------------------------------------------------------------// // void LIN_RX_Ask(uchar id) // // // //definition: Send Syn frame to slaver, Slaver will send back the data // //parameter: uchar id // //---------------------------------------------------------------------------// void LIN_RX_Ask(uchar id) {uchar parity_id;LIN_RX_Idx=0;LIN_Send_Break_Sync();parity_id=LIN_GetPID(id);USART_UCA0_Send_Byte(parity_id); }如這里的時序,master端發送Ask(break+sync+PID),然后slave同步并返回數據幀。 這個比較容易理解,類似于I2C,SPI,1 wire 總線。
6.接收處理: 將接收處理部分寫成單獨的函數,然后放到串口接收中斷中 //----------------------------------------------------------------------------// // void USART_UCA0_Send_Byte(uchar data) //----------------------------------------------------------------------------// void USART_UCA0_Send_Byte(uchar data) {UCA0TXBUF = data;while(!Get_Bit(UC0IFG,UCA0TXIFG)); }//---------------------------------------------------------------------------// // void LIN_Readbuf_Pro(uchar data) // // put this function into RX intterruption // //---------------------------------------------------------------------------// void LIN_Readbuf_Pro(uchar data) {switch(LIN_RX_Idx){case 0:if(data==0x55){LIN_RX_Idx=1;} break;case 1:LIN_RX_Frame.id=data&0x3F;LIN_RX_Idx=2;break;case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:LIN_RX_Frame.d[LIN_RX_Idx-2]= data;LIN_RX_Idx++;break;case 10: LIN_RX_Frame.chksum=data;LIN_RX_Idx=0;break;} }串口接收中斷:
//----------------------------------------------------------------------------// // USCI0RX_ISR UCA0 Interruption //----------------------------------------------------------------------------// #pragma vector=USCIAB0RX_VECTOR __interrupt void USCI0RX_ISR(void) {uchar data=0;data = UCA0RXBUF;// if (UC0IFG&UCA0RXIFG) // {LIN_Readbuf_Pro(data); // } }7.串口設置
#define BAUD_UCA0 10417//----------------------------------------------------------------------------// uchar Get_UCBRS(float baud) {return ((uchar)((baud-(uint16)baud)*8+0.5))<<1; }//----------------------------------------------------------------------------// // void Init_Serial_Ports(void) //----------------------------------------------------------------------------// void Init_Serial_Ports(void) {float tmp_baud;SetPinMode(UCA0_TXD_PIN);SetPinMode(UCA0_RXD_PIN); tmp_baud=CPU_F/2/BAUD_UCA0;UCA0CTL1 |= UCSSEL_2 + UCSWRST; //Set the clock of UCA0 =SMCL,UCSWRST Enable,initial all USCI registors UCA0BR0 =(uchar)(tmp_baud); //Low 8 bitsUCA0BR1 =(uchar)((uint16)tmp_baud>>8); // //High 8bits, NO parity check UCA0MCTL = Get_UCBRS(tmp_baud);UCA0CTL1 &= ~UCSWRST; //clear UCSWRST bitUC0IE |= UCA0RXIE; //Enable RX Interruptor }[7]測試板電路設計
? ? [1]電源部分
? ? ? ? ? ?先設計打算使用于24V電路,所以輸入端,和LIN總線電壓為24V,但是實際應用調試的油泵為12V,所以主供電也為12V。 這里做個說明.?
?
?[2]MSP430部分相對簡單,最小系統,然后把端口都引出去
[3]LIN接口電路
[4]調試用TTL串行口電路
? ?增加緩沖電路,能有效加強TTL串口的可靠,穩定性。
[5]電路指示
[6]預留的一個大功率IO驅動口,用于驅動外部電磁閥等器件
[7]Layout
? ? 根據schematic,布好PWB后,生成工藝文件以及BOM發給PCB工廠進行打樣生產。
[8]實際調試,正常驅動某品牌汽車油泵
總結
以上是生活随笔為你收集整理的MSP430 LIN总线编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2021全球与中国智能音频SoC芯片市场
- 下一篇: Elasticsearch 入门到精通-