飞思卡尔XS128系列(二) PWM模块

发布者:水手谷水手最新更新时间:2021-08-27 来源: eefocus关键字:飞思卡尔  PWM模块 手机看文章 扫描二维码
随时随地手机看文章

为有别于其他讲解PWM模块的文章,本文不打算拿出大篇幅对PWM模块各个寄存器进行详细讲解,因为那些东西网上、书店到处都是。如果英语好的话,可以参考datasheet,762页的PDF文档,可惜了我那可怜的英文水平……


本文将结合着实际智能小车的控制来写点东西,多写点控制策略上的东西。


如在寄存器方面有何疑问,都可以留言,我都尽力解答。


首先我电磁车上关于PWM的代码:

//PWM.C


void Steering_PWM_Init(void)

 {

    PWMCTL_CON67 = 1; //PWM通道67级联,B或SB作为时钟源

    PWME_PWME7 = 0;

    PWMPRCLK_PCKB = 0x3; //预分频 B 8分频 10MHz

    PWMSCLB = 0x01;   //SB_CLK = B_CLK / (2*1) == 5MHz

    PWMPOL_PPOL7 = 1; //起始高电平

     PWMCLK_PCLK7 = 1; //PWM模块时钟选择SB

    PWMCNT6 = 0x00; //PWMCNTx:通道计数寄存器

     PWMCNT7 = 0x00;

    PWMPER67 = 50000; // 周期==(1/5M)*(50000)=10ms; 

    

    PWMCAE_CAE7 = 0;  //左对齐 

 }


void Motor_PWM_Init(void)

{


    PWMCTL_CON01 = 1;   //PWM通道01,45级联,A或SA作为时钟源

    PWMCTL_CON45 = 1;

    

    PWMPRCLK_PCKA = 0x2; //预分频 A 4分频 20MHz

    PWMSCLA = 0x01;  //SB_CLK = B_CLK / (2*1) == 10MHz

    PWMPOL_PPOL1 = 1;

    PWMPOL_PPOL5 = 1;

    PWMCLK_PCLK1 = 1;

    PWMCLK_PCLK5 = 1;

    PWMCNT0 = 0x00;

    PWMCNT1 = 0x00;

    PWMCNT4 = 0x00;

    PWMCNT5 = 0x00;

    PWMPER01 = 10000; // 1ms ;1KHz 

    PWMPER45 = 10000; // 1ms :1KHz

    

    PWMCAE_CAE1 = 0;

    PWMCAE_CAE5 = 0;  

}


//控制舵机

void Set_PWM67(uint16 duty, uint16 period)

{

    if(duty <= period)

    {

        PWMPER67 = period;

        PWMDTY67 = duty;    

    }

   

    

}


//控制电机

void Set_PWM01(uint16 duty, uint16 period)

{

    if(duty <= period)

    {

        PWMPER01 = period;

        PWMDTY01 = duty;    

    }

     

}


void Set_PWM45(uint16 duty, uint16 period)

{

    if(duty <= period)

    {

        PWMPER45 = period;

        PWMDTY45 = duty;    

    }

     

}



//PWM.h


/******************************************************************************

*           PWM模块

*******************************************************************************/



void Steering_PWM_Init(void);


void Motor_PWM_Init(void);


void Set_PWM01(uint16 duty, uint16 period);


void Set_PWM67(uint16 duty, uint16 period);


void Set_PWM45(uint16 duty, uint16 period);


#define Start_PWM01()   {PWME_PWME1 = 1;}

#define Stop_PWM01()    {PWME_PWME1 = 0;}


#define Start_PWM67()   {PWME_PWME7 = 1;}

#define Stop_PWM67()    {PWME_PWME7 = 0;}


#define Start_PWM45()   {PWME_PWME5 = 1;}

#define Stop_PWM45()    {PWME_PWME5 = 0;}


首先,上述代码默认PWM通道是关闭的,所以在使用时需要先用定义的宏去打开PWM模块。


舵机部分:


PWM控制的无非就是舵机和电机。咱们先谈谈舵机,先使用宏Start_PWM67();打开67通道级联的PWM模块,然后就可以对舵机的转角进行实际操作了。


转角的控制一般有查表的开环控制和PD的闭环控制,查表就是先根据位置量列出一个数组分别对应着各位置量时的转角参数。


如:


左右极限值和中心值为:2120/5380/3750

