概要
1、vscode開發環境搭建
2、EtherCAT與RK3562通訊測試
3、編程IGH主站+HPM極限通訊測試
4、ADC+EUI顯示測試
5、ADC遠采系統
1.vscode開發環境搭建
1.1 SDK包下載
SDK包:
- SDK
- 編譯鏈
- 驅動下載器的openocd(配置文件在sdk文件夾下,不在ocd工程里)配置文件
- python3
- cmake + ninja + 其他編譯腳本
- FTDI驅動
官方開發指定用的是 SEGGER Embedded Studio ,但由于對eclipse系的東西實在沒有好感,于是摸索使用vscode開發的方法。
1.2 工程
從SDK目錄下 hpm_sdk\samples\ 拉取任意工程,我這里拉了GPIO工程
在VSCODE中安裝需要的擴展:
·Cortex-Debug
·CMake Tool

3.配置系統的 SDK路徑、交叉編譯鏈路徑、python3、ninja 幾個環境.
但由于我不想往系統的PATH里面添加太多環境,于是在項目根目錄加CMakePresets.json
{
"version":3,
"configurePresets":[
{
"name":"tinnu-path",
"displayName":"tinnu獨立環境",
"description":"正在使用編譯器",
"binaryDir":"${sourceDir}/out/build/${presetName}",
"generator":"Ninja",
"environment":{
"GNURISCV_TOOLCHAIN_PATH":"E:/sdkpath/toolchains/rv32imac_zicsr_zifencei_multilib_b_ext-win",
"HPM_SDK_BASE":"E:/sdkpath/hpm_sdk",
"PATH":"E:/sdkpath/tools/python3;E:/sdkpath/tools/ninja;"
},
"cacheVariables":{
"CM***E_INSTALL_PREFIX":"${sourceDir}/out/install/${presetName}",
"CM***E_C_COMPILER":"E:/sdkpath/toolchains/rv32imac_zicsr_zifencei_multilib_b_ext-win/bin/riscv32-unknown-elf-gcc.exe",
"CM***E_CXX_COMPILER":"E:/sdkpath/toolchains/rv32imac_zicsr_zifencei_multilib_b_ext-win/bin/riscv32-unknown-elf-g++.exe",
"HPM_BUILD_TYPE":"flash_xip",
"CM***E_BUILD_TYPE":"debug"
}
}
]
}
如果不配置CMakePresets.json,要么就改系統環境變量,要么在CMakeList.txt里面加入ENV,但PATH的修改還是需要加環境變量,在CMakeList.txt里面加不生效:
set(ENV{GNURISCV_TOOLCHAIN_PATH}"E:/sdkpath/toolchains/rv32imac_zicsr_zifencei_multilib_b_ext-win")
set(ENV{HPM_SDK_BASE}"E:/sdkpath/hpm_sdk/")
4.配置cmake路徑
如果也不希望在系統層面安裝cmake,或者以前安裝過其他版本的cmake,可以選擇在工程內配置特定版本的cmake,這里就配置官方提供的版本:

創建/打開 .vscode/setting.json
"cmake.cmakePath":"E:/sdkpath/tools/cmake/bin/cmake.exe",
"cmake.additionalCompilerSearchDirs":[
"E:/sdkpath/toolchains/rv32imac_zicsr_zifencei_multilib_b_ext-win/bin"
]
5.配置編譯類型為xip。打開 .vscode/setting.json
"cmake.defaultVariants":{
"buildType":{
"default":"debug",
"description":"The build type.",
"choices":{
"flash_xip":{
"short":"flash_xip",
"long":"flash_xip.",
"buildType":"flash_xip"
}
}
}
}
6.配置編譯宏。打開 .vscode/setting.json
"cmake.configureArgs":[
"-DBOARD=hpm5e00evk"
]
7.編譯
1.3 調試
安裝調試器的驅動,調試器為板載FT2232HL,官方SDK打包下面: ./tools/FTDI_InstallDriver
-注意,由于WIN11的BUG,每次重新插入USB后(注意,是插入USB后!)都需要重新安裝驅動,否則不識別
打開官方下載軟件,官方SDK打包根目錄下的 ./start_gui
點擊 Launch GDB Server 這是集成了啟動openocd的命令,具體命令會在點擊后出現,可以在powershell里面手動執行

