“告別檢測系統(tǒng)能力缺陷!10+年LabVIEW視覺資深專家手把手教你:5000+分鐘高清教程(含工具、算法原理、實戰(zhàn)操作、項目優(yōu)化全流程講解)”——從傳統(tǒng)視覺算法→深度學習建?!I(yè)級部署"
2025-12-30 08:06:30
67 
在現(xiàn)代工業(yè)自動化中,PLC遠程控制功能越來越重要,尤其是在設(shè)備分布廣泛或環(huán)境復(fù)雜的場景中。通過無線通信技術(shù),可以實現(xiàn)PLC的遠程控制,顯著提高生產(chǎn)效率和運維便捷性。本文將詳細介紹基于無線的PLC遠程控制設(shè)置方法。 以DTD418MB 實現(xiàn)組態(tài)王對AB820 PLC 的遠程無線控制為例。 一、硬件連接 將上位機與 DTD418MB 通過通訊線連接,一端接入 DTD418MB 的 RJ45 接口,另一端接入上位機的 RJ45 接口; 同樣,用通訊線將 PLC 與 DTD418MB 連接,一端接入 DTD418MB 的
2025-12-24 11:36:55
95 
中小工廠砸?guī)资f搞智能改造,結(jié)果踩了最冤的坑:花 “智慧工廠系統(tǒng)” 的錢,買的只是個 “升級款工廠監(jiān)控系統(tǒng)”—— 只能看設(shè)備轉(zhuǎn)不轉(zhuǎn),沒法調(diào)生產(chǎn)、降能耗,錢直接打了水漂。智能改造選系統(tǒng),真的像開盲盒?其實只要搞懂核心區(qū)別,再找對工具,就能避開 “花大錢買錯工具” 的坑 —— 有人物聯(lián)網(wǎng)就是中小廠的 “智能改造避坑指南庫” 。 一、智能改造最易踩的坑:系統(tǒng)認錯,錢白扔 很多廠剛?cè)腴T時,都會把這倆核心系統(tǒng)搞混: 智慧工廠系
2025-12-19 14:20:21
137 
一、文字教程簡介本教程旨在演示EWD22S-A01TR的正確接線方法。材料準備EWD22S-A01TR一臺220V交流電源一根220V交流電燈一臺433M天線一根接線步驟電源輸入端連接將220V交流電源火線與EWD22S-A01TR的電源輸入L端連接將220V交流電源零線與EWD22S-A01TR的電源輸入N端連接電燈輸出端連接將220V交流電燈火線與E
2025-12-11 19:33:48
192 
不同的開發(fā)環(huán)境,設(shè)置方法也各不相同。本文將手把手教你如何在主流的CS+for CC、e2studio和IAR Embedded Workbench中完成這兩項重要配置。
2025-12-11 16:33:20
4263 
你是否在選購SG三相隔離變壓器時感到迷茫,擔心選錯型號導致能效低下或設(shè)備損壞?對于設(shè)備維護人員和采購者來說,錯誤選擇不僅浪費資金,更可能帶來持續(xù)的運維問題。今天,我們從專業(yè)角度出發(fā),手把手教你
2025-12-11 15:47:41
213 
?在電商競爭日益激烈的今天,掌握商品價格動態(tài)已成為商家制定靈活定價策略的關(guān)鍵。本文將手把手教你如何通過京東API實現(xiàn)實時價格監(jiān)控,為您的商業(yè)決策提供數(shù)據(jù)支撐。 一、京東API的價值解析 京東開放平臺
2025-12-09 17:36:26
781 
視覺算子詳解》一書;開發(fā)了《龍哥手把手教你學視覺》系列包含視覺、運動控制、深度學習在內(nèi)的全套5000+分鐘視頻教程。
發(fā)燒友官方統(tǒng)計累計學員達20000余人,部分學員現(xiàn)任職于華為、比亞迪、富士康等頭部
2025-12-04 09:28:20
視覺算子詳解》一書;開發(fā)了《龍哥手把手教你學視覺》系列包含視覺、運動控制、深度學習在內(nèi)的全套5000+分鐘視頻教程。
發(fā)燒友官方統(tǒng)計累計學員達20000余人,部分學員現(xiàn)任職于華為、比亞迪、富士康等頭部
2025-12-03 13:50:14
“告別檢測系統(tǒng)能力缺陷!10+年LabVIEW視覺資深專家手把手教你:5000+分鐘高清教程(含工具、算法原理、實戰(zhàn)操作、項目優(yōu)化全流程講解)”——從傳統(tǒng)視覺算法→深度學習建模→工業(yè)級部署"
2025-12-02 08:07:22
310 
當我們談?wù)摗爸悄芄S”時,許多傳統(tǒng)企業(yè)的管理者第一反應(yīng)是:推倒重來,投資千萬,周期漫長,望而卻步。但這其實是一個巨大的誤解! 智能化的本質(zhì)是“賦能”,而非“替代” 。本文將為你揭秘,如何利用成熟可靠的工業(yè)互聯(lián)網(wǎng)技術(shù),像給老汽車安裝“自動駕駛套件”一樣,讓你的傳統(tǒng)工廠實現(xiàn)低成本、高效率的“賽博重生”! 一、靈魂拷問:為什么要改造?目標在哪? 改造不是跟風,而是為了解決切膚之痛。在動工前,必須先進行靈魂拷問:
2025-11-25 16:51:42
355 
迅為Hi3403開發(fā)板極速啟航 | 手把手帶你玩轉(zhuǎn)核心例程,輕松上手AI視覺!
2025-11-19 13:56:08
1537 
【迅為RK3568開發(fā)板NPU實戰(zhàn)】別再閑置你的NPU!手把手教你玩轉(zhuǎn)RKNN-Toolkit2 的使用
2025-11-11 14:21:10
696 
對智慧視覺領(lǐng)域感興趣,或是行業(yè)從業(yè)者注意啦!11月13日20:00,RT-Thread攜手富瀚微技術(shù)專家,為您帶來FH8626V300L全棧開發(fā)實戰(zhàn)線上直播,手把手帶你從芯片解讀到RT-Thread
2025-11-11 11:53:35
628 
【RK3568 NPU實戰(zhàn)】別再閑置你的NPU!手把手帶你用迅為資料跑通Android AI檢測Demo,附完整流程與效果
2025-11-10 15:58:29
942 
《手把手教你設(shè)計CPU》書上運行Verilog仿真測試那章說為了重現(xiàn)仿真環(huán)境,最好在Linux環(huán)境下。不知道移植蜂鳥是否需要在Linux環(huán)境下,直接在Windows操作系統(tǒng)可否移植開發(fā)。
2025-11-10 07:42:13
前提條件:
1)開發(fā)板是Digilent的ARTY A7-35T開發(fā)版,也就是《手把手教你設(shè)計CPU-RISC-V處理器》中介紹的那塊板子
2)vivado安裝正常,可以啟動,跑make mcs
2025-11-07 06:05:07
想用ESP32-S3開發(fā)板驅(qū)動無刷電機卻不知從何下手?本教程將手把手教你完成從硬件連接到軟件編程的全流程,無論你是新手還是有一定經(jīng)驗的開發(fā)者,都能輕松掌握!本教程代碼已全部開源!后臺私信關(guān)鍵詞
2025-11-06 18:03:59
457 
想要快速掌握LuatOS GNSS定位調(diào)試?本文將以手把手的方式,帶領(lǐng)您一步步完成調(diào)試流程。無論您是初學者還是有一定經(jīng)驗的開發(fā)者,這份實用操作指南都能幫助您有效提升調(diào)試效率,確保定位功能穩(wěn)定可靠
2025-11-04 18:30:08
1323 
你是否也遇到過這些困擾:電腦突然變得異??D,程序無響應(yīng)?想知道電腦狀態(tài),卻懶得每次都打開任務(wù)管理器?想要實時監(jiān)控系統(tǒng)性能,又沒有合適的工具?別擔心!今天我們教你一個簡單又低成本的方法——用
2025-11-04 18:05:07
403 
最近發(fā)布的202102版本的Nuclei Studio IDE增加了QEMU仿真器,可支持RV-STAR開發(fā)板的仿真,本教程旨在介紹如何使用該仿真環(huán)境進行RISC-V嵌入式開發(fā)。
系統(tǒng)環(huán)境
Windows 10-64bit
軟件平臺
Nuclei Studio IDE 202102版
Nuclei Studio的下載和安裝
在芯來科技官網(wǎng)文檔與工具頁面可以下載 Nuclei Studio IDE軟件,其鏈接如下:
https://www.nucleisys.com/download.php
根據(jù)自己的操作系統(tǒng)下載對應(yīng)的文件即可,IDE不需要安裝,下載后直接解壓縮即可使用;
啟動Nuclei Studio
在 Nuclei Studio 解壓縮的目錄下雙擊 NucleiStudio.exe 即可啟動 IDE;第一次啟動 Nuclei Studio 將會彈出對話框要求設(shè)置 Workspace 目錄路徑,該目錄將用于存放后續(xù)創(chuàng)建的項目工程文件。設(shè)置好 Workspace 路徑,再單擊 “Launch” 啟動 Nuclei Studio;啟動后頁面如下圖,推薦打開 Launch Bar 功能,方便快速編譯和調(diào)試。打開菜單欄 “Window -> Preferences”,搜索 “bar”,勾選第一個選項 “Enable the Launch Bar”即可啟用 Launch Bar 功能。下滑查看更多
新建模板helloworld工程
在菜單欄中,選擇 “File-> New -> C/C++ Project” 開始新建工程,在彈窗中雙擊選擇 “C Managed Build” ;
新的頁面中 “Project name” 填寫 “helloworld” , “Project type”選擇 “Nuclei SDK Project For GD32VF103 SoC” 和 “RISC-V Cross GCC” ,如下圖,點擊 “Next” 。新的頁面不用修改,直接點擊 “Next” 即可;
我們在選擇 Board 時,請記得一定要選 gd32vf103v_rvstar 這塊板子噢!
在選擇模板工程頁面修改“Project Example”選項為“baremetal_helloworld”。
后續(xù)頁面不需要修改,點擊“Next”直到最后一頁,點擊“Finish”完成新建模板helloworld工程。最終IDE界面顯示如下:
調(diào)試helloworld
在Launch Bar可以看到有兩個配置如下圖
我們看一下QEMU的配置,這些已經(jīng)配置好了,如果不太了解的同學,這里基本上可以不用進行任何設(shè)置。
然后選中 debug 模式并啟動 debug
編譯器對代碼進行編譯后,會跳出 Switch 框,選 Switch 后進入調(diào)試模式
調(diào)試模式的界面如下
IDE提供了豐富的調(diào)試工具,具體的就不一一介紹了,大家可以去嘗試。
雖然是在QEMU仿真環(huán)境下,但應(yīng)用的還是gdb調(diào)試工具,所以也是支持gdb命令行調(diào)試的,選中Debugger Console,就可以輸入gdb命令了。
我們可以查看一下仿真環(huán)境下的寄存器。結(jié)果如下圖,更多命令使用大家可以自行查閱gdb的使用手冊。
當然,也可以在圖形界面中查看寄存器。
在工具欄選 :
Window ->Show View ->Registers
在彈出的 Registers 框中,就可以非常方便的查看寄存器信息。我們可以在調(diào)試過程中查看相關(guān)信息的變化。
運行helloworld
在調(diào)試模式下代碼無bug,我們可以直接運行代碼查看運行結(jié)果,在run程序前,一定要將之前啟動的QEMU結(jié)束掉,不管是openOCD還是QEMU的進程都是排它性,所以運行或者調(diào)試結(jié)束后,一定要記得點關(guān)閉按鈕。不然后報錯如下圖:
結(jié)束QEMU依次點下面三個按鈕,確保進程已結(jié)束。
結(jié)束調(diào)試后開始運行前,建議clean一下工程,在工程名上左鍵->clean Project,IDE就會幫您清除掉編譯生成的編譯文件。
直接點運行,就可以了看到IDE開始編譯代碼并運行,如果代碼正確,就會輸出代碼的結(jié)果。
下滑查看更多
在沒有連接板子的情況下,我們成功運行了helloworld程序。
至此,在Nuclei Studio中基于QEMU進行嵌入式代碼開發(fā)和調(diào)試的介紹就結(jié)束了。
2025-10-31 08:54:30
?上期內(nèi)容講解了UART串口通信的應(yīng)用方法,本期內(nèi)容的主角是另一種嵌入式系統(tǒng)中常用的通信協(xié)議——I2C(Inter-Integrated Circuit)。本期內(nèi)容將帶領(lǐng)大家使用RV-STAR開發(fā)板來控制OLED液晶屏顯示不同的字符和圖像,從而初步了解I2C總線通信的應(yīng)用方法。
系統(tǒng)環(huán)境
Windows 10-64bit
軟件平臺
[size=14.6667px]NucleiStudio IDE 202102版或PlatformIO IDE
硬件需求
RV-STAR開發(fā)板、
0.96英寸OLED顯示屏(I2C接口)
I2C協(xié)議介紹
I2C是由NXP(原PHILIPS)公司開發(fā)的兩線式串行總線,用于連接微控制器及其外圍芯片,目前已成為一種行業(yè)標準,在微控制器設(shè)計中被大量采用,在RV-STAR所使用的GD32VF103微控制器上也集成了I2C接口。
I2C總線的主要特點是接線簡單,硬件上只需兩條線,一根SCL時鐘線用于收發(fā)雙方的時鐘節(jié)拍,一根SDA數(shù)據(jù)線負責傳輸數(shù)據(jù),因此I2C是一種同步通信。
I2C可以掛載多個參與通信的器件,即多機模式,且任何一個器件都可以作為主機,在多數(shù)情況下由微控制器作為主機,在本次的實驗中也是如此。
I2C的數(shù)據(jù)傳輸流程和UART具有相似之處,包括起始信號、數(shù)據(jù)傳輸和停止信號,其中和UART不同的地方在于,數(shù)據(jù)傳輸?shù)淖止?jié)數(shù)沒有限制,可以一次傳輸很多個字節(jié),每個字節(jié)后跟有一個應(yīng)答位(即ACK),有點類似于UART的停止位。
I2C在應(yīng)用時,在發(fā)送了起始信號(Start)后,要先發(fā)送一個7位的從機地址,緊跟著的第8位是數(shù)據(jù)方向位(R/W),“0”表示接下來要發(fā)送數(shù)據(jù),“1”表示接下來要讀數(shù)據(jù)。當發(fā)送完這個8個位后,如果發(fā)送的地址有設(shè)備存在,這個設(shè)備應(yīng)該回復(fù)一個ACK(拉低SDA,輸出“0”),這樣才會繼續(xù)進行通信流程。
OLED液晶屏介紹
OLED(Organic Light-Emitting Diode,有機發(fā)光二極管)因為具備輕薄、省電、顯示效果好等特性,被廣泛應(yīng)用手機、音樂播放器等電子設(shè)備中。
本次實驗用到的OLED液晶屏參數(shù)如下:
尺寸0.96英寸
分辨率128*64
可視角度大于160°
功耗0.06w
供電范圍3.3v~5v
工作溫度-30℃~70℃
體積27mm*27mm*2mm
亮度可通過指令控制
驅(qū)動芯片SSD1306
接口I2C
GD32VF103的I2C接口
GD32VF103的I2C(內(nèi)部集成電路總線)模塊提供了符合工業(yè)標準的兩線串行制接口,可用于MCU和外部I2C設(shè)備的通訊。I2C總線使用兩條串行線:串行數(shù)據(jù)線SDA和串行時鐘線SCL。I2C接口模塊實現(xiàn)了I2C協(xié)議的標速模式(最高100KHz)和快速模式(最高400KHz),具備CRC計算和校驗功能,支持SMBus(系統(tǒng)管理總線)和 PMBus(電源管理總線)。此外還支持多主機I2C總線架構(gòu)。I2C接口模塊也支持DMA模式,可有效減輕CPU的負擔。
更詳細內(nèi)容請參考《GD32VF103用戶手冊》。
實驗部分
首先需要將RV-STAR開發(fā)板及OLED顯示屏參照下圖使用杜邦線進行連線:
然后在IDE中進行代碼編寫,在使用I2C接口的時候,首先要對其進行初始化:先使能外設(shè)時鐘,然后將SDA、SCL兩個引腳配置為開漏模式,之后需要依次設(shè)置I2C的時鐘速率、地址,然后使能I2C和ACK。其相關(guān)代碼如下:
[size=0.85em]void I2C_Configuration(void)
{
uint32_t GPIO_SDA, GPIO_SCL;
uint32_t GPIO_PIN_SDA, GPIO_PIN_SCL;
rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_I2C1);
GPIO_SDA = GPIOB;
GPIO_PIN_SDA = GPIO_PIN_11;
GPIO_SCL = GPIOB;
GPIO_PIN_SCL = GPIO_PIN_10;
gpio_init(GPIO_SCL, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_SCL);
gpio_init(GPIO_SDA, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_SDA);
i2c_clock_config(I2C1, 400000, I2C_DTCY_2);
i2c_mode_addr_config(I2C1, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0x30);
i2c_enable(I2C1);
i2c_ack_config(I2C1, I2C_ACK_ENABLE);
}
在本次實驗中,由于使用的是“主發(fā)從收”模式,RV-STAR開發(fā)板作為主機,通過向OLED屏幕發(fā)送指令和數(shù)據(jù),從而控制OLED屏幕顯示不同的字符和圖像,所以除初始化I2C外設(shè)的函數(shù)外,接下來需要實現(xiàn)一個讓主機向從機發(fā)送字節(jié)的函數(shù),其代碼和注釋如下:
void I2C_WriteByte(uint8_t addr, uint8_t data)
{
/* wait until I2C bus is idle */
while(i2c_flag_get(I2C1, I2C_FLAG_I2CBSY));
/* send a start condition to I2C bus */
i2c_start_on_bus(I2C1);
/* wait until SBSEND bit is set */
while(!i2c_flag_get(I2C1, I2C_FLAG_SBSEND));
/* send slave address to I2C bus*/
i2c_master_addressing(I2C1, 0x78, I2C_TRANSMITTER);
/* wait until ADDSEND bit is set*/
while(!i2c_flag_get(I2C1, I2C_FLAG_ADDSEND));
/* clear ADDSEND bit */
i2c_flag_clear(I2C1, I2C_FLAG_ADDSEND);
/* send a addr byte */
i2c_data_transmit(I2C1, addr);
/* wait until the transmission data register is empty*/
while(!i2c_flag_get(I2C1, I2C_FLAG_TBE));
/* send a data byte */
i2c_data_transmit(I2C1, data);
/* wait until the transmission data register is empty*/
while(!i2c_flag_get(I2C1, I2C_FLAG_TBE));
/* send a stop condition to I2C bus*/
i2c_stop_on_bus(I2C1);
/* wait until stop condition generate */
while(I2C_CTL0(I2C1)&0x0200);
}
發(fā)送字節(jié)的過程在代碼中配有詳細注釋(其中OLED屏幕的I2C地址默認為0x78),在實現(xiàn)了I2C的初始化和字節(jié)發(fā)送功能后,OLED的具體控制實現(xiàn)起來就相當容易了,其相關(guān)接口和函數(shù)的說明在代碼中都進行了注釋,這里不進行贅述,大家可以通過閱讀項目源代碼進行了解。
完整代碼請參考https://github.com/Nuclei-Software/nuclei-board-labs/tree/master/rvstar/i2c/i2c_oled_screen
實驗現(xiàn)象參考以下動圖
2025-10-31 08:48:56
相對于抽象層次更高的C/C++語言,匯編語言是一門抽象層次比較低的語言,面向的是最底層的硬件,直接使用處理器的基本指令。雖然現(xiàn)在大多數(shù)的程序設(shè)計已經(jīng)不再使用匯編語言,但是在一些特殊的場合,譬如底層驅(qū)動、引導程序、高性能算法庫等領(lǐng)域,匯編語言還經(jīng)常扮演著重要的角色。
系統(tǒng)環(huán)境
Windows 10-64bit
軟件平臺
Nuclei Studio IDE 202102版
匯編語句組成
匯編程序的最基本元素是指令,指令集是處理器架構(gòu)的最基本要素,因此RISC-V匯編語言的最基本元素自然是一條條的RISC-V指令。除了指令之外,由于此處所用RISC-V工具鏈是GCC工具鏈,因此一般的GNU匯編語法也能被GCC的匯編器識別,GNU匯編語法中定義的偽操作、操作符、標簽等語法規(guī)則均可以在RISC-V匯編語言中使用。
一條典型的RISC-V匯編語句由4部分組成,包含如下字段:
[size=0.85em][label:] opcode [operands] [;comment]
[標簽:]操作碼[操作數(shù)][;注釋]
標簽
表示當前指令的位置標記。
操作碼
可以是如下任意一種:
RISC-V指令的指令名稱,譬如addi指令、lw指令等。
匯編語言的偽操作。
用戶自定義的宏。
操作數(shù)
操作碼所需的參數(shù),與操作碼之間以空格分開,可以是符號、常量,或者由符號和常量組成的表達式。
注釋
為了程序代碼便于理解而添加的信息,注釋并不發(fā)揮實際功能,僅起到注解作用。注釋是可選的,如果添加注釋,需要注意以下規(guī)則:
以“;”或者“#”作為分隔號,以分隔號開始的本行之后部分到本行結(jié)束都會被當作注釋。
或者使用類似C語言的注釋語法//和/* */對單行或者大段程序進行注釋。
匯編程序偽操作
在匯編語言中,有一些特殊的操作助記符通常被稱為偽操作(Pseudo Ops)。偽操作在匯編程序中的作用是指導匯編器處理匯編程序的行為,且僅在匯編過程中起作用,一旦匯編結(jié)束,偽操作的使命就此結(jié)束。
此處所用的RISC-V工具鏈是GCC工具鏈,一般的GNU匯編語法中定義的偽操作均可在RISC-V匯編語言中使用。經(jīng)過不斷地增加,目前GNU匯編中定義的偽操作數(shù)目眾多,感興趣的讀者可以自行查閱完整的GNU匯編語法手冊。這里將僅簡單介紹一些常見的偽操作。.globalsymbol_name 或者 .globlsymbol_name.global和.globl偽操作用于定義一個全局的符號,使得鏈接器能夠全局識別它,即一個程序文件中定義的符號能夠被所有其他程序文件可見。.weaksymbol_name
在匯編程序中,符號的默認屬性為強 (strong),.weak偽操作則用于設(shè)置符號的屬性為弱 (weak),如果此符號之前沒有定義過,那么同時創(chuàng)建此符號并定義其屬性為 weak。如果符號的屬性為 weak,那么它無須定義具體的內(nèi)容。在鏈接的過程中,另外一個屬性為 strong的同名符號可以將此weak符號的內(nèi)容強制覆蓋。利用此特性, .weak偽操作常用于預(yù)留一個空符號,使得其能夠通過匯編器語法檢查,但是在后續(xù)的程序中定義符號的真正實體,并且在鏈接階段將空符號覆蓋并鏈接。.aligninteger
.align 偽操作用于將當前PC地址推進到 “2的integer次方字節(jié)” 對齊的位置。譬如 “.align 3” 表示將當前PC地址推進到8個字節(jié)對齊的位置處。.sectionname [, subsection]
.section 偽操作指明將接下來的代碼匯編鏈接到名為 name的段 (Section)中,還可以指定可選的子段 (Subsection),常見的段有 .text、.data、.rodata、.bss。例如 ,“.section .text”偽操作將接下來的代碼匯編鏈接到 .text段。
匯編程序定義標簽
標簽名稱通常在一個冒號(:)之前,常見的標簽分為文本標簽和數(shù)字標簽。
文本標簽在一個程序文件中是全局可見的,因此定義必須使用獨一無二的命名,文本標簽通常被作為分支或跳轉(zhuǎn)指令的目標地址,示例如下:
loop://定義一個名為loop的標簽,該標簽代表了此處的PC地址
......
j loop//跳轉(zhuǎn)指令跳轉(zhuǎn)到標簽loop所在的位置
數(shù)字標簽為0~9之間的數(shù)字表示的標簽,數(shù)字標簽屬于一種局部標簽,需要時可以被重新定義。在被引用時,數(shù)字標簽通常需要帶上一個字母“f”或者“b”的后綴,“f”表示向前,“b”表示向后,示例如下:
j 1f //跳轉(zhuǎn)到“向前尋找第一個數(shù)字為1的標簽”所在的位置,即下一行
//(標簽為1)所在的位置
1:
j 1b//跳轉(zhuǎn)到“向后尋找第一個數(shù)字為1的標簽”所在的位置,即上一行
//(標簽為1)所在的位置
匯編程序定義宏
宏(macro)是將匯編語言中具有一組獨立功能的匯編語句組織在一起,然后可以以宏調(diào)用的方式進行調(diào)用。示例如下:
.macro mac, a, b, c //定義一個名為mac的宏,參數(shù)為a、b、c
mul t0, b, c// mul指令將b和c相乘得到乘積寫入t0寄存器
add a, t0, a// add指令將a與t0相加,將乘累加結(jié)果寫入a
.endm
//調(diào)用mac宏
mac x1, x2, x3
完整實例
為了便于理解匯編程序,我們以 RV-STAR工程的非向量中斷處理匯編代碼為實例,講解匯編程序。
在 Nuclei Studio中新建一個 helloworld工程。芯來科技官網(wǎng)的文檔與工具頁面可以下載Nuclei Studio,下載后解壓縮,在 Nuclei Studio解壓縮的目錄下雙擊 NucleiStudio.exe即可啟動 IDE。
第一次啟動 Nuclei Studio將會彈出對話框要求設(shè)置 Workspace目錄路徑,該目錄將用于存放后續(xù)創(chuàng)建的項目工程文件。設(shè)置好 Workspace路徑,再單擊 “Launch”啟動 Nuclei Studio。
啟動后推薦打開Launch Bar功能,方便快速編譯和調(diào)試。打開菜單欄“Window -> Preferences”,搜索“bar”,勾選第一個選項“Enable the Launch Bar”即可啟用Launch Bar功能。
在菜單欄中,選擇“File-> New -> C/C++ Project”開始新建工程,在彈窗中雙擊選擇“C Managed Build”。
新的頁面中“Project name”填寫“iasm”,“Project type” 選擇“Nuclei SDK Project For GD32VF103 SoC”和“RISC-V Cross GCC”,如下圖,點擊“Next”。新的頁面不用修改,直接點擊“Next”即可。
在選擇模板工程頁面修改“Project Example”選項為“baremetal_helloworld”,后續(xù)頁面不需要修改,點擊“Next”直到最后一頁,點擊“Finish”完成新建helloworld工程。
打開 “nuclei_sdk->SoC->gd32vf103->Common->Source->GCC->intexc_g32vf103.S” 文件,翻到第144行開始到184行結(jié)束就是非向量中斷處理匯編代碼。這里列出具體代碼,逐行講解各個匯編代碼的作用。
.section .text.trap//將接下來的代碼匯編鏈接到text段的trap段中
.align 6//2的6次方字節(jié)位置對齊
.global exc_entry//全局變量exc_entry
.weak exc_entry//定義屬性為弱的變量exc_entry
exc_entry://名為exc_entry的標簽
SAVE_CONTEXT//調(diào)用宏SAVE_CONTEXT,作用是保存上下文
SAVE_CSR_CONTEXT//調(diào)用宏SAVE_CSR_CONTEXT,作用是保存寄存器內(nèi)容
csrr a0, mcause//將寄存器mcause的值傳入通用寄存器a0
mv a1, sp//將sp的值傳入通用寄存器a1
call core_exception_handler//調(diào)用中斷處理函數(shù),將前面?zhèn)鞯腶0和a1作為函數(shù)的參數(shù)
RESTORE_CSR_CONTEXT//調(diào)用宏RESTORE_CSR_CONTEXT,作用是恢復(fù)保存的寄存器內(nèi)容
RESTORE_CONTEXT //調(diào)用宏RESTORE_CONTEXT,作用是恢復(fù)保存的上下文
mret //退出中斷處理函數(shù)
在匯編中調(diào)用C/C++函數(shù)
除了在C/C++程序中內(nèi)嵌匯編程序之外,還可以在匯編程序中調(diào)用C/C++函數(shù)。這種情形在實際的工程中也很常見,C/C++語言構(gòu)造的函數(shù)非常普遍,前面的中斷處理函數(shù)中正是調(diào)用C/C++的函數(shù)。
在介紹C/C++函數(shù)調(diào)用之前,先介紹應(yīng)用程序二進制接口(Abstract Binary Interface,ABI),ABI描述了應(yīng)用程序和操作系統(tǒng)之間、應(yīng)用和它的庫之間,以及應(yīng)用的組成部分之間的接口。
ABI涵蓋了如下細節(jié):
數(shù)據(jù)類型的大小、布局和對齊。
函數(shù)調(diào)用約定(控制著函數(shù)的參數(shù)如何傳送以及接受返回值),例如,是所有的參數(shù)都通過棧傳遞,還是部分參數(shù)通過寄存器傳遞;哪個寄存器用于哪個函數(shù)參數(shù);通過棧傳遞的第一個函數(shù)參數(shù)是最先還是最后推到棧上。
系統(tǒng)調(diào)用的編碼和一個應(yīng)用如何向操作系統(tǒng)進行系統(tǒng)調(diào)用。
在一個完整的操作系統(tǒng)ABI中,目標文件的二進制格式、程序庫等。
其中,函數(shù)調(diào)用約定決定了函數(shù)調(diào)用時參數(shù)傳遞和函數(shù)返回結(jié)果的規(guī)則,有關(guān)RISC-V架構(gòu)ABI的函數(shù)調(diào)用約定,可以查看RISC-V的架構(gòu)手冊。
對于RISC-V匯編程序而言,在匯編程序中調(diào)用C/C++語言函數(shù),必須遵照ABI所定義的函數(shù)調(diào)用規(guī)則,即函數(shù)參數(shù)由寄存器a0~a7傳遞,函數(shù)返回由寄存器a0~a1指定。上面匯編實例中調(diào)用的c函數(shù)代碼如下:
uint32_t core_exception_handler(unsigned long mcause, unsigned long sp)
{
uint32_t EXCn = (uint32_t)(mcause & 0X00000fff);
EXC_HANDLER exc_handler;
if ((EXCn < MAX_SYSTEM_EXCEPTION_NUM) && (EXCn >= 0)) {
exc_handler = (EXC_HANDLER)SystemExceptionHandlers[EXCn];
} else if (EXCn == NMI_EXCn) {
exc_handler = (EXC_HANDLER)SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM];
} else {
exc_handler = (EXC_HANDLER)system_default_exception_handler;
}
if (exc_handler != NULL) {
exc_handler(mcause, sp);
}
return 0;
}
此函數(shù)有兩個參數(shù),分別為mcause和sp,返回一個返回值。所以匯編中調(diào)用此函數(shù)前,分別向a0和a1寄存器中寫入mcause和sp的值。
2025-10-31 08:46:48
?上期內(nèi)容我們介紹了定時器的PWM輸出功能,本期內(nèi)容來介紹一下定時器的正交譯碼器功能(編碼器接口)。正交譯碼器是和正交編碼器外設(shè)配合使用的,可對編碼器輸入的脈沖進行計數(shù)進而實現(xiàn)速度測量,本期內(nèi)容我們通過一個使用旋轉(zhuǎn)編碼器的計數(shù)小實驗,來初步了解它的應(yīng)用方法。
系統(tǒng)環(huán)境
Windows 10-64bit
軟件平臺
NucleiStudio IDE 202102版
或 PlatformIO IDE
硬件需求
RV-STAR開發(fā)板
旋轉(zhuǎn)編碼器
正交編碼器
正交編碼器(Quadrature Encoder)是一種用于測量旋轉(zhuǎn)速度和方向的傳感器。常見的正交編碼器有兩個輸出信號:A信道和B信道。每個信道可以對運動進行測量并產(chǎn)生數(shù)字脈沖,這兩個脈沖的相位相差90度(因此稱為“正交”),這使得你可以根據(jù)它們判斷運動的方向,通過積分(累加)運算后,還可以用來測算距離。
上圖中,A和B分別連接到兩個傳感器單元上,黑白相間的圓環(huán)稱之為「柵格」。傳感器單元和柵格的實現(xiàn)方式有很多種,包括「反射式傳感器+反光率不同的柵格」「對射式傳感器+鏤空光柵」「霍爾傳感器+磁極圓環(huán)」「觸點+導軌」等。
本次實驗中,我們使用的是下圖所示的市面上常見的旋轉(zhuǎn)編碼器(數(shù)字電位器):
GD32VF103的正交譯碼器
正交譯碼器功能使用TIMERx_CH0和TIMERx_CH1引腳生成的CI0和CI1正交信號各自相互作用產(chǎn)生計數(shù)值。通過設(shè)置SMC=0x01、0x02或0x03來選擇是僅由CI0、僅由CI1、或者由CI0和CI1來決定定時器的計數(shù)方向。在每個方向選擇源的電平改變期間,DIR位是由硬件自動改變的。計數(shù)器計數(shù)方向改變的機制如下方的圖表所示。
正交譯碼器可以當作一個帶有方向選擇的外部時鐘,這意味著計數(shù)器會在0和自動加載值之間連續(xù)地計數(shù)。因此,用戶必須在計數(shù)器開始計數(shù)前配置TIMERx_CAR寄存器。
實驗部分
首先需要參照如下的示意圖,對RV-STAR開發(fā)板和旋轉(zhuǎn)編碼器進行連線:
然后在集成開發(fā)環(huán)境中創(chuàng)建一個新工程,開始編寫代碼。
首先需要對定時器的編碼器接口進行配置,我們使用的是TIMER2的編碼器接口,對應(yīng)的是PA6和PA7引腳,首先要使能它們的外設(shè)時鐘和復(fù)用時鐘,然后配置為浮空輸入模式。
接著需要創(chuàng)建定時器初始化參數(shù)結(jié)構(gòu)體,對定時器的功能進行配置,其中需要注意的是要將結(jié)構(gòu)體參數(shù)的預(yù)分頻系數(shù)設(shè)為0,周期設(shè)為10000(即定時器的自動加載值,也可以設(shè)為其他值),然后需要將定時器的模式設(shè)置為TIMER_ENCODER_MODE2(編碼器模式,使用CI0和CI1計數(shù)),然后將定時器的計數(shù)值配置為5000(這樣讀取定時器計數(shù)的初值就是5000),最后使能TIMER2。
相關(guān)代碼實現(xiàn)如下:
[size=0.85em]void encoder_init()
{
/* TIMER2_CH0 - PA6, TIMER2_CH1 - PA7 */
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_AF);
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_6 | GPIO_PIN_7);
rcu_periph_clock_enable(RCU_TIMER2);
timer_deinit(TIMER2);
/* initialize TIMER init parameter struct */
timer_parameter_struct timer_initpara;
timer_struct_para_init(&timer_initpara);
/* TIMER2 configuration */
timer_initpara.prescaler = 0;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = 10000; /* set auto-reload value */
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_init(TIMER2, &timer_initpara);
/* select the encoder mode */
timer_slave_mode_select(TIMER2, TIMER_ENCODER_MODE2);
timer_counter_value_config(TIMER2, 5000); /* config the initial value */
timer_enable(TIMER2);
}
本次實驗,我們通過串口的打印輸出來查看編碼器的計數(shù)值,因此在主程序中需要對串口進行初始化,然后在循環(huán)體中,每次讀取依次定時器的計數(shù)值,再打印輸出到串口。
[size=0.85em]int main()
{
encoder_init();
gd_com_init(GD32_COM0);
int counter = 0;
while (1) {
counter = timer_counter_read(TIMER2);
printf("Counter: %dn", counter);
delay_1ms(500);
}
}
代碼編寫完成后,進行編譯和上傳,然后打開串口終端(波特率115200),可以查看到在串口終端中輸出定時器的初值為5000:
然后順時針旋轉(zhuǎn)編碼器的旋鈕,觀察到計數(shù)值增加,并且每轉(zhuǎn)動一個單位計數(shù)值增加4,符合芯片數(shù)據(jù)手冊中的功能描述:
逆時針旋轉(zhuǎn),計數(shù)值減少:
掃碼獲取實驗源碼https://github.com/Nuclei-Software/nuclei-board-labs/tree/master/rvstar/timer/timer_encoder_counter
2025-10-31 08:21:16
?外部中斷是單片機實時地處理外部事件的一種機制。具體指的是,當某種外部事件發(fā)生時,單片機的中斷系統(tǒng)迫使CPU暫停正在執(zhí)行的程序,轉(zhuǎn)而去進行中斷事件的處理;中斷處理完畢后,又返回被中斷的程序處,繼續(xù)執(zhí)行下去。這里我們以Nuclei Board Labs中exti_key_interrupt應(yīng)用程序為例,簡單講解外部中斷的非向量處理模式。
系統(tǒng)環(huán)境
Windows 10-64bit
軟件平臺
[size=14.6667px]NucleiStudio IDE 202102版
硬件需求
RV-STAR開發(fā)板
中斷知識介紹
外部中斷處理介紹
在SoC層面,GD32VF103芯片有多個外部中斷源,具體包含哪些外部中斷,可以在GD32VF103用戶手冊的第六章:中斷/事件控制器(EXTI)中查看。
本次實驗使用用戶按鍵連接的GPIO作為外部中斷觸發(fā)源,經(jīng)過SoC層面的中斷/事件控制器(EXTI)檢測后,再傳遞給增強的內(nèi)核中斷控制器(ECLIC),交由內(nèi)核進行中斷管理。
關(guān)于GPIO的使用請看《RVMCU課堂[11]——GPIO使用篇》,這里不做介紹。
中斷/事件控制器(EXTI)的架構(gòu)框圖如下:
EXTI(中斷/事件控制器)有19個獨立的邊沿檢測單元,分別對應(yīng)連接EXTI0~18,其中的16個中斷源連接的是GPIO。EXTI有三種觸發(fā)類型:上升沿觸發(fā)、下降沿觸發(fā)和任意沿觸發(fā)。EXTI中的每 一個邊沿檢測電路都可以獨立配置和屏蔽。
中斷初始化函數(shù)介紹
為了方便進一步講解,我們先打開Nuclei Board Labs中exti_key_interrupt實驗的main.c函數(shù)源碼。其中,main函數(shù)調(diào)用的“ECLIC_Register_IRQ”函數(shù)就是中斷配置函數(shù)。截取ECLIC初始化函數(shù)代碼如下:[size=0.85em]/* ECLIC config */
returnCode = ECLIC_Register_IRQ( EXTI0_IRQn, ECLIC_NON_VECTOR_INTERRUPT,
ECLIC_LEVEL_TRIGGER,
1,
0,
NULL);
在《RVMCU課堂[10]——處理器內(nèi)部中斷篇》已經(jīng)對此函數(shù)各參數(shù)的作用有了比較詳細的介紹,在這里我們只講一下會產(chǎn)生疑惑的兩個參數(shù),也就是第一個和最后一個參數(shù)。
第一個參數(shù)設(shè)置要配置的中斷號。這里我們講解一下如何確定這個參數(shù)的值。已知實驗要使用外部按鍵接GPIO觸發(fā)外部中斷,那么我們從按鍵看起。
RV-STAR的按鍵的電路原理圖如下:
可以看到,按鍵接到了PA0引腳上。接下來我們查閱GD32VF103用戶手冊的第六章:中斷/事件控制器(EXTI),發(fā)現(xiàn)PA0對應(yīng)的EXTI中斷源為0號。
由此可知,我們知道本次實驗使用的GPIO引腳PA0對應(yīng)的是EXTI0,所以這里是EXTI0中斷。所有可用的中斷號都在“IRQn_Type”枚舉當中,在gd32vf103.h文件當中可以查看RV-STAR的所有中斷號??梢钥闯?,從19號開始后面的都是外部中斷,如果配置不同的中斷,需要修改此參數(shù)為對應(yīng)的中斷號。
最后一個參數(shù)配置的是中斷處理函數(shù)。直接來看的話,雖然這里寫的是“NULL”,但是并不代表沒有中斷處理函數(shù)。RV-STAR的中斷向量表是存儲在flash當中的,這就意味著運行時不能直接修改其中的數(shù)據(jù),所以在不修改源碼的情況下,RV-STAR不能通過這個參數(shù)修改中斷向量表。這里填寫任何函數(shù),都不會修改這個中斷號對應(yīng)的中斷處理函數(shù)的地址。所以這個參數(shù)寫“NULL”,實際上還是使用中斷向量表里面的默認函數(shù)。
后面的“EXTI0_IRQHandler”函數(shù)就是外部中斷0的默認中斷處理函數(shù)。詳細的中斷向量表可以在startup_gd32vf103.S文件開頭部分查看,這里就不一一列舉。
中斷處理函數(shù)介紹
知道了中斷處理函數(shù)是什么,我們再回到main.c當中,找到“EXTI0_IRQHandler”函數(shù),具體內(nèi)容如下:
[size=0.85em]void EXTI0_IRQHandler(void)
{
if (RESET != exti_interrupt_flag_get(WAKEUP_KEY_PIN)){
if(RESET == gd_rvstar_key_state_get(KEY_WAKEUP)){
/* toggle RED led */
gd_rvstar_led_toggle(LED3);
}
}
/* clear EXTI lines pending flag */
exti_interrupt_flag_clear(WAKEUP_KEY_PIN);
}
中斷處理函數(shù)中開始是按鍵去抖。之后切換LED的狀態(tài),也就是由亮到滅或者由滅到亮。最后一步是清除EXTI0的中斷等待標志。
因為使用的是中斷的非向量處理模式,所以在執(zhí)行中斷處理函數(shù)前會跳轉(zhuǎn)到非向量中斷統(tǒng)一的中斷入口,保存上下文入棧,再跳轉(zhuǎn)至對應(yīng)的中斷處理函數(shù)中執(zhí)行里面的指令,所以函數(shù)內(nèi)不需要手動增加保存上下文和恢復(fù)上下文的操作。
完整實例
為了便于理解外部中斷程序,我們以Nuclei Board Labs中exti_key_interrupt實驗為實例,實際感受一下外部中斷的流程。
新建一個RV-STAR的helloworld工程,具體步驟請參考往期內(nèi)容。
打開Nuclei Board Labs中的exti_key_interrupt文件夾,復(fù)制main.c的內(nèi)容替換之前新建的helloworld工程main.c的內(nèi)容。
工程運行框圖如下:
在main函數(shù)當中,一開始是一系列的初始化內(nèi)容,包括開發(fā)板初始化,外部中斷初始化和ECLIC初始化。
開發(fā)板初始化(Board Config)包含開發(fā)板上LED3初始化和按鍵初始化。
外部中斷初始化(EXTI config)包含按鍵外部中斷初始化,主要是GPIO的配置。
ECLIC初始化(ECLIC config)是之前講的ECLIC初始化函數(shù)。
以上初始化完成后,main函數(shù)執(zhí)行while(1)循環(huán),等待中斷的到來。
當按下PA0按鍵,觸發(fā)外部中斷,進入外部中斷處理函數(shù)當中,按鍵彈起,執(zhí)行LED狀態(tài)轉(zhuǎn)換的功能,最后退出中斷處理函數(shù)。
例子main函數(shù)代碼和對照介紹如下:[size=0.85em]int main(void)
{
int32_t returnCode;
/* Board Config */
gd_rvstar_led_init(LED3);
gd_rvstar_key_init(WAKEUP_KEY_GPIO_PORT,KEY_MODE_EXTI);
/* EXIT config */
key_exti_init();
/* ECLIC config */
returnCode = ECLIC_Register_IRQ(EXTI0_IRQn, ECLIC_NON_VECTOR_INTERRUPT,
ECLIC_LEVEL_TRIGGER, 1, 0, NULL);
/* Enable interrupts in general */
__enable_irq();
while(1);
return 0;
}
實際運行
工程新建完畢,需要在Launchbar工具中切換使用openocd的debug配置,如下圖:
點擊編譯工程,再點擊Debug下拉框切換為Run,點擊開始運行。下載結(jié)束記得點擊關(guān)閉openocd。
最終運行效果如下:
每當按鍵抬起,led的狀態(tài)切換一次。
2025-10-31 07:39:46
?GPIO是通用輸入輸出接口(General Purpose Input Output)的簡稱,是微控制器最基本也是最常用的外設(shè),本期內(nèi)容將介紹GPIO的基本原理,然后通過「點亮LED」與「按鍵控制LED」兩個小實驗帶領(lǐng)大家了解GPIO基本輸出與輸入功能的使用方法。
系統(tǒng)環(huán)境
Windows 10-64bit
軟件平臺
[size=14.6667px]NucleiStudio IDE 202102版
[size=14.6667px]或 PlatformIO IDE
硬件需求
RV-STAR開發(fā)板
GPIO基本原理
GPIO的全稱是通用輸入輸出接口(General Purpose Input/Output),是很多外設(shè)能夠正常工作的基礎(chǔ),MCU上除了一些特定功能的引腳(如電源引腳)外,其他的引腳基本都可以作為GPIO來使用。
GD32VF103的GPIO端口以“組”的形式工作,命名方式為Px(x=A, B, C, D, E···),每組配置有16個引腳。GPIO端口和其他的備用功能(AFs)共用引腳,在特定的封裝下獲得最大的靈活性。
每個GPIO引腳都可以通過軟件配置為輸出(推挽或開漏)、輸入、外設(shè)備用功能或者模擬模式。每個GPIO引腳都可以配置為上拉、下拉或浮空。除模擬模式外,所有的GPIO引腳都具備大電流驅(qū)動能力。
(標準GPIO端口的基本結(jié)構(gòu))
GPIO具有下列特征:
輸入/輸出方向控制
施密特觸發(fā)器輸入功能使能控制
每個引腳都具有弱上拉/下拉功能
推挽/開漏輸出使能控制
置位/復(fù)位輸出使能
可編程觸發(fā)沿的外部中斷——使用EXTI配置寄存器
模擬輸入/輸出配置
備用功能輸入/輸出配置
端口鎖定配置
實驗1:點亮LED
RVSTAR有一個板載的RGB LED,通過PA1、PA2、PA3三個引腳控制LED_G、LED_R、LED_B三個顏色,通過原理圖可以得知:要點亮LED需要通過GPIO引腳輸出一個低電平,當然也可以通過輸出PWM控制三個顏色LED的亮度,進而組合產(chǎn)生不同的顏色。
下面將通過實驗點亮LED_G,并令其以2秒為間隔閃爍:
(RGB LED原理圖 - 1)
(RGB LED原理圖 - 2)
[size=14.6667px]首先參照之前的教程,使用NucleiStudio IDE或PlatformIO IDE創(chuàng)建工程,[size=14.6667px]在main.c文件內(nèi)編寫代碼如下:
/* 實驗1:點亮LED */
#include "nuclei_sdk_hal.h"
void led_config();
void led_on();
void led_off();
int main(void)
{
// 首先對外設(shè)進行初始化操作
led_config();
while (1)
{
led_on();// 點亮LED
delay_1ms(2000); // 延時2秒
led_off(); // 熄滅LED
delay_1ms(2000); // 延時2秒
}
}
void led_config()
{
// 使能GPIOA端口的外設(shè)時鐘
rcu_periph_clock_enable(RCU_GPIOA);
// 將PA1初始化為推挽輸出模式
gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_1);
}
void led_on()
{
// 將輸出引腳置位為0,輸出低電平,燈亮
gpio_bit_reset(GPIOA, GPIO_PIN_1);
}
void led_off()
{
// 將輸出引腳置位為1,輸出高電平,燈熄
gpio_bit_set(GPIOA, GPIO_PIN_1);
}
[size=14.6667px]然后將工程文件進行編譯和上傳,將可以觀察到板載的綠色LED以2秒為間隔進行閃爍。[size=14.6667px]運行結(jié)果如下:
實驗2:按鍵控制LED
[size=14.6667px]實驗1我們使用了GPIO的輸出功能點亮了LED,實驗2將帶領(lǐng)大家[size=14.6667px]使用GPIO的輸入功能:[size=14.6667px]用RVSTAR的板載按鍵控制LED的亮和滅,在使用它之前我們需要了解一點[size=14.6667px]按鍵消抖的知識。
(按鍵的原理圖)
[size=14.6667px]RVSTAR有一個板載的按鍵,連接到了MCU的PA1引腳上,按鍵沒按下時,PA1引腳通過一個下拉電阻接地,處于低電平狀態(tài),按鍵按下時PA1引腳被拉高到3.3V,處于高電平狀態(tài)。由于按鍵是機械結(jié)構(gòu),在按下和彈起的瞬間會產(chǎn)生抖動,即引腳上的電平狀態(tài)不會被立刻拉高或拉低到穩(wěn)定狀態(tài),因此[size=14.6667px]為了能夠準確檢測用戶的按鍵操作[size=14.6667px],往往需要通過一定的方法進行[size=14.6667px]消抖處理[size=14.6667px]:
常用的按鍵消抖方法有硬件消抖和軟件消抖:硬件消抖是通過在按鍵兩端增加電容的方式實現(xiàn)的,成本較高;而軟件消抖是在第一次檢測到電平變化后延時一定時間后再次檢測電平狀態(tài),如果檢測到仍處于按下時的電平狀態(tài),那么說明用戶進行了完整的按鍵操作,這個延時時間跟具體的硬件有關(guān),經(jīng)測試,在RVSTAR的按鍵上大約需要是設(shè)置100毫秒的延時比較合適。
使用NucleiStudio IDE或PlatformIO IDE創(chuàng)建工程,在main.c文件內(nèi)編寫代碼如下:
/* 實驗2:按鍵控制LED */
#include "nuclei_sdk_hal.h"
void led_config();
void led_on();
void led_off();
void key_config();
bit_status key_get_status();
bit_status led_status = 0; // 用來記錄led的當前狀態(tài)
int main(void)
{
led_config();
key_config();
led_off();
while (1)
{
// 第一次檢測按鍵按下
if(key_get_status() == SET)
{
// 軟件延時100ms用以消除抖動
delay_1ms(100);
// 再次檢測按鍵是否按下
if(key_get_status() == SET)
{
switch (led_status)
{
case 0:
led_on();
break;
case 1:
led_off();
break;
default:
break;
}
led_status = !led_status; // 每次按鍵操作后切換led的狀態(tài)
}
}
}
}
void led_config()
{
// 打開GPIOA端口的外設(shè)時鐘
rcu_periph_clock_enable(RCU_GPIOA);
// 將PA1初始化為推挽輸出模式
gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_1);
}
void led_on()
{
// 將輸出引腳置位為0,輸出低電平,燈亮
gpio_bit_reset(GPIOA, GPIO_PIN_1);
}
void led_off()
{
// 將輸出引腳置位為1,輸出高電平,燈熄
gpio_bit_set(GPIOA, GPIO_PIN_1);
}
void key_config()
{
rcu_periph_clock_enable(RCU_GPIOA); // 開啟外設(shè)時鐘
rcu_periph_clock_enable(RCU_AF); // 開啟復(fù)用時鐘
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_0); // 將PA0初始化為浮空輸入模式
}
bit_status key_get_status()
{
// 獲得輸入引腳的狀態(tài),其中bit_status是一個固件庫定義的枚舉類型
return gpio_input_bit_get(GPIOA, GPIO_PIN_0);
}
[size=14.6667px]然后將工程文件進行編譯和上傳,將可以觀察到:上電后LED不亮,每次按下按鍵后LED的狀態(tài)會發(fā)生切換。
運行結(jié)果如下:
實驗完整資料
實驗源碼:https://github.com/Nuclei-Software/nuclei-board-labs/tree/master/rvstar/gpio
原理圖:
https://www.rvmcu.com/quickstart-doc-u-pdf-id-235.html
2025-10-31 07:16:40
PWM(脈沖寬度調(diào)制)可用于電機的調(diào)速、LED的亮度調(diào)節(jié)、無源蜂鳴器輸出音調(diào)等,是嵌入式系統(tǒng)開發(fā)中經(jīng)常采用的方法。本期內(nèi)容以一個用無源蜂鳴器播放音樂的例子,帶領(lǐng)大家了解使用定時器PWM輸出功能的方法。
系統(tǒng)環(huán)境
Windows 10-64bit
軟件平臺
NucleiStudio IDE 202102版
或 PlatformIO IDE
硬件需求
RV-STAR開發(fā)板
無源蜂鳴器
脈沖寬度調(diào)制
脈沖寬度調(diào)制(Pulse Width Modulation,PWM)是利用微控制器的數(shù)字輸出來對模擬電路進行控制的一種非常有效的技術(shù)。
PWM的控制方式就是對逆變電路開關(guān)器件的通斷進行控制,使輸出端得到一系列幅值相等的脈沖,用這些脈沖來代替正弦波或所需要的波形。也就是在輸出波形的半個周期中產(chǎn)生多個脈沖,使各脈沖的等值電壓為正弦波形,所獲得的輸出平滑且低次諧波少。按一定的規(guī)則對各脈沖的寬度進行調(diào)制,既可改變逆變電路輸出電壓的大小,也可改變輸出頻率。其中,一個周期內(nèi)脈沖時間占總時間的比值稱為占空比。
簡言之,如果你想讓電機的速度變慢或者控制的LED變暗,只需降低PWM的占空比,這使得原本需要控制模擬電壓或電流才能達到的效果,通過數(shù)字方式也能夠?qū)崿F(xiàn),這樣可以大幅度降低系統(tǒng)的成本和功耗。
無源蜂鳴器
無源蜂鳴器是很常見的一個電子元件,相信讀者朋友們都見過可以播放生日歌的電子蠟燭,那個就是靠無源蜂鳴器來播放的。無源蜂鳴器的內(nèi)部不帶振蕩源,通過使用50%占空比、頻率500Hz~4.5kHz的PWM驅(qū)動,就可以播放出不同音調(diào)的聲音。
GD32VF103的定時器
GD32VF103的定時器分為三種類型,分別是基本定時器、通用定時器和高級定時器,其中普通定時器和高級定時器都支持PWM輸出功能,在本次的實驗中使用TIMER2(普通定時器)來進行PWM輸出實驗。
實驗部分
首先通過NucleiStudio或者PlatformIO等開發(fā)工具創(chuàng)建工程,然后在工程目錄中添加“tone.h”和“main.c”文件,然后開始進行代碼的編寫。
首先,我們要為蜂鳴器發(fā)出的不同音調(diào)所需要的頻率進行預(yù)先的定義,以下的經(jīng)調(diào)音測試后的D調(diào)的不同音符所對應(yīng)的頻率,直接復(fù)制到“tone.h”中即可:
[size=0.85em]#define NTD0 -1
#define NTD1 293
#define NTD2 329
#define NTD3 368
#define NTD4 390
#define NTD5 438
#define NTD6 492
#define NTD7 554
#define NTDL1 147
#define NTDL2 166
#define NTDL3 185
#define NTDL4 196
#define NTDL5 221
#define NTDL6 248
#define NTDL7 278
#define NTDH1 585
#define NTDH2 657
#define NTDH3 700
#define NTDH4 781
#define NTDH5 882
#define NTDH6 990
#define NTDH7 1112
然后,在“main.c”中,我們要實現(xiàn)三個函數(shù):
buzzer_init() -- 初始化蜂鳴器
buzzer_on(int freq) -- 蜂鳴器根據(jù)頻率發(fā)聲
buzzer_off() -- 關(guān)閉蜂鳴器
下面依次進行講解,首先是buzzer_init(),我們使用的是PB1引腳,它對應(yīng)著TIMER2的CH3通道,要依次使能端口時鐘、復(fù)用時鐘、定時器時鐘,然后把引腳初始化為推挽輸出模式。
[size=0.85em]void buzzer_init()
{
rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_AF);
rcu_periph_clock_enable(RCU_TIMER2);
gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_1);
}
然后是buzzer_on(int freq),它接收不同的頻率參數(shù),對定時器進行配置,輸出50%占空比的不同頻率的PWM波,進而控制蜂鳴器發(fā)聲。實現(xiàn)方法參考下方代碼,其中要注意的是預(yù)分頻系數(shù)、周期以及PWM輸出的占空比等幾個參數(shù)的配置。
[size=0.85em]void buzzer_on(int freq)
{
timer_oc_parameter_struct timer_ocinitpara;
timer_parameter_struct timer_initpara;
timer_deinit(TIMER2);
/* initialize TIMER init parameter struct */
timer_struct_para_init(&timer_initpara);
/* TIMER2 configuration */
timer_initpara.prescaler = 107;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = 1000000 / freq;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TIMER2, &timer_initpara);
/* initialize TIMER channel output parameter struct */
timer_channel_output_struct_para_init(&timer_ocinitpara);
/* CH3 configuration in PWM mode */
timer_ocinitpara.outputstate = TIMER_CCX_ENABLE;
timer_ocinitpara.outputnstate = TIMER_CCXN_DISABLE;
timer_ocinitpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
timer_ocinitpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH;
timer_ocinitpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW;
timer_ocinitpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
timer_channel_output_config(TIMER2, TIMER_CH_3, &timer_ocinitpara);
/* auto-reload preload enable */
timer_auto_reload_shadow_enable(TIMER2);
timer_enable(TIMER2);
/* CH3 configuration in PWM mode1,duty cycle 50% */
timer_channel_output_pulse_value_config(TIMER2, TIMER_CH_3, 500000 / freq);
timer_channel_output_mode_config(TIMER2, TIMER_CH_3, TIMER_OC_MODE_PWM0);
timer_channel_output_shadow_config(TIMER2, TIMER_CH_3, TIMER_OC_SHADOW_DISABLE);
}
第三個函數(shù)buzzer_off(),這個比較簡單,只需復(fù)位定時器即可。
[size=0.85em]void buzzer_off()
{
timer_deinit(TIMER2);
}
最后需要用兩個數(shù)組分別存儲一段音樂的音符、節(jié)拍,這里以“小星星”的前16拍為例,然后在主循環(huán)中對這兩個數(shù)組進行遍歷,就可以實現(xiàn)播放音樂的效果。
[size=0.85em]int notes[] = {
NTD1, NTD1, NTD5, NTD5,
NTD6, NTD6, NTD5,
NTD4, NTD4, NTD3, NTD3,
NTD2, NTD2, NTD1
};
int beats[] = {
1, 1, 1, 1,
1, 1, 2,
1, 1, 1, 1,
1, 1, 2
};
int main()
{
buzzer_init();
int length = sizeof(notes) / sizeof(notes[0]);
while (1) {
for (int i = 0; i < length; i++) {
buzzer_on(notes);
delay_1ms(500 * beats);
buzzer_off();
}
delay_1ms(1000);
}
}
完成代碼編寫后,將無源蜂鳴器的(+)引腳接到RV-STAR開發(fā)板的PB5引腳上,另一個引腳接地,然后編譯、上傳,就可以聽到蜂鳴器播放“小星星”啦~
實驗源碼https://github.com/Nuclei-Software/nuclei-board-labs/tree/master/rvstar/timer/timer_pwmout_buzzer
2025-10-31 06:38:13
面對復(fù)雜多樣的嵌入式通信需求,Air8000 模塊的 CAN 接口開發(fā)尤為重要。本文以實戰(zhàn)為導向,詳細拆解 Air8000 模塊 CAN 接口的開發(fā)流程與配置方法,從環(huán)境搭建到代碼實現(xiàn),再到實際測試,讓你零基礎(chǔ)也能輕松掌握,實現(xiàn)高效、穩(wěn)定的數(shù)據(jù)通信。 ? 一、CAN 概述 ? 控制器局域網(wǎng)(Controller Area Network,CAN)是一種廣泛應(yīng)用于工業(yè)控制、汽車電子等領(lǐng)域的實時通信協(xié)議,由德國博世公司于 1986 年提出并標準化(ISO 11898)。其核心采用多主(Multi-Master)總線架構(gòu)
2025-10-29 14:04:55
256 
?ADC(Analog to Digital Converter,模數(shù)轉(zhuǎn)換器)是指將連續(xù)變化的模擬信號轉(zhuǎn)換為離散的數(shù)字信號的電子器件。ADC可以將真實世界的模擬信號,例如溫度、壓力、聲音等,轉(zhuǎn)換成更容易儲存、處理和發(fā)射的數(shù)字形式,因此被廣泛應(yīng)用在各種產(chǎn)品中。本期我們將通過一個讀取電位器電壓值的小實驗來了解RV-STAR開發(fā)板上ADC的使用方法。
系統(tǒng)環(huán)境
Windows 10-64bit
軟件平臺
NucleiStudio IDE 202102版或 PlatformIO IDE
硬件需求
RV-STAR開發(fā)板
旋轉(zhuǎn)電位器
GD32VF103的ADC外設(shè)
GD32VF103包含一個12位精度的ADC,它是一種采用逐次逼近方式的模擬數(shù)字轉(zhuǎn)換器,它有18個多路復(fù)用通道,可以轉(zhuǎn)換來自16個外部通道和2個內(nèi)部通道的模擬信號。模擬看門狗允許應(yīng)用程序來檢測輸入電壓是否超出用戶設(shè)定的高低閾值。各種通道的A/D轉(zhuǎn)換可以配置成單次、連續(xù)、掃描或間斷轉(zhuǎn)換模式。ADC轉(zhuǎn)換的結(jié)果可以按照左對齊或右對齊的方式存儲再16位寄存器中。片上的硬件過采樣機制可以通過減少來自MCU的相關(guān)計算負擔來提高性能。
高性能:
?可配置12位、10位、8位、或者6位分辨率;
自校準;
可編程采樣時間;
數(shù)據(jù)寄存器可配置數(shù)據(jù)對齊方式;
支持規(guī)則數(shù)據(jù)轉(zhuǎn)換的DMA請求。
模擬輸入通道:
16個外部模擬輸入通道;
1個內(nèi)部溫度傳感通道(VSENSE);
1個內(nèi)部參考電壓輸入通道(VREFINT)。
轉(zhuǎn)換開始的發(fā)起:
軟件;
硬件觸發(fā)。
轉(zhuǎn)換模式:
轉(zhuǎn)換單個通道,或者掃描一序列的通道;
單次模式,每次觸發(fā)轉(zhuǎn)換一次選擇的輸入通道;
連續(xù)模式,連續(xù)轉(zhuǎn)換所選擇的輸入通道;
間斷模式;
同步模式(適用于具有兩個或多個ADC的設(shè)備)。
模擬看門狗。
中斷的產(chǎn)生:
規(guī)則組或注入組轉(zhuǎn)換結(jié)束;
模擬看門狗事件。
過采樣:
16位的數(shù)據(jù)寄存器;
可調(diào)整的過采樣率,從2x到256x;
高達8位的可編程數(shù)據(jù)移位。
ADC供電要求:2.6V到3.6V,一般電源電壓為3.3V。
ADC輸入范圍:VREF- ≤VIN ≤VREF+。
實驗部分
本次實驗使用的外設(shè)部件為旋轉(zhuǎn)電位器,它是一個典型的模擬器件,通過旋轉(zhuǎn)旋鈕可以輸出0到供電電壓VCC之間的模擬量。
通過查閱電路原理圖得知,RV-STAR的PC0引腳對應(yīng)著一個ADC復(fù)用通道,我們使用它來連接旋轉(zhuǎn)電位器外設(shè),連線參考如下表:
RV-STAR旋轉(zhuǎn)編碼器
PC0OUT
3V3VCC
GNDGND
旋轉(zhuǎn)編碼器的供電一定要接3V3不能接5V,否則可能因為輸入電壓過高而燒壞芯片。
完成電路連線之后就可以創(chuàng)建工程開始編寫代碼了,首先需要定義一系列的配置函數(shù),用于初始化時鐘、外設(shè)引腳和進行ADC的配置:
void rcu_config(void)
{
rcu_periph_clock_enable(RCU_GPIOC);
rcu_periph_clock_enable(RCU_ADC1);
rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV8);
}
void gpio_config(void)
{
gpio_init(GPIOC, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_0);
}
void adc_config(void)
{
/* reset ADC */
adc_deinit(ADC1);
/* ADC mode config */
adc_mode_config(ADC1, ADC_MODE_FREE);
/* ADC scan function enable */
adc_special_function_config(ADC1, ADC_SCAN_MODE, ENABLE);
/* ADC contineous function enable */
adc_special_function_config(ADC1, ADC_CONTINUOUS_MODE, ENABLE);
/* ADC data alignment config */
adc_data_alignment_config(ADC1, ADC_DATAALIGN_RIGHT);
/* ADC channel length config */
adc_channel_length_config(ADC1, ADC_REGULAR_CHANNEL, 1);
adc_external_trigger_source_config(ADC1, ADC_REGULAR_CHANNEL, ADC0_1_EXTTRIG_REGULAR_NONE);
adc_external_trigger_config(ADC1, ADC_REGULAR_CHANNEL, ENABLE);
delay_1ms(1);
adc_enable(ADC1);
adc_calibration_enable(ADC1);
adc_software_trigger_enable(ADC1, ADC_REGULAR_CHANNEL);
adc_regular_channel_config(ADC1, 0, ADC_CHANNEL_10, ADC_SAMPLETIME_55POINT5);
}
其中,我們使用的PC0管腳對應(yīng)著ADC1的通道10,編寫配置函數(shù)的時候要注意,另外在本應(yīng)用中,ADC被配置為獨立的連續(xù)掃描模式,使用常規(guī)通道觸發(fā)(即軟件觸發(fā))。
在主函數(shù)中,周期性的讀取ADC的值,然后打印到串口終端,對應(yīng)的代碼如下:
#include "nuclei_sdk_hal.h"
#include
void rcu_config(void);
void gpio_config(void);
void adc_config(void);
uint16_t adc_value;
int main(void)
{
rcu_config();
gpio_config();
adc_config();
gd_com_init(GD32_COM0);
while (1) {
delay_1ms(1000);
adc_value = adc_regular_data_read(ADC1);
printf("rn ADC1 regular channel 10 data = %d rn", adc_value);
printf("rn ***********************************rn");
}
}
以上就是完整的代碼內(nèi)容,完成后,將RV-STAR開發(fā)板連接到電腦,編譯并上傳代碼,打開串口終端,旋轉(zhuǎn)電位器旋鈕,可以觀察到打印到串口終端的讀數(shù)發(fā)生了改變,說明ADC功能正常開啟。
實驗源碼:https://github.com/Nuclei-Software/nuclei-board-labs/tree/master/rvstar/adc/adc_regular_scan
2025-10-29 06:56:24
本文將分享我們團隊提高E203軟核主頻的辦法。
查閱芯來科技官方出版的《手把手教你設(shè)計CPU——RISC-V處理器篇》教材,我們發(fā)現(xiàn),原本設(shè)計的E203主時鐘域應(yīng)該是100MHZ
2025-10-29 06:19:19
看門狗定時器(Watch Dog Timer,WDT或WDGT),是一種微控制器為了防止程序“跑飛”而設(shè)計的一種硬件機制,讓系統(tǒng)在因電磁干擾或者軟件錯誤而當機的時候可以復(fù)位系統(tǒng),從而具備自修復(fù)的能力。本期內(nèi)容將帶領(lǐng)大家了解看門狗的基本原理和RV-STAR的獨立看門狗(FWDGT)的使用方法。
系統(tǒng)環(huán)境
Windows 10-64bit
軟件平臺
NucleiStudio IDE 202102版或 PlatformIO IDE
硬件需求
RV-STAR開發(fā)板
看門狗定時器的基本原理
看門狗定時器實際上一個計數(shù)器,在計數(shù)溢出時會產(chǎn)生一個復(fù)位信號,正常情況下首先給看門狗定時器設(shè)置一個超時時間,然后程序在超時時間內(nèi)定期對定時器進行重載操作(也叫做“喂狗”操作),從而避免正常程序發(fā)生復(fù)位。
當系統(tǒng)發(fā)生意料之外的故障使得軟件跑飛,看門狗定時器無法被按時重載時,看門狗硬件就會產(chǎn)生一個系統(tǒng)復(fù)位,讓系統(tǒng)重新運行,從而達到恢復(fù)功能的效果。
GD32VF103的獨立看門狗定時器(FWDGT)
獨立看門狗定時器(FWDGT)具有獨立的時鐘源(IRC40K)。因此就算主時鐘失效的,它仍然能保持工作狀態(tài),這適用于需要獨立環(huán)境且對計時精度要求不高的場合。
當內(nèi)部向下計數(shù)器的值達到0,獨立看門狗會產(chǎn)生一個復(fù)位。使能獨立看門狗的寄存器寫保護功能可以避免寄存器的值被意外的配置篡改。
主要特性:
自由運行的12位向下計數(shù)器
如果看門狗定時器被使能,那么當向下計數(shù)器的值達到0時產(chǎn)生系統(tǒng)復(fù)位;
獨立時鐘源,獨立看門狗定時器在主時鐘故障時仍能工作;
獨立看門狗定時器硬件控制位,可以用來控制是否在上電時自動啟動看門狗定時器;
可以配置獨立看門狗定時器在調(diào)試模式下選擇停止還是繼續(xù)工作。
實驗部分
FWDGT實驗的思路如下:
首先對系統(tǒng)進行初始化操作,然后讓紅色的LED點亮50ms(用于指示系統(tǒng)發(fā)生了復(fù)位),接著將FWDGT的超時時間設(shè)置為1000ms(非精確),然后在主函數(shù)中每間隔900ms做一次FWDGT計數(shù)器重載防止其復(fù)位,并且用綠色LED狀態(tài)切換表示程序正在運行(FWDGT沒有復(fù)位)。
同時用KEY_WKUP按鍵連線的中斷線來模擬一個軟件故障,當該按鍵被按下時觸發(fā)中斷服務(wù),在該中斷服務(wù)程序中寫入一個點亮藍色LED并進入while(1)的死循環(huán)來模擬軟件跑飛,不能返回主程序。這樣FWDGT計數(shù)器不能及時被重載,當計數(shù)值到0時,發(fā)生FWDGT復(fù)位,在系統(tǒng)復(fù)位后,通過點亮紅色LED來指示FWDGT發(fā)生。
完整的實現(xiàn)代碼如下:
#include "nuclei_sdk_hal.h"
uint32_t millis(void);
uint32_t start = 0;
uint32_t now = 0;
int main()
{
/* enable IRC40K */
rcu_osci_on(RCU_IRC40K);
/* wait till IRC40K is ready */
while (SUCCESS != rcu_osci_stab_wait(RCU_IRC40K)) ;
/* confiure FWDGT counter clock: 40KHz(IRC40K) / 64 = 0.625 KHz */
fwdgt_config(625, FWDGT_PSC_DIV64);
/* after 1 seconds to generate a reset */
fwdgt_enable();
gd_rvstar_led_init(LED1);
gd_rvstar_led_init(LED2);
gd_rvstar_led_init(LED3);
gd_rvstar_led_on(LED3);
delay_1ms(50);
gd_rvstar_led_off(LED3);
start = millis();
gd_rvstar_key_init(KEY_WAKEUP, KEY_MODE_EXTI);
__enable_irq();
while (1) {
now = millis();
if (now - start >= 900) {
fwdgt_counter_reload();
start = now;
}
/* toggle green led */
gd_rvstar_led_toggle(LED1);
delay_1ms(100);
}
}
void EXTI0_IRQHandler(void)
{
if (RESET != exti_interrupt_flag_get(WAKEUP_KEY_EXTI_LINE)) {
if (RESET == gd_rvstar_key_state_get(KEY_WAKEUP)) {
gd_rvstar_led_off(LED1);
gd_rvstar_led_on(LED2);
while (1);
}
}
/* clear EXTI lines pending flag */
exti_interrupt_flag_clear(WAKEUP_KEY_EXTI_LINE);
}
/**
* brief Returns the number of milliseconds since the board began running the current program.
*
* return Number of milliseconds since the program started (uint32_t)
*/
uint32_t millis(void)
{
return (uint32_t)(SysTimer_GetLoadValue() * (4000.F / SystemCoreClock));
}
在IDE中創(chuàng)建工程,將上述代碼編譯上傳到開發(fā)板,可以觀察到,開發(fā)板的板載LED短暫閃了下紅色后,開始進入持續(xù)的綠色快速閃爍狀態(tài),當按下WKUP按鍵后,LED開始亮藍色,持續(xù)不到1s后,又閃了下紅色后然后進入持續(xù)的綠色快速閃爍狀態(tài),說明看門狗起到了作用使系統(tǒng)發(fā)生了復(fù)位。?
實驗源碼:
https://github.com/Nuclei-Software/nuclei-board-labs/tree/master/rvstar/wdgt/fwdgt_key_int
2025-10-29 06:01:39
前言:在嵌入式開發(fā)中,一個小小的接口問題往往會卡殼半天,尤其是像HDMI熱插拔這種和硬件、內(nèi)核驅(qū)動都掛鉤的場景。最近調(diào)試T527板卡時,就遇到了HDMI熱插拔失靈的麻煩,經(jīng)過一番排查終于解決,今天把整個過程整理成筆記,希望能幫到有同樣困擾的朋友。一、明確HDMI“失效”現(xiàn)象在開始排查前,得先把問題現(xiàn)象摸透。這次遇到的HDMI問題主要集中在“插拔檢測”上,具體
2025-10-17 08:32:25
994 
在 BUCK 電源設(shè)計中,MOS 管的 “快開快關(guān)” 是減少損耗的關(guān)鍵,而實現(xiàn)這一需求的核心,離不開前級驅(qū)動與滯回比較器的精妙配合。今天我們就從電路搭建到參數(shù)計算,手把手教你搞定 BUCK 電源的滯回電路,即使是新手也能跟著一步步實操!
2025-10-16 11:03:33
2364 
本開發(fā)指南將手把手幫工程師們了解芯片的各個模塊,對照手冊熟悉各個模塊的寄存器配置。同時,分享一些常見的錯誤用法,助您規(guī)避誤區(qū),從而提高開發(fā)效率。
2025-10-07 09:15:00
858 
以下文章內(nèi)容由CW32生態(tài)社區(qū)用戶End提供: https://gitee.com/xcet/embedded-cw32-board-template/tree/master/ref/CW32-GCC-Clion-Template 最近 CLion 對非商業(yè)用途免費了,我立馬下載了最新的CLion2025,現(xiàn)在針國產(chǎn)武漢芯源半導體的 CW32單片機 搭建CLion+GCC+ CMake 開發(fā)環(huán)境。 CLion是一款由JetBrains開發(fā)的跨平臺集成開發(fā)環(huán)境(IDE),專門為C和C++設(shè)計。以其智能編碼輔助、易用的項目管理和強大的內(nèi)置工具(如調(diào)試器、靜態(tài)分析工具、單元測試框架)而著稱,支持遠程協(xié)作和嵌入式開發(fā)
2025-09-29 18:00:31
6699 
BLE藍牙配網(wǎng)如何兼顧便捷性與穩(wěn)定性?STA+SoftAP雙模式給出最優(yōu)解。下面從技術(shù)原理到實戰(zhàn)案例,手把手教你搭建雙模式配網(wǎng)系統(tǒng),無需復(fù)雜代碼,輕松實現(xiàn)設(shè)備快速聯(lián)網(wǎng),小白也能秒變專家。
2025-09-20 15:20:43
1307 
一、IO調(diào)試方法使用組態(tài)軟件在線數(shù)據(jù)監(jiān)控功能進行第三方ProfinetIO或Profinet網(wǎng)關(guān)調(diào)試,通過西門子(STEP7-MicroWINSMART、TIAPortal)和Codesys進行調(diào)試驗證。1.1STEP7-MicroWINSMART平臺在使用STEP7-MicroWINSMART平臺調(diào)試ProfinetIO時,需先借助S7-200PLC才可進
2025-09-18 19:33:00
1657 
,我們就整理了一版超詳細的手把手開發(fā)教程,從架構(gòu)解析、代碼實戰(zhàn),到知識庫配置與智能體調(diào)試,流程完善、操作門檻低!大家也可以根據(jù)實際場景需求,大膽發(fā)揮想象,自定義開
2025-09-12 17:40:07
1702 
H100服務(wù)器停工一天損失的算力成本可能比維修費還高。今天,我們給大家總結(jié)一套“防掉卡秘籍”,從日常管理到環(huán)境把控,手把手教你把掉卡風險壓到最低。一、供電是“生命線”,這3點必須盯緊H100滿載功耗
2025-09-05 11:03:06
855 
我司產(chǎn)品ECAN-E02擁有MQTT工作模式,在此工作模式下,可以選擇使用阿里云平臺進行相關(guān)測試與通信。1MQTT工作模式概述首先讓我們了解一下什么是MQTT工作模式。MQTT(MessageQueuingTelemetryTransport)是一種輕量級的消息傳輸協(xié)議,特別適用于物聯(lián)網(wǎng)(IoT)和資源受限的環(huán)境。相較于傳統(tǒng)的請求-響應(yīng)模式,發(fā)布-訂閱(Pu
2025-09-04 19:34:20
1214 
無論你的技術(shù)背景如何,本教程都將以手把手的方式,拆解AT指令A(yù)PN設(shè)置的全流程。專網(wǎng)連接不再是門檻,即刻開啟自主配置之旅! APN是設(shè)備連接到運營商網(wǎng)絡(luò)的“身份證” ——當設(shè)備插入SIM卡并注冊到
2025-09-04 14:40:47
875 
我們正在參加全球電子成就獎的評選,歡迎大家?guī)臀覀兺镀薄x謝支持來源:內(nèi)容由半導體行業(yè)觀察編譯自semiengineeringChiplet是一種滿足持續(xù)增長的計算能力和I/O帶寬需求的方法,它將SoC功能拆分成更小的異構(gòu)或同構(gòu)芯片(稱為芯片集),并將這些Chiplet集成到單個系統(tǒng)級封裝(SIP)中,其中總硅片尺寸可能超過單個SoC的光罩尺寸。SIP不僅
2025-09-04 11:51:37
643 
宏集MC系列模塊化控制器是基于RaspberryPi的高性能4核控制器,運動控制循環(huán)時間最快可達500微秒,實現(xiàn)了計算能力和成本之間的最佳平衡,適用于多軸運動控制和CNC控制。教程目的本系列教程將使用宏集MC系列控制器,詳細介紹通過CODESYSV3來進行PLC測試編程的步驟,旨在使初次接觸宏集MC系列控制器的使用者了解該板卡的連接、配置、調(diào)試。通過該教程的
2025-08-26 17:31:25
1030 
在云原生時代,存儲是制約應(yīng)用性能的關(guān)鍵瓶頸。本文將帶你深入理解K8s存儲類的設(shè)計原理,并手把手實現(xiàn)與Ceph的完美集成,讓你的集群存儲性能提升300%!
2025-08-22 11:50:09
698 車載以太網(wǎng)時間同步精度不足?gPTP協(xié)議實現(xiàn)±50ns級同步革命!本文深度剖析gPTP協(xié)議在自動駕駛多傳感器融合中的關(guān)鍵作用,從硬件選型到LinuxPTP工具鏈配置,手把手教你搭建高精度時間同步系統(tǒng)!
2025-08-20 11:39:26
2024 
ISO 26262合規(guī)指南,從ASIL分級到工具落地,手把手教你用靜態(tài)代碼分析(Perforce QAC)實現(xiàn)高效合規(guī)。
2025-08-07 17:33:55
970 
認識頻率漂移 一 、 頻率漂移的概念 頻率漂移,簡單來說,就是晶振實際輸出頻率和標稱頻率之間出現(xiàn)了偏差。就好比你買了一個標稱每分鐘擺動60次的擺鐘,但實際使用時,它每分鐘可能擺動61次或者59次,這多出來或者少掉的擺動次數(shù),就類似于晶振的頻率漂移。在電子設(shè)備中,晶振就如同一個精準的時鐘,為整個系統(tǒng)提供穩(wěn)定的頻率信號,一旦出現(xiàn)頻率漂移,就相當于這個時鐘走不準了。 二 、 漂移帶來的嚴重后果 別小看這小小的頻率漂移,它可
2025-07-25 16:36:22
544 E104-BT01是成都億佰特電子科技有限公司基于德州儀器(TI)CC2541射頻芯片研發(fā)的符合藍牙協(xié)議5.0的模塊,該模塊主從一體,可實現(xiàn)模塊點對點間的藍牙連接,實現(xiàn)模塊間數(shù)據(jù)透傳,支持串口指令配置模塊參數(shù)和功能。廣泛應(yīng)用于智能穿戴、家庭自動化、家庭安防、個人保健、智能家電、配飾與遙控器、汽車、照明、工業(yè)互聯(lián)網(wǎng)、智能數(shù)據(jù)采集、智能控制等領(lǐng)域。本文將通過模塊
2025-07-24 19:33:33
1399 
在現(xiàn)代工業(yè)自動化控制領(lǐng)域,實現(xiàn)PLC無線控制可以帶來更高的靈活度和便利性。PLC可以配備無線通訊模塊,這些模塊可以直接與PLC連接,能夠與觸摸屏或上位機等其他設(shè)備或系統(tǒng)進行無線通信,實現(xiàn)數(shù)據(jù)的傳輸和控制命令的發(fā)送。 PLC無線控制模塊采用全數(shù)字加密無線傳輸技術(shù),應(yīng)用范圍覆蓋冶煉、化工、新能源、石油等16大工業(yè)行業(yè),在復(fù)雜惡劣環(huán)境中平均連續(xù)使用壽命超過8年。以下是兩例無線通訊模塊在工業(yè)現(xiàn)場實現(xiàn)PLC無線控制的典型應(yīng)用: 一、無
2025-07-24 17:07:27
414 
VGLite是NXP提供的輕量級2D圖形API,本文將手把手帶你實現(xiàn)VGLite圖形驅(qū)動適配RT-Thread。文章分為上、下兩篇,將手把手教您移植。上篇對RT-ThreadNano內(nèi)核與Finsh組件進行移植,下篇則教您改寫SDK中的VGLite代碼以將其適配到RT-ThreadNano中。
2025-07-17 14:40:47
3160 
零基礎(chǔ)搭建本次實驗將會使用到的軟件是Keil和STM32CubeMX,沒有這兩個軟件沒有請在網(wǎng)上自行下載。本章節(jié)零基礎(chǔ)手把手教會你搭建最快捷、最簡單的STM32代碼
2025-07-03 19:32:31
1190 
《手把手教你做PC》系列直播課再度開播!《KaihongOS筆記本電腦開發(fā)實戰(zhàn)第十二課:WIFI驅(qū)動框架適配》將于07月02日19:00開播↑掃碼入群,領(lǐng)課程講義資料包↑深開鴻資深工程師親臨直播間
2025-07-01 08:08:03
454 
感謝大家對Splashtop的熱情關(guān)注!目前我們的應(yīng)用已在蘋果AppStore及安卓GooglePlay全面上線。但由于上架審核需要一定的時間,所以暫時未登陸國內(nèi)應(yīng)用市場。不過,別擔心,今天這份詳細指南將手把手教你如何在國內(nèi)安
2025-06-27 17:01:24
534 
項目越大,越需要靠譜的版本控制系統(tǒng)。Perforce P4不僅是Epic官方推薦的源代碼控制工具,更是大廠團隊協(xié)作的核心支持之一。如何配置P4+UE?手把手教你怎么用↓↓↓
2025-06-25 11:22:11
1247 
識別三個維度,手把手教你高效完成防護器件選型!一、選型必看:核心參數(shù)解析不同防護器件的參數(shù)差異較大,抓住關(guān)鍵參數(shù)才能精準匹配客戶的需求:TVS(瞬態(tài)電壓抑制二極管)
2025-06-11 14:19:42
683 
《手把手教你做星閃無人機》系列直播課再度開播!《KaihongOS星閃無人機開發(fā)實戰(zhàn)⑩:KaihongOSLite系統(tǒng)專題》↑掃碼入群,領(lǐng)課程講義資料包↑深開鴻資深工程師親臨直播間依托筆電實戰(zhàn)產(chǎn)品
2025-06-10 08:06:24
427 
使用BasicStation或PiWAN連接到TheThingsNetwork將樹莓派設(shè)置為LoRaWAN網(wǎng)關(guān)乍一看可能令人望而生畏,但有了合適的工具和指導,它就會成為一個有意義的DIY網(wǎng)絡(luò)項目。在本文中,我們將介紹如何使用手動構(gòu)建的BasicStation或基于Docker的PiWAN堆棧將樹莓派連接到TheThingsNetwork(TTN)。但首先,什
2025-06-09 16:23:40
1778 
如果您對遠程errDump調(diào)試功能感到陌生,本教程將通過一步步操作演示,教您如何配置遠程日志采集、解析errDump文件,以及定位關(guān)鍵錯誤信息,讓您輕松獨立完成調(diào)試任務(wù)。 下文特別分享errDump功能及Air8101開發(fā)板實操驗證。 一、errDump功能介紹 1.1 errDump有什么用? errDump是LuatOS系統(tǒng)中的錯誤日志上報模塊,主要用于遠程調(diào)試與故障診斷。 其原理是將模塊運行過程中產(chǎn)生的錯誤信息或者應(yīng)用日志,通過TCP/UDP上報到互聯(lián)網(wǎng)上的指定服務(wù)器,技術(shù)人員可以在服
2025-06-05 18:32:53
1005 
在高并發(fā)網(wǎng)絡(luò)服務(wù)場景中,Linux內(nèi)核的默認網(wǎng)絡(luò)參數(shù)往往無法滿足需求,導致性能瓶頸、連接超時甚至服務(wù)崩潰。本文基于真實案例分析,從參數(shù)解讀、問題診斷到優(yōu)化實踐,手把手教你如何調(diào)優(yōu)Linux網(wǎng)絡(luò)參數(shù),支撐百萬級并發(fā)連接。
2025-05-29 09:21:13
758 《手把手教你做星閃無人機》系列直播課再度開播!《KaihongOS星閃無人機開發(fā)實戰(zhàn)⑨:無線通信編程之SLE專題》↑掃碼入群,領(lǐng)課程講義資料包↑深開鴻資深工程師親臨直播間依托筆電實戰(zhàn)產(chǎn)品案例細致剖析
2025-05-27 08:05:45
418 
MIMO設(shè)備功率測量太復(fù)雜?TS-RadiMation幫你一鍵搞定!本文詳細解析MIMO功率測量全流程,從配置到數(shù)據(jù)分析,助你快速掌握關(guān)鍵測試技巧,提升測試效率!
2025-05-26 17:42:05
593 
《手把手教你做PC》系列直播課再度開播!《KaihongOS筆記本電腦開發(fā)實戰(zhàn)第九課:全功能TypeC驅(qū)動框架適配》將于5月21日19:00開播↑掃碼入群,領(lǐng)課程講義資料包↑深開鴻資深工程師親臨直播
2025-05-20 08:07:51
496 
正點原子Linux系列全新視頻教程來啦!手把手教你MP257開發(fā)板,讓您輕松入門!
一、視頻觀看
正點原子手把手教你學STM32MP257-第1期:https://www.bilibili.com/video/BV1UtEizyE7Z
二、更多詳細介紹
2025-05-16 10:42:23
針對全棧開發(fā)者設(shè)計的實戰(zhàn)教程,本文聚焦LuatOS平臺log庫的高效使用,從基礎(chǔ)配置到高級調(diào)試策略,手把手教你搭建可擴展的日志系統(tǒng),提升項目維護效率。 今天,我們一起來認識LuatOS的log庫
2025-05-12 15:23:30
1380 
都會覺得無從下手。別擔心!這篇文章將用通俗易懂的方式,帶你了解 CentOS 中的防火墻配置,并通過一個實際案例,手把手教你如何正確設(shè)置防火墻規(guī)則。
2025-05-08 11:52:03
978 
《手把手教你做PC》系列直播課再度開播!《KaihongOS筆記本電腦開發(fā)實戰(zhàn)⑦:Audio音頻驅(qū)動框架適配》將于4月23日19:00開播↑掃碼入群,領(lǐng)課程講義資料包↑深開鴻資深工程師親臨直播間依托
2025-04-22 08:05:41
493 
注意事項,從安裝準備到后期維護,手把手教你正確操作,確保監(jiān)測數(shù)據(jù)真實可靠!一、安裝前:做好3項準備,事半功倍1.檢查設(shè)備完整性開箱驗貨:核對測縫計型號、配件(護管、
2025-04-21 15:31:47
461 
困惑。別擔心!接下來南京峟思手把手教你正確使用VW-102A讀數(shù)儀,快速獲取精準數(shù)據(jù)!一、VW-102A讀數(shù)儀是什么?為什么需要它?VW-102A讀數(shù)儀是專門為振
2025-04-21 14:28:41
638 
總結(jié),手把手教你逆襲甩鍋。Modbus TCP常見問題主要包括連接建立、錯誤代碼識別、數(shù)據(jù)處理和地址沖突等。 以下是一些常見問題的解答: 問題一: 如何判斷Modbus TCP連接是否建立? 答:進行
2025-04-16 17:17:57
1259 
;HelloWorld"到"Hey,AI"記得剛?cè)胄袝r,點亮一個LED燈都激動半天。如今,我們的嵌入式設(shè)備已經(jīng)可以直接和AI大模型對話了!這不僅是技術(shù)的進步,更是開發(fā)思路的革命。今天,我將手把手教大家如何在開發(fā)板上接
2025-04-11 18:19:08
1889 
博主好!致敬葉濤 管鍇 張心雨三位AI具身智能-智能體方面的專家、導師!
《零基礎(chǔ)開發(fā)AI Agent——手把手教你用扣子做智能體》一不懂編程的多數(shù)大眾也可以開發(fā)Agent,這意義深遠,功德無量
2025-04-10 12:16:28
一、物理層深度剖析 1.1 差分信號的本質(zhì) CAN總線采用****雙線差分傳輸 ,核心原理圖解: markdown CAN_H ────── /───────── / ___ / CAN_L ──────/ ───────── 顯性狀態(tài)(Dominant) :CAN_H電壓 ≥ 2.5V,CAN_L ≤ 1.5V → 差值≥1V 隱性狀態(tài)(Recessive) :CAN_H/CAN_L均為2.5V → 差值≈0V 物理層參數(shù)對照表 : 參數(shù) 標準值 測試方法 終端電阻 120Ω ±1% 萬用表直接測量 最大傳輸距離 10km @ ≤5Kbps 示波器+時延測試儀 波特率容差 ±1% 專用CAN分析儀
2025-04-10 11:10:29
1054 一、物理層深度剖析
1.1 差分信號的本質(zhì)
CAN總線采用****雙線差分傳輸,核心原理圖解:
markdown
CAN_H ──────\\\\ /─────────
\\\\/
\\\\___/
CAN_L ──────/\\\\─────────
顯性狀態(tài)(Dominant):CAN_H電壓 ≥ 2.5V,CAN_L ≤ 1.5V → 差值≥1V
隱性狀態(tài)(Recessive):CAN_H/CAN_L均為2.5V → 差值≈0V
物理層參數(shù)對照表:
參數(shù)
標準值
測試方法
終端電阻
120Ω ±1%
萬用表直接測量
最大傳輸距離
10km @ ≤5Kbps
示波器+時延測試儀
波特率容差
±1%
專用CAN分析儀
共模電壓抑制
±2V
隔離示波器測量
1.2 波特率計算公式
markdown
位時間 = 同步段 + 傳播時間段 + 相位緩沖段1 + 相位緩沖段2
總位數(shù) = 同步段(SJW) + 時間段1(TS1) + 時間段2(TS2)
STM32配置示例(500Kbps):
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ; // 同步跳轉(zhuǎn)寬度=1TQ
hcan1.Init.TimeSeg1 = CAN_BS1_9TQ;// 時間段1=9TQ
hcan1.Init.TimeSeg2 = CAN_BS2_4TQ;// 時間段2=4TQ
// 總位時間=1+9+4=14TQ → 時鐘頻率=8MHz → TQ=0.125μs → 波特率=1/(14 * 0.125μs)=500Kbps
1.3 終端電阻調(diào)試技巧
錯誤現(xiàn)象:總線波形畸變、通信不穩(wěn)定
檢測方法:
斷電測量總線兩端電阻(應(yīng)為120Ω±5%)
上電后用示波器觀察終端反射波形
解決方案:
# 終端電阻計算公式(單位Ω)
def calc_termination_resistance(length):
# 每米電纜約60Ω特性阻抗
return 120 - (length * 60) / 1000
# 示例:總線長度40m → 120 - 24 = 96Ω → 需補48Ω電阻
二、數(shù)據(jù)鏈路層全解析(幀結(jié)構(gòu)+仲裁機制)
2.1 CAN幀類型對比表
幀類型
標識符長度
用途
DLC最大值
標準幀
11位
普通數(shù)據(jù)傳輸
8字節(jié)
擴展幀
29位
復(fù)雜設(shè)備通信
8字節(jié)
遠程幀
11/29位
請求數(shù)據(jù)
-
錯誤幀
-
錯誤通知
-
2.2 經(jīng)典仲裁過程演示
場景:三個節(jié)點同時發(fā)送數(shù)據(jù)
markdown
節(jié)點A: ID=0x100 (0b000100000000)
節(jié)點B: ID=0x200 (0b001000000000)
節(jié)點C: ID=0x080 (0b000010000000)
仲裁過程:
第一位:全顯性 → 繼續(xù)比較
**第二位:A=0, B=0, C=1 → C失去仲裁權(quán)**
后續(xù)位比較后,A勝出總線使用權(quán)
STM32仲裁配置要點:
// 使能自動重傳功能(默認開啟)
hcan1.Init.AutoRetransmission = ENABLE;
// 設(shè)置重試次數(shù)(最大16次)
hcan1.Init.RetryCount = 3;
2.3 錯誤檢測機制詳解
五級錯誤防護體系:
CRC校驗:15位循環(huán)冗余校驗
位填充:每5個相同電平插入相反電平
ACK校驗:接收節(jié)點必須發(fā)送顯性確認
幀格式校驗:7個保留位必須為隱性
總線監(jiān)控:持續(xù)檢測總線邏輯電平
錯誤計數(shù)器動態(tài)調(diào)整算法:
markdown
當檢測到錯誤時:
TEC += 8(發(fā)送錯誤)或 REC += 1(接收錯誤)
當TEC > 127時:進入總線關(guān)閉狀態(tài)
2.4 位時間同步技術(shù)
同步機制:
硬同步:在幀起始位強制對齊
重新同步:通過調(diào)整時間段2補償時鐘偏差
STM32時間參數(shù)配置示例:
// 配置同步跳轉(zhuǎn)寬度為1個時間量子
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
?
// 時間段分配(假設(shè)系統(tǒng)時鐘16MHz)
CAN_BtrTypeDef sCanBtr;
sCanBtr.SyncJumpWidth = CAN_SJW_1TQ;
sCanBtr.TimeSeg1 = CAN_BS1_9TQ;// 傳播延遲補償
sCanBtr.TimeSeg2 = CAN_BS2_4TQ;// 相位緩沖
三、數(shù)據(jù)鏈路層核心機制
3.1 CAN協(xié)議棧全景圖
應(yīng)用層(CANopen/J1939)
↓
網(wǎng)絡(luò)層(路由/錯誤處理)
↓
數(shù)據(jù)鏈路層(幀結(jié)構(gòu)/仲裁)
↓
物理層(差分信號/終端電阻)
3.2 幀結(jié)構(gòu)深度拆解
標準幀格式(11位ID):
| 仲裁場(11b) | 控制場(6b) | 數(shù)據(jù)場(0-8B) | CRC場(15b) | ACK場(1b) | 幀結(jié)束(7b) |
仲裁場:包含節(jié)點ID和幀類型標識
控制場:DLC(數(shù)據(jù)長度碼) + IDE(擴展標識符)
CRC場:15位循環(huán)冗余校驗(生成多項式:x1?+x1?+...+1)
STM32 CRC配置示例:
// CAN1 CRC初始化
hcan1.Instance->CRCD = 0xFFFF; // 初始值
hcan1.Instance->CRCSA = 0x0000;// 起始地址
3.3 仲裁機制詳解
29位擴展幀仲裁過程:
優(yōu)先級位 → 源地址 → 參數(shù)組號(PGN)
優(yōu)先級計算:ID31-ID26位決定(數(shù)值越小優(yōu)先級越高)
源地址沖突檢測:同一網(wǎng)絡(luò)內(nèi)節(jié)點地址必須唯一
仲裁時序仿真:
def can_arbitration(id_list):
sorted_ids = sorted(id_list, key=lambda x: bin(x).count(\'1\'))
return sorted_ids[0]
?
# 示例:三個節(jié)點同時發(fā)送
nodes = [0x18FEF100, 0x18FEF200, 0x18FEF300]
winner = can_arbitration(nodes)# 輸出0x18FEF100
四、CANopen協(xié)議深度實戰(zhàn)
4.1 對象字典(Object Dictionary)
OD結(jié)構(gòu)示例:
索引類型描述
0x2000ARRAY 電機控制參數(shù)
0x2000[0]UINT16目標轉(zhuǎn)速(rpm)
0x2000[1]FLOAT 加速度(m/s2)
0x2001RECORD故障代碼
0x2001[0]BITFIELD 故障標志位
STM32 SDO傳輸實現(xiàn):
// SDO客戶端上傳數(shù)據(jù)
void SDO_Upload(uint16_t index, uint8_t subindex) {
CO_SDO_Req req;
CO_SDO_ReqInit(&req);
req.Cmd = CO_SDO_CMD_UPLOAD_REQ;
req.Index = index;
req.SubIndex = subindex;
if (CO_SDO_Transmit(&req) == CO_SDO_OK) {
Process_SDO_Response(req.Data);
}
}
4.2 NMT網(wǎng)絡(luò)管理
狀態(tài)遷移圖:
INIT → PRE-OPERATIONAL → OPERATIONAL → STOPPED
↑↑↓
└──RESET←───────────────────┘
心跳報文配置:
// 心跳生產(chǎn)者配置
CO_NMT_HeartbeatConfig(0x01, 0x00, 500);// 節(jié)點ID=1,周期500ms
五、J1939協(xié)議核心要點
5.1 參數(shù)組號(PGN)編碼規(guī)則
PGN = PF(8b) << 8 | PS(8b)
PF: 參數(shù)組功能(0-255)
PS: 參數(shù)組子功能(0-255)
典型PGN解析:
PGN
PF
PS
描述
0xFEFC
0xFE
0xFC
發(fā)動機轉(zhuǎn)速請求
0xFEF0
0xFE
0xF0
冷卻液溫度
0xFECA
0xFE
0xCA
車輛位置報告
5.2 多包數(shù)據(jù)傳輸
傳輸流程:
請求 → 確認 → 數(shù)據(jù)包1 → 數(shù)據(jù)包2 → ... → 結(jié)束符
STM32多包發(fā)送實現(xiàn):
// 多包數(shù)據(jù)發(fā)送(最大12字節(jié)/包)
void CAN_Send_MultiPacket(uint8_t *data, uint16_t length) {
uint8_t packets[6][8] = {0};
uint8_t packet_count = (length + 7) / 8;
for (int i=0; i<packet_count; i++) {
packets[i][0] = 0x00;// 流控制字段
memcpy(&packets[i][1], &data[i*8], 8);
CAN_TransmitPacket(packets[i]);
}
}
六、STM32HAL庫實戰(zhàn)進階
6.1 完整初始化流程
// 1. GPIO配置(CubeMX生成)
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOB_CLK_ENABLE();
// CAN_RX/TX引腳配置
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
?
// 2. CAN初始化(含過濾器配置)
void MX_CAN1_Init(void)
{
CAN_HandleTypeDef hcan1;
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 5;// 500Kbps
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_9TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_4TQ;
hcan1.Init.Mode = CAN_MODE_NORMAL;
if (HAL_CAN_Init(&hcan1) != HAL_OK) {
Error_Handler();
}
// 濾波器配置(接收ID=0x100-0x1FF)
CAN_FilterTypeDef sFilterConfig = {0};
sFilterConfig.FilterBank = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x100 << 13;
sFilterConfig.FilterIdLow = 0x1FF << 13 | 0xFFFF;
HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig);
}
6.2 數(shù)據(jù)收發(fā)實戰(zhàn)
// 數(shù)據(jù)發(fā)送(PDO模擬)
void CAN_Send_PDO(uint8_t node_id, uint16_t position) {
CAN_TxHeaderTypeDef TxHeader = {0};
uint8_t TxData[8] = {0};
TxHeader.StdId = 0x200 + node_id;// PDO ID
TxHeader.IDE = CAN_ID_STD;
TxHeader.DLC = 2;
TxData[0] = (position >> 8) & 0xFF;
TxData[1] = position & 0xFF;
HAL_CAN_AddTxMessage(&hcan1, &TxHeader, TxData, &TxMailbox);
}
?
// 接收回調(diào)(帶錯誤檢測)
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) {
CAN_RxHeaderTypeDef RxHeader;
uint8_t RxData[8] = {0};
if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RxData) == HAL_OK) {
if (RxHeader.DLC != 2) {
// 數(shù)據(jù)長度異常處理
return;
}
uint16_t value = (RxData[0] << 8) | RxData[1];
Process_Sensor_Data(value);
}
}
七、工業(yè)級應(yīng)用案例解析
7.1 電動汽車三電系統(tǒng)
BMS電池管理:通過CAN總線監(jiān)控單體電壓/溫度
電機控制器:接收扭矩指令并反饋轉(zhuǎn)速
OBC車載充電機:與BMS通信實現(xiàn)充電保護
通信拓撲:
BMS → CAN → MCU → CAN → 電機控制器
↑↓
充電樁
7.2 智能倉儲機器人
多機協(xié)同:50+臺AGV通過CAN總線同步路徑規(guī)劃
實時監(jiān)控:電量/故障狀態(tài)實時上報
抗干擾方案:
雙絞線屏蔽層接地
隔離收發(fā)器(如ADuM1201)
冗余幀重傳機制
八、調(diào)試與優(yōu)化技巧
示波器觀察:
檢查CAN_H/CAN_L差分波形(正常應(yīng)為方波)
波特率驗證(500Kbps對應(yīng)周期2μs)
錯誤分析:
錯誤幀計數(shù):HAL_CAN_GetError(&hcan1)
總線負載率:CAN總線分析儀檢測
性能優(yōu)化:
使用CAN FD(Flexible Data Rate)提升帶寬
優(yōu)化過濾器配置減少CPU開銷
采用環(huán)形緩沖區(qū)處理高頻率數(shù)據(jù)
九、擴展學習資源
經(jīng)典CAN vs CAN FD:帶寬從1Mbps提升至5Mbps
AUTOSAR架構(gòu):標準化汽車軟件架構(gòu)
TSN時間敏感網(wǎng)絡(luò):工業(yè)4.0通信新標準
2025-04-10 11:08:08
隨著工業(yè)自動化和信息化的快速發(fā)展,不同系統(tǒng)之間需要高效、靈活地進行數(shù)據(jù)交互與通信。然而,各系統(tǒng)往往采用不同的通信協(xié)議和報文格式,導致數(shù)據(jù)傳輸存在兼容性問題。軟件網(wǎng)關(guān)應(yīng)運而生,它通過圖形界面配置、零代碼開發(fā)的方式,實現(xiàn)報文的靈活映射與轉(zhuǎn)發(fā)。這種模塊化設(shè)計不僅降低了開發(fā)難度和成本,還提高了系統(tǒng)的可擴展性和維護性,能夠滿足復(fù)雜多變的工業(yè)場景需求,為系統(tǒng)集成與數(shù)據(jù)交
2025-04-03 20:02:56
1163 
為例,給大家從測量范圍、精度、環(huán)境適應(yīng)性三大核心維度,手把手教你選對型號!第一步:明確工程監(jiān)測需求選型前需明確以下問題:1、監(jiān)測目標:需監(jiān)測的縫寬變化范圍是多大?
2025-04-03 10:58:41
654 
在土木工程中,振弦式土體沉降計是監(jiān)測土石壩、邊坡、地基等沉降變形的“眼睛”。但想要它精準工作,安裝步驟是關(guān)鍵!如果埋設(shè)不當或組件連接錯誤,可能導致數(shù)據(jù)偏差甚至設(shè)備損壞。南京峟思將一步步為大家解析振弦式土體沉降計的安裝流程,從鉆孔到調(diào)試,幫你避開常見“坑點”,確保測量結(jié)果可靠耐用!一、安裝前:準備工作別馬虎工具備齊,事半功倍鉆孔工具:鉆孔機(孔徑≥90mm)、
2025-04-03 10:20:44
536 
的今天,高端顯卡維修已成“暴利暗流”。虛高報價、偷換配件、技術(shù)陷阱……用戶稍有不慎,輕則損失數(shù)萬,重則設(shè)備報廢。今天小助手將揭露行業(yè)亂象,手把手教你識別套路,并推薦
2025-04-02 20:31:44
3453 
甚至微型服務(wù)器時,你是否也遇到過程序卡頓、視頻處理延遲的尷尬?今天我們就手把手教你用Python并行處理技術(shù),讓樹莓派的性能瞬間翻倍!歡迎在評論區(qū)曬出你的優(yōu)化方案,
2025-03-26 17:08:28
757 
在物聯(lián)網(wǎng)開發(fā)領(lǐng)域,選擇合適的硬件平臺與操作系統(tǒng)是項目成功的關(guān)鍵。本文將帶領(lǐng)你從零開始,通過詳細的步驟與示例代碼,掌握Air780EPM與LuatOS的入門開發(fā)流程,并深入探討其核心功能與擴展?jié)摿Α?? 一、必須先要告訴你的一些廢話 這里,先要告訴你一些前提條件,雖然聽著像是廢話,但是如果你不知道的話,可能后面會比較懵逼,所以還是希望你能夠認真看一看這一節(jié)。 這個項目的產(chǎn)品定義是:模組每隔3秒,就往串口輸出一次 “ hello world” 字符
2025-03-25 16:38:31
570 
Developer Ethan 同學,手把手教您編譯/構(gòu)建 KiCad 源碼: 開發(fā)工具安裝 環(huán)境變量配置 使用 VS2022 構(gòu)建 KiCad 參與直播的小伙伴還有機會獲得 KiCon Badge
2025-03-24 11:14:00
1472 
資料介紹:
STM32Cube學習筆記,一步一步手把手帶你進入STM32Cube的世界,包括點燈,按鍵,串口,ADC,DAC等等一共16篇。
純分享貼,有需要可以直接下載附件獲取完整資料!
(如果內(nèi)容有幫助可以關(guān)注、點贊、評論支持一下哦~)
2025-03-22 17:02:25
介紹本文適用于零基礎(chǔ),手把手教你搭建基于STM32單片機控制億佰特E22-M系列、E220-M系列和E32-M系列模塊,旨在降低M系列模塊開發(fā)難度,幫助大家更快上手M系列的模組。本次教程分為“上篇
2025-03-20 19:33:08
728 
《零基礎(chǔ)開發(fā)AI Agent——手把手教你用扣子做智能體》是一本為普通人量身打造的AI開發(fā)指南。它不僅深入淺出地講解了Agent的概念和發(fā)展,還通過詳細的工具介紹和實戰(zhàn)案例,幫助讀者快速掌握
2025-03-18 12:03:28
為助力開發(fā)者迅速掌握『KaihongOS輕量系統(tǒng)開發(fā)技術(shù)』與『星閃無線通信技術(shù)』,實現(xiàn)快速上手與深度體驗,“開鴻Developer社區(qū)”攜手“電子發(fā)燒友”再次聯(lián)合推出《手把手教你做星閃無人機
2025-03-18 10:33:15
”攜手“電子發(fā)燒友”聯(lián)合推出了 《KaihongOS手把手系列直播課程》,該系列課程以實際產(chǎn)品為案例,詳細講解每個產(chǎn)品的開發(fā)全流程。
此次首發(fā)內(nèi)容是《手把手教你做PC-KaihongOS筆記本電腦開發(fā)
2025-03-18 10:25:04
4G模組Air780EPM作為廣和通推出的高性能Cat.1bis無線通信模塊,憑借其低功耗、高集成度及豐富的外設(shè)接口,在工業(yè)物聯(lián)網(wǎng)、智能終端、車載設(shè)備等領(lǐng)域展現(xiàn)出卓越的適配性。 一、概述 ? 開發(fā)方式 :Air780EPM 僅支持 LuatOS 軟件開發(fā)方式,不支持 AT 指令開發(fā)方式。若使用 AT 指令開發(fā)方式,可選擇 Air780EQ。 LuatOS 開發(fā)優(yōu)勢 :相對 C-SDK 入門更簡單,開發(fā)更方便,開發(fā)時間更快。 適用對象 :本文的 GPIO 設(shè)計指導針對 Air780EPM 用于 LuatOS 開發(fā)方式時的注意事項。 G
2025-03-17 16:07:20
928 
【第四章 定時任務(wù)】手把手教你玩轉(zhuǎn)新版正點原子云
承接上篇,除了報警聯(lián)動這個功能,原子云還有一個特色功能也是各開發(fā)者喜歡用的,定時任務(wù)功能。
【正點原子】云平臺:原子云(點擊登錄原子云)
前言
2025-03-13 10:19:45
本帖最后由 jf_85110202 于 2025-3-13 14:43 編輯
【第三章 警報聯(lián)動】手把手教你玩轉(zhuǎn)新版正點原子云
新版原子云網(wǎng)址:原子云(點擊登錄原子云)
原子云特色功能:設(shè)置
2025-03-12 16:05:20
【第二章 模型與設(shè)備連接】手把手教你玩轉(zhuǎn)新版正點原子云玩過物聯(lián)網(wǎng)的朋友們都知道,我們在接觸各大主流云平臺時會知道物模型的概念。
本實驗就是針對原子云中模型與設(shè)備連接,舉個簡單例子說明,溫度傳感器通過
2025-03-12 09:27:14
的新技術(shù)實踐指南,助你把握科技大勢。
▊《零基礎(chǔ)開發(fā)AI Agent——手把手教你用扣子做智能體》
葉濤管鍇張心雨 著
不懂編程也可以開發(fā)Agent
Agent(智能體)是大模型落地的重要方向
2025-03-10 16:29:54
【第一章 透傳策略】手把手教你玩轉(zhuǎn)新版正點原子云
1. 本次實驗使用正點原子D40 Mini 4G Cat1 DTU數(shù)傳模塊
1.1 D40數(shù)傳模塊資料
具體使用和資料下載可到:D40 Mini
2025-03-05 16:52:19
開發(fā)者集結(jié)!《手把手教你做星閃無人機》第二課開講啦!
2025-02-17 19:40:50
703 
帶來的現(xiàn)實。無論你是開發(fā)者、研究員、內(nèi)容創(chuàng)作者,還是 AI 愛好者,OpenAI 強大的語言模型都能為你的工作和生活帶來無限可能。 本指南將手把手教你獲取并使用 OpenAI API 密鑰,從零基礎(chǔ)到高級應(yīng)用,全程無障礙!針對中國用戶,我們提供獨家優(yōu)化方案,讓你輕松繞過
2025-02-15 17:26:43
5582 
導讀面對一臺ZMC600E運動控制器與多臺伺服電機,我們該怎樣讓它工作起來?本文帶你了解PLCOPen,并詳細講解如何使用AWStudio控制電機運動。在自動化領(lǐng)域,運動控制是一件很復(fù)雜的事情,包含了上位機通訊,工業(yè)現(xiàn)場總線通信協(xié)議,運動控制算法,伺服電機控制等領(lǐng)域知識。致遠電子自主研發(fā)的AWStudio的AWPLC解決方案可以快速實現(xiàn)運動控制編程。AWSt
2025-02-10 11:38:23
1217 
在這篇教程中,將教你使用Arduino創(chuàng)建一個互動式LED墻壁時鐘。這個項目結(jié)合了創(chuàng)意和技術(shù),設(shè)計出一個功能性強且視覺效果驚人的時鐘,它配備了互動式的LED燈。無論你是Arduino的新手還是已有
2025-02-08 17:47:12
”再次聯(lián)合推出《手把手教你做星閃無人機—KaihongOS星閃無人機開發(fā)實戰(zhàn)》系列課程,該課程與《手把手教你做PC—KaihongOS筆記本電腦開發(fā)實戰(zhàn)》同步并行,
2025-01-13 19:42:52
921 
直播預(yù)告看了這么多期直播,你是否也會好奇?NVH實際用起來難不難?不同類型故障的探頭布置有何差異?軟件該如何設(shè)置?燃油車與新能源電車測試時有何不同?我們又為何總是強調(diào),維修后再次診斷的重要性?關(guān)于這些問題,你都可以在我們本周的直播中找到答案!本周四,1月9日晚8點,全國技術(shù)能手、上海市五一勞動獎?wù)芦@得者——林創(chuàng)創(chuàng)老師,將空降虹科Pico直播間!從汽修冠軍到經(jīng)
2025-01-08 11:40:59
824 
”攜手“電子發(fā)燒友”聯(lián)合推出了《KaihongOS手把手系列直播課程》,該系列課程以實際產(chǎn)品為案例,詳細講解每個產(chǎn)品的開發(fā)全流程。此次首發(fā)內(nèi)容是《手把手教你做PC-
2025-01-06 20:46:51
916 
評論