分类: 飞思卡尔智能车 Freescale Intelligent Car

记录飞思卡尔智能车竞赛的教训、经验和心得。

  • 14 – 输出控制:电机输出

    电机输出是车轮的动力来源,智能车的控制最后都要落实到电机输出。
    参考 https://feichashao.com/ftm/

    输出到电机的电压是不变的(12V),要控制输出动力大小,就要控制占空比的大小。
    占空比越大,动力输出越大。(可以当作是线性的)

    对于平衡直立车,输出动力的大小应该是 直立控制量+速度控制量+方向控制量 的叠加,而且左右轮各自的量是不一样的。
    获得了直立速度方向控制量的总和,就可以输出到电机上了。
    (更多…)

  • 13 – 读取传感器:数字摄像头

    读取摄像头是高潮,运气好的话几行代码一调就出来,不幸的话,整一个多月发现摄像头原来是坏的orz…

    时序关系

    帧。 帧是一幅完整的图像。以我们所用的数字摄像头为例(型号我忘了),默认设置下1秒有30帧。

    场。 一帧包含两个场,奇数场和偶数场。奇数场传送奇数行数据,偶数场传送偶数行数据。如果一帧(一副完整图片)有480行,那么奇数场和偶数场会各有240行,奇数场传第1,3,5….行,传完后到偶数场传2,4,6….行。奇数场和偶数场传送的是同一幅图像的不同行,对提取道路信息来说,只使用奇数场/偶数场的数据就足够了。每一场的开始,会出现一个场中断。

    行。 如果一幅图像是640*480,那么一行就有640个像素点。 每一行的开始,会出现一个行中断。
    (更多…)

  • 12 – 读取传感器:编码器

    对于四轮车,只要电机的输出保持恒定,速度基本是恒定的。
    但平衡直立车要控制直立,就算是原地不动,电机的输出每时每刻都在发生变化。
    所以,要进行速度控制,获得当前小车的实际速度相当重要。


    编码器有好多种,主要区别是单向双向,200线500线等不同精度,AB相输出,AZ相输出等区别。
    其实对于平衡直立车,左右轮各一个200线的单向编码器就足够了。(大概100元一个)

    200线的单向编码器,有一个A相输出,简单地说,就是轮子转一圈,就输出200个脉冲,也就是每转1/200圈,编码器就输出一个脉冲。
    通过统计单位时间的脉冲,即可得到小车当前的行走速度。

    K60有两个脉冲计数模块,够用。
    XS128只有一个脉冲计数模块,需要在电路上另加一个加计数器(74LS系列即可)进行计数。

    (更多…)

  • 11 – 读取传感器:加速度计、陀螺仪

    平衡直立车要想保证直立,得知当前角度和角速度尤为重要;
    加速度计常用两种:数字加速度计和模拟加速度计;
    数字加速度计一般通过I2C来传送数据,模拟加速度计直接给出电压读数;
    模拟加速度计使用较为简单,而且读取速度和精度基本能满足平衡直立车的需求;
    数字加速度计可以进行丰富的配置,获得更加理想的数据而不耗费单片机过多资源。
    陀螺仪用来测量角速度。这里用的是模拟陀螺仪,直接用ADC读数。

    计算角度的方法

    牛顿老人家说过: F = ma; 加速度计能测量加速度a,从而可以得知测量方向上所受的重力分量;
    accelerometer
    测出小车前后水平放置时,加速度计的读数,可以得到±G的读数。小车行走时,加速度计的读数除以G的读数,就能得到角度值了。
    具体请参考互补滤波算法:https://feichashao.com/balance_filter/
    (更多…)

  • 10 – 中断:中断优先级

    前面讲到了各种中断。
    PIT中断用于控制小车的直立速度角度;
    EXTI中断用于处理摄像头的行场中断;
    UART中断用于串口通信;

    直立控制必须1ms进行一次计算,所以PIT中断一次都不能少;
    摄像头的行场中断缺一不可,而且行场中断来了必须马上处理,处理过程不能暂停,否则图像会采集出错;
    UART不要求马上反应,但需要处理每个请求;

    那么问题来了,一个中断正在处理的时候,另一个中断来了,怎么办?
    中断优先级的设置,可以让每个中断都得到处理,且能按照优先级进行中断嵌套。(优先级低的中断正在处理的时候,来了优先级高的中断,会先暂停优先级低的中断,执行完优先级高的中断后再继续进行处理。)

    好消息是,在K60和XS128中设置中断优先级都不难。
    (更多…)

  • 9 – 中断:PIT定时中断

    PIT是个非常准的定时中断(相比delay函数来说),说好的1ms触发一次中断就是1ms触发一次。
    PIT是平衡直立车的灵魂,因为角度计算,速度计算,和方向控制都高度依赖于积分,而积分的“单位时间”5ms靠的就是PIT中断。

    PIT中断的配置也很简单。设置好中断时间间隔(这里是1ms),写好中断处理函数,就可以啦。
    要注意的是,中断处理函数要尽可能简单,把复杂的工作留给主循环。

    K60

    这里用野火的底层库,详情请参考《三天入门 Cortex-M4——Kinetis 系列》PIT 定时中断模块。

    初始化

    函数原型
    [cc lang=”C”]
    void pit_init(PITn,u32 cnt);
    [/cc]
    调用示例
    [cc lang=”C”]
    pit_init(PIT0,100000); //初始化 PIT0,定时 100000 个时钟周期
    [/cc]

    中断处理

    中断重定向
    [cc lang=”C”]
    #undef VECTOR_084
    #define VECTOR_084 PIT0_IRQHandler //重新定义 84 号中断为 PIT0_IRQHandler 中断
    extern void PIT0_IRQHandler(); //PIT0 定时中断服务函数
    [/cc]
    中断处理函数
    [cc lang=”C”]
    void PIT0_IRQHandler(void)
    {
    PIT_Flag_Clear(PIT0); //清中断标志位
    // Do sth.
    }
    [/cc]

    (更多…)

  • 8 – 中断:EXTI外部中断

    EXTI外部中断可用来应付那些“出现时机不确定”的事件。比如说,按键,摄像头的行场中断,测速编码器的输入等。
    例如,设定A1引脚上升沿能触发EXIT中断,A1连接一个按钮,按钮按下那瞬间,A1产生上升沿,触发中断,进行按钮事件的处理。

    K60

    同样,K60使用野火的底层库,参考《三天入门 Cortex-M4》EXTI 外部 GPIO 中断例程。

    初始化

    函数原型
    [cc lang=”C”]
    void exti_init(PORTx, u8 n,exti_cfg);
    [/cc]
    调用例子
    [cc lang=”C”]
    void
    exti_init(PORTA,17,rising_down);//下拉,上升沿触发中断
    [/cc]
    (更多…)

  • 7 – 输入/输出:UART(串口)

    UART是单片机与计算机通信的重要工具,可以外接蓝牙模块进行通信,也可以通过有线连接usb进行通信。
    通过有线usb连接计算机时,单片机上只需连接TX,RX,GND,一般不需要连接VCC。
    单片机的底层库一般都自带了UART通信模块,激活对应管脚,设定好波特率即可在程序中调用。
    波特率决定数据的传输速率,波特率越高传输越快。一般为了稳定,传简单的数据用9600就够;传图像的话,最好用115200或以上,节省时间。

    K60

    K60用的是野火的底层库,可以参考它的手册;

    输出

    输出的话,定义好输出端口和波特率就能用。
    [cc lang=”C”]
    uart_init (UART1,19200); //初始化 串口 1 波特率为 19200
    uart_putchar (UART1,’F’); //发送一个字符’F’
    uart_sendStr (UART1,”uart_str 函数发送数据”); //发送字符串
    [/cc]

    开启Uart输入中断

    [cc lang=”C”]
    // isr.h
    // 串口输入中断服务
    #undef VECTOR_061
    #define VECTOR_061 UART0_IRQHandler
    extern void UART0_IRQHandler(void);
    [/cc]
    [cc lang=”C”]
    // main.c
    // main() 函数内
    //打开串口中断
    UART_IRQ_EN(UART0);
    [/cc]
    (更多…)

  • 6 – 输入/输出:DMA

    DMA, Direct Memory Access. 设定后,无需CPU干预即可将外设数据读到RAM中去。
    摄像头组需要不断读取图像到内存,DMA可以分担图像读取的操作,大大减少了CPU的负担,于是我们可以有更多资源处理其他事情。
    DMA另一个好处是可以跟着摄像头的PCLK读取数据,图像不会有噪点。
    坏消息是,XS128不带DMA功能,呵呵。

    通过DMA读取图像的方法:
    1. 初始化摄像头管脚输入方向,初始化DMA;
    2. 场中断到来,允许行中断;
    3. 行中断到来,开启DMA,让DMA读取一行的数据;
    4. 关闭DMA,等待下一次行中断。

    (更多…)

  • 5 – 输入/输出:I2C

    I2C是一种串行通信总线,维基百科有比较详细的介绍 http://zh.wikipedia.org/zh-cn/I%C2%B2C

    它需要SDA和SCL两个接口来进行与外部硬件的通信。
    我们用到的数字加速度计用的就I2C通信的,用I2C的好处是,它只占用2个管脚就可以读14bit精度的数据,且外部的电路自带了各种滤波,而AD转换要读取8bit就用掉8个管脚。
    对I2C的工作方式,我的理解是,要用I2C读取外部硬件(比如数字加速度计),首先要向外部硬件发送“请求”,把要读取的寄存器地址请求过去,然后能得到相应的数据反馈。