配置vscode調試設置:
-創建/打開 .vscode/launch.json
{
"configurations":[
{
"name":"remote",
"cwd":"${workspaceRoot}",
"type":"cortex-debug",
"request":"launch",
"servertype":"external",
"gdbTarget":"localhost:3333",
"device":"hpm5e00",
"executable":"build/output/demo.elf",
"runToEntryPoint":"main",
"gdbPath":"E:/sdkpath/toolchains/rv32imac_zicsr_zifencei_multilib_b_ext-win/bin/riscv32-unknown-elf-gdb.exe",
"targetId":"hpm5e00"
}
]
}
點擊F5即可啟動調試



2.Ethercat與RK3562通訊測試
2.1 Ethercat與RK3562通訊測試
下載 SSC TOOL
我以前開發 Ethercat 使用的是5.12版本的SSC TOOL ,但是發現這個版本加載 HPM 的xml后無法在創建工程時顯示配置,看了下教程,是使用5.13版本的。
由于官方下載渠道的SSC TOOL是需要ETG會員賬號,之前了解過這個賬號應該是要每年給德國公司交錢才行。只能找些別的渠道,最終找到gitcode。你還真別說,gitcode的baba雖然掉錢眼里,還爬蟲github出過丑聞,但對于個人開發者來說,他確實是提供了一個不錯的渠道。
V5.13
https://gitcode.com/open-source-toolkit/a3990
V5.12
https://gitcode.com/open-source-toolkit/9f481
git clone
https://gitcode.com/open-source-toolkit/a3990.git
下載ethercat上位機軟件
最官方的肯定是倍福自己的TwinCAT下載。
https://tr.beckhoff.com.cn/login/index.php
- 但老實說,官方的東西雖然UI,但概念上還是有些晦澀和難找的。尤其是最新的 TwinCAT3 還是附加在 Visual Studio 的,可能對于純粹的嵌入式開發者來說問題不大(只要你的硬盤沒被各種版本的vivado塞滿),但對于廣泛開發上下位機的小伙伴就不太友好了,嵌入到 Visual Studio 里面可能會對 Visual Studio 本身的環境產生某些不可估計的掣肘。
- 另外就是這個軟件安裝起來還是比較麻煩的,還吃網卡類型。當初第一次接觸的時候,半天掃不到下位機。讓下位機廠家幫忙調試半天都搞不定,最后重啟一下突然好了……
另外就是使用嵌入式開發板,刷入 linux-rt 使用 igh 上位機用命令行測試。我個人感覺這個方法還是比較簡便的(如果省略掉編譯linux-rt內核與交叉編譯igh主站驅動的工作)
主站準備
我以前開發ethercat的時候就安裝過 TwinCAT3 ,不再贅述(太過麻煩,不想回憶了)
另外手頭有創龍的 3562EVM 板卡,剛好官方適配了 Linux-RT + IGH Ethercat 主站,以下分別測試
2.2 下位機軟件生成編譯
項目創建配置
把 /hpm_sdk\samples\ethercat\ecat_io、/hpm_sdk\samples\ethercat\port 拉出來單獨一個文件夾
按照之前設置 CMakePresets.json
{
"version":3,
"configurePresets":[
{
"name":"tinnu-path",
"displayName":"tinnu獨立環境",
"description":"正在使用編譯器",
"binaryDir":"${sourceDir}/out/build/${presetName}",
"generator":"Ninja",
"environment":{
"GNURISCV_TOOLCHAIN_PATH":"E:/sdkpath/toolchains/rv32imac_zicsr_zifencei_multilib_b_ext-win",
"HPM_SDK_BASE":"E:/sdkpath/hpm_sdk",
"PATH":"E:/sdkpath/tools/python3;E:/sdkpath/tools/ninja;"
},
"cacheVariables":{
"CM***E_INSTALL_PREFIX":"${sourceDir}/out/install/${presetName}",
"CM***E_C_COMPILER":"E:/sdkpath/toolchains/rv32imac_zicsr_zifencei_multilib_b_ext-win/bin/riscv32-unknown-elf-gcc.exe",
"CM***E_CXX_COMPILER":"E:/sdkpath/toolchains/rv32imac_zicsr_zifencei_multilib_b_ext-win/bin/riscv32-unknown-elf-g++.exe",
"HPM_BUILD_TYPE":"flash_xip",
"CM***E_BUILD_TYPE":"debug"
}
}
]
}
按照上一篇帖子,設置 .vscode/setting.json
生成 SSC 源碼
倍福為了把 ethercat 這只現金奶牛牢牢掌握在自己手里,相關的源碼必須用他們的軟件生成。因此HPM方面的例程是缺了這塊源碼的(這個對于其他的芯片也都是這樣的,開發過ethercat就會知道)
上面下載了SSC TOOL,把HPM專用的設置導入SSC TOOL。
- Tool->Options->Configurations里面,點擊+號,導入SDK里的配置文件:/hpm_sdk\samples\ethercat\ecat_io下面的SSC\Config\HPM_ECAT_IO_Config

