文章目录
概要
使用stc8g1k08的pca模块产生50hz的pwm驱动舵机
技术细节
- 原理(最后有详细代码,不想看可略过)
首先我们要配置的就是相关控制寄存器来控制pca模块的模式和开启,详情如下图所示
其次,由于舵机控制需要的是50hz的信号,所以我们需要配置pca输入时钟为定时器0溢出脉冲,因为其他都是系统时钟分频,怎么分都达不到要求,详细配置如下图所示
而且当使用定时器时,我们的周期又不能太小。pwm有6,7,8,10,位的,我们使用6位pwm,详细配置如下图所示
上图中pwm模块的频率等于输入的频率/64,这也是为什么我们用六位的原因。因为我们使用的是定时器0的频率,且单片机频率为12m,位数越高,定时器0的计数值可能达不到那么低。
这里我们的定时器0周期计算就是
T=1/(pwm频率*64)
上面CCAPMn、PCA_PWMn取决于你用的哪个引脚输出,详细引脚在手册中如下图所示:
还有相关的占空比设置的寄存器CCAPnL和CCAPnH,相关计算如下面的例子所示
CCAP2L=0x38;//PWM占空比(40H-38H)/40H
CCAP2H=0x38;//溢出时自动填装到CCAP0L里,实现无干扰更新
- 相关代码
#include <STC8G.H>
/**
* @brief 定时器初始化
* @param 无
* @retval 无
*/
void Timer0_Init(void) //313微秒@12.000MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x54; //设置定时初始值
TH0 = 0xF1; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
EA=1;
PT1=0;
}
void Delay(unsigned int xms)
{
unsigned char i,j;
while(xms)
{
i = 15;
j = 90;
do
{
while(--j);
}
while(--i);
xms--;
}
}
void main(void)
{
P3M0 = 0xff; // 将P3配置为推挽输出
P3M1 = 0x00;
P1M0 = 0xff; // 将P1口配置为推挽输出
P1M1 = 0x00;
CCON=0x00;//停止PCA计数
CMOD=0x04;//PCA计数脉冲设为定时器0的溢出脉冲
CL= 0x00;
CH= 0x00;
CCAPM2=0x42; //PCA模块1为PWM工作模式
PCA_PWM2=0x80; //PCA模块1输出6位PWM
CCAP2L=0x38;//PWM占空比(40H-38H)/40H
CCAP2H=0x38;//溢出时自动填装到CCAP0L里,实现无干扰更新
CR=1;//启动PCA计数
Timer0_Init();//定时器初始化
while(1)
{
CCAP2H=0x38; //PWM占空比(40H-38H)/40H
Delay(1000); //延时1s
CCAP2H=0x3e; //PWM占空比(40H-3eH)/40H
Delay(1000);
}
}
void Timer0_Isr(void) interrupt 1
{
//用于PCA模块的频率输入
//313微秒@12.000MHz
//pwm频率为舵机50hz
}
小结
使用pca硬件产生pwm驱动舵机,减少了程序的复杂程度,并且对舵机的操控变得更简单快捷。
欢迎交流指正!