const uint16 steer_arr[253] = {

        2120, 2132, 2145, 2158, 2171, 2184, 2197, 2210,

        2223, 2236, 2249, 2262, 2275, 2288, 2301, 2314,

        2326, 2339, 2352, 2365, 2378, 2391, 2404, 2417,

        2430, 2443, 2456, 2469, 2482, 2495, 2508, 2521,

        2533, 2546, 2559, 2572, 2585, 2598, 2611, 2624,

        2637, 2650, 2663, 2676, 2689, 2702, 2715, 2728,

        2740, 2753, 2766, 2779, 2792, 2805, 2818, 2831,

        2844, 2857, 2870, 2883, 2896, 2909, 2922, 2935,

        2947, 2960, 2973, 2986, 2999, 3012, 3025, 3038,

        3051, 3064, 3077, 3090, 3103, 3116, 3129, 3141,

        3154, 3167, 3180, 3193, 3206, 3219, 3232, 3245,

        3258, 3271, 3284, 3297, 3310, 3323, 3336, 3348,

        3361, 3374, 3387, 3400, 3413, 3426, 3439, 3452,

        3465, 3478, 3491, 3504, 3517, 3530, 3543, 3555,

        3568, 3581, 3594, 3607, 3620, 3633, 3646, 3659,

        3672, 3685, 3698, 3711, 3724, 3737, 3750, 3762,

        3775, 3788, 3801, 3814, 3827, 3840, 3853, 3866,

        3879, 3892, 3905, 3918, 3931, 3944, 3956, 3969,

        3982, 3995, 4008, 4021, 4034, 4047, 4060, 4073,

        4086, 4099, 4112, 4125, 4138, 4151, 4163, 4176,

        4189, 4202, 4215, 4228, 4241, 4254, 4267, 4280,

        4293, 4306, 4319, 4332, 4345, 4358, 4370, 4383,

        4396, 4409, 4422, 4435, 4448, 4461, 4474, 4487,

        4500, 4513, 4526, 4539, 4552, 4565, 4577, 4590,

        4603, 4616, 4629, 4642, 4655, 4668, 4681, 4694,

        4707, 4720, 4733, 4746, 4759, 4771, 4784, 4797,

        4810, 4823, 4836, 4849, 4862, 4875, 4888, 4901,

        4914, 4927, 4940, 4953, 4966, 4978, 4991, 5004,

        5017, 5030, 5043, 5056, 5069, 5082, 5095, 5108,

        5121, 5134, 5147, 5160, 5173, 5185, 5198, 5211,

        5224, 5237, 5250, 5263, 5276, 5289, 5302, 5315,

        5328, 5341, 5354, 5367, 5380

};


这是我电磁车的,一开始我也是用的开环查表的方式,可能有人要说了,怎么这么多,这要手工排不排到眼花啊?其实这是因为传感器是模拟量,一般没这么多啊,好吧,如果各位和我一样懒,其实咱们可以另外写一个程序帮我们在建表。


如:

#include

#include


#define min 2120 

#define max 5380

#define count 253


using namespace std;


int main(int argc, char *argv[])

{

    int i = 0;

    cout << "const uint16 steering_arr[count] = {";

    

    for(i = 0;i <= count - 1;i++)

    {

        if(i) cout << ", ";

        if(!(i%8)) cout << endl << "/t";

        cout << min + (max - min) * i / (count - 1);

    }

    cout<<",/n";

    cout << endl << "};" << endl;

    return 0;

}


这下简单了吧!呵呵,谁叫咱会偷懒呢,还有一点要注意的是因为这里位置量比较多,所以整个列表都是均匀排布的,当位置量较少时,最好是中间密,两边疏,这样有利于智能车的直道的稳定性。

或是如下PD控制:

#define KP_steering_ 8

#define KD_steering_ 3


#define KP_steering 16

#define KD_steering 6


uint16 temp;

sint16 error;

   

pre_pos_ = pos_;

