小R科技-WIFI机器人网·机器人创意工作室

 找回密码
 立即注册
查看: 170354|回复: 137

【机器人创意工作室教程七】WIFI智能小车机器人驱动板源代码合成与编写

  [复制链接]
发表于 2012-9-27 22:56:51 | 显示全部楼层 |阅读模式
        WIFI机器人网·机器人创意工作室的驱动板源代码和上位机源工程早已公布出来,车友们可以任意修改并应用于自己制作的机器人和其他模型上面。不过最近工作室发现有个别人对工作室的代码稍作修改,就冠冕堂皇地开卖了,对于此种人我们不做过多评价,大家心里明白就行,这也是中国IT界的通病,放不放源码,的确很纠结!
        好了,言归正传,本期教程应许多单片机不太熟悉的车友的要求,对工作室驱动板源代码结构进行简单的讲解,并举两个例子说明如何合并工作室发布的新功能和如何自行拓展功能。驱动板硬件资料的详细说明在这篇帖子:http://www.wifi-robots.com/thread-158-1-1.html
         修改工作室的驱动板源代码需要安装keil 4,这个软件在我们各个群的共享里面有,自行下载后安装并破解即可。
         首先,来看看驱动板源代码的架构:

                                     源码架构.png
工作室发布的源代码一级目录大概如此,这里面有四个文件是我们要关注的,其他的文件都可以忽略。
1、最上面的lib文件夹:这个文件夹是驱动板的库文件,比如机械手驱动函数库,就在这里面。
2、Source文件夹:这个文件夹是驱动板的所有C代码放置的地方,我们重点要修改的就是这里面的程序。
3、motor_con.uvproj文件:此文件即工程文件,安装了keil 4之后,系统会自动关联,以后修改源代码就只需要双击这个图标即可。
4、motor_con.hex:  这个文件就是keil 4编译出来的固件,也就是要烧录到驱动板里面去的固件。

下面来看看二级目录。lib目录里面就只有一个库文件,这个一般不用关心,所以我们不再细看。主要是看Source文件夹:

                               Source.png
分别解释一下:
Config.h: 该文件保存有机器人的各种初始化信息,包括引脚定义、定时器定义、舵机初始角度、电机输出端口等等配置。这个文件也是我们最常修改的文件之一。
main.c:    主函数文件,这个文件中有一个main()函数,单片机的程序执行就是从这个main()函数开始的。
motor.c     电机、引脚初始化。
timer.c       定时器中断文件,包含各个定时器的中断实现。
uart.c         串口中断文件,与上位机的通信就在这里实现。
其他.h结尾的文件:均为头文件,包含各种函数的声明,有兴趣者可以自行打开。

基本文件的架构介绍完了,可以看出工作室的驱动板源代码架构层次是非常明朗的,这样很方便代码的编写和维护。

接下来,以工作室发布的一个升级包“上电点亮流水灯”为例,讲解一下如何合并代码。
首先从工作室的下位机源码发布帖中下载该升级包,解压可得到SelfTest.c,SelfTest.h,main.c三个文件。根据原有的源工程对比,可以发现,多了SelfTest.c,SelfTest.h这两个文件,同时,main.c文件中原来的代码是:
  1. 您可以任意修改本程序,并应用于自行研发的智能小车机器人及其他电子产品上,但是禁止用于向他人牟取暴利。
  2. By WIFI机器人网·机器人创意工作室
  3. */
  4. #include "stc_new_8051.h"
  5. #include "motor.h"
  6. #include "uart.h"
  7. #include <stdio.h>
  8. #include "type.h"
  9. #include "timer.h"

  10. void main(void)
  11. {
  12. UART_init();
  13. /* 定时器0作为舵机专用,不建议更改配置 */
  14. Timer0_Init();
  15. /* 定时器1为自由状态,用户可灵活使用 */
  16. Timer1_Init();
  17. Motor_Init();
  18.   while(1)
  19.   {
  20.       ;
  21.   }
  22. }
