<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

MM32F5270 UART實現LIN通信

靈動MM32MCU ? 來源:靈動MM32MCU ? 作者:靈動MM32MCU ? 2024-01-04 17:35 ? 次閱讀

1?

LIN總線簡介

LIN(Local Interconnect Network)總線是基于UART/SCI(通用異步收發器/串行接口)的低成本串行通訊協議,其目標定位于車身網絡模塊節點間的低端通信,主要用于智能傳感器和執行器的串行通信。LIN總線采用單主多從的組網方式,沒有CAN總線那樣的仲裁機制,輔以簡單驅動程序便可實現LIN協議。LIN節點由控制芯片和LIN收發器構成,一般通過芯片搭載的UART模塊來實現,主節點控制傳輸時刻,控制整個網絡的通信,從節點按照主節點的調度進行通信。

2?

LIN報文結構

LIN總線上有“顯性”和“隱性”兩種互補的邏輯電平。顯性電平是邏輯 0,隱性電平是邏輯1,總線上實行“線與”。

一幀LIN報文由幀頭(Header)和應答(Response)兩部分組成。主機任務負責發送幀頭,從機任務接收幀頭并對幀頭所包含信息進行解析,然后決定是發送應答,還是接收應答,還是不作任何反應。幀在總線上的傳輸如下圖所示:

65fff5f2-aae4-11ee-8b88-92fbcf53809c.png

幀頭包括同步間隔段、同步段以及受保護ID段(PID)。應答包括數據段和校驗和段。LIN報文幀整體結構如下圖所示。

66128fdc-aae4-11ee-8b88-92fbcf53809c.png

同步間隔段

同步間隔段標志一幀的開始,由同步間隔(Break)和間隔符(Break Delimiter)構成。同步間隔段至少有13個顯性位,間隔符至少有一個隱形位。

同步段

同步段固定一個字節,值固定為0x55。

在LIN幀中,除了同步間隔段,后面各段都是通過字節域的格式傳輸的。LIN的字節域就是指標準的UART數據傳輸格式,字節域包括1位起始位(顯性)+8位數據位+1位停止位(隱性)。數據傳輸都是先發送LSB,最后發送 MSB。LIN總線將下降沿作為判斷標志,通過字節0x55(01010101b)進行同步,從機節點上可以采用非高精度時鐘,如果存在偏差,可以通過同步場來調整,使從機節點數據的波特率與主機節點一致。

受保護ID段

受保護ID段由6位幀ID和2位奇偶校驗位組成,幀ID范圍為0x00~0x3F共64個。

幀ID標識了幀的類別,從機任務根據幀頭ID作出反應(接收/發送/忽略應答),其中P0與P1效驗如下:

P0 = ID0⊕ID1⊕ID2⊕ID4

P1 = ?(ID1⊕ID3⊕ID4⊕ID5)

其中“⊕”代表“異或”運算,“?”代表“取非”運算。

由公式可以看出,PID 不會出現全 0 或全 1 的情況,如果從機節點收到了“0xFF”或“0x00”,可判斷傳輸錯誤。LIN總線根據幀ID的不同,將報文分為信號攜帶幀、診斷幀、保留幀。

662cf476-aae4-11ee-8b88-92fbcf53809c.png

應注意從機應答幀是一個完整的幀,與幀結構中的“應答”不同。

數據段

數據段包含1~8個字節,可以分為兩種數據類型:信號和診斷消息。信號由信號攜帶幀傳遞,診斷消息由診斷幀傳遞。LIN協議規定可傳輸的LIN字節數為2、4、8,并不是1~8內任意一個數字。一般應用方面會統一字節數,通常是每幀傳輸8個字節。

校驗和段

校驗和段是為了對幀傳輸內容進行效驗。效驗分為標準型校驗與增強型校驗。

將校驗對象的各字節作帶進位二進制加法(當結果大于等于256 時就減去255),并將所得最終的和逐位取反,以該結果作為要發送的校驗和。接收方根據校驗和類型,對接收數據作相同的帶進位二進制加法,最終的和不取反,并將該和與接收到的校驗和作加法,如果結果為0xFF,則校驗和無誤。這在一定程度上保證了數據傳輸的正確性。

采用標準型還是增強型是由主機節點管理,發布節點和收聽節點根據幀ID來判斷采用哪種校驗和。

66453e32-aae4-11ee-8b88-92fbcf53809c.png

3?

LIN通信實驗

MM32F5270的UART支持LIN協議下收發斷開符號,通過配置UART,根據總線特征編寫LIN驅動程序,實現LIN總線通信。相關代碼參考靈動官網的LibSamples或在此基礎上修改。

3.1 LIN驅動程序

同步間隔段

配置UART支持LIN協議下收發斷開符號:

voidLIN_MASTER_Break(void)
{
LIN_MASTER_TXBRK_InterruptFlag=0;

UART_LINCmd(UART1,ENABLE);
UART_SendBreak(UART1);

while(0==LIN_MASTER_TXBRK_InterruptFlag)
{
}
}

同步段

主機發送0x55:

voidLIN_MASTER_SyncByte(void)
{
LIN_MASTER_SendData(0x55);
}

受保護ID段

uint8_tLIN_FrameIDToPID(uint8_tFrameID)
{
uint8_ti=0;
uint8_tP0=0,P1=0,PID=0xFF;
uint8_tID_BIT[6]=
{
0,0,0,0,0,0
};

if(FrameID

數據段

主機發送數據:

voidLIN_MASTER_SendData(uint8_tData)
{
UART_SendData(UART1,Data);

while(RESET==UART_GetFlagStatus(UART1,UART_FLAG_TXC))
{
}
}

從機發送數據:

voidLIN_SLAVE_SendData(uint8_tData)
{
UART_SendData(UART1,Data);

while(RESET==UART_GetFlagStatus(UART1,UART_FLAG_TXC))
{
}
}

校驗和段

標準型校驗:

uint8_tLIN_ClassicChecksum(uint8_t*Buffer,uint8_tLength)
{
uint8_ti=0;
uint16_tChecksum=0;

for(i=0;i0xFF)
{
Checksum%=0xFF;
}
}

return(~(uint8_t)(Checksum&0x00FF));
}

增強型校驗:

uint8_tLIN_EnhancedChecksum(uint8_tPID,uint8_t*Buffer,uint8_tLength)
{
uint8_ti=0;
uint16_tChecksum=PID;

for(i=0;i0xFF)
{
Checksum%=0xFF;
}
}

return(~(uint8_t)(Checksum&0x00FF));
}

主機發送幀頭

voidLIN_MASTER_SendHeader(uint8_tPID)
{
LIN_MASTER_Break();

LIN_MASTER_SyncByte();

LIN_MASTER_SendData(PID);
}

主機發送報文

診斷幀ID包括主機請求幀0x3C、從機應答幀0x3D,診斷幀用標準型校驗和,其他幀使用增強型校驗和。

voidLIN_Master_SendFrame(uint8_tFrameID,uint8_t*Buffer,uint8_tLength)
{
uint8_ti=0;
uint8_tChecksum=0;
uint8_tPID=LIN_FrameIDToPID(FrameID);

if((0x3C==FrameID)||(0x3D==FrameID))
{
Checksum=LIN_ClassicChecksum(Buffer,Length);
}
else
{
Checksum=LIN_EnhancedChecksum(PID,Buffer,Length);
}

LIN_MASTER_SendHeader(PID);

for(i=0;i

從機發布數據

從機解析幀頭信息,將主機發送的PID得到幀ID,根據幀ID選擇校驗類型,發送數據段和校驗和段。

voidLIN_SLAVE_Response(uint8_t*Buffer,uint8_tLength)
{
uint8_ti=0;
uint8_tChecksum=0,FrameID=0;

FrameID=LIN_PIDToFrameID(LIN_SLAVE_RxBuffer[1]);
Checksum=0;

if((0x3C==FrameID)||(0x3D==FrameID))
{
Checksum=LIN_ClassicChecksum(Buffer,Length);
}
else
{
Checksum=LIN_EnhancedChecksum(LIN_SLAVE_RxBuffer[1],Buffer,Length);
}

for(i=0;i

3.2 主機程序

主機UART配置

voidUART_Configure(uint32_tBaudrate)
{
GPIO_InitTypeDefGPIO_InitStruct;
NVIC_InitTypeDefNVIC_InitStruct;
UART_InitTypeDefUART_InitStruct;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_UART1,ENABLE);

UART_StructInit(&UART_InitStruct);
UART_InitStruct.BaudRate=Baudrate;
UART_InitStruct.WordLength=UART_WordLength_8b;
UART_InitStruct.StopBits=UART_StopBits_1;
UART_InitStruct.Parity=UART_Parity_No;
UART_InitStruct.HWFlowControl=UART_HWFlowControl_None;
UART_InitStruct.Mode=UART_Mode_Rx|UART_Mode_Tx;
UART_Init(UART1,&UART_InitStruct);

UART_IDLRConfig(UART1,100);/*LINMasterOnly!!!*/

UART_ITConfig(UART1,UART_IT_RX,ENABLE);
UART_ITConfig(UART1,UART_IT_TXBRK,ENABLE);

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);

GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_7);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_7);

GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_High;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_Init(GPIOA,&GPIO_InitStruct);

GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
GPIO_Init(GPIOA,&GPIO_InitStruct);

NVIC_InitStruct.NVIC_IRQChannel=UART1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStruct);