error = pos_ - pre_pos_;


   if(pos_ <= 30 && pos_ >= -30)

   {    

        temp = Steer_Angle_Center + KP_steering_  * ~pos_ - KD_steering_  * error;

        

        if(temp < 2120)

        {

            Set_PWM67(2120, 50000);

            test_steering = 2120; 

        }

        else if(temp > 5380)

        {

            Set_PWM67(5300, 50000);

            test_steering = 5380; 

        }

        else

        {

            Set_PWM67(temp, 50000);

            test_steering = temp;   

        }

        

   }

   else if(pos_ > 30 || pos_ < -30)

   {

        temp = Steer_Angle_Center + KP_steering * ~pos_ - KD_steering * error;

        

        if(temp < 2120)

        {

            Set_PWM67(2120, 50000);

            test_steering = 2120; 

        }

        else if(temp > 5380)

        {

            Set_PWM67(5380, 50000);

            test_steering = 5380; 

        }

        else

        {

            Set_PWM67(temp, 50000);

            test_steering = temp;   

        }

   }

   else

   {

        _asm(nop);

   }


电机部分:


谈到电机,必然先谈电机驱动,前几届的队伍多半是用33886作为智能车的电机驱动芯片,但我个人认为33886驱动能力有限,且发热量过半,还因为飞思卡尔比赛的原因使该芯片一篇难求,水涨船高,蛮贵的,其实不如使用4个功率MOS管搭建H桥电路来用于电机驱动,具体做法以及如何搭线(如何搭线关系到是否可以反转制动)不打算在这里详说,有时间专门写篇文章讨论这个。


言归正传,还是谈电机控制,电机控制无非是一开始就给个速度让它跑,


如:

//假设电机驱动,一路用PWM,另一路用IO口置低电平

Start_PWM01();

Set_PWM01(5000,10000);


这种开环控制因为电池电压以及实际路况等原因,必然不是最好的。


PID控制的引入可以很好的解决这个问题,我采用的是PID与BANG-BANG控制相结合的方法,由PID是控制精度,BANG-BANG是控制力度,达到了比较好的效果。

这里简单讲讲BANG-BANG控制,对调速范围宽、静态误差小和动态响应快的随动系统来说,单闭环控制是不能满足要求的,所以随动系统采用电流环、速度环和位置环来完成控制。在随动系统控制中,PID控制具有结构简单且在对象模型不确知的情况下也可达到有效控制的特点,但对模型参数变化及干扰的适应能力较差。BANG-BANG控制在系统偏差大,可加大系统的控制力度,提高系统的快速性,因此,BANG-BANG控制是随动系统中不可缺少的控制方式。说明白点就是即时间最优控制的各个分量u(t)都是时间t的分段常值函数,并在开关时间上由一个恒值到另一个恒值的跳变。而映射到智能车上所谓一个恒值到另一个恒值就是速度的最小值到最大值。

关键字:飞思卡尔  PWM模块 引用地址:飞思卡尔XS128系列(二) PWM模块

上一篇:MC9S12G128内存映射(本地地址,逻辑地址,全局地址)
下一篇:飞思卡尔XS128系列(三) PIT

推荐阅读最新更新时间:2024-11-12 11:45

