【TI-RSLK 试用报告】+ 避障小车

[复制链接]

1

主题

4

帖子

30

积分

一粒轻沙

Rank: 1

积分
30
楼主
查看: 7037回复: 3 发表于 2019-3-5 23:25:51   只看该作者
本帖最后由 电赛小编 于 2019-4-11 17:42 编辑

      大约23号下午收到机器人套件,急忙拿着回家,到手后怀着激动的心情打开,结果少了5个螺丝:L,盒子里面是2个手册,外加小车的各种套件,金属底盘还是挺好看的,以前就玩过以低功耗为特点的msp430,msp432和msp430(图1)长得很像。但是430有点老了,16位的单片机也过时了,432的到来TI还是有意识的。好了废话不多说,进入主题。
      MSP432还是以ARMCortex-M4F为内核(图2,ARM的合作伙伴),本文将以CCS(图3)作为IDE来编写程序,用图文展示一个避障小车的一步步成型。
       首先准备材料:TI小车一部,CCS安装包一个,CCS程序包及相关软件一个,TI培训课程一套,MSP432数据手册和引脚图(图4

       1.小车,要注意螺丝很多,不要掉了。盒中没有J-link,ST-link之类的仿真器,直接用线连就可以。要注意线的安全,车下的传感器的线很容易弄坏,由其是从底盘的洞中塞的时候。

       2.关于IDE安装包,Keil,IAR,CCS都可以用,注意安装时的选项就行。但是因为是TI赞助的,我就用CCS了(第一次用),还有就是下载CCS时最好不要用下载器,直接下安装包就好。下载器会因为网络问题波动很大。
       3.CCS程序包及相关软件,链接:CCS程序包
      4.TI培训课程,要注意有一节是没有中文的,不过无伤大雅,下面是课程介绍和我的学习过程
         (1)电流和电压,主要是介绍电流电压电阻的关系,学好物理就行:lol,还介绍了TI的软件示波器,在程序包的文件夹里
         (2)ARM芯片的介绍,比如用的Cortex-M系列的内核,介绍了冯诺依曼和哈佛结构(猜猜单片机是哪个?)后面又介绍了寻址和汇编,以及ROM和RAM,还有大小端存储,RISC和CISC的关系
          (3)MSP432,主要介绍了中断和断点
          (5)电池电压调节,介绍了电池的供电和超频,说起超频我想起了当时做过的飞思卡尔的KEAZ128,为了提高性能,超频是最有用的,还有一个问题,你知道VCCVDDVSS,GND,AGND,DGND,PGND之间的区别吗?
          (6)GPIO,主要是介绍了IO口的通常用法和寄存器,各个IO口都有自己独特的功能,比如PWM,中断。。。。其实从这往后都是数据手册的领域了,而且TI的数据手册很有意思,比如IO口,P1口和P2口可以合成PA,用半字操作写入端口PA时,所有的16位都写入端口,当用字节操作写入端口PA的下字节时,上字节保持不变,所以说MSP432中int字长应该是2还是4,(keil,VC++,TC)
           (7)有限状态机,比如mealy状态的转变不仅和当前状态有关,而且跟各输入信号有关,Moore状态机状态的转变只和当前状态有关,寻线的指导理论。
           (8)连接输入与输出,主要说触碰开关,正负逻辑的设计,再次强调LED的作用。
           (9)SysTick 定时器,脉宽调制,PWM,定时/计数器的工作原理和相关寄存器,电机响应的正弦曲线
           (10)调试实时系统,主要介绍了中断向量表,优先级,种类
           (11)液晶显示屏,说到这让我想起了LCD1602,12864,OLED,只要弄好通讯和引脚就没有问题,还有就是本单片机中同步串行通信大约 6 微秒,如果慢,可以采用DMA。
           (12)直流电机,主要介绍了电机内部结构,而且PWM的方向控制很有意思,方向引脚以及直接用PWM控制方向
           (13)定时器 ,定时器来生成脉宽调制输出,轮子相同的PWM但其速度还是有差别,所以我们可以用PID控制,形成闭环
           (14)实时系统 ,主要还是讲中断
           (15)数据采集系统,信号采集的平均值作为返回值,可以提高信噪比,在以前做体重仪的时候,采集10次取平均值,才能做到精准测量
           (16)转速计,其实就是我们经常用的编码器,光电码盘,与其类似。不过他是给你发上升沿,1圈360个,没有涉及正交解码
           (17)控制系统,主要讲了PID控制,
           (18)串行通讯,就是UART,做好功课,了解原理和名词就行,比如波特率和比特率。
           (19)(20)这都是套装里没有的就不多说了,想学的可以去查,主要就是CC2650,ZigBee,WiFi。这3种无线技术,从传输距离来说,是WIFI>ZigBee>蓝牙;从功耗来说,是WIFI>蓝牙>ZigBee,后两者仅靠电池供电即可; 从传输速率来讲,是WIFI>蓝牙>ZigBee。目前来说,WIFI的优势是应用广泛,已经普及到千家万户;ZigBee的优势是低功耗和自组网;UWB无载波无线通信技术的优势是传输速率;蓝牙的优势组网简单。
           剩下的就是程序的编写和思路了,因为要做避障小车,主要用车子前端的触碰开关,电机,测速计,后方的距离传感器。所以我们用的技术就是IO口的输入,ADC的检测,上升沿的检测,以及中断和优先级设置,还有定时器的定时检测。所以我前进时触碰开关设为第一优先级,后退时距离检测器优先,所以用定时器一直循环,就可以实现避障小车的避障。下面是主要程序。
  1.   DisableInterrupts();  
  2.   Clock_Init48MHz();
  3.   LaunchPad_Init();   // built-in switches and LEDs
  4.   Bump_Init();        // bump switches
  5.   Motor_InitSimple(); // initialization
  6.   Tach_Init(); //tachometer
  7.   EnableInterrupts();
  8.   Distance_Init(); //Distance measure
  9.   while(1){
  10.       Detection();
  11.      }
复制代码
其实中断和定时是最难的,也是最精粹的,接下来是诉苦时间,哈哈。TI公司从我刚进大学就有耳闻,学校还有TI的合作实验室但是一直没用TI的核心板,只用了TPS63070,很惊艳,就是不好焊,想起当时的数据手册看的我头皮发麻,一句一句翻译,电阻还选错了,害我烧了板子,焊板子也难受,因为引脚都在下面,VQFN封装。后来就是一直用ST的32,恩智浦的KEA和K60,现在用TI的板子一个最大的问题就是程序少,数据手册是英文还可以克服,还有就是教程的所用下载包有点难受,开始时一直没找到,直到后来才发现,还有寄存器编程真难受,想库了,不过这是必经的路。这次看数据手册一开始半天都没找到IO口的寄存器,没想到在后面,我还以为是GPIO,PORT之类的名字,还有就是检测黑线的红外还需要充能。。。。没想到。TI的网上资料还是少了,尤其是微处理器方面,希望用的人越来越多。插一句:有一点我要说,CCS我开始没抱希望,不过很好用(真香),尤其是鼠标移到函数上下方会出现函数的释义框,惊艳。没有Keil的日常崩溃(狗头)
最后感谢电赛论坛的小编**姐,TI论坛的SusanYang,(日常泡TI,还是挺好的),以及 TI和全国大学生电子设计竞赛培训网给我们的机会,谢谢。



打赏

参与人数 1赫兹币 +5 收起 理由
jason-peng + 5 赞一个!

查看全部打赏

20

主题

124

帖子

290

积分

二氧化硅

Rank: 2

积分
290
沙发
发表于 2019-3-6 10:26:20   只看该作者
感谢楼主的分享,非常的详细,尤其是代码,能给予的启发很多,希望能有更多人能像楼主一样分享宝贵的经验。:)