复制代码

现在变成了:
  1. 您可以任意修改本程序,并应用于自行研发的智能小车机器人及其他电子产品上,但是禁止用于向他人牟取暴利。
  2. By WIFI机器人网·机器人创意工作室
  3. */
  4. #include "stc_new_8051.h"
  5. #include "motor.h"
  6. #include "uart.h"
  7. #include <stdio.h>
  8. #include "type.h"
  9. #include "timer.h"
  10. #include "SelfTest.h"

  11. void main(void)
  12. {

  13. TestApp_Init();
  14. UART_init();

  15. /* 定时器0作为舵机专用,不建议更改配置 */
  16. Timer0_Init();
  17. /* 定时器1为自由状态,用户可灵活使用 */
  18. Timer1_Init();
  19. Motor_Init();

  20.   while(1)
  21.    {
  22.      ;
  23.    }
  24. }
复制代码
请注意如上的第10、15行代码部分。这就是在原有的C程序上修改的地方。
如果是原来没有的文件,比如说SelfTest.c,SelfTest.h,我们就可以直接把这两个文件按照源码发布帖那边的提示,放到Source文件夹下。
那么原来就有的main.c这个文件,我们就应该参考这两个文件的不同处,进行代码移植。
把上面的main.c文件中红色部分的代码,分别拷贝到原有的main.c文件相应的位置,保存即可。

至此,新的功能就移植完毕了,参考着每次源码发布帖里面的提示,其实非常简单的事情。移植完成后,需要重新生成一个新的固件,用keil 4的编译功能,点一下即可生成motor_con.hex文件,然后参考教程五,烧录到驱动板,新的功能就加进来了!

     那么如果想自己加入新的功能该怎么做呢?我们以加入“P22口控制的车灯”为例,假设开启车灯的指令为FF040100FF,关闭为FF040000FF。
首先,要先想好你要加入的功能需要用哪个管脚,你可以参考驱动板发布帖中的引脚说明图自行选择。现在,我们是准备用P22这个口来控制车灯,所以第一步就是在Config.h文件里面加入引脚定义:
  1. sbit MAINLIGHT_CON=P2^2;
复制代码
    这就定义了,我们接车大灯是P22这个接口。
然后,在motor.h文件中,定义车大灯的宏定义,这样我们在具体的调用中就不用使用MAINLIGHT_CON=1这种很不直观的方式了,方便代码的阅读理解。
  1. #define MAINLIGHT_TURNON MAINLIGHT_CON=0;
  2. #define MAINLIGHT_TURNOFF MAINLIGHT_CON=1;
复制代码
    从上面的宏定义可以看到,车灯打开这个宏执行时,MAINLIGHT_CON这个引脚,也就是P22脚是低电平的,此时如果外面是高电平,那么车灯就亮了,而当执行车灯关闭这个宏定义时,MAINLIGHT_CON=1,是高电平,车灯就关闭了。当然,这里用的是灌电流,也可以使用拉电流方式,但是比较驱动力比较弱,车灯没那么亮。

