一、前言
本文使用C8051F340自带的可编程计数阵列PCA0,工作在8位脉宽调制器方式,产生PWM脉宽调制波形输出。将PCA输出配置到P0.0脚输出。
本文主要是为了记录自己的学习知识点,同时也分享给同样的初学者们,大佬勿喷。
1、PCA0介绍
PCA0每个模块都可以被独立地用于对应的CEXn引脚产生脉宽调制(PWM)输出。PWM输出的频率取决于PCA计数器/定时器的时基。使用模块的捕捉/比较寄存器PCA0CPLn改变PWM输出信号的占空比。当PCA计数器/定时器的低字节(PCA0L)与PCA0CPLn中的值相等时,CEXn引脚上的输出被置‘1’;当PCA0L中的计数值溢出时,CEXn输出被复位。
当计数器/定时器的低字节PCA0L溢出时(从0xFF到0x00),保存在PCA0CPHn中的值被自动装入到PCA0CPLn,不需软件干预。通过将PCA0CPMn寄存器中的ECOMn和PWMn位置‘1’来使能8位脉冲宽度调制器方式。
2 占空比介绍
由上述方程可知,最大占空比为100%(PCA0CPHn = 0),最小占空比为0.39%(PCA0CPHn = 0xFF)。可以通过清‘0’ECOMn位产生0%的占空比。
二、程序展示
1、头文件部分
#include <c8051f340.h>
#define SYSCLK 12000000
void Osc_Init (void);
void PORT_Init (void);
void PCA0_Init (void);
2、主程序部分
main ()
{
unsigned int delay_count; // 用于延迟
bit duty_direction = 0; // 0 是下降沿; 1是上升沿
PCA0MD = 0x00; // 关闭看门狗
PORT_Init (); // 端口初始化
Osc_Init (); // 晶振初始化
PCA0_Init (); //PCA0初始化
while (1)
{
// 软件延时一会
for (delay_count = 15000; delay_count > 0; delay_count--);
if (duty_direction == 1) // 上升沿
{
// 检测ECOM0位
if ((PCA0CPM0 & 0x40) == 0x00)
{
PCA0CPM0 |= 0x40; // ECOM0置1
}
else
{
PCA0CPH0--;
if (PCA0CPH0 == 0x00)
{
duty_direction = 0; // 改为下降沿
}
}
}
else // 下降沿
{
if (PCA0CPH0 == 0xFF)
{
PCA0CPM0 &= ~0x40; //ECOM0清0
duty_direction = 1;
}
else
{
PCA0CPH0++;
}
}
};
}
3、 晶振初始化程序
void OscR_Init (void)
{
OSCICN = 0x83; // 使用内部晶振的最大频率
CLKSEL = 0x00; // 选择内部时钟作为时钟源
}
4、端口初始化程序
void PORT_Init (void)
{
XBR0 = 0x00;
XBR1 = 0x41; //将CEX0接到P0.0,
P0MDOUT |= 0x01; //设置P0.0为推挽输出
}
5、PCA0初始化程序
void PCA0_Init (void)
{
PCA0CN = 0x00; // 停止计时器,清楚所有标志位
PCA0MD = 0x08; //使用系统时钟
PCA0CPM0 = 0x42; //选择8位脉宽调制模式
PCA0CPH0 = 256 - (256 * 0.5); //设置占空比为50%
CR = 1; // 启动计时
}