生活随笔
收集整理的這篇文章主要介紹了
STM32 —— LIN
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
STM32 —— LIN
/*
? LIN 總線的主要特性有
? ? 單主機 多從機概念
? ? 基于普通 UART/SCI 接口的低成本硬件實現 低成本軟件或作為純狀態機
? ? 從機節點不需要石英或陶瓷諧振器可以實現自同步
? ? 保證信號傳輸的延遲時間
? ? 低成本的單線設備
? ? 速度高達 20kbit/s
? 總線的通訊由單個主機控制 每個報文幀都用一個分隔信號起始 ,一個同步場和一個標識符場 .
? 這些都由主機任務發送 從機任務則是發回數據場和校驗場
? ? ? ?報文路由 報文的內容由識別符命名 識別符不指出報文的目的地 但解釋數據的含義 最大的
? 標識符數量是 64 其中 4 個保留用于專用的通訊 譬如軟件升級或診斷
? 多播 由于引入了報文濾波的概念 任何數目的節點都可以同時接收報文 并同時對此報文做出反應
? 位速率
? ? 最大的波特率是 20kbit/s 它是由單線傳輸媒體的 EMI 限制決定 最小的波特率是 1kbit/s 可以避免
? 和實際設備的超時周期沖突,為使用低成本的 LIN 器件 建議使用下面的位速率
? ? 建議的位速率
? ? 低速 ? ? ?中速 ? ? ?高速
? ? 2400 bit/s ?9600 bit/s ?19200 bit/s
? 單主機 無仲裁
? ? 只有包含主機任務的控制器節點可以傳輸報文頭,一個從機任務對這個報文頭作出響應,由于沒有仲
? 裁過程,如果多于一個從機回應,則將產生錯誤.這種情況下的錯誤界定可由用戶按照應用要求指定.
? 安全性
? ? 錯誤檢測
? ? ? 監控 發送器比較總線 應當 的值和 現在 的值
? ? ? 數據場的校驗和以 256 為模并取反 將 MSB 的進位加到 LSB 上
? ? ? 標識符場的雙重奇偶校驗保護
? 連接
? ? LIN 網絡節點的最大數量不僅由標識符的數量限制 見上面的信息路由 也由總線的物理特性限制
? ? 建議 LIN 網絡的節點數量不應超過 16 否則 節點增加將減少網絡阻抗 會導致環境條件變差
? ? 禁止無錯誤的通訊 每一個增加的節點都可以減少約 3 的網絡阻抗 30k || 1k
? ? 網絡中總的 電 線 通訊導線 長度應少于或等于 40m
? ? 主機節點的總線端電阻典型值是 1k 從機節點是 30k
? 總線值
? ? 總線有兩個互補的邏輯值 顯性 或 隱性 相應的位值和電壓值
? ? ? 表 2.2 邏輯和物理總線值
? ? 邏輯值 ? ?位值 ?總線電壓
? ? 顯性 ? ? ?0 ? ? 地
? ? 隱性 ? ? ?1 ? ? 電池
? 應答
? ? ? 正確接收報文后的應答過程在 LIN 協議中沒有定義 主機控制單元檢查由主機任務初始化的報文
? ? 和由它自己的從機任務接收的報文的一致性 如果不一致 例如 丟失從機響應 校驗和不正確等等 主
? ? 機任務可以改變報文的進度表
? ? 如果從機檢測到不一致 從機控制器將保存這個信息并將它用診斷信息的形式向主機控制單元請求
? ? 診斷信息可按普通報文幀的形式進行發送
? ? 每個報文幀都由一個同步間隔 SYNCH BREAK 起始 接著是同步場 SYNCH FIRLD 這個同
? 步場在幾倍的位定時長度中包含了 5 個下降沿 即 隱性 到 顯性 的轉換
? 一個報文幀 是由一個主機節點發送的報文頭和一個主機或從機節點發送的響應組成
? 報文幀的報文頭包括一個同步間隔場 SYNCH BREAK FIELD,一個同步場 SYNCH FIELD,和一個標識符場
? ? 報文幀的響應 RESPONSE 則由 3 個到 9 個字節場組成 2 或 4 或 8 字節的數據場 DATA FIELD
? 和一個校驗和場 CHECKSUM FIELD
? ? 字節場的格式 通常的 SCI 或 UART 串行數據格式 8N1 編碼 每個字節場
? 的長度是 10 個位定時 BIT TIME 起始位 START BIT 是一個 顯性 位 它標志著字節場的開始
? 接著是 8 個數據位 首先發送最低位 停止位 STOP BIT 是一個 隱性 位 它標志著字節場的結束
? 報文頭場 HEADER fields
? 同步間隔 SYNCHRONISATION BREAK
? ? 為了能清楚識別報文幀的開始 報文幀的第一個場是一個同步間隔 SYNCH BREAK 同步間隔場
? SYNCH BREAK FIELD 是由主機任務發送.它使所有的從機任務與總線時鐘信號同步
? ? 同步間隔場有兩個不同的部分,第一個部分是由一個持續 T SYNBRK 或更長時間 即最小是
? T SYNBRK 不需要很嚴格 的顯性總線電平 接著的第二部分是最少持續 T SYNDEL 時間的隱性電平
? 作為同步界定符 第二個場允許用來檢測下一個同步場 SYNCH FIELD 的起始位最大的間隔和界定
? 符時間沒有精確的定義 但必須符合整個報文頭 T HEADER_MAX 的總體時間預算
? 同步場 SYNCH FIELD
? 同步場 SYNCH FIELD 包含了時鐘的同步信息 同步場 SYNCH FIELD 的格式是 0x55 表
? 現在 8 個位定時中有 5 個下降沿 即 隱性 跳變到 顯性 的邊沿 見圖 3.4
? 標識符場 IDENTIFIER FIELD
? 標識符場 ID-FIELD 定義了報文的內容和長度 其中 內容是由 6 個標識符 IDENTIFIER 位和
? 兩個 ID 奇偶校驗位 ID PARITY bit 表示 見圖 3.5 標識符位的第 4 和第 5 位 ID4 和 ID5 定義了
? 報文的數據場數量 N DATA 見表 3.2 這將把 64 個標識符分成 4 個小組 每組 16 個標識符 這些標識
? 符分別有 2 4 和 8 個數據場
? 響應場 RESPONSE field
? 數據場 DATA FIELD 和 ?校驗和場 CHECKSUM FIELD
? 數據場通過報文幀傳輸 由多個 8 位數據的字節場組成 傳輸由 LSB 開始
? 校驗和場 CHECKSUM FIELD
? 校驗和場是數據場所有字節的和的反碼和按 帶進位加 ADDC 方式計算 每個進位
? 都被加到本次結果的最低位 LSB 這就保證了數據字節的可靠性,所有數據字節的和的補碼與校驗和字節之加的和必須是 0xFF
*/
#include "lin.h"
#include "lin_queue.h"
#include "lin_handle.h"
#include "target.h"#define LIN_CHANNEL UART4
#define RCC_LIN_APB RCC_APB1PeriphClockCmd
#define RCC_LIN_CLK RCC_APB1Periph_UART4
#define LIN_BOAURATE 19200
#define LIN_IRQ UART4_IRQn
#define LIN_INT_FUNC UART4_IRQHandler#define LIN_PORT GPIOC
#define LIN_TX_PIN GPIO_Pin_10
#define LIN_RX_PIN GPIO_Pin_11
#define LIN_TX_CONFIG() GPIOConfig(LIN_PORT, LIN_TX_PIN, GPIO_Mode_AF_PP)
#define LIN_RX_CONFIG() GPIOConfig(LIN_PORT, LIN_RX_PIN, GPIO_Mode_IN_FLOATING)#define LIN_CS_PORT GPIOC
#define LIN_CS_PIN GPIO_Pin_12
#define LIN_CS_CONFIG() GPIOConfig(LIN_CS_PORT, LIN_CS_PIN, GPIO_Mode_Out_PP)
#define LIN_CS_ENABLE() GPIO_SetBits(LIN_CS_PORT, LIN_CS_PIN)static void lin_gpio_init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);LIN_TX_CONFIG();LIN_RX_CONFIG();LIN_CS_CONFIG();LIN_CS_ENABLE();
}static void lin_nvic_init(void)
{NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = LIN_IRQ;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);
}static void lin_uart_init(void)
{USART_InitTypeDef USART_InitStructure;RCC_LIN_APB(RCC_LIN_CLK, ENABLE);USART_InitStructure.USART_BaudRate = LIN_BOAURATE;USART_InitStructure.USART_WordLength = USART_WordLength_8b;USART_InitStructure.USART_StopBits = USART_StopBits_1;USART_InitStructure.USART_Parity = USART_Parity_No ;USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;USART_Init(LIN_CHANNEL, &USART_InitStructure);USART_LINBreakDetectLengthConfig(LIN_CHANNEL, USART_LINBreakDetectLength_11b);USART_LINCmd(LIN_CHANNEL, ENABLE);USART_Cmd(LIN_CHANNEL, ENABLE);USART_ITConfig(LIN_CHANNEL, USART_IT_RXNE, ENABLE);USART_ITConfig(LIN_CHANNEL, USART_IT_TXE, DISABLE);USART_ITConfig(LIN_CHANNEL, USART_IT_LBD, ENABLE);
}void LINInit(void)
{lin_gpio_init();lin_nvic_init();lin_uart_init();
}void LINSendChar(uint8_t ch)
{USART_SendData(LIN_CHANNEL, ch);while(!USART_GetFlagStatus(LIN_CHANNEL, USART_FLAG_TXE));
}void LINSendBreak(void)
{USART_SendBreak(LIN_CHANNEL);
}#define BIT(A,B) ((A >> B) & 0x01)uint8_t LINCalID(uint8_t id)
{uint8_t 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;
}uint8_t LINCalChecksum(uint8_t id, uint8_t *data)
{uint32_t sum = id;uint8_t i;for(i = 0; i < 8; i++){sum += data[i];if(sum & 0xFF00){sum = (sum & 0x00FF) + 1;}}sum ^= 0x00FF;return (uint8_t)sum;
}//========================================================================================================
void LIN_INT_FUNC(void)
{uint8_t ret;if(USART_GetITStatus(LIN_CHANNEL, USART_IT_RXNE)){USART_ClearITPendingBit(LIN_CHANNEL, USART_IT_RXNE);ret = USART_ReceiveData(LIN_CHANNEL);//LINQueuePush(&lin_recv, ret);}if(USART_GetITStatus(LIN_CHANNEL, USART_IT_LBD)){USART_ClearITPendingBit(LIN_CHANNEL, USART_IT_LBD); // 檢測到同步間隔場//LinStatusSet(SYNCH);}if(USART_GetFlagStatus(LIN_CHANNEL, USART_FLAG_ORE) == SET) // 溢出{USART_ClearFlag(LIN_CHANNEL, USART_FLAG_ORE);USART_ReceiveData(LIN_CHANNEL);}
}
總結
以上是生活随笔為你收集整理的STM32 —— LIN的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。