UART_Cmd(UART1,ENABLE);
}

主機中斷服務子程序

voidUART1_IRQHandler(void)
{
uint8_ti=0;

if(SET==UART_GetITStatus(UART1,UART_IT_TXBRK))
{
UART1_RxLength=0;

UART_ClearITPendingBit(UART1,UART_IT_TXBRK);

UART_ITConfig(UART1,UART_IT_RXIDLE,ENABLE);

LIN_MASTER_TXBRK_InterruptFlag=1;
}

if(SET==UART_GetITStatus(UART1,UART_IT_RX))
{
UART1_RxBuffer[UART1_RxLength]=UART1->RDR&0x00FF;

UART1_RxLength=(UART1_RxLength+1)%100;

UART_ClearITPendingBit(UART1,UART_IT_RX);
}

if(SET==UART_GetITStatus(UART1,UART_IT_RXIDLE))
{
for(i=0;i

主機例程

主機間隔500ms發布和接收數據,發送幀ID和數據依次累加:

voidUART_LIN_Master_Sample(void)
{
uint8_ti=0;
uint8_tFrameID=0,Mode=0;
uint8_tBuffer[2]={0,0};

printf("
Test%s",__FUNCTION__);

LIN_MASTER_RxLength=0;
LIN_MASTER_RxFinish=0;

for(i=0;i

3.3 從機程序

從機UART配置

使能UART LIN總線模式、使能UART接收斷開幀中斷、使能接收單字節中斷。

voidUART_Configure(uint32_tBaudrate)
{
GPIO_InitTypeDefGPIO_InitStruct;
NVIC_InitTypeDefNVIC_InitStruct;
UART_InitTypeDefUART_InitStruct;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_UART1,ENABLE);

UART_StructInit(&UART_InitStruct);
UART_InitStruct.BaudRate=Baudrate;
UART_InitStruct.WordLength=UART_WordLength_8b;
UART_InitStruct.StopBits=UART_StopBits_1;
UART_InitStruct.Parity=UART_Parity_No;
UART_InitStruct.HWFlowControl=UART_HWFlowControl_None;
UART_InitStruct.Mode=UART_Mode_Rx|UART_Mode_Tx;
UART_Init(UART1,&UART_InitStruct);

UART_LINCmd(UART1,ENABLE);

UART_ITConfig(UART1,UART_IT_RX,ENABLE);
UART_ITConfig(UART1,UART_IT_RXBRK,ENABLE);

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);

GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_7);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_7);

GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_High;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_Init(GPIOA,&GPIO_InitStruct);

GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
GPIO_Init(GPIOA,&GPIO_InitStruct);

NVIC_InitStruct.NVIC_IRQChannel=UART1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStruct);

UART_Cmd(UART1,ENABLE);
}

從機中斷服務子程序

voidUART1_IRQHandler(void)
{
uint8_ti=0;

if(SET==UART_GetITStatus(UART1,UART_IT_RXBRK))
{
UART1_RxLength=0;

UART_ClearITPendingBit(UART1,UART_IT_RXBRK);

UART_ITConfig(UART1,UART_IT_RXIDLE,ENABLE);
}

if(SET==UART_GetITStatus(UART1,UART_IT_RX))
{
UART1_RxBuffer[UART1_RxLength]=UART_ReceiveData(UART1);

UART1_RxLength=(UART1_RxLength+1)%100;

UART_ClearITPendingBit(UART1,UART_IT_RX);
}

if(SET==UART_GetITStatus(UART1,UART_IT_RXIDLE))
{
for(i=0;i

從機例程

從機對幀頭包含信息解析,確定是發送應答,還是接收應答。

voidUART_LIN_Slave_Sample(void)
{
uint8_ti=0;
uint8_tChecksum=0,FrameID=0;
uint8_tLength=0,Buffer[100];

printf("
Test%s",__FUNCTION__);

Length=0;
LIN_SLAVE_RxLength=0;
LIN_SLAVE_RxFinish=0;

for(i=0;i

3.4 驗證

通過UART接口連接兩塊MM32F5270 MiniBoard,觀察串口調試助手:

66589932-aae4-11ee-8b88-92fbcf53809c.png

先由主機發布數據,從機接收數據,接著由從機發布數據,主機接收數據,依次循環進行。根據截圖信息,主從機收發數據一致,與程序邏輯相符,兩塊板LIN通信成功。







審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • uart
    +關注

    關注

    22

    文章

    1162

    瀏覽量

    100195
  • 異步收發器
    +關注

    關注

    0

    文章

    36

    瀏覽量

    10804
  • 串行通訊
    +關注

    關注

    2

    文章

    77

    瀏覽量

    16280
  • LIN通信
    +關注

    關注

    2

    文章

    8

    瀏覽量

    3728
  • MM32
    +關注

    關注

    1

    文章

    105

    瀏覽量

    607

原文標題:靈動微課堂 (第280講)|MM32F5270 UART實現LIN通信

文章出處:【微信號:MindMotion-MMCU,微信公眾號:靈動MM32MCU】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    MM32F5270平臺ADC注入通道的單周期采樣的實現

    MM32F5270的ADC可配置4個注入通道來擴展轉換通道,那么可進行轉換的通道最多可達20個。
    的頭像 發表于 06-01 17:25 ?1188次閱讀
    <b class='flag-5'>MM32F5270</b>平臺ADC注入通道的單周期采樣的<b class='flag-5'>實現</b>

    基于MM32F5270開發板獲取雨滴傳感器的數據相關資料介紹

    1、基于MindSDK對接雨滴傳感器我們還是來介紹一下開發板的相關參數。靈動MM32F5270開發板是搭載安謀科技“星辰”STAR-MC1處理器的全新高性能 MM32F5270微控制器,這個
    發表于 08-24 15:20

    一文解析MM32F5270開發板+PWM測試與調制

    1、MM32F5270開發板+ PWM測試與調制  PWM接口引腳  MM32F5270開發板有引出PWM引腳給我們,我們可以直接使用就行?! ≈饕a部分如下  2.1 hal_tim.c
    發表于 09-06 11:24

    MM32F5270(STAR-MC1內核)RT-Thread完整版的移植教程

    基本把rtt移植到mm32f5270中。移植驗證在main.c中main函數添加點燈的代碼。如果能夠看到led在閃爍,就說明移植成功了?,F象shell適配適配uart驅動實現ops的5個函數將ops
    發表于 12-23 17:17

    MM32F5270總線架構設計

    本文介紹了MM32F5270 中所采用的多并發總線架構,并通過帶顯示的音頻播放器的實例說明了該架構在實際應用中所能達到的吞吐率提升效果。
    的頭像 發表于 05-11 11:15 ?1898次閱讀
    <b class='flag-5'>MM32F5270</b>總線架構設計

    基于MM32F5270控制器的I2S音頻播放

    MM32F5270 系列控制器支持 I2S 總線接口,本章節在接下來會對 MM32F5270 I2S進行介紹,并使用 MM32F5270 和 CS4344 芯片進行 I2S 通信來演示
    的頭像 發表于 09-16 10:39 ?1633次閱讀

    MM32F5270 產品手冊(中文版)

    MM32F5270 產品手冊(中文版)
    發表于 02-23 18:45 ?0次下載
    <b class='flag-5'>MM32F5270</b> 產品手冊(中文版)

    MM32F5270 產品手冊(英文版)

    MM32F5270 產品手冊(英文版)
    發表于 02-23 18:45 ?0次下載
    <b class='flag-5'>MM32F5270</b> 產品手冊(英文版)

    MM32F5270 用戶手冊(中文版)

    MM32F5270 用戶手冊(中文版)
    發表于 02-23 18:46 ?0次下載
    <b class='flag-5'>MM32F5270</b> 用戶手冊(中文版)

    MM32F5270 用戶手冊(英文版)

    MM32F5270 用戶手冊(英文版)
    發表于 02-23 18:46 ?0次下載
    <b class='flag-5'>MM32F5270</b> 用戶手冊(英文版)

    MM32F5270 勘誤表(中文版)

    MM32F5270 勘誤表(中文版)
    發表于 02-23 18:47 ?0次下載
    <b class='flag-5'>MM32F5270</b> 勘誤表(中文版)

    MM32F5270 勘誤表(英文版)

    MM32F5270 勘誤表(英文版)
    發表于 02-23 18:48 ?0次下載
    <b class='flag-5'>MM32F5270</b> 勘誤表(英文版)

    MM32F5270平臺ADC注入通道的單周期采樣的實現

    MM32F5270的ADC可配置4個注入通道來擴展轉換通道,那么可進行轉換的通道最多可達20個。
    的頭像 發表于 05-26 09:31 ?426次閱讀
    <b class='flag-5'>MM32F5270</b>平臺ADC注入通道的單周期采樣的<b class='flag-5'>實現</b>

    MM32F5270平臺ADC注入通道的單周期采樣的實現

    MM32F5270的ADC可配置4個注入通道來擴展轉換通道,那么可進行轉換的通道最多可達20個。
    的頭像 發表于 05-26 09:32 ?571次閱讀
    <b class='flag-5'>MM32F5270</b>平臺ADC注入通道的單周期采樣的<b class='flag-5'>實現</b>

    基于MM32F5270的I2S音頻播放

    基于MM32F5270的I2S音頻播放
    的頭像 發表于 10-30 17:13 ?629次閱讀
    基于<b class='flag-5'>MM32F5270</b>的I2S音頻播放
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>