2

主题

26

帖子

240

积分

慕课讲师

积分
240
板凳
发表于 2019-3-6 12:54:57   只看该作者
赞美楼主!非常详细的试用报告!:)

1

主题

4

帖子

30

积分

一粒轻沙

Rank: 1

积分
30
4#
发表于 2019-3-9 23:44:14   只看该作者
IO口设置
  1. void Port1_Init(void){
  2.   P1->SEL0 = 0x00;
  3.   P1->SEL1 = 0x00;                        // P1.4,P1.1选择通用I/O
  4.   P1->DIR = 0x01;                         // P1.4 ,P1.1 输入, P1.0 输出
  5.   P1->REN = 0x12;                         // 启用上拉或下拉
  6.   P1->OUT = 0x12;                         // 上拉
  7. }
复制代码

触碰开关bump
  1. // P4.7,P4.6,P4.5,P4.3,P4.2,P4.0
  2. void Bump_Init(void){
  3.     P4->SEL0 &= ~0xED;//选择通用I/O   0001 0010
  4.     P4->SEL1 &= ~0xED;
  5.     P4->DIR &= ~0xED;//配置为输入
  6.     P4->REN |= 0xED;//1110 1101启用上拉或下拉
  7.     P4->OUT |= 0xED;//下拉
  8. }
复制代码