第三步,做完了车大灯的宏定义之后,我们就来具体实现车灯工作了。
工作室驱动板的所有动作执行都在串口中断里面,所以我们需要修改Uart.c文件。打开Uart.c文件,找到void Communication_Decode(void) 函数,此函数是解析上位机发送的数据包的,我们的车灯执行函数就要加在这里。
  1. void Communication_Decode(void)
  2. {
  3. if(buffer[0]==0x00)
  4. {
  5. switch(buffer[1])
  6. {
  7. case 0x01:MOTOR_GO_FORWARD; return;
  8. case 0x02:MOTOR_GO_BACK; return;
  9. case 0x03:MOTOR_GO_LEFT; return;
  10. case 0x04:MOTOR_GO_RIGHT; return;
  11. case 0x00:MOTOR_GO_STOP; return;
  12. default: return;
  13. }
  14. }
  15. else if(buffer[0]==0x01)
  16. {
  17. if(buffer[2]>180)
  18. return;
  19. switch(buffer[1])
  20. {
  21. case 0x01:se_timer[0]=buffer[2]; return;
  22. case 0x02:se_timer[1]=buffer[2]; return;
  23. case 0x03:se_timer[2]=buffer[2]; return;
  24. case 0x04:se_timer[3]=buffer[2]; return;
  25. case 0x05:se_timer[4]=buffer[2]; return;
  26. case 0x06:se_timer[5]=buffer[2]; return;
  27. case 0x07:se_timer[6]=buffer[2]; return;
  28. case 0x08:se_timer[7]=buffer[2]; return;
  29. default : return;
  30. }
  31. }
  32. else if(buffer[0]==0x04) //车灯控制使用灌电流方式
  33. {
  34. switch(buffer[1])
  35. {
  36. case 0x01:
  37. MAINLIGHT_TURNON;
  38. break;
  39. case 0x00:
  40. MAINLIGHT_TURNOFF;
  41. break;
  42. default:return;
  43. }

  44. }
  45. else
  46. {
  47. return;
  48. }
  49. }
复制代码
从上面的第32行-45行代码可以看到,我们在if分支上多了一个分支,这个分支用以判断是否上位机的开灯数据包到来了,如果发现类型位为0x04且命令位为0x01,那么只需MAINLIGHT_TURNON;
这个宏定义,也就是把P22引脚给拉低了,即对FF040100FF这个命令做出开灯动作。反之,则拉高P22引脚,车灯熄灭。

OK,在Keil 里面执行编译,即可生成包含P22大灯的驱动固件了,还等什么?赶紧烧录到驱动板里面,开到床底下找东西去吧~~~





评分

参与人数 1金钱 +1 收起 理由
渴望蓝天Sam + 1 很给力!

查看全部评分

回复

使用道具 举报

发表于 2012-9-27 22:58:10 | 显示全部楼层
沙发,管理员出品,必是精品,嘿嘿
回复 支持 反对

使用道具 举报

发表于 2012-9-28 11:00:57 | 显示全部楼层
哈哈,,,辛苦啊   这下我得好好看看,争取来自己写, 有的时候合并的时候会有冲突 ,可能是共用了一个端口了吧。不过我现在雷达还是不好用,单刷雷达的那个也是一样,雷达里不会不信号
回复 支持 反对

使用道具 举报

发表于 2012-9-28 13:06:22 | 显示全部楼层
的确,好了学习学习啦,谢谢分享
回复 支持 反对

使用道具 举报

发表于 2012-9-29 16:16:23 | 显示全部楼层
管理员出品,必是精品
回复 支持 反对

使用道具 举报

发表于 2012-9-29 21:35:39 | 显示全部楼层
学习支持?????

回复 支持 反对

使用道具 举报

发表于 2012-10-1 23:09:30 | 显示全部楼层
学习 支持  
回复 支持 反对

使用道具 举报

发表于 2012-10-1 23:12:52 | 显示全部楼层
学习 支持  
回复 支持 反对

使用道具 举报

发表于 2012-10-2 12:39:40 | 显示全部楼层
很好 先收藏了
回复 支持 反对

使用道具 举报

发表于 2012-10-2 15:06:23 | 显示全部楼层
持续关注。。。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

新品特惠推荐上一条 /2 下一条

QQ|QQ技术咨询1|QQ技术咨询2|商务合作微信1:xiaorgeek001|商务合作微信2:XiaoRGEEK|诚聘英才|Archiver|手机版|小R科技-WIFI机器人网·机器人创意工作室 ( 粤ICP备15000788号-6 )

GMT+8, 2024-4-25 19:12 , Processed in 1.093978 second(s), 29 queries .

Powered by XiaoR GEEK X3.4

© 2014-2021 XiaoR GEEK

快速回复 返回顶部 返回列表