




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、如何快速构建一个智能小车RTOS入门实战篇构建一个智能小车具体功能:能够实现小车的,使小车追随手掌的而。模块避障模块目标目录如何在开发板上运行RT-ThES32F0334硬件硬件使用调试器连接开发板和PC端硬件连接Ø 安装MDK5Ø 安装对应的packageØ 安装需要的驱动文件Ø RT-Th源代码搭建环境根目录名描述bsp板级支持包componentsRT-Th的各个组件代码,例如文件系统, shellincludeRT-Th内核的头文件libcpu各类的移植代码,此处包含了Cortex-M0的移植文件srcRT-Th内核的源文件源码结构说明bsp目录
2、下描述applicationsRT-Th的用户例程, 应用层代码就写到这里driversRT-Th的驱动,不同平台的底层驱动具体实现Libraries所用的固件库文件Project.uvprojxKEIL5 工程文件BSP目录结构工程源码连接终端工具运行结果运行结果如何配置BSP解压 env.zip 压缩文件,双击打开EnvEnvenv到右键快捷菜单Envenv到右键快捷菜单后 es32f0334 目录下右键打开env配置工程配置工程开启Sensor框架和。配置工程,保存设置;输入命令 scons target=mdk5 重新生成工程配置工程运行,输入 list_device 查看编译并备。到
3、系统中的设配置工程模块模块也就是小车的模块,他的作用是让小车能够跑起来。那么如何让单片机小车的呢?电Ø 比较常见的方式是:使用信号通过电机驱动板机,进而小车的。电机1电机驱动板MCU电机2模块每个车轮都对应,通过调节的占空比,产生不同大小的电压,就可以了。车轮旋转的快慢和方向右旋停转左旋左侧电压大于右侧电压左侧电压等于右侧电压左侧电压小于右侧电压模块在RTOS中,编程的思路就是多线程的编程,把一个系统拆分成一个个小而具体的任务,他们之间相互各自的任务。并完成线程就是RT-Th中最基本的调度,每一个线程就对应一个任务,有各自的优先级。因此,我们可以创建一个线程,用来小车的。模块/* m
4、otion1.c */int motion_init(void)rt_th_t motion_tid = RT_NULL;= (struct rt_device_*)rt_device_find(_NAME);motion_tid = rt_th_create("mot_th", motion_th_entry, RT_NULL, 512, 5, 12); if (motion_tid != RT_NULL)rt_th_startup(motion_tid);return 0;创建线程/* applications/motion1.c */static struct rt_
5、device_*= RT_NULL;/*句柄*/static rt_uint16_t pulse_lf = MOTION_PERIOD / 2, pulse_lb, pulse_rf = MOTION_PERIOD / 2, pulse_rb;static void motion_th_entry(void *parameter)while(1)rt_set(, LEFT_FORWARD_CH , MOTION_PERIOD, pulse_lf); rt_set(, LEFT_BACK_CH, MOTION_PERIOD, pulse_lb);rt_set(, RIGHT_FORWARD_CH
6、, MOTION_PERIOD, pulse_rf); rt_set(, RIGHT_BACK_CH, MOTION_PERIOD, pulse_rb);rt_kprintf("lf:%d, lb:%d, rf:%d, rb:%dn", pulse_lf, pulse_lb, pulse_rf, pulse_rb); rt_th_mdelay(100);创建线程添加applications目录下motion1.c 文件到工程里,然后在mian.c 里调用motion_init() 即可完成模块的初始话,然后调用motion_start()小车就开始前进了。创建线程编译并运行
7、创建线程参考main函数里LED闪烁的实现,再创建一个线程实现跑马灯的效果。把test1.c中的内容替换到main.c,补充剩余部分代码。实验一:创建一个线程static void led_entry(void *parameter)while(1)rt_pin_write(LED1_PIN, PIN_HIGH); rt_pin_write(LED2_PIN, PIN_LOW); rt_th_mdelay(500); rt_pin_write(LED1_PIN, PIN_LOW); rt_pin_write(LED2_PIN, PIN_HIGH); rt_th_mdelay(500);实验一:
8、创建一个线程int main(void)rt_th_t led_tid = RT_NULL;/* set PC08/PC09 pin mode to output */ rt_pin_mED1_PIN, PIN_MODE_OUTPUT); rt_pin_mED2_PIN, PIN_MODE_OUTPUT);led_tid = rt_th_create("led_th", led_entry, RT_NULL, 512, 5, 12); if (led_tid != RT_NULL)rt_th_startup(led_tid); motion_init();return RT
9、_EOK;实验一:创建一个线程避障模块避障模块的功能是根据小车距手掌的距离的不同,调整小车的,实现小车随手掌的移动而移动的效果。测距模块使用的是HC-SR04超声波测距模块,驱动已经实现,可以直接使用。避障模块将驱动文件port.c和hc_sr04.c添加到工程,传感器就自动到系统上了。输入 list_device 命令,可以查看到系统的传感器。避障模块在进行多线程编程的时候,要注意:当一个线程在无事可做、空闲的时候要及时的让出CPU,以便让其他的线程获得CPU运行。对于传感器来说,数据到达的时间是不确定的,为了不占据CPU资源,最好使用中断接收的方式。但是,如果直接在接收中断里处理数据的话,
10、会降低系统的实时性。所以,数据处理是在线处理数据。进行,中断只是做一个通知,通知线程去在中断和线程间进行通信时,我们制。使用信号量作知机避障模块信号量是RT-Th中一种轻型的用于解决线程间、中断的API,通过使与线程之间同步问题的内核对象,它有用这些API可以完成线程间同步或互斥的目的。信号量常用的部分API如下所示:函数描述rt_sem_create()创建信号量rt_sem_delete()删除信号量rt_sem_take ()获取信号量rt_sem_trytake()无等待获取信号量rt_sem_release()信号量信号量传感器中断模式使用流程:接收线程超声波中断模式打开中断回调中断
11、回调信号量获取到信号量读数据获取不到信号量,挂起避障模块避障模块的实现/* evade1.c */static rt_err_t evade_rx_callback(rt_device_t dev, rt_size_t size)rt_sem_release(evade_rx_sem);return 0;int evade_init(void)static rt_th_t evade_th_tid = RT_NULL; rt_device_t dev = RT_NULL;evade_rx_sem = rt_sem_create("evade_sem", 0, RT_IPC_
12、FLAG_FIFO);/* 创建数据处理线程的相关代码 */ dev = rt_device_find(DEV_NAME);rt_device_open(dev, RT_DEVICE_FLAG_INT_RX); rt_device_set_rx_indicate(dev, evade_rx_callback); return 0;避障模块static void evade_th_entry(void *parameter)rt_device_t dev = parameter; struct rt_sensor_data data; rt_size_t res;while (1)rt_sem_
13、take(evade_rx_sem, RT_WAITING_FOREVER); res = rt_device_(dev, 0, &data, 1);if (res = 1)/* 处理数据*/避障模块我们在处理数据的线,根据距离的变化改变小车的行为。为了达到小车随手一起的效果,我们可以弄一个简单的小车行为和离手距离的对应,如下表所示:避障模块/* evade1.c */if(ximity = 0 | ximity > 300)rt_kprintf("motion stopn");else if(data.da
14、ximity < 100)rt_kprintf("motion backn");else if(ximity < 200)rt_kprintf("motion stopn");else if(ximity < 300)rt_kprintf("motion forwaldn");避障模块将 evade1.c 添加到工程,并在 main.c里调用evade_init函数即可完成避障模块的初始化。避障模块led的亮灭,每当按下使用信号量,用按键的中断来key1
15、就改变一次led的亮灭状态。把test2.c中的内容替换到main.c,补充剩余部分代码。实验二:使用信号量同步static void led_entry(void *parameter)while(1)rt_sem_take(led_rx_sem, RT_WAITING_FOREVER);if(rt_pin_(LED1_PIN) = PIN_LOW)rt_pin_write(LED1_PIN, PIN_HIGH);rt_kprintf("led1 offn");elsert_pin_write(LED1_PIN, PIN_LOW);rt_kprintf("led
16、1 onn");void key1_callback(void *args)rt_kprintf("key down!n"); rt_sem_release(led_rx_sem);实验二:使用信号量同步编译代码到开发板,运行。运行结果现在,模块是一个线程,避障模块也是一个线程,如何做才能让这两个线程通讯,使避障模块触发模块,进而小车的呢?这里就要引入集的概念了。使用避障模块触发模块集主要用于线程间的同步,与信号量不同,它的特点是可以实现一对多,多对多的同步。即一个线程与多个的都设置为:其中任意一个唤醒线程,或几个到达后才唤醒线程进行后续的处理。集工作机制RT-T
17、h定义的集有以下特点:ØØ每个线程可拥有32个标志;(如果线程还未来得无排队性,即多次向线程发送同一及读走),其效果等同于只发送一次;集特点集的部分API如下所示:函数描述rt_event_create()创建集rt_event_delete()删除集rt_event_send()发送rt_event_recv()接收集如何将原本的新一次应该改为集应用到模块和避障模块之间呢?模块就是一个轮询的模式,每隔100ms更量,这种模式实时性太差了。的驱动的模式,就是在的API,当没有模块的线程里到达的时候,就说明添加一个接收小车的状态不需要改变,线程就停在这里。当避障模块要改变小车
18、的状态时,就发一个通知模块,模块接收到之后就继续运行,更新一次的量。避障模块修改模块,添加的机制/* motion2.c */#define MOTION_CHANGE(1 << 0)static void motion_th_entry(void *parameter)rt_uint32_t e; while (1)rt_event_recv(motion_event, MOTION_CHANGE, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, &e);rt_set(, LEFT_FORWARD_C
19、H, MOTION_PERIOD, pulse_lf); rt_set(, LEFT_BACK_CH, MOTION_PERIOD, pulse_lb);rt_set(, RIGHT_FORWARD_CH, MOTION_PERIOD, pulse_rf); rt_set(, RIGHT_BACK_CH, MOTION_PERIOD, pulse_rb); rt_kprintf("lf:%d, lb:%d, rf:%d, rb:%dn", pulse_lf, pulse_lb, pulse_rf, pulse_rb);避障模块避障模块void motion_forward(
20、void)pulse_lf = MOTION_ pulse_lb = 0; pulse_rf = MOTION_ pulse_rb = 0;_PERIOD / 2;_PERIOD / 2;rt_event_send(motion_event, MOTION_CHANGE);MSH_CMD_EXPORT(motion_forward, motion forward);void motion_back(void)pulse_lf = 0; pulse_lb = MOTION_ pulse_rf = 0; pulse_rb = MOTION_PERIOD / 2;_PERIOD / 2;rt_eve
21、nt_send(motion_event, MOTION_CHANGE);MSH_CMD_EXPORT(motion_back, motion back);的motion1.c替换为motion2.c,并在main.c中完成将工motion模块的初始化。编译到开发板上之后,输入对。应令可以小车的避障模块然后修改避障模块的实现,将打印log的语句换为模块的接口。if(ximity = 0 | ximity > DIS_STOP)motion_stop();else if(ximity < DIS_NEAR)motion_back();motion_start();else if(ximity < DIS_FAR)motion_stop();避障模块的evade1.c替换为evade2.c,并在main.c中添加将工evade模块的初始化。编译到开发板上之后,避障模小
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 烟囱安全评估协议
- 通信光缆铺设围挡施工合同
- 数据泄露赔偿协议
- 石家庄市电影院租赁合同
- 设备转让协议书签订
- 房地产合同定制
- 城市文化国标施工合同样本
- 体育馆工程围墙施工合同
- 商业大楼硬化施工合同
- 教育机构教师劳动合同样本
- ZZ028 中职法律实务赛项赛题-2023年全国职业院校技能大赛拟设赛项赛题完整版(10套)
- 深基坑工程设计方案专项论证意见
- 青岛版二年级数学下册《周期问题》教案
- GB/T 307.1-2005滚动轴承向心轴承公差
- GB/T 23468-2009坠落防护装备安全使用规范
- GB/T 14801-2009机织物与针织物纬斜和弓纬试验方法
- 国家开放大学电大《计算机应用基础(本)》终结性考试试题答案(格式已排好)任务一
- 2023年惠州市交通投资集团有限公司招聘笔试题库及答案解析
- 第一学期期末大作业(经济学)
- 腮腺肿瘤课件
- 变压器保护课件
评论
0/150
提交评论