飞思卡尔智能车—电磁循迹(组别通用)
电磁循迹部分设计思路: 电感采集电磁信号,放大,整流,滤波,AD采集 电磁信号放大电路: 运放选用NE5532,对信号进行两次放大,放大倍数可通过电位器调节,此电路需使用9V-12V电源供电。 正负9V电源电路: 9V电源使用简单的7809芯片。 电路板3D图: 电路板大小为4*9cm,六路运放,适用于所有电磁组智能车。电路板运行稳定,备赛及比赛过程中未出现任何问题。
[单片机]
基于飞思卡尔MCU的汽车信息娱乐系统方案
方案描述: 与快速发展的便携式电子产品保持同步,同时专注于本身严格的质量标准和车型生命周期的要求,是汽车制造商和车载信息娱乐系统供应商面临的挑战。 飞思卡尔 提供成熟的 汽车信息娱乐 平台解决方案,帮助车载信息娱乐系统设计人员满足这些快速变化的需求。 方案设计图:
[汽车电子]
基于<font color='red'>飞思卡尔</font>MCU的汽车信息娱乐系统方案
mc9s12 c语言,飞思卡尔mc9s12的prm文件详解之二
关于Codewarrior 中的 .prm 文件 要讨论单片机的地址映射,就必须要接触.prm文件,本篇的讨论基于 Codewarrior 5.0 编译器,单片机采用MC9S12XS128。 通过项目模板建立的新项目中都有一个名字为“project.prm”的文件,位于Project Settings- Linker Files文件夹下。一个标准的基于XS128的.prm文件起始内容如下: .prm文件范例: /* This is a linker parameter file for the MC9S12XS128 */ /*This file is setup to use the HCS12X core only.If
[单片机]
飞思卡尔KL16时钟配置
引脚 EXTAL0:晶振入,XTAL0:晶振出 配置 MCG_C7的OSCSEL为0,选择外部晶振 所以MCG_C1的FRDIV需要取后面的值,例如8M晶振取011即256分频,结果为31.25khz,在PLL模式下,MCG_C1的FRDIV在晶振分频以后必须在31.25khz-39.625khz MCG_C6中PLLS说明,PLL应为2-4MHZ,则MCG_C5中的PRDIV0的数值被外部晶振频率除之后为2-4MHZ. MCG_SC中FCRDIV为快速时钟,外部晶振频率除以FCDIV的结果须在31.25KHZ-4MHZ
[单片机]
雅特生科技推出内置飞思卡尔QorlQ P5020处理器单板计算机
雅特生科技不但是成功研发VME电路板的设备商之一,而且还一直致力于开发可支持VME技术的新产品,并制定了多项研发计划,确保这种技术不会轻易被时代淘汰 雅特生科技 (Artesyn Embedded Technologies) 宣布推出一款全新的高性能VME单板计算机MVME8105,让高端产品如工业设备控制系统、自动化指挥系统(C4ISR)以及负责关键任务的相关应用不但可以充分发挥其计算性能,而且还可支持更高的数据带宽以及享有更长的生命周期。过去30多年来,雅特生科技的VME产品一直广泛应用于半导体生产设备(SPE)、光刻、雷达、声纳(sonar)和列车控制系统。但在实际应用时,这些系统很多时候必须倚赖反向兼容的技术
[工业控制]
飞思卡尔推出精密阀门控制器SoC,打造强大安全的液压连接
该解决方案高度集成,配备了基于物联网技术的预防性维护联网诊断,可降低成本、简化设计并加快产品上市 飞思卡尔半导体日前已推出两种高度集成的阀门控制器片上系统(SoC),具有高精度电流测量、SPI连接及精密的功能性安全管理功能,可对液压和气动系统进行控制。 飞思卡尔的新型SB0410/SB0800 SoC是单芯片模拟控制器,专为同时管理八个阀门而设计,可调节电流并运行电机。这些器件适用于带高浪涌电流的负载,允许驱动至高频(高达5 kHz)。目标应用包括:液压和气动系统、制氧机、医疗设备、3D打印机、饮料自动售货机、农业和工厂设备以及灌溉用水控制。 与网络连接时,通过支持专为严苛环境设计的预测性维护和诊
[工业控制]
飞思卡尔技术论坛中国站在深圳隆重开幕
        2014年5月20日,深圳讯- 由飞思卡尔半导体(Freescale Semiconductor)主办的飞思卡尔技术论坛(FTF)中国站在深圳拉开帷幕,这是本论坛第四次选择在深圳召开。 在论坛开幕式上,专程来到中国出席本届论坛的飞思卡尔总裁兼CEO Gregg Lowe发表主题演讲,聚焦在飞思卡尔对于融合了大数据、安全性和云计算的智能互联新世界的展望。飞思卡尔高级领导团队的其他成员也一同登台,展示飞思卡尔的微控制器、传感器、模拟器件和网络解决方案所支持的各种设备,是如何将物联网(IoT)带到人们的生活中。   (飞思卡尔总裁兼CEO Gregg Lowe) “从2005年起,飞思卡尔技术
[手机便携]
飞思卡尔16位单片机(三)——GPIO输出功能测试
一、GPIO介绍 GPIO是单片机最常用的功能,XEP100单片机的并行I/O的资源很丰富,XEP100的IO有PORTA、PORTB、PORTH、PORTJ、PORTM、PORTP、PORTS、PORTT、PORTK和PORTE共10组IO。这些I/O口除了具有通用I/O功能外,还分别具有专用I/O的功能。可以根据需要进行设置,专用I/O功能启用后,通用I/O功能自动关闭。 在使用单片机的并行I/O时要进行一些设置,主要的设置如下所示: 1功能设置 每个I/O子系统都有一个功能设置寄存器,其中的几个位用于部分或者全部引脚的功能设定,设定为专用功能后,方向设置功能可能自然禁止,但上拉、下拉及降功率驱动功能一般仍然有效,具体
[单片机]
<font color='red'>飞思卡尔</font>16位单片机(三)——GPIO输出功能测试
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved