使用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
for (j=0; j<535; j++);
}
/****************************************************************************
* 名 称: 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;
}
使用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
for (j=0; j<535; j++);
}
/****************************************************************************
* 名 称: 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;
}
举报