线传感器
  1. void Reflectance_Init(void){
  2.     P7->SEL0 &= ~0xFF;
  3.     P7->SEL1 &= ~0xFF;
  4.     P7->DIR &= ~0xFF;
  5.     P5->SEL0 &= ~0x08;
  6.     P5->SEL1 &= ~0x08;
  7.     P5->DIR |=0x08;
  8. }
复制代码

Timer_A中断
  1. //***********************A2*****************************//
  2. void TimerA2_Init(void(*task)(void), uint16_t period){
  3.   TimerA2Task = task;             // 用户功能
  4.   TIMER_A2->CTL &= ~0x0030;       // 停止定时器A2
  5.   TIMER_A2->CTL = 0x0280;
  6.   TIMER_A2->CCTL[0] = 0x0010;
  7.   TIMER_A2->CCR[0] = (period - 1);   // 比较匹配值
  8.   TIMER_A2->EX0 = 0x0005;    // 时钟分频器/6
  9. // 所有设备初始化后在主程序中启用的中断
  10.   NVIC->IP[3] = (NVIC->IP[3]&0xFFFFFF00)|0x00000040; // 优先级2
  11.   NVIC->ISER[0] = 0x00001000;   // 在NVIC中启用中断12
  12.   TIMER_A2->CTL |= 0x0014;      // 在上升模式下重置和启动计时器A2
  13. }

  14. void TimerA2_Stop(void){
  15.   TIMER_A2->CTL &= ~0x0030;       //停止计时器A2
  16.   NVIC->ICER[0] = 0x00001000;     // 禁用NVIC中的中断12
  17. }

  18. void TA2_0_IRQHandler(void){
  19.   TIMER_A2->CCTL[0] &= ~0x0001; // 确认捕获/比较中断0
  20.   (*TimerA2Task)();             // 执行用户任务
  21. }
复制代码

电机motor
  1. void Motor_Init(void){
  2.     P1->SEL0 &= ~0xC0;//0011 1111,P1.6,P1.7
  3.     P1->SEL1 &= ~0xC0;
  4.     P2->SEL0 &= ~0xC0;//P2.6,P2.7
  5.     P2->SEL1 &= ~0xC0;
  6.     P3->SEL0 &= ~0xC0;//P3.6,P3.7
  7.     P3->SEL1 &= ~0xC0;   //初始化6个GPIO线路并将驱动程序置于休眠状态
  8.     P1->DIR |= 0xC0;// 1100 0000配置为输出
  9.     P2->DIR |= 0xC0;
  10.     P3->DIR |= 0xC0;
  11.     P3->OUT &= ~0xC0;//0011 1111输出低电平
  12. }
复制代码

PWM
  1. void PWM_Init1(uint16_t period, uint16_t duty){
  2.   if(duty >= period) return;     // bad input
  3.   P2->DIR |= 0x10;               // P2.4 output
  4.   P2->SEL0 |= 0x10;              // P2.4 Timer0A functions
  5.   P2->SEL1 &= ~0x10;             // P2.4 Timer0A functions
  6.   TIMER_A0->CCTL[0] = 0x0080;    // CCI0 toggle    比较模式:输入选择 CCIxA(外部触发),异步捕获, 当计时器计数到 TAxCCRn值时,将切换输出。输出周期是定时器周期的两倍。
  7.   TIMER_A0->CCR[0] = period;     // Period is 2*period*8*83.33ns is 1.333*period   保存数据(比较或者捕获)周期,分母
  8.   TIMER_A0->EX0 = 0x0000;        //    divide by 1 扩展寄存器,除法器
  9.   TIMER_A0->CCTL[1] = 0x0040;    // CCR1 toggle/reset        当计时器计数到taxccrn值时,将切换输出。当计时器计数为taxccr0值时,将被重置。
  10.   TIMER_A0->CCR[1] = duty;       // CCR1 duty cycle is duty1/period    占空比,分子
  11.   TIMER_A0->CTL = 0x0230;        // SMCLK=12MHz, divide by 1, up-down mode 0010 0011 0000,时钟源SMCLK,分频/1,上升下降模式,不允许中断
复制代码
转速计或者编码器
  1. void Tachometer_Init(void){
  2.   P9->SEL0 &= ~0x04;//  P9.2 作为输入口
  3.   P9->SEL1 &= ~0x04;               
  4.   P9->DIR &= ~0x04;               
  5.   P10->SEL0 &= ~0x20; // P10.5作为输入口
  6.   P10->SEL1 &= ~0x20;              
  7.   P10->DIR &= ~0x20;              
  8.   TimerA3Capture_Init(&tachometerRightInt, &tachometerLeftInt);//定时器A3取左右轮胎的转速
  9. }
复制代码
以上就是大体的各部分初始化



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