首頁 > 評(píng)測 > 【LKS32AT085評(píng)測】2.電動(dòng)自行車一線通應(yīng)用之SIF
【LKS32AT085評(píng)測】2.電動(dòng)自行車一線通應(yīng)用之SIF
- [導(dǎo)讀]
- 本帖最后由 yang377156216 于 2022-9-19 15:47 編輯 #申請(qǐng)?jiān)瓌?chuàng)# @21小跑堂 前言前面說到可以通過某個(gè)專業(yè)領(lǐng)域應(yīng)用去打開市場,這里想推薦一個(gè)領(lǐng)域:兩輪電動(dòng)自行車。這個(gè)東西相信大家都非常熟悉,幾乎每天都
本帖最后由 yang377156216 于 2022-9-19 15:47 編輯
#申請(qǐng)?jiān)瓌?chuàng)# @21小跑堂
前言
前面說到可以通過某個(gè)專業(yè)領(lǐng)域應(yīng)用去打開市場,這里想推薦一個(gè)領(lǐng)域:兩輪電動(dòng)自行車。這個(gè)東西相信大家都非常熟悉,幾乎每天都要與它打交道,屬于家家必備的一大件了。就我所知,目前一輛兩輪車上面要用到主控芯片的有這幾大電子設(shè)備:電機(jī)電控器、鋰電池 BMS、蓄電池充電器、液晶儀表盤、智能輪轂鎖、防盜報(bào)警器以及高端點(diǎn)的還帶中央物聯(lián)網(wǎng)數(shù)采模塊。此外還有周邊衍生出來的一些產(chǎn)品:智能交流/直流充電樁、換電柜以及專業(yè)的新能源檢測設(shè)備等等。可以看到這個(gè)領(lǐng)域?qū)?MCU 的需求量是巨大的,盡管與汽車電子的要求差距很大,但我相信發(fā)展到最后,這個(gè)領(lǐng)域的所有電子產(chǎn)品也需要起碼達(dá)到工業(yè)級(jí)的標(biāo)準(zhǔn)了,而不會(huì)再像現(xiàn)在這么 Low。之前與行業(yè)內(nèi)的客戶工程師聊天,據(jù)說雅迪無錫研發(fā)就一直有在招聘比亞迪的汽車應(yīng)用開發(fā)工程師去搞兩輪車的應(yīng)用,卷到極致了吧?!那正好說明這條賽道的生意機(jī)會(huì)多多呀。
兩輪電動(dòng)車行業(yè)情況
根據(jù)中國自行車協(xié)會(huì)數(shù)據(jù)顯示,2021年我國電動(dòng)兩輪車保有量已經(jīng)達(dá)到3.4億輛,電動(dòng)車?yán)塾?jì)銷量達(dá)成4100萬輛。按照當(dāng)前電動(dòng)兩輪車的 3~5 年自然更替的周期來看,這是一個(gè)市場規(guī)模千億級(jí)、且穩(wěn)定發(fā)展的產(chǎn)業(yè)。
有專家預(yù)計(jì),2022年中國兩輪電動(dòng)車保有量將達(dá)到3.5億輛。且市場需求仍將保持增長態(tài)勢,未來三年,電動(dòng)兩輪車替換量有望達(dá)到8000萬輛,整體需求量約1.8億輛,年均銷售量超過6000萬輛。
2021年兩輪電動(dòng)車市場集中度進(jìn)一步提高,品牌生存競爭加劇,以雅迪為代表的傳統(tǒng)品牌企業(yè)通過高端化、智能化產(chǎn)品路線提升品牌價(jià)值,以九號(hào)、小牛為代表的新勢力品牌大舉鋪設(shè)渠道擴(kuò)張份額。2021年兩輪電動(dòng)車產(chǎn)品智能化水平明顯提升,未來必將還出現(xiàn)新勢力品牌的鯰魚效應(yīng)。
進(jìn)入2022年,隨著大量城市電動(dòng)車新國標(biāo)過渡期結(jié)束,兩輪電動(dòng)車換購又將迎來一輪小高峰;此外,在節(jié)能減排、碳達(dá)峰、綠色出行等政策指引及產(chǎn)業(yè)鏈上下游發(fā)展助推下,兩輪電動(dòng)車市場依舊擁有較大的增長潛力。在高質(zhì)量發(fā)展的時(shí)代背景驅(qū)動(dòng)及消費(fèi)升級(jí)需求推動(dòng)下,兩輪電動(dòng)車產(chǎn)品向高品質(zhì)、智能化、個(gè)性化發(fā)展。電池續(xù)航、性能進(jìn)一步提升,車型設(shè)計(jì)更加符合細(xì)分用戶騎行場景需要;智能化技術(shù)應(yīng)用水平提升,使用體驗(yàn)升級(jí)。在智能化發(fā)展趨勢下,兩輪電動(dòng)車的市場競爭將逐漸導(dǎo)向產(chǎn)品智能化競爭以及基于智能兩輪電動(dòng)車的服務(wù)生態(tài)的競爭。
不僅國內(nèi)保有量以及銷量數(shù)據(jù)在逐年遞增,在國際市場出口數(shù)量和金額更是呈大幅上升趨勢,以下兩圖分別展示了這兩組數(shù)據(jù):
關(guān)于更多的行業(yè)分析,可以參見我附件內(nèi)容中的兩份調(diào)研報(bào)告:
艾瑞咨詢聯(lián)合魯大師發(fā)布的一則研究報(bào)告--《2022年中國兩輪電動(dòng)車行業(yè)白皮書》
電子發(fā)燒友記者發(fā)布的一則新聞--《兩輪電動(dòng)車市場需求廣闊》
電動(dòng)自行車通信協(xié)議團(tuán)體標(biāo)準(zhǔn)
電動(dòng)自行車安全問題關(guān)系人民群眾生命財(cái)產(chǎn)安全、關(guān)系社會(huì)和諧穩(wěn)定,強(qiáng)化電動(dòng)自行車先期治理既是保障群眾生命財(cái)產(chǎn)安全的重要舉措,也是目前推動(dòng)產(chǎn)業(yè)高質(zhì)量發(fā)展、搶占市場份額的重要抓手。為了更規(guī)范化的管理電動(dòng)自行車生產(chǎn)、銷售與安全使用,需要有一些規(guī)范和標(biāo)準(zhǔn)在符合民生國情的基礎(chǔ)上頒布出來。
眾所周知,無錫是全國最大的電動(dòng)車生產(chǎn)基地之一,集中了新日、雅迪、愛瑪、臺(tái)鈴、小刀等頭部品牌,帶動(dòng)了江蘇及本地近300多家整車、配件企業(yè)為全國貢獻(xiàn)了三分之一多的產(chǎn)銷量,無錫電動(dòng)車產(chǎn)業(yè)的發(fā)展態(tài)勢,是全國電動(dòng)車行業(yè)發(fā)展的風(fēng)向標(biāo)。同時(shí),無錫市已有電動(dòng)車銷售門店800多家,備案銷售品牌724家,電動(dòng)車社會(huì)保有量已超350多萬輛,雅迪、新日、愛瑪、臺(tái)鈴、小刀、新蕾、歐派、新大洲、金箭、小鳥、格林豪泰、捷安特、小牛、九號(hào)、綠源、綠佳、立馬等知名品牌在無錫均有銷售。由此可見,無錫市電動(dòng)車的生產(chǎn)、銷售、上牌、上路行駛、市場監(jiān)管等工作尤為重要。
4月25日,江蘇省自行車電動(dòng)車協(xié)會(huì)根據(jù)《江蘇省自行車電動(dòng)車協(xié)會(huì)團(tuán)體標(biāo)準(zhǔn)管理辦法》有關(guān)規(guī)定,正式批準(zhǔn)發(fā)布《電動(dòng)自行車通信協(xié)議》團(tuán)體標(biāo)準(zhǔn),標(biāo)準(zhǔn)編號(hào)為:T/JSEBA 0022022,該標(biāo)準(zhǔn)將于今年10月25日起正式實(shí)施。此次《電動(dòng)自行車通信協(xié)議》團(tuán)體標(biāo)準(zhǔn)制修訂工作,由無錫市市場監(jiān)管局、市工信局指導(dǎo),江蘇省自行車電動(dòng)車協(xié)會(huì)牽頭,聯(lián)合主要生產(chǎn)廠家、認(rèn)證機(jī)構(gòu)、質(zhì)檢部門、科研院所等單位組成起草小組,歷時(shí)4個(gè)多月,進(jìn)行了多輪認(rèn)真討論與修訂,并采納了社會(huì)與行業(yè)專家意見后完成。這份標(biāo)準(zhǔn)是極具歷史意義和代表性質(zhì)的。
最終形成的通訊協(xié)議團(tuán)體標(biāo)準(zhǔn)中主要涉及到了常用的通訊協(xié)議,分別為一線通、RS485 和 CAN , 完整版的文檔我也搜索到了,一并放在附件里給大家參閱。
一線通 SIF 協(xié)議
下面要講今天的主角了一線通 SIF 協(xié)議。在早些年間很多 MCU 都沒有標(biāo)準(zhǔn)的串行 UART 通訊口,更加別說帶 IIC、SPI 等接口了,外圍硬件通訊接口資源嚴(yán)重匱乏,在需要和其它設(shè)備或者器件進(jìn)行簡單的通訊時(shí)(速度要求不高,硬件上只能提供一根通訊線),可以使用 SIF 協(xié)議來完成數(shù)據(jù)交互。什么是一線通 SIF 呢?以下框圖示意了一個(gè)連接應(yīng)用場景:
SIF 協(xié)議滿足以下一些特點(diǎn):
-
一線通 SIF 協(xié)議比較簡單,實(shí)現(xiàn)起來成本較低,適用于一些數(shù)據(jù)量不大且通訊品質(zhì)要求不那么高的場景;
-
屬于單線主從單工通訊模式,類似 1-Wire 協(xié)議但又與之有很大不同,為單工通訊的,即設(shè)備要么僅作為發(fā)送端,要么僅作為接收方,比如上面框圖中 BMS 為發(fā)送發(fā)(主機(jī)),控制器和充電器僅為接收方(從機(jī));
-
波特率要么像 UART 一樣提前固定好,要么讓接收端自動(dòng)適應(yīng)發(fā)送方的同步信號(hào)從而來解析出匹配到的波特率;
-
一次傳輸一幀數(shù)據(jù),每幀數(shù)據(jù)由 同步信號(hào)(發(fā)送主報(bào)文的前導(dǎo)信號(hào)) + 數(shù)據(jù)信號(hào)(8bit * 12個(gè)數(shù)據(jù)位的有效數(shù)據(jù)內(nèi)容,按一定占空比進(jìn)行發(fā)送)+ 結(jié)束信號(hào)(一幀完整的數(shù)據(jù)發(fā)送結(jié)束的標(biāo)志信號(hào)) 3個(gè)部分組成,傳輸結(jié)束后要求線路空閑狀態(tài)為低電平,每次傳輸需一次性完整傳輸所有數(shù)據(jù);
-
數(shù)據(jù)的電平遵守 TTL 規(guī)范。
一般一線通接口原理設(shè)計(jì)如下,IN 為主機(jī)單片機(jī)的輸出口,OUT 為總線接口:
可以看到主機(jī)的輸出口是為下拉的,一般 IO 內(nèi)部自帶下拉也可以外部增加下拉電阻,而接收方的從機(jī)默認(rèn)是需要被上拉的,上拉電阻值一般要求為 5V上拉 2.2K,3.3V 上拉 1K。
SIF 邏輯電平信號(hào)定義如下:
關(guān)于信號(hào)定義還有如下一些注意點(diǎn):
-
32Tosc 范圍為 0.5ms,考慮到響應(yīng)速度,不要超過1ms
-
同步信號(hào):>992Tosc 的低電平 + 32Tosc 的高電平,空閑位時(shí)間>15ms(0.5ms*992/32=15ms)
-
數(shù)據(jù)位邏輯 1 符合 高電平時(shí)間 > 低電平時(shí)間 + 0.5ms;
-
數(shù)據(jù)位邏輯 0 符合 低電平時(shí)間 > 高電平時(shí)間 + 0.5ms;
-
高低電平的比例一般使用 0.5ms 和 1ms 的比例,及占空比為 1:2 (適宜取 75%)
凌鷗 SIF 接口驅(qū)動(dòng)代碼
如果不用硬件 SIF 接口而用定時(shí)器中斷+IO 模擬,那需要將定時(shí)器更新時(shí)長設(shè)置為一個(gè) Tosc,在中斷處理函數(shù)中判斷是否有數(shù)據(jù)需要發(fā)送,調(diào)用如下發(fā)送數(shù)據(jù)的處理函數(shù):
- #define SIF_VERSION 1
- #define SIF_SYNC 53
- #define SIF_SEND_COUNT 3
- volatile static uint8_t sif_sync_tosc = 0;
- volatile static uint8_t sif_send_tosc = 0;
- volatile static uint8_t state_mode = 0;
- volatile static int8_t bit_cnt = 7;
- volatile static uint8_t byte_cnt = 0;
- static uint8_t result[64] = {0};//需要發(fā)送的數(shù)據(jù)
- volatile static uint8_t length = 0;//數(shù)據(jù)的長度
- static void sif_send_data_handle(uint8_t state)
- {
- switch(state)
- {
- case SYNC_SIGNAL://同步模式
- if (sif_sync_tosc < SIF_SYNC - 2) {
- sif_turn_off();
- } else {
- sif_turn_on();
- }
- sif_sync_tosc++;
- if (sif_sync_tosc >= SIF_SYNC)
- {
- state_mode = SEND_DATA;
- sif_sync_tosc = 0;
- bit_cnt = 7;
- byte_cnt = 0;
- sif_send_tosc = 0;
- }
- break;
- case SEND_DATA: //發(fā)送數(shù)據(jù)
- static uint8_t res;
- uint8_t count = SIF_SEND_COUNT;
- static uint8_t nums = sizeof(uint8_t) * 8;
- uint8_t *p = (uint8_t *)result;
- sif_send_tosc = sif_send_tosc % count;
- uint8_t data = (p[byte_cnt] >> bit_cnt) & 0x1;
- if (data)
- {
- if (sif_send_tosc == 0)
- {
- sif_turn_off();
- sif_send_tosc ++;
- }
- else if (sif_send_tosc == 1)
- {
- sif_turn_on();
- sif_send_tosc ++;
- } else {
- sif_send_tosc = 0;
- }
- }
- else
- {
- if (sif_send_tosc == 0)
- {
- sif_turn_off();
- sif_send_tosc++;
- }
- else if (sif_send_tosc == 2)
- {
- sif_turn_on();
- sif_send_tosc = 0;
- } else
- {
- sif_send_tosc++;
- }
- }
- if (sif_send_tosc == 0)
- {
- if (--bit_cnt < 0)
- {
- byte_cnt++;
- bit_cnt = 7;
- }
- if (byte_cnt >= length)
- {
- state_mode = SEND_DATA_COMPLETE;
- break;
- }
- }
- break;
- case SEND_DATA_COMPLETE://數(shù)據(jù)發(fā)送完成,將標(biāo)志位清0
- state_mode = 0;
- sif_turn_off();
- length = 0;
- memset(result, 0, sizeof(result));
- break;
- default:
- break;
- }
- }
可以發(fā)現(xiàn)模擬的方式發(fā)送 SIF 數(shù)據(jù)幀還是非常復(fù)雜的,下面來看看使用凌鷗的 SIF 接口如何實(shí)現(xiàn)發(fā)送數(shù)據(jù)。由于官方SDK 開發(fā)包以及其它參考資料中都沒有提及該接口如何使用,底層驅(qū)動(dòng)函數(shù)庫中也還沒有將其做好來直接給用戶使用,所以得根據(jù) UM 手冊(cè)和參照 UART 的抽象層驅(qū)動(dòng)寫法自己去實(shí)現(xiàn)。
下面為 SIF 外設(shè)驅(qū)動(dòng)程序 lks32at08x_sif.c 和 lks32at08x_sif.h :
- /*******************************************************************************
- * 版權(quán)所有 (C)2015, LINKO SEMICONDUCTOR Co.ltd
- *
- * 文件名稱: lks32at08x_sif.c
- * 文件標(biāo)識(shí):
- * 內(nèi)容摘要: SIF 外設(shè)驅(qū)動(dòng)程序
- * 其它說明: 無
- * 當(dāng)前版本: V 1.0
- * 作 者: yang377156216
- * 完成日期:
- *
- * 修改記錄1:
- * 修改日期:
- * 版 本 號(hào):V 1.0
- * 修 改 人:
- * 修改內(nèi)容:創(chuàng)建
- *
- ******************************************************************************/
- #include "lks32at08x_sif.h"
- /*******************************************************************************
- 函數(shù)名稱: void SIF_Init(SIF_TypeDef *SIFx, SIF_InitTypeDef *SIF_InitStruct)
- 功能描述: SIF 初始化
- 操作的表: 無
- 輸入?yún)?shù): SIF_TypeDef *SIFx, SIF_InitTypeDef *SIF_InitStruct
- 輸出參數(shù): 無
- 返 回 值: 無
- 其它說明:
- 修改日期 版本號(hào) 修改人 修改內(nèi)容
- -------------------------------------------------------------------------------
- 2022/08/19 V1.0 yang377156216 創(chuàng)建
- ******************************************************************************/
- void SIF_Init(SIF_TypeDef *SIFx, SIF_InitTypeDef *SIF_InitStruct)
- {
- if (SIFx == SIF0)
- {
- //開啟 SIF 的時(shí)鐘,這里默認(rèn)就是開啟的;
- }
- SIFx ->CFG &= ~(0x01 << 1);
- SIFx ->CFG |= (SIF_InitStruct->Endian << 1);
- SIFx ->FREQ &= ~(0x0F << 4);
- SIFx ->FREQ |= (SIF_InitStruct->Tosc << 4);
- SIFx ->FREQ &= ~(0x01 << 0);
- SIFx ->FREQ |= (SIF_InitStruct->Duty << 0);
- SIFx ->IRQ &= ~(0x01 << 0);
- SIFx ->IRQ |= (SIF_InitStruct->TxIE << 0);
- }
- /*******************************************************************************
- 函數(shù)名稱: void SIF_DeInit(SIF_TypeDef *SIFx)
- 功能描述: SIF 反初始化
- 操作的表: 無
- 輸入?yún)?shù): SIF_TypeDef *SIFx
- 輸出參數(shù): 無
- 返 回 值: 無
- 其它說明:
- 修改日期 版本號(hào) 修改人 修改內(nèi)容
- -------------------------------------------------------------------------------
- 2022/08/19 V1.0 yang377156216 創(chuàng)建
- ******************************************************************************/
- void SIF_DeInit(SIF_TypeDef *SIFx)
- {
- SIFx ->CFG = 1;
- SIFx ->FREQ = 0;
- SIFx ->IRQ = 0;
- SIFx ->WDATA = 0;
- SIFx ->CFG = 0;
- }
- /*******************************************************************************
- 函數(shù)名稱: void SIF_StructInit(SIF_InitTypeDef *SIF_InitStruct)
- 功能描述: SIF 結(jié)構(gòu)體初始化
- 操作的表: 無
- 輸入?yún)?shù): SIF_InitTypeDef *SIF_InitStruct
- 輸出參數(shù): 無
- 返 回 值: 無
- 其它說明:
- 修改日期 版本號(hào) 修改人 修改內(nèi)容
- -------------------------------------------------------------------------------
- 2022/08/19 V1.0 yang377156216 創(chuàng)建
- ******************************************************************************/
- void SIF_StructInit(SIF_InitTypeDef *SIF_InitStruct)
- {
- SIF_InitStruct->Duty = SIF_DUTY_2_1;
- SIF_InitStruct->Endian = SIF_ENDIAN_LSB;
- SIF_InitStruct->Tosc = SIF_Tosc_32US_Default;
- SIF_InitStruct->TxIE = SIF_TX_IE_DIS;
- }
- /*******************************************************************************
- 函數(shù)名稱: void SIF_MouduleEnable(SIF_TypeDef *SIFx, uint8_t enable)
- 功能描述: SIF 模塊使能/關(guān)閉
- 操作的表: 無
- 輸入?yún)?shù): SIF_TypeDef *SIFx, uint8_t enable
- 輸出參數(shù): 無
- 返 回 值: 無
- 其它說明:
- 修改日期 版本號(hào) 修改人 修改內(nèi)容
- -------------------------------------------------------------------------------
- 2022/08/19 V1.0 yang377156216 創(chuàng)建
- ******************************************************************************/
- void SIF_MouduleEnable(SIF_TypeDef *SIFx, uint8_t enable)
- {
- if(enable == ENABLE)
- {
- SIFx ->CFG |= SIF_MODULE_EN;
- }
- else
- {
- SIFx ->CFG &= ~SIF_MODULE_EN;
- }
- }
- /*******************************************************************************
- 函數(shù)名稱: void SIF_LastByte_Set(SIF_TypeDef *SIFx, uint8_t enable)
- 功能描述: SIF 結(jié)束本次傳輸
- 操作的表: 無
- 輸入?yún)?shù): SIF_TypeDef *SIFx, uint8_t enable
- 輸出參數(shù): 無
- 返 回 值: 無
- 其它說明:
- 修改日期 版本號(hào) 修改人 修改內(nèi)容
- -------------------------------------------------------------------------------
- 2022/08/19 V1.0 yang377156216 創(chuàng)建
- ******************************************************************************/
- void SIF_LastByte_Set(SIF_TypeDef *SIFx, uint8_t enable)
- {
- if(enable == ENABLE)
- {
- SIFx ->CFG |= SIF_LAST_BYTE_EN;
- }
- }
- /*******************************************************************************
- 函數(shù)名稱: void SIF_SendData(SIF_TypeDef *SIFx, uint8_t data)
- 功能描述: SIF 發(fā)送數(shù)據(jù)
- 操作的表: 無
- 輸入?yún)?shù): SIF_TypeDef *SIFx, uint8_t data
- 輸出參數(shù): 無
- 返 回 值: 無
- 其它說明:
- 修改日期 版本號(hào) 修改人 修改內(nèi)容
- -------------------------------------------------------------------------------
- 2022/08/19 V1.0 yang377156216 創(chuàng)建
- ******************************************************************************/
- void SIF_SendData(SIF_TypeDef *SIFx, uint8_t data)
- {
- SIFx->WDATA = data;
- }
- /*******************************************************************************
- 函數(shù)名稱: uint32_t SIF_GetIRQFlag(SIF_TypeDef *SIFx, uint32_t tempFlag)
- 功能描述: 取得 SIF 中斷標(biāo)志
- 操作的表: 無
- 輸入?yún)?shù): SIF_TypeDef *SIFx, uint32_t tempFlag
- 輸出參數(shù): 無
- 返 回 值: SIF 中斷標(biāo)志
- 其它說明:
- 修改日期 版本號(hào) 修改人 修改內(nèi)容
- -------------------------------------------------------------------------------
- 2022/08/19 V1.0 yang377156216 創(chuàng)建
- ******************************************************************************/
- uint32_t SIF_GetIRQFlag(SIF_TypeDef *SIFx, uint32_t tempFlag)
- {
- if (((SIFx->IRQ & tempFlag) != Bit_RESET) && \
- (SIFx->IRQ & SIF_TX_IE_EN) != Bit_RESET)
- {
- return 1;
- }
- return 0;
- }
- /*******************************************************************************
- 函數(shù)名稱: void SIF_ClearIRQFlag(SIF_TypeDef *SIFx, uint32_t tempFlag)
- 功能描述: 清除 SIF 中斷標(biāo)志位
- 操作的表: 無
- 輸入?yún)?shù): SIF_TypeDef *SIFx, uint32_t tempFlag
- 輸出參數(shù): 無
- 返 回 值: 無
- 其它說明:
- 修改日期 版本號(hào) 修改人 修改內(nèi)容
- -------------------------------------------------------------------------------
- 2022/08/19 V1.0 yang377156216 創(chuàng)建
- ******************************************************************************/
- void SIF_ClearIRQFlag(SIF_TypeDef *SIFx, uint32_t tempFlag)
- {
- SIFx->IRQ |= tempFlag;
- }
- /*********************** (C) COPYRIGHT LINKO SEMICONDUCTOR *****END OF FILE****/
- /*******************************************************************************
- * 版權(quán)所有 (C)2015, LINKO SEMICONDUCTOR Co.ltd
- *
- * 文件名稱: lks32at08x_sif.h
- * 文件標(biāo)識(shí):
- * 內(nèi)容摘要: SIF 驅(qū)動(dòng)頭文件
- * 其它說明: 無
- * 當(dāng)前版本: V 1.0
- * 作 者: yang377156216
- * 完成日期:
- *
- * 修改記錄1:
- * 修改日期:
- * 版 本 號(hào):V 1.0
- * 修 改 人:
- * 修改內(nèi)容:創(chuàng)建
- *
- ******************************************************************************/
- #ifndef __LKS32AT08x_SIF_H
- #define __LKS32AT08x_SIF_H
- /* Includes ------------------------------------------------------------------*/
- #include "lks32mc08x_lib.h"
- typedef struct
- {
- __IO uint32_t CFG;
- __IO uint32_t FREQ;
- __IO uint32_t IRQ;
- __IO uint32_t WDATA;
- } SIF_TypeDef;
- typedef enum
- {
- SIF_Tosc_32US_Default = 0x00,
- SIF_Tosc_32US = 0x01,
- SIF_Tosc_64US = 0x02,
- SIF_Tosc_96US = 0x03,
- SIF_Tosc_128US = 0x04,
- SIF_Tosc_160US = 0x05,
- SIF_Tosc_192US = 0x06,
- SIF_Tosc_220US = 0x07,
- SIF_Tosc_256US = 0x08,
- SIF_Tosc_288US = 0x09,
- SIF_Tosc_320US = 0x0A,
- } SIF_ToscSet;
- typedef struct
- {
- uint8_t Endian; /*SIF 大小端,1 = MSB , 0 = LSB 默認(rèn)*/
- uint8_t Tosc; /*96Mhz 系統(tǒng)時(shí)鐘下,基準(zhǔn)時(shí)間單位 Tosc 設(shè)置*/
- uint8_t Duty; /*SIF 傳輸 Data 占空比*/
- uint8_t TxIE; /*發(fā)送中斷使能*/
- } SIF_InitTypeDef;
- #ifndef SIF0
- #define SIF0 ((SIF_TypeDef *) SIF_BASE)
- #endif
- #ifndef SIF_MCU_MCLK
- #define SIF_MCU_MCLK (96000000LL) /* 系統(tǒng)時(shí)鐘 */
- #endif
- #define SIF_LAST_BYTE_EN (1 << 4) /*是否結(jié)束本次傳輸*/
- #define SIF_ENDIAN_LSB 0 /*低端先發(fā)送*/
- #define SIF_ENDIAN_MSB 1 /*高端先發(fā)送*/
- #define SIF_MODULE_EN (1 << 0) /*SIF 模塊使能*/
- #define SIF_DUTY_2_1 0 /*占空比為 2:1*/
- #define SIF_DUTY_3_1 1 /*占空比為 3:1*/
- #define SIF_TX_IE_DIS 0 /*SIF 中斷禁止*/
- #define SIF_TX_IE_EN 1 /*SIF 中斷使能*/
- /*中斷標(biāo)志定義*/
- #define SIF_TX_IFLAG (1 << 4) /*發(fā)送完成中斷*/
- void SIF_MouduleEnable(SIF_TypeDef *SIFx, uint8_t enable);
- void SIF_LastByte_Set(SIF_TypeDef *SIFx, uint8_t enable);
- void SIF_DeInit(SIF_TypeDef *SIFx);
- void SIF_Init(SIF_TypeDef *SIFx, SIF_InitTypeDef *SIF_InitStruct);
- void SIF_StructInit(SIF_InitTypeDef *SIF_InitStruct);
- void SIF_SendData(SIF_TypeDef *SIFx, uint8_t data);
- uint32_t SIF_GetIRQFlag(SIF_TypeDef *SIFx, uint32_t tempFlag);
- void SIF_ClearIRQFlag(SIF_TypeDef *SIFx, uint32_t tempFlag);
- #endif /*__lks32mc08x_SIF_H */
- /************************ (C) COPYRIGHT LINKO SEMICONDUCTOR *****END OF FILE****/
驅(qū)動(dòng)代碼寫好后編寫了測試的發(fā)送代碼,只需要調(diào)用 SIF_SendData 這個(gè)接口即可實(shí)現(xiàn)發(fā)送 SIF 幀數(shù)據(jù),另外還更改了不同的占空比和 Tosc 時(shí)間進(jìn)行測試,驗(yàn)證了底層驅(qū)動(dòng)的正確性,將驅(qū)動(dòng)添加進(jìn)了 lib 包中:
整個(gè)測試工程的 keil 目錄如下:
下面是抓取的邏輯圖:
該接口只能做到硬件的 SIF 發(fā)送,而要做接收的話還得用傳統(tǒng)的 定時(shí)器 + 一個(gè)GPIO口模擬方式進(jìn)行采樣解析,接收解析代碼參考之前其它平臺(tái)使用過的成功示例:
- /*******************************************************************************
- *@時(shí) 間 : 2022-2-22
- *@摘 要 : 主程序文件
- *@芯 片 :
- *
- *******************************************************************************/
- /*================================= Demo說明 ===================================
- 定時(shí)器 + 一個(gè)GPIO口進(jìn)行通訊數(shù)據(jù)讀取
- ==============================================================================*/
- /* 包含的頭文件 ---------------------------------------------------------------*/
- //與實(shí)際單片機(jī)相關(guān)
- /* 宏定義 ---------------------------------------------------------------------*/
- #define DATA_REV_PIN gpio_input_bit_get(GPIOB,BIT(9)) //定義數(shù)據(jù)接收引腳(根據(jù)實(shí)際項(xiàng)目進(jìn)行更改)
- #define LOW 0 //低電平
- #define HIGH 1 //高電平
- #define SYNC_L_TIME_NUM 1100 //同步信號(hào)低電平時(shí)間:50ms = 50000us / 50us = 1000
- #define SYNC_H_TIME_NUM_MIN 8 //同步信號(hào)高電平最小時(shí)間:500-100us = 400us / 50us = 8
- #define SYNC_H_TIME_NUM_MAX 12 //同步信號(hào)高電平最大時(shí)間:500+100us = 600us / 50us = 12
- #define SHORT_TIME_NUM_MIN 9 //一個(gè)邏輯周期中短的時(shí)間最小值:500-50us = 450us / 50us = 9
- #define SHORT_TIME_NUM_MAX 11 //一個(gè)邏輯周期中短的時(shí)間最大值:500+50us = 550us / 50us = 11
- #define LONG_TIME_NUM_MIN 18 //一個(gè)邏輯周期中長的時(shí)間最小值:1ms-100us = 900us / 50us = 18
- #define LONG_TIME_NUM_MAX 22 //一個(gè)邏輯周期中長的時(shí)間最大值:1ms+100us = 1100us / 50us = 22
- #define LOGIC_CYCLE_NUM_MIN 26 //一個(gè)邏輯周期最小時(shí)間:1.5ms-200us = 1300us / 50us = 26
- #define LOGIC_CYCLE_NUM_MAX 34 //一個(gè)邏輯周期最大時(shí)間:1.5ms+200us = 1700us / 50us = 34
- #define HALF_LOGIC_CYCLE_MIN 13 //一個(gè)邏輯周期的1/2最小時(shí)間:750-100us = 650us / 50us = 13
- #define HALF_LOGIC_CYCLE_MAX 17 //一個(gè)邏輯周期的1/2最大時(shí)間:750+100us = 850us / 50us = 17
- #define END_SIGNAL_TIME_NUM 100 //結(jié)束信號(hào)電平時(shí)間:5ms低電平 + Nms高電平,實(shí)際檢測5ms低電平就行,一幀數(shù)據(jù)發(fā)送完成后檢測5ms低電平就代表完成了,不發(fā)數(shù)據(jù)的時(shí)候上拉電阻拉高了
- #define REV_BIT_NUM 8 //接收的bit位個(gè)數(shù),看是按字節(jié)接收還是按字接收,1字節(jié)=8bit,1字=2字節(jié)=16bit
- #define REV_DATA_NUM 12 //接收的數(shù)據(jù)個(gè)數(shù)
- /* 類型定義 -------------------------------------------------------------------*/
- typedef enum
- {
- INITIAL_STATE=0, //初始狀態(tài),等待接收同步信號(hào)
- SYNC_L_STATE=1, //接收同步低電平信號(hào)狀態(tài)
- SYNC_H_STATE=2, //接收同步高電平信號(hào)狀態(tài)
- DATA_REV_STATE=3, //讀取數(shù)據(jù)碼電平狀態(tài)
- END_SIGNAL_STATE=4, //接收結(jié)束電平信號(hào)狀態(tài)
- RESTART_REV_STATE=5 //接收過程出錯(cuò)重新接收狀態(tài)
- }REV_STATE_e; //接收數(shù)據(jù)狀態(tài)枚舉
- /* 變量定義 -------------------------------------------------------------------*/
- unsigned char receive_state=0; //接收數(shù)據(jù)狀態(tài)
- unsigned char receive_bit_num=0; //接收的bit位個(gè)數(shù)
- unsigned char receive_data_num=0; //接收的數(shù)據(jù)個(gè)數(shù)
- //接收數(shù)據(jù)緩存數(shù)組-用一個(gè)數(shù)組來緩存數(shù)據(jù),51個(gè)數(shù)據(jù)字節(jié)
- unsigned char receive_data_buf[REV_DATA_NUM]={0};
- unsigned char receive_data[REV_DATA_NUM] = {0};
- unsigned int H_L_Level_time_cnt=0; //高低電平時(shí)間計(jì)數(shù)
- uint8_t start_H_L_Level_timming_flag=0; //開始高低電平計(jì)時(shí)標(biāo)記
- uint8_t has_read_bit = 0; //1-已經(jīng)讀取一個(gè)bit位
- uint8_t check_OK = 0; //1-校驗(yàn)和正確,0-校驗(yàn)和失敗
- uint8_t read_success=0; //一幀數(shù)據(jù)是否讀取成功,0-不成功,1-成功
- uint8_t Pin_Old = 0;
- uint8_t Pin_New = 0;
- uint8_t Pin_Change_Flag = 0;
- uint8_t BitFinish_Flag = 0;
- /* 函數(shù)聲明 -------------------------------------------------------------------*/
- void GPIO_Init(void); //GPIO初始化函數(shù)
- void Timer1_Init(void); //定時(shí)器1初始化函數(shù)
- void Receive_Data_Handle(void); //接收數(shù)據(jù)處理
- void Check_Sum_Handle(void); //校驗(yàn)和處理
- /* 函數(shù)定義 -------------------------------------------------------------------*/
- /*******************************************************************************
- *函數(shù)名稱 : SIF_Handle
- *函數(shù)功能 : SIF 解析函數(shù),在主循環(huán)中調(diào)用
- *輸入?yún)?shù) : void
- *輸出返回 : void
- *******************************************************************************/
- void main(void)
- {
- GPIO_Init(); //GPIO初始化,設(shè)置數(shù)據(jù)接收引腳P10為浮空輸入,檢測高低電平
- Timer1_Init(); //定時(shí)器1初始化,定時(shí)周期為:5微秒
- while(1)
- {
- SIF_Handle();
- }
- }
- /*******************************************************************************
- *函數(shù)名稱 : SIF_Handle
- *函數(shù)功能 : SIF 解析函數(shù),在主循環(huán)中調(diào)用
- *輸入?yún)?shù) : void
- *輸出返回 : void
- *******************************************************************************/
- void SIF_Handle(void)
- {
- if (read_success == 1) //如果成功讀取一幀數(shù)據(jù)
- {
- //一幀數(shù)據(jù)接收成功后先根據(jù)協(xié)議要求進(jìn)行校驗(yàn)和,驗(yàn)證數(shù)據(jù)的正確性
- Check_Sum_Handle();
- //如果數(shù)據(jù)正確,根據(jù)接收的數(shù)據(jù)進(jìn)行分析獲取需要的內(nèi)容
- if (check_OK)
- {
- memcpy(receive_data, receive_data_buf, REV_DATA_NUM);
- }
- read_success = 0; //讀取一幀數(shù)據(jù)清0
- }
- }
- /*******************************************************************************
- *函數(shù)名稱 : Timer1_isr
- *函數(shù)功能 : 定時(shí)器1中斷處理函數(shù)
- *輸入?yún)?shù) : void
- *輸出返回 : void
- *******************************************************************************/
- void TIMER1_IRQHandler(void)
- {
- if(SET == timer_interrupt_flag_get(TIMER1, TIMER_INT_CH0))
- {
- /* clear channel 0 interrupt bit */
- timer_interrupt_flag_clear(TIMER1, TIMER_INT_CH0);
- Pin_New = DATA_REV_PIN;
- if (start_H_L_Level_timming_flag==1)
- {
- H_L_Level_time_cnt++; //高低電平維持時(shí)間計(jì)數(shù)變量
- Pin_Change_Flag = 0;
- BitFinish_Flag = 0;
- if(Pin_New != Pin_Old)
- {
- Pin_Change_Flag = 1;
- if(0 == Pin_New)
- {BitFinish_Flag = 1;}
- }
- Pin_Old = Pin_New;
- }
- Receive_Data_Handle(); //接收數(shù)據(jù)處理,波特率自適應(yīng)
- led_toggle(LED2);//測試用的 LED
- }
- }
- /*******************************************************************************
- *函數(shù)名稱 : Receive_Data_Handle
- *函數(shù)功能 : 接收數(shù)據(jù)處理
- *輸入?yún)?shù) : void
- *輸出返回 : void
- *******************************************************************************/
- void Receive_Data_Handle(void)
- {
- switch (receive_state) //檢測當(dāng)前接收數(shù)據(jù)狀態(tài)
- {
- case INITIAL_STATE: //初始狀態(tài),未接收到同步信息,進(jìn)行同步判斷
- if (DATA_REV_PIN == LOW) //判斷接收引腳的電平狀態(tài),當(dāng)讀到低電平時(shí),開始計(jì)時(shí)
- {
- receive_bit_num = 0; //重置bit位計(jì)數(shù)器
- receive_data_num = 0; //重置接收數(shù)據(jù)個(gè)數(shù)
- H_L_Level_time_cnt = 0; //高低電平計(jì)時(shí)變量清0
- start_H_L_Level_timming_flag = 1; //開始高低電平計(jì)時(shí)
- receive_state = SYNC_L_STATE; //進(jìn)入讀取同步低電平信號(hào)狀態(tài)
- memset(receive_data_buf, 0 ,REV_DATA_NUM);
- }
- break;
- case SYNC_L_STATE: //在讀取同步低電平信號(hào)期間
- if (DATA_REV_PIN == HIGH) //同步信號(hào)低電平檢測期間讀到高電平
- {
- if (H_L_Level_time_cnt >= SYNC_L_TIME_NUM)//如果同步信號(hào)低電平時(shí)間>=SYNC_L_TIME_NUM
- { //同步信號(hào)低電平時(shí)間要>=10ms
- H_L_Level_time_cnt = 0; //高低電平計(jì)時(shí)變量清0
- receive_state = SYNC_H_STATE; //進(jìn)入讀取同步信號(hào)高電平狀態(tài)
- }
- else
- {
- receive_state = RESTART_REV_STATE; //進(jìn)入重新接收狀態(tài)
- }
- }
- break;
- case SYNC_H_STATE: //在讀取同步信號(hào)高電平期間
- if (DATA_REV_PIN == LOW) //同步信號(hào)高電平檢測期間讀到低電平
- {
- //判斷同步信號(hào)高電平時(shí)間是否在1ms±100us之間
- if (H_L_Level_time_cnt >= SYNC_H_TIME_NUM_MIN && H_L_Level_time_cnt <= SYNC_H_TIME_NUM_MAX)
- {
- H_L_Level_time_cnt = 0; //高低電平計(jì)時(shí)變量清0
- receive_state = DATA_REV_STATE; //進(jìn)入讀取數(shù)據(jù)狀態(tài)
- }
- else
- {
- receive_state = RESTART_REV_STATE; //進(jìn)入重新接收狀態(tài)
- }
- }
- else //如果在同步信號(hào)高電平檢測期間,時(shí)間超過2ms±200us,認(rèn)為超時(shí)
- {
- //判斷時(shí)間是否超時(shí) 2ms±200us
- if (H_L_Level_time_cnt >= LOGIC_CYCLE_NUM_MAX)
- {
- receive_state = RESTART_REV_STATE; //進(jìn)入重新接收狀態(tài)
- }
- }
- break;
- case DATA_REV_STATE: //在讀取數(shù)據(jù)碼電平期間
- if ((has_read_bit==0) && (H_L_Level_time_cnt >= HALF_LOGIC_CYCLE_MIN && H_L_Level_time_cnt <= HALF_LOGIC_CYCLE_MAX))
- {
- receive_data_buf[receive_data_num] |= DATA_REV_PIN;
- has_read_bit = 1;
- }
- //如果已經(jīng)讀取一個(gè)bit位,且時(shí)間計(jì)數(shù)已經(jīng)>=2ms±200us,說明一個(gè)邏輯周期過去了
- if ((has_read_bit==1) && (H_L_Level_time_cnt >= LOGIC_CYCLE_NUM_MIN && H_L_Level_time_cnt <= LOGIC_CYCLE_NUM_MAX))
- //if ((has_read_bit==1) && (1 == BitFinish_Flag))
- {
- H_L_Level_time_cnt = 0; //高低電平計(jì)時(shí)變量清0
- has_read_bit = 0; //清0,讀取下一個(gè)bit位
- receive_bit_num++; //接收的bit數(shù)++
- if (receive_bit_num == REV_BIT_NUM) //如果一個(gè)字節(jié)8個(gè)bit位接收完成
- {
- //receive_data[receive_data_num] = receive_data_buf[receive_data_num];
- receive_data_num++; //接收的數(shù)據(jù)個(gè)數(shù)++
- receive_bit_num = 0; //接收bit位個(gè)數(shù)清0重新接收
- if (receive_data_num == REV_DATA_NUM) //如果數(shù)據(jù)采集完畢
- {
- receive_state = END_SIGNAL_STATE; //進(jìn)入接收結(jié)束低電平信號(hào)狀態(tài)
- }
- }
- else //如果一個(gè)字節(jié)8個(gè)bit位還沒有接收完成
- {
- //將接收數(shù)據(jù)緩存左移一位,數(shù)據(jù)從低bit位開始接收
- receive_data_buf[receive_data_num] = receive_data_buf[receive_data_num] >> 1;
- }
- }
- break;
- case END_SIGNAL_STATE: //在接收結(jié)束信號(hào)低電平期間
- if (DATA_REV_PIN == LOW)
- {
- if (H_L_Level_time_cnt >= END_SIGNAL_TIME_NUM) //如果讀到低電平時(shí)間>=5ms
- {
- read_success = 1; //一幀數(shù)據(jù)讀取成功
- SIF_Handle();
- start_H_L_Level_timming_flag = 0; //停止高低電平計(jì)時(shí)
- H_L_Level_time_cnt = 0; //定時(shí)器計(jì)數(shù)值清0
- receive_state = INITIAL_STATE; //接收狀態(tài)清0
- }
- }
- else //結(jié)束信號(hào)低電平檢測期間一直為低
- {
- //if (H_L_Level_time_cnt >= SYNC_L_TIME_NUM) //如果讀到低電平時(shí)間>=10ms,認(rèn)為超時(shí)
- { //一幀數(shù)據(jù)發(fā)送完成后需要間隔50ms才發(fā)送第二幀數(shù)據(jù),期間肯定會(huì)被拉高
- receive_state = RESTART_REV_STATE; //進(jìn)入重新接收狀態(tài)
- }
- }
- break;
- case RESTART_REV_STATE: //重新接收數(shù)據(jù)狀態(tài)
- start_H_L_Level_timming_flag = 0; //停止高低電平計(jì)時(shí)
- H_L_Level_time_cnt = 0; //定時(shí)器計(jì)數(shù)值清0
- receive_state = INITIAL_STATE; //接收狀態(tài)清0
- break;
- }
- }
- /*******************************************************************************
- *函數(shù)名稱 : Check_Sum_Handle
- *函數(shù)功能 : 校驗(yàn)和處理
- *輸入?yún)?shù) : void
- *輸出返回 : void
- *******************************************************************************/
- void Check_Sum_Handle(void)
- {
- unsigned char i = 0, checkByte = 0;
- unsigned long checkXor = 0;
- for ( i = 0; i < (REV_DATA_NUM ); i++)
- {
- checkXor = checkXor ^ receive_data_buf[i];
- }
- checkByte = (unsigned char)checkXor;
- if (checkByte == receive_data_buf[REV_DATA_NUM-1]) //校驗(yàn)和正確
- {
- check_OK = 1; //標(biāo)記校驗(yàn)成功
- }
- else
- {
- check_OK = 0; //標(biāo)記校驗(yàn)失敗
- }
- }
- uint8_t * pGetSIFData(void)
- {
- return receive_data;
- }
到這已經(jīng)完成了 LKS32AT085 芯片的 SIF 協(xié)議測試,使用的是中斷發(fā)送的方式,對(duì) LAST_BYTE 那位的使用還存在疑惑:因?yàn)槲疫沒有關(guān)注停止信號(hào)的發(fā)送情況,那是否靠這位去發(fā)出停止信號(hào)的呢?
儀表盤液晶屏幕一線通應(yīng)用
之前給新思維做儀表項(xiàng)目的時(shí)候買過一個(gè)帶一線通接口走新思維協(xié)議的儀表液晶模塊,淘寶鏈接如下:
https://item.taobao.com/item.htm?spm=a1z09.2.0.0.47f72e8d5ah35W&id=593789766798&_u=tckiua7c9d2
這次可以直接拿 LKS32AT085 芯片的 SIF 接口來與之通訊,控制其顯示不同的數(shù)據(jù)了,協(xié)議內(nèi)容我放在附件中了,具體實(shí)現(xiàn)代碼由于涉及到機(jī)密不在這貼出,下面為效果展示圖:
小結(jié)
經(jīng)過一番折騰終于將 LKS32AT085 芯片自帶的 SIF 通訊接口玩起來了,不再用 timer+io 的方式去模擬了,簡化了大量的實(shí)現(xiàn)流程和代碼量,著實(shí)適用于電動(dòng)自行車一線通領(lǐng)域,以后再做兩輪電動(dòng)自信車電控和儀表項(xiàng)目會(huì)優(yōu)先考慮凌鷗的專用芯片了。另外,如果一線通能做到像汽車上的 K 線一樣有專門的標(biāo)準(zhǔn)去將其“車規(guī)化”,那它在其它領(lǐng)域中也必將會(huì)逐漸普及起來。
- 本文系21ic原創(chuàng),未經(jīng)許可禁止轉(zhuǎn)載!
網(wǎng)友評(píng)論
- 聯(lián)系人:巧克力娃娃
- 郵箱:board@21ic.com
- 我要投稿
-
歡迎入駐,開放投稿
行業(yè)新聞
論壇活動(dòng)
more+
公開課
more+
項(xiàng)目外包
more+
- NRF52810藍(lán)牙數(shù)字耳機(jī)找人定制
預(yù)算:¥30005天前
- 125KW模塊式PCS軟硬件外包開發(fā)
預(yù)算:¥1100000015小時(shí)前
- 12V汽車啟動(dòng)電源項(xiàng)目BMS設(shè)計(jì)
預(yù)算:¥50000023小時(shí)前
- 數(shù)據(jù)可視化軟件 開發(fā)
預(yù)算:¥5000023小時(shí)前
- PLC項(xiàng)目調(diào)試修改
預(yù)算:¥100001天前
- 起動(dòng)電機(jī)控制器開發(fā)
預(yù)算:¥1100001天前