2021-08-20 16:47:40 索煒達電子 1296
項目編號:E392
文件大小:36.5M
源碼說明:帶中文注釋
開發(fā)環(huán)境:C編譯器
簡要概述
背景
在做這輛小車之前,正值我大學學習生涯的迷茫期。有關嵌入式的學習,我基本是自學的。自學最大的壞處就是,沒有一個系統(tǒng)的學習提綱,你無法充分了解你學習的進度、水平以及未來的方向。你可能會因為一個小成果而覺得自己可以了,也可能會突然有一天遇到一個專業(yè)知識更強的同齡人,而自我否定。為了能夠接觸到新知識,鞏固以前所學,我決定做這樣一輛小車。
選擇操作系統(tǒng)
在這之前我只學過 UCOS,但是 ucos 商用并不免費,一直耿耿于懷。所以趁著這次機會本著學習的目的我選擇了 RT-Thread。期間也有考慮過 freertos 等其他實時操作系統(tǒng)但最終還是選擇了 RT-Thrad 。
準備階段
下載 RT-Thread 源碼。
激光雷達,作為學生黨買淘寶上最便宜。(當初買的時候最便宜的一款也要 499 QAQ,現(xiàn)在好像便宜點了)
PCB的繪制,或者使用最小系統(tǒng)板外加模塊。
我選擇的是 stm32f429-apollo 因為手頭正好有正點原子 F429 的開發(fā)板,有好多驅(qū)動稍加修改甚至不修改直接就可以用了。
硬件部分
1.主控芯片
stm32f429igt6
因為基礎工程是根據(jù) bsp stm32f429-apollo 改的,所以電路原理圖上一些引腳的分配我也盡量按照 apollo 開發(fā)板的方案設計。
2.電機驅(qū)動部分
電機驅(qū)動芯片使用 L298N ??刂菩≤嚨乃俣扰c方向。
電路原理圖如下:
電機自帶AB相編碼器,用于測速(pi閉環(huán)控制)。
3.激光雷達
查激光雷達數(shù)據(jù)手冊
激光雷達需要 5v 供電,串口通信,一個 M_SCTP PWM輸入口控制轉(zhuǎn)速(M_SCTP可默認拉高省出pwm口)。
4.藍牙串口
因為使用了 RT-Thread 的組件 FinSH,( FinSH 組件是 RT-Thread 的一大亮點。)為了方便無線調(diào)試,我使用兩個配對好的藍牙串口來通信,即插即用。
5.其他
另外我還外加了 mpu9250模塊,SDRAM、W25Q128、蜂鳴器、oled屏...等 用于以后的擴展。
程序部分
整體的思路如下:
eaix4線程: 用于對激光雷達數(shù)據(jù)的處理。
wireless線程: 用于無線傳輸。
mpu9250線程: 用于9軸姿態(tài)傳感器數(shù)據(jù)的處理。
speed線程: 用于速度的閉環(huán)控制。
master線程: 作為主線程負責創(chuàng)建其他子線程,以及處理其他子線程發(fā)送的傳感器信息。
1.激光雷達
查看雷達開發(fā)手冊
圖一: 掃描命令
圖二: 掃描命令
當向激光雷達設備發(fā)送 [A5 60] 的時候,激光雷達會連續(xù)不斷的返回掃描到的數(shù)據(jù),直到你發(fā)送停止掃描命令為止,基于這種特性選擇使用 RT-Thread 的消息隊列機制。
rt_err_t eaix4_open(const char *name)
{
rt_err_t res;
/* 查找系統(tǒng)中的串口設備 */
eaix4_device = rt_device_find(name);
/* 查找到設備后將其打開 */
if (eaix4_device != RT_NULL)
{
/* 注冊回調(diào)函數(shù) eaix4_intput */
res = rt_device_set_rx_indicate(eaix4_device, eaix4_intput);
/* 檢查返回值 */
if (res != RT_EOK)
{
rt_kprintf("set %s rx indicate error.%d\n", name, res);
return -RT_ERROR;
}
/* 打開設備,以可讀寫、中斷方式 */
res = rt_device_open(eaix4_device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
/* 檢查返回值 */
if (res != RT_EOK)
{
rt_kprintf("open %s device error.%d\n", name, res);
return -RT_ERROR;
}
}
else
{
rt_kprintf("can't find %s device.\n", name);
return -RT_ERROR;
}
/* 初始化消息隊列對象 */
rt_mq_init(&Eaix4Mq, "EAIX4", Eaix4Buff, 1, sizeof(Eaix4Buff), RT_IPC_FLAG_FIFO);
return RT_EOK;
}
/* 串口接收數(shù)據(jù)回調(diào)函數(shù) */
static rt_err_t eaix4_intput(rt_device_t dev, rt_size_t size)
{
rt_uint8_t ch;
/* 讀取1字節(jié)數(shù)據(jù) */
if (rt_device_read(eaix4_device, 0, &ch, 1) == 1)
{
/* 將數(shù)據(jù)發(fā)送到消息隊列中 */
rt_mq_send(&Eaix4Mq, &ch, 1);
}
return RT_EOK;
}
/* 讀取消息隊列中的數(shù)據(jù) */
rt_uint8_t eaix4_getchar(void)
{
rt_uint8_t ch;
/* 讀取消息隊列中的數(shù)據(jù) */
rt_mq_recv(&Eaix4Mq, &ch, 1, RT_WAITING_FOREVER);
return ch;
}
/* 向激光雷達發(fā)送數(shù)據(jù) */
void eaix4_putchar(const rt_uint8_t c)
{
rt_size_t len = 0;
rt_uint32_t timeout = 0;
do
{
len = rt_device_write(eaix4_device, 0, &c, 1);
timeout++;
}
while (len != 1 && timeout < 500);
}
2.添加激光雷達控制命令
#include <finsh.h>
#define stop "-s"
#define force_stoppage "-fs"
#define start_scanning "-sc"
#define force_start_scanning "-fsc"
#define get_version_information "-gvf"
#define get_health_status "-ghs"
void Eaix4Scaning()
{
eaix4_putchar(0xA5);
eaix4_putchar(0x60);
}
void Eaix4stop()
{
eaix4_putchar(0xA5);
eaix4_putchar(0x65);
}
void Eaix4Version()
{
eaix4_putchar(0xA5);
eaix4_putchar(0x90);
}
void Eaix4Health()
{
eaix4_putchar(0xA5);
eaix4_putchar(0x91);
}
void eaix4cmd(int argc, char **argv)
{
if (argc > 1)
{
if (!rt_strcmp(argv[1], stop))
{
Eaix4stop();
}
else if (!rt_strcmp(argv[1], force_stoppage))
{
eaix4_putchar(0xA5);
eaix4_putchar(0x00);
}
else if (!rt_strcmp(argv[1], start_scanning))
{
Eaix4Scaning();
}
else if (!rt_strcmp(argv[1], force_start_scanning))
{
eaix4_putchar(0xA5);
eaix4_putchar(0x61);
}
else if (!rt_strcmp(argv[1], get_version_information))
{
Eaix4Version();
}
else if (!rt_strcmp(argv[1], get_health_status))
{
Eaix4Health();
}
else
{
rt_kprintf("ERROR command !\n");
}
}
}
MSH_CMD_EXPORT(eaix4cmd, -s - fs - sc - fsc - gvf - ghs);
MSH_CMD_EXPORT 的作用就是向 msh 中增加命令。
幾個主要的命令
命令行演示
實物:
文件列表:
目錄│文件列表:
└ LidarCar
│ project.uvprojx.lnk
├ doc
│ │ RM-MPU-9250A-00.pdf
│ │ rtthread_manual.zh.pdf
│ │ SDRAM布線規(guī)則.doc
│ │ STM32F429IGT6.pdf
│ │ YDLIDAR X4 使用手冊.pdf
│ │ YDLIDAR X4 開發(fā)手冊.pdf
│ └ YDLIDAR X4 數(shù)據(jù)手冊.pdf
├ picture
│ │ bsp選擇.png
│ │ PCB.jpg
│ │ 俯視圖.jpg
│ │ 命令行操作.gif
│ │ 掃描命令1.png
│ │ 掃描命令2.png
│ │ 效果演示.gif
│ │ 數(shù)據(jù).png
│ │ 正視圖.jpg
│ │ 激光雷達pcb接口.png
│ │ 激光雷達接口.png
│ │ 電機驅(qū)動電路.png
│ │ 硬件架構.png
│ │ 藍牙pcb接口.png
│ └ 軟件結(jié)構.png
└ rt-thread
│ .gitattributes
│ .gitignore
│ .travis.yml
│ AUTHORS
│ ChangeLog.md
│ Kconfig
│ LICENSE
│ README.md
│ README_zh.md
├ bsp
│ └ LidarCarBSP
│ │ .config
│ │ .gitignore
│ │ EventRecorderStub.scvd
│ │ Kconfig
│ │ LICENSE
│ │ project.uvoptx
│ │ project.uvprojx
│ │ README.md
│ │ rt-thread_stm32f4xx.BAT
│ │ rtconfig.h
│ │ rtconfig.py
│ │ SConscript
│ │ SConstruct
│ │ stm32_rom.icf
│ │ stm32_rom.ld
│ │ stm32_rom.sct
│ ├ applications
│ │ │ app_beep.c
│ │ │ app_beep.h
│ │ │ app_command.c
│ │ │ app_command.c.orig
│ │ │ app_command.h
│ │ │ app_eaix4.c
│ │ │ app_eaix4.h
│ │ │ app_motor.c
│ │ │ app_motor.h
│ │ │ app_move.c
│ │ │ app_move.h
│ │ │ app_mpu9250.c
│ │ │ app_mpu9250.h
│ │ │ app_slam.c
│ │ │ app_slam.c.orig
│ │ │ app_slam.h
│ │ │ app_speed.c
│ │ │ app_speed.h
│ │ │ app_uart.c
│ │ │ app_uart.c.orig
│ │ │ app_uart.h
│ │ │ app_wirelessuart.c
│ │ │ app_wirelessuart.h
│ │ │ event.c
│ │ │ event.h
│ │ │ main.c
│ │ │ main.c.orig
│ │ │ master_thread.c
│ │ │ master_thread.h
│ │ └ SConscript
│ ├ DebugConfig
│ │ │ rt-thread_stm32f4xx_STM32F401RCTx.dbgconf
│ │ └ rt-thread_stm32f4xx_STM32F429IGTx.dbgconf
│ ├ DMP
│ │ ├ driver
│ │ │ ├ eMPL
│ │ │ │ │ dmpKey.h
│ │ │ │ │ dmpmap.h
│ │ │ │ │ inv_mpu.c
│ │ │ │ │ inv_mpu.h
│ │ │ │ │ inv_mpu_dmp_motion_driver.c
│ │ │ │ └ inv_mpu_dmp_motion_driver.h
│ │ │ ├ include
│ │ │ │ │ log.h
│ │ │ │ │ mlinclude.h
│ │ │ │ │ mlmath.h
│ │ │ │ │ mlos.h
│ │ │ │ │ mltypes.h
│ │ │ │ │ mpu.h
│ │ │ │ └ stdint_invensense.h
│ │ │ └ stm32L
│ │ │ │ log_stm32.c
│ │ │ └ packet.h
│ │ ├ eMPL-hal
│ │ │ │ eMPL_outputs.c
│ │ │ └ eMPL_outputs.h
│ │ ├ mllite
│ │ │ │ data_builder.c
│ │ │ │ data_builder.h
│ │ │ │ hal_outputs.c
│ │ │ │ hal_outputs.h
│ │ │ │ invensense.h
│ │ │ │ message_layer.c
│ │ │ │ message_layer.h
│ │ │ │ mlmath.c
│ │ │ │ ml_math_func.c
│ │ │ │ ml_math_func.h
│ │ │ │ mpl.c
│ │ │ │ mpl.h
│ │ │ │ results_holder.c
│ │ │ │ results_holder.h
│ │ │ │ start_manager.c
│ │ │ │ start_manager.h
│ │ │ │ storage_manager.c
│ │ │ └ storage_manager.h
│ │ └ mpl
│ │ │ accel_auto_cal.h
│ │ │ compass_vec_cal.h
│ │ │ fast_no_motion.h
│ │ │ fusion_9axis.h
│ │ │ gyro_tc.h