完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
使用cc2530定时器一的模模式来产生pwm波。计数寄存器T1CC0的值确定pwm波周期,比较寄存器T1CCn(T1CCnH和T1CCnL)确定占空比。
(关于定时器的知识请查阅相关文档) 代码实现 /**************************************************************************** * 名 称: InitT1() * 功 能: 定时器初始化,TICKSPD 是16 MHz系统不配置时默认是2分频,即16MHz * 入口参数: 无 * 出口参数: 无 ****************************************************************************/ void InitT1() { CLKCONCMD &= ~0x40; //设置系统时钟源为32MHZ晶振 while(CLKCONSTA & 0x40); //等待晶振稳定为32M CLKCONCMD &= ~0x07; //设置系统主时钟频率为32MHZ CLKCONCMD |= 0x38; //时钟速度32 MHz 定时器标记输出设置[5:3]250kHz PERCFG |= 0x40; //定时器1 的IO位置 1:备用位置2 P2SEL &= ~0x10; //定时器1优先 P2DIR |= 0xC0; //第1优先级:定时器1通道2-3 P1DIR |= 0xff; //端口1为输出 P1SEL |= 0x01; //timer1 通道2映射口P1_0 T1CC2H = 0x01; T1CC2L = 0x77; //T1CCn寄存器确定占空比 T1CC0H = 0x13; //20ms的周期时钟,频率为50ms定时器计数周期为0.000004 T1CC0L = 0x88; //定时时长=寄存器值*定时器计数周期 T1CCTL2 = 0x24; // 模式选择 通道2比较模式 T1CTL = 0x02; //模式选择 模模式 } 舵机控制原理 舵机的伺服系统由可变宽度的脉冲来进行控制,控制线是用来传送脉冲的。脉冲的参数有最小值,最大值,和频率。一般而言,舵机的基准信号都是周期为20ms,宽度为1.5ms。这个基准信号定义的位置为中间位置。舵机有最大转动角度,中间位置的定义就是从这个位置到最大角度与最小角度的量完全一样。最重要的一点是,不同舵机的最大转动角度可能不相同,但是其中间位置的脉冲宽度是一定的,那就是1.5ms。 根据舵机控制的原理,舵机的控制一般需要一个20ms左右的时基脉冲<周期>,该脉冲的高电平部分一般为0.5ms-2.5ms<占空比2.5%~12.5%>范围内的角度控制脉冲部分,总间隔为2ms。 即: 0.5ms--------------0度; 1.0ms------------45度; 1.5ms------------90度; 2.0ms-----------135度; 2.5ms-----------180度; 代码实现 修改比较寄存器的值改变pwm波 /**************************************************************************** * 名 称: servo * 功 能: 将舵机角度转化为对应寄存器值并赋值寄存器 * 入口参数: angle 舵机角度 * 出口参数: 无 ****************************************************************************/ void servo(int angle) { double time;//脉冲时间 int cont;//寄存器值 time=angle*11.1+510.0;//脉冲时间与角度计算公式 cont=(int)((time/1000000)/0.000004);//脉冲时间与寄存器值的计算公式 T1CC2H=(unsigned char)(cont>>8);//寄存器赋值 T1CC2L=(unsigned char)cont; } 注意:注意控制舵机的信号,电源要共地。 完整代码 /**************************************************************************** * 文 件 名: main.c * 作 者: by的cc2530 * 修 订: * 版 本: 1.0 * 描 述: cc2530 定时计数器1产生周期50hz的pwm波以控制舵机 ****************************************************************************/ #include typedef unsigned char uchar; typedef unsigned int uint; #define PWM P1_0 // P1.0口控制LED1 void servo(int angle); /**************************************************************************** * 名 称: InitLed() * 功 能: 设置pwM相应的IO口 * 入口参数: 无 * 出口参数: 无 ****************************************************************************/ void InitLed(void) { P1DIR |= 0x01; //P1.0定义为输出 PWM = 1; //使LED1灯上电默认为熄灭 } /**************************************************************************** * 名 称: DelayMS() * 功 能: 毫秒延时 * 入口参数: msec 单位为毫秒 * 出口参数: 无 ****************************************************************************/ void DelayMS(uint msec) { uint i,j; for (i=0; i } /**************************************************************************** * 名 称: InitT1() * 功 能: 定时器初始化,TICKSPD 是16 MHz系统不配置时默认是2分频,即16MHz * 入口参数: 无 * 出口参数: 无 ****************************************************************************/ void InitT1() { CLKCONCMD &= ~0x40; //设置系统时钟源为32MHZ晶振 while(CLKCONSTA & 0x40); //等待晶振稳定为32M CLKCONCMD &= ~0x07; //设置系统主时钟频率为32MHZ CLKCONCMD |= 0x38; //时钟速度32 MHz 定时器标记输出设置[5:3]250kHz PERCFG |= 0x40; //定时器1 的IO位置 1:备用位置2 P2SEL &= ~0x10; //定时器1优先 P2DIR |= 0xC0; //第1优先级:定时器1通道2-3 P1DIR |= 0xff; //端口1为输出 P1SEL |= 0x01; //timer1 通道2映射口P1_0 T1CC2H = 0x01; //20%占空比为200us T1CC2L = 0x77; //修改T1CC2L可调整led的亮度 T1CC0H = 0x13; //20ms的周期时钟,频率为50ms定时器计数周期为0.000004 T1CC0L = 0x88; //定时时长=寄存器值*定时器计数周期 T1CCTL2 = 0x24; // 模式选择 通道2比较模式 T1CTL = 0x02; //模模式250KHz 1分频 } /**************************************************************************** * 程序入口函数 ****************************************************************************/ void main(void) { InitLed(); //调用初始化函数 InitT1(); //定时器初始化及pwm配置 while(1) { for(int i=0;i<180;i++) { servo(i); DelayMS(50); } for(int i=180;i>0;i--) { servo(i); DelayMS(50); } } } /**************************************************************************** * 名 称: servo * 功 能: 将舵机角度转化为对应寄存器值并赋值寄存器 * 入口参数: angle 舵机角度 * 出口参数: 无 ****************************************************************************/ void servo(int angle) { double time;//脉冲时间 int cont;//寄存器值 time=angle*11.1+510.0;//脉冲时间与角度计算公式 cont=(int)((time/1000000)/0.000004);//脉冲时间与寄存器值的计算公式 T1CC2H=(unsigned char)(cont>>8);//寄存器赋值 T1CC2L=(unsigned char)cont; } |
|
|
|
只有小组成员才能发言,加入小组>>
3314 浏览 9 评论
2995 浏览 16 评论
3494 浏览 1 评论
9059 浏览 16 评论
4088 浏览 18 评论
1180浏览 3评论
605浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
599浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2335浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1896浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 21:51 , Processed in 0.996652 second(s), Total 50, Slave 41 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号