創建SSC工程:File->New->custom 選擇剛導入的HPM配置

導入應用:Tool->Application->Import

生成C代碼

拉到/hpm_sdk\samples\ethercat\ecat_io\SSC下面
補丁說明
官網教程里面提到了需要打補丁但實測下來,打補丁反而會導致下位機卡在INIT里面,不打反而是正常的。
2.3 調試
編譯下載調試
編譯后,按照上一篇帖子,設置 .vscode/launch.json
打開官方下載軟件,官方SDK打包根目錄下的 ./start_gui
- 點擊 Launch GDB Server 這是集成了啟動openocd的命令,具體命令會在點擊后出現,可以在powershell里面手動執行

點擊F5
使用創龍3562+IGH掃描設備
掃描從站

掃描EEPROM SII表
bin/ethercat sii_read -p 0 -v
SII Area:
800c8166000000001234000000007700
4d504800010000000100000000000000
00000000000000000000000000000000
00108000801080000400000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
0000000000000000000000000f000100
SII Category0x000a(STRINGS),71words
080b454341545f4465766963650a6469
676974616c5f696f0853796e6368726f
6e0b534d2d53796e6368726f6e21496e
707574436f756e7465722070726f6365
73732064617461206d617070696e670c
496e707574436f756e746572224f7574
707574436f756e7465722070726f6365
73732064617461206d617070696e670d
4f7574707574436f756e74657200
SII Category0x001e(General),16words
01000202002300000000000c00000100
11000000000000000000000000000000
SII Category0x0028(FMMU),2words
010203ff
SII Category0x0029(SyncM),16words
00108000260001018010800022000102
00110400640001030014040020000104
SII Category0x0032(TXPDO),8words
001a0103000500000060000607200000
SII Category0x0033(RXPDO),8words
00160102000700001070000807200000
SII Category0x003c(DC),12words
00000000000000000000000000000000
0000030400000000
(1) 設備基礎信息(SII Header)
廠商ID:0x000c80(十六進制) → Beckhoff Automation GmbH(標準EtherCAT廠商代碼)
產品碼:0x00006681 → 特定設備型號標識符(需查Beckhoff文檔確認具體型號)
版本號:0x00007700 → 硬件版本V7.7
序列號:0x00001234 → 設備唯一序列號4660
EEPROM配置校驗:末字節0x0001表示校驗通過
(2)字符串描述(Category 0x000a: STRINGS)
解碼后關鍵標識:
設備名稱:"ECAT_Device"(45 43 41 54 5f 44 65 76 69 63 65)
功能描述:
- "digital_io" → 數字輸入/輸出模塊
- "Synchron" & "SM-Synchron" → 支持同步功能
- "InputCounter process data mapping" → 輸入計數器PDO映射
- "OutputCounter process data mapping" → 輸出計數器PDO映射
(3)同步管理器配置(Category 0x0029: SyncM)
4個同步管理器定義:

(4)分布式時鐘配置(Category 0x003c: DC)
關鍵值:0x0304
- 比特0-2:0x04 → 支持DC同步模式
- 比特3-7:0x03 → 時鐘精度±50ns(高精度級別)
(5)FMMU配置(Category 0x0028)
字段:01 02 03 ff
- FMMU0:啟用,邏輯→物理地址映射
- FMMU1:啟用,方向為輸入
- FMMU2:啟用,用于同步狀態管理
- 0xFF:填充終止符
讀寄存器
上面分析過,輸入是 0x1400 ,我們可以看一下:
- 進入OP模式bin/ethercat state -p 0 OP
- bin/ethercat reg_read -p 0 -t uint32 0x1400

使用TWinCAT掃描設備
掃描從站



監控輸入

設置輸出

3.編程IGH主站+HPM極限通訊測試
上文中使用TWinCAT和IGH主站命令行進行簡單的讀取,但工程應用還是需要嵌入到程序中。
接下來,我們使用RK3562+LINUX RT+IGH主站的庫,編程輪詢讀寫HPM從站,并測試通訊的極限速度。
3.1 配置查詢
從站配置
#./ethercat slaves-v
=Master0,Slave0=
Alias:13330
Device:Main
State:SAFEOP+ERROR
Flag:E
Identity:
Vendor Id:0x0048504d
Product code:0x00000001
Revision number:0x00000001
Serial number:0x00000000
DL information:
FMMU bit operation:no
Distributed clocks:yes,64bit
DC system time transmission delay:0ns
Port Type Link Loop Signal NextSlave RxTime[ns] Diff[ns] NextDc[ns]
0 MII up open yes -402292431400
1 MII down closed no ----
2 MII down closed no ----
3 N/A down closed no ----
Mailboxes:
Bootstrap RX:0x0000/0,TX:0x0000/0
Standard RX:0x1000/128,TX:0x1080/128
Supported protocols:CoE
General:
Group:ECAT_Device
Image name:
Order number:digital_io
Device name:digital_io
CoE details:
Enable SDO:yes
Enable SDO Info:yes
Enable PDO Assign:no
Enable PDO Configuration:no
Enable Upload at startup:no
Enable SDO complete access:yes
Flags:
Enable SafeOp:no
Enable notLRW:no
Current consumption:0mA
PDO配置
#bin/ethercat cstruct
/* Master 0, Slave 0, "digital_io"
* Vendor ID: 0x0048504d
* Product code: 0x00000001
* Revision number: 0x00000001
*/
ec_pdo_entry_info_tslave_0_pdo_entries[]={
{0x7010,0x00,32},/* OutputCounter */
{0x6000,0x00,32},/* InputCounter */
};
ec_pdo_info_tslave_0_pdos[]={
{0x1600,1,slave_0_pdo_entries+0},/* OutputCounter process data mapping */
{0x1a00,1,slave_0_pdo_entries+1},/* InputCounter process data mapping */
};
ec_sync_info_tslave_0_syncs[]={
{0,EC_DIR_OUTPUT,0,NULL,EC_WD_DISABLE},
{1,EC_DIR_INPUT,0,NULL,EC_WD_DISABLE},
{2,EC_DIR_OUTPUT,1,slave_0_pdos+0,EC_WD_ENABLE},
{3,EC_DIR_INPUT,1,slave_0_pdos+1,EC_WD_DISABLE},
{0xff}
};
PDO映射
#./ethercat pdos-p0
SM0:PhysAddr0x1000,DefaultSize 128,ControlRegister0x26,Enable1
SM1:PhysAddr0x1080,DefaultSize 128,ControlRegister0x22,Enable1
SM2:PhysAddr0x1100,DefaultSize 4,ControlRegister0x64,Enable1
RxPDO0x1600"OutputCounter process data mapping"
PDO entry0x7010:00,32bit,"OutputCounter"
SM3:PhysAddr0x1400,DefaultSize 4,ControlRegister0x20,Enable1
TxPDO0x1a00"InputCounter process data mapping"
PDO entry0x6000:00,32bit,"InputCounter"
3.2 IGH主站配置
主站工程創建
拉取IGH主站源碼,在 examples 下有例程。其中 rtai 這類的是高實時性要求的情況,需要編譯為內核模塊注冊進內核里,用起來比較麻煩,特別是一些現有的項目里面想要遷移ethercat的話,還是使用 user 比較好。
拷貝 examples/dc_user 例程到獨立目錄,配置CMakeLists指定igh主站編譯主機里面的cmake,然后在TARGET_LINK_LIBRARIES里面添加EtherLab:
include(/home/user/toolchain/rk/3562rt/ethercat/install/lib/cmake/ethercat/ethercat-config.cmake)
TARGET_LINK_LIBRARIES(${PROJECT_NAME}PRIVATE
-lpthread-lssl-lcrypto-lrt
EtherLab::ethercat)
主站配置與從站地址定位
首先獲取配置句柄 ec_slave_config_t
通過 ethercat slaves -v 可以獲取 Alias Vendor Id Product code 填進 ecrt_master_slave_config 的參數里。
然后配置需要讀取的寄存器,獲取偏移位置:
通過 ethercat pdos -p 0 可以獲取 PDO entry 信息,填入 ecrt_slave_config_reg_pdo_entry 的參數里面。
主站輪詢讀取
先接收EtherCAT數據
ecrt_master_receive(master);
ecrt_domain_process(domain1);
使用 EC_READ_U32 和 EC_WRITE_U32 修改寄存器數據
修改之后發送回去EtherCAT從站
ecrt_domain_queue(domain1);
ecrt_master_send(master);
3.3 主從站極限速度測試
主站配置用于檢測的翻轉IO
初始化
board_init();
gpio_set_pin_output_with_initial(HPM_GPIO0,GPIO_DI_GPIOC,10,0);
gpio_set_pin_output_with_initial(HPM_GPIO0,GPIO_DI_GPIOB,30,0);
gpio_set_pin_output_with_initial(HPM_GPIO0,GPIO_DI_GPIOB,31,0);
這里使用邏輯分析儀監視這些IO的電平
獨立一個程序測試IO翻轉
intmain(void)
{
uint8_tstatus;
board_init();
gpio_set_pin_output_with_initial(HPM_GPIO0,GPIO_DI_GPIOB,31,0);
gpio_set_pin_input(HPM_GPIO0,GPIO_DI_GPIOC,8);
while(1)
{
status=gpio_read_pin(HPM_GPIO0,GPIO_DI_GPIOC,8);
gpio_write_pin(HPM_GPIO0,GPIO_DI_GPIOB,31,!status);
}
}
測試發現,翻轉速度達到納秒級,足夠進行ethercat翻轉實驗
配置ethercat模擬EEPROM讀寫控制的函數
staticUINT8 pin2_level=0;
staticUINT32 counter=0;
voidAPPL_SetLed(UINT32 value)
{
UINT8 led0=((value&1)? BOARD_ECAT_OUT_ON_LEVEL:!BOARD_ECAT_OUT_ON_LEVEL);
UINT8 led1=((value&2)? BOARD_ECAT_OUT_ON_LEVEL:!BOARD_ECAT_OUT_ON_LEVEL);
UINT8 led2=((value&4)? BOARD_ECAT_OUT_ON_LEVEL:!BOARD_ECAT_OUT_ON_LEVEL);
gpio_write_pin(BOARD_ECAT_OUT1_GPIO,BOARD_ECAT_OUT1_GPIO_PORT_INDEX,BOARD_ECAT_OUT1_GPIO_PIN_INDEX,led0);
gpio_write_pin(BOARD_ECAT_OUT2_GPIO,BOARD_ECAT_OUT2_GPIO_PORT_INDEX,BOARD_ECAT_OUT2_GPIO_PIN_INDEX,led1);
gpio_write_pin(HPM_GPIO0,GPIO_DI_GPIOB,30,led2);
gpio_write_pin(HPM_GPIO0,GPIO_DI_GPIOB,31,!led2);
}
UINT32APPL_GetDipSw(void)
{
UINT8 pin0_level=gpio_read_pin(BOARD_ECAT_IN1_GPIO,BOARD_ECAT_IN1_GPIO_PORT_INDEX,BOARD_ECAT_IN1_GPIO_PIN_INDEX);
UINT8 pin1_level=gpio_read_pin(BOARD_ECAT_IN2_GPIO,BOARD_ECAT_IN2_GPIO_PORT_INDEX,BOARD_ECAT_IN2_GPIO_PIN_INDEX);
// UINT8 pin2_level = gpio_read_pin(HPM_GPIO0, GPIO_DI_GPIOC, 8);
pin2_level=!pin2_level;
UINT32 val=pin0_level<<0|pin1_level<<1|pin2_level<<2;
gpio_write_pin(HPM_GPIO0,GPIO_DI_GPIOC,10,pin2_level);
if((counter++&0xFFF)==0)
{
printf("poll count: %X\n",counter);
}
returnval;
}
讀寫極限測試
通過修改主站代碼。
while(1)
{
// 1. 等待下一個周期
wakeupTime=timespec_add(wakeupTime,cycletime);
clock_nanosleep(CLOCK_TO_USE,TIMER_ABSTIME,&wakeupTime,NULL);
clock_gettime(CLOCK_TO_USE,¤tTime);
counter++;
if(DIFF_NS(lastFlipTime,currentTime)>=1000000000)
{
printf("counter: %d(%d)\n",counter,counter2);
counter=0;
counter2=0;
lastFlipTime=currentTime;
}
// 2. 接收EtherCAT數據
ecrt_master_receive(master);
ecrt_domain_process(domain1);
// 3. 讀取所有16個模擬量輸入通道
// for (int i = 0; i < 16; i++)
inti=0;
{
// 獲取當前通道的偏移量
offset=analog_in_offsets[i];
// 從域數據中讀取16位值
fresh_pd=ecrt_domain_data(domain1);
raw_value=EC_READ_U32(fresh_pd+offset);
if(raw_value!=raw_valueo)
{
raw_valueo=raw_value;
raw_write=raw_value;
counter2++;
}
}
EC_WRITE_U32(fresh_pd+et_output_offsets,raw_write);
ecrt_domain_queue(domain1);
ecrt_master_send(master);
}
分別使用1ms周期、300us周期對從站進行輪詢,PB30都能跟上PC10,這證明了兩件事
- 當前架構下, ethercat 能夠滿足300us輪詢。
- 一旦主站發起通訊,從站會按照主站的輪詢速度刷新數據。(這個我做過打印測試,在主站程序不運行的時候,從站是滿速刷新,一旦主站發起通訊,就按照主站速度刷新)
以下是使用邏輯分析儀測試的結果
分析
首先明確,當前例程的從站是先讀后寫:
voidAPPL_Application(void)
{
InputCounter0x6000=APPL_GetDipSw();
APPL_SetLed((UINT32)OutputCounter0x7010);
}
根據時序圖分析,可得:從站的處理邏輯是:在主站進行了一次讀寫后,在刷新緩存(即模擬的EEPROM),而非每次主站的請求到達才調用 APPL_SetLed、APPL_GetDipSw 獲取數據。這種緩存刷新機制有效避免數據輪詢的時間開銷。
純寫極限測試
主站不管從站是否來得及刷新,拼命寫,測試最高可以到33us左右,我這里測試了一個50us:
while(1)
{
// 1. 等待下一個周期
wakeupTime=timespec_add(wakeupTime,cycletime);
clock_nanosleep(CLOCK_TO_USE,TIMER_ABSTIME,&wakeupTime,NULL);
clock_gettime(CLOCK_TO_USE,¤tTime);
counter++;
if(DIFF_NS(lastFlipTime,currentTime)>=1000000000)
{
printf("counter: %d(%d)\n",counter,counter2);
counter=0;
counter2=0;
lastFlipTime=currentTime;
}
// 2. 接收EtherCAT數據
ecrt_master_receive(master);
ecrt_domain_process(domain1);
// 3. 讀取所有16個模擬量輸入通道
// for (int i = 0; i < 16; i++)
inti=0;
{
// 獲取當前通道的偏移量
offset=analog_in_offsets[i];
// 從域數據中讀取16位值
fresh_pd=ecrt_domain_data(domain1);
raw_value=EC_READ_U32(fresh_pd+offset);
}
// 5. 準備并發送輸出數據
raw_write=raw_write?0:0x7;
EC_WRITE_U32(fresh_pd+et_output_offsets,raw_write);
ecrt_domain_queue(domain1);
ecrt_master_send(master);
}
4.ADC+EUI顯示測試
4.1 EUI
HPM有個專門串行驅動外部數碼管(如 74 系列的 595 芯片)的EUI外設,可以在占用少量IO口的情況下驅動大量數碼管。
相關例程在 hpm_sdk\components\segment_led\ 下。
我們使用這個驅動庫,需要在 CMakeLists.txt 里面添加
set(CONFIG_HPM_SEGMENT_LED1)
這就自動把從模塊加載進工程中編譯。
初始化
init_eui_pins(BOARD_EUI);
clock_add_to_group(BOARD_EUI_CLOCK_NAME,0);
uint32_ts_eui_clock_freq=clock_get_frequency(BOARD_EUI_CLOCK_NAME);
init_eui_config();
segment_led_config_eui_instance(BOARD_EUI,s_eui_clock_freq);
segment_led_config_blink_period(500,500);
可以通過 segment_led_config_disp_blink 函數設置哪些位閃動。
通過 segment_led_set_disp_data 設置指定數碼管顯示。
后面對ADC結果顯示,需要對字符串顯示進行封裝:
staticinlinevoidsegment_led_set_disp_dataX(uint8_tindex,chariid,intisDot)
{
if(iid<'0'||iid>'F')
iid=0;
else
iid=iid-'0';
segment_led_set_disp_data(index,s_disp_code_8_seg[iid]|(isDot?BOARD_EUI_SEG_DP_BIT_MASK:0));
}
staticvoidupdate_seg_led_disp_dataX(charshow[],intdotId)
{
segment_led_set_disp_dataX(0,show[0],dotId 0);
segment_led_set_disp_dataX(1,show[1],dotId 1);
segment_led_set_disp_dataX(2,show[2],dotId 2);
segment_led_set_disp_dataX(3,show[3],dotId 3);
segment_led_set_disp_dataX(4,show[4],dotId==4);
}
4.2 ADC測試
例程默認ADC初始化流程:
/* ADC pin initialization */
board_init_adc16_pins();
/* ADC clock initialization */
board_init_adc_clock(BOARD_APP_ADC16_BASE,true);
/* ADC16 common initialization */
init_common_config(conv_mode);
/* ADC16 read patter and DMA initialization */
init_period_config();
board_init_adc16_pins 所定義的引腳為 IOC_PAD_PF26。
由于官方沒有提供原理圖,無法得知PF26具體連接到哪里,只能根據 IO文檔 猜測。

看描述應該是兩個類似天線SMA接口(紅色標注),但手上沒有這種差分線。這里還標注了J3[6]的位置,J3是下面的電機接口排針。J3[6]應該就是第六根,絲印為ADC_C。
在while循環里面輪詢獲取當前的ADC值,并轉化為字符串存儲在全局變量 bShowValue 中:
voidperiod_handler(void)
{
uint16_tresult;
doublevalue;
adc16_get_prd_result(BOARD_APP_ADC16_BASE,BOARD_APP_ADC16_CH_1,&result);
value=result*3.3/0xFFFF;
snprintf(bShowValue,32,"%.4f",value);
}
4.3 整合顯示
通過數碼管顯示當前采樣:
b=strcspn(bShowValue,".");
strncpy(tShow,bShowValue,5);
if(b<5)
{
strncpy(tShow+b,bShowValue+b+1,5-b);
}
update_seg_led_disp_dataX(tShow,b-1);
引出3.3V,采用電阻進行分壓。用ADC_C分別測試兩個分壓的采樣:

測試效果

5.ADC遠采系統
項目功能:3562主站,通過ethercat 遠采HPM從站的ADC碼值,輸出到CSV文件,通過WPS生成點圖觀察
5.1 HPM從機端驅動
加快ADC采樣周期,假設HPM設置200HMz運行,ADC周期觸發需要以100K分頻才能跟得上1ms的通訊周期:
215?3=98304
配置函數修改:
voidinit_period_config(void)
{
adc16_channel_config_tch_cfg;
adc16_prd_config_tprd_cfg;
/* get a default channel config */
adc16_get_channel_default_config(&ch_cfg);
/* initialize an ADC channel */
ch_cfg.ch =BOARD_APP_ADC16_CH_1;
ch_cfg.sample_cycle=APP_ADC16_CH_SAMPLE_CYCLE;
adc16_init_channel(BOARD_APP_ADC16_BASE,&ch_cfg);
prd_cfg.ch =BOARD_APP_ADC16_CH_1;
prd_cfg.prescale =15;/* Set divider: 2^22 clocks */
prd_cfg.period_count=3;/* 104.86ms when AHB clock at 200MHz is ADC clock source */
adc16_set_prd_config(BOARD_APP_ADC16_BASE,&prd_cfg);
}
修改上傳數據,在函數APPL_Application中:
InputCounter0x6000=result*3.3/0xFFFF*1000;
5.2 主機端
讀取反饋數據,輸出到CSV文件:
offset=analog_in_offsets[0];
fresh_pd=ecrt_domain_data(domain1);
uint32_tva=EC_READ_U32(fresh_pd+offset);
printf("ADC %d mV\n",va);
bQueue.push(va);
if(bQueue.size()>2000)
{
// 輸出到CSV文件
staticintfile_index=0;
charfilename[64];
sprintf(filename,"data_output_%d.csv",file_index++);
FILE*fp=fopen(filename,"w");
if(fp){
fprintf(fp,"Value\n");
while(!bQueue.empty()){
fprintf(fp,"%d\n",bQueue.front());
bQueue.pop();
}
fclose(fp);
printf("Data saved to %s\n",filename);
}else{
printf("Failed to create file %s\n",filename);
// 清空隊列
while(!bQueue.empty()){
bQueue.pop();
}
}
}
5.3 測試環境
使用一個ICL8038作為正弦波形發生源:

輸入上次ADC項目同一端口:

5.4 輸出效果

文章來源:EEFocus
開發者ID:day_day
-
測試
+關注
關注
9文章
6155瀏覽量
131246 -
ethercat
+關注
關注
19文章
1487瀏覽量
44919 -
HPM
+關注
關注
2文章
50瀏覽量
8240
發布評論請先 登錄
華為開發者大會2021:軟件部總裁龔體 鴻蒙系統 一次開發 多端部署 萬物互連
三星2021開發者大會:第一次線上形式的虛擬開發者大會
開發者分享 | HPM5E-EC-DEV:基于HPM5E00的EtherCAT開發板分享
開發者分享 | 一次完整的 HPM EtherCAT 實戰:環境、通信與極限測試
評論