测试了下,没有问题,4路PWM输出正常。
STC12H系列-PCA相关程序.rar
(45.8 KB)
#define MAIN_Fosc 24000000UL //定义主时钟
#include "..\..\STC12H.h"
/************* 功能说明 **************
请先别修改程序, 直接下载"01-PCA-4路PWM-C语言"里的"PCA.hex"测试.
4路PCA都配置成10位PWM的应用.
本例 PWM0(CCP0)-->P3.7, PWM1(CCP1)-->P3.5, PWM2(CCP2)-->P2.0, PWM3(CCP3)-->P2.4, 用户可以自行修改切换到其它端口.
PWM0、PWM1、PWM2输出呼吸灯效果,PWM3间歇输出。
******************************************/
/************* 本地常量声明 **************/
/************* 本地变量声明 **************/
u16 pwm; //pwm
bit B_PWM_Dir; //方向, 0为+, 1为-.
u8 cnt;
/************* 本地函数声明 **************/
void UpdatePwm(u8 ch, u16 pwm_value); // ch: PCA序号, 0~3对应 PCA0 ~ PCA3, pwm_value: pwm值, 这个值是输出低电平的时间.
void PCA_config(u8 clk, u8 wide); // clk: 选择时钟, 0: 12T, 1: 2T, 2: Timer0溢出率, 3: ECI引脚输入, 4: 1T, 5: 4T, 6: 6T, 7: 8T
// wide: pwm的宽度, 0: 8位PWM, 1: 7位PWM, 2: 6位PWM, 3: 10位位PWM
void PwmOutContinue(u8 ch, u8 level); // ch: PCA序号, 0~3对应 PCA0 ~ PCA3, level: 连续输出的电平,0为低电平, 1为高电平.
void delay_ms(u8 ms);
/************* 外部函数和变量声明 *****************/
/******************** 主函数 **************************/
void main(void)
{
PCA_config(4, 3); //clk=4: 选择时钟1T, 3: 10位PWM
P3n_push_pull(Pin7+Pin5); // P3.7 P3.5设置为推挽输出
P2n_push_pull(Pin4+Pin0); // P2.4 P2.0设置为推挽输出
pwm = 128;
B_PWM_Dir = 0;
while (1)
{
delay_ms(2);
if(B_PWM_Dir)
{
if(--pwm <= 8) B_PWM_Dir = 0;
}
else
{
if(++pwm >= 1016) B_PWM_Dir = 1;
}
UpdatePwm(PCA0, pwm); //更新PWM.
UpdatePwm(PCA1, pwm); //更新PWM.
UpdatePwm(PCA2, pwm); //更新PWM.
if(++cnt >= 4) //8ms一个周期, 演示如何关闭 开启PWM.
{
cnt = 0;
UpdatePwm(PCA3, 256); //输出占空比1/4的PWM, 时间为2ms.
}
else if(cnt == 1) PwmOutContinue(PCA3, 0); //连续输出低电平0, 时间为2ms.
else if(cnt == 2) UpdatePwm(PCA3,768); //输出占空比3/4的PWM, 时间为2ms.
else if(cnt == 3) PwmOutContinue(PCA3, 1); //连续输出高电平1, 时间为2ms.
}
}
//========================================================================
// 函数: void delay_ms(u8 ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 版本: V1.0, 2016-5-10
// 备注:
//========================================================================
void delay_ms(u8 ms)
{
u16 i;
do
{
i = MAIN_Fosc / 10000;
while(--i) ;
}while(--ms);
}
//========================================================================
// 函数: void PCA_config(u8 clk, u8 wide)
// 描述: PCA配置函数。
// 参数: clk: 选择时钟, 0: 12T, 1: 2T, 2: Timer0溢出率, 3: ECI引脚输入, 4: 1T, 5: 4T, 6: 6T, 7: 8T
// wide: pwm的宽度, 0: 8位PWM, 1: 7位PWM, 2: 6位PWM, 3: 10位位PWM
// 返回: none.
// 版本: VER1.0
// 版本: V1.0, 2016-5-10
// 备注:
//========================================================================
void PCA_config(u8 clk, u8 wide)
{
P_SW2 |= 0x80;
CR = 0;
CH = 0;
CL = 0;
CMOD = (CMOD & ~0x0E) | ((clk & 7) << 1); // PCA时钟选择, 0: 12T, 1: 2T, 2: Timer0溢出率, 3: ECI引脚输入, 4: 1T, 5: 4T, 6: 6T, 7: 8T
PCA0_PWM(wide); //PWM宽度 0: 8位PWM, 1: 7位PWM, 2: 6位PWM, 3: 10位位PWM
PCA1_PWM(wide); //PWM宽度 0: 8位PWM, 1: 7位PWM, 2: 6位PWM, 3: 10位位PWM
PCA2_PWM(wide); //PWM宽度 0: 8位PWM, 1: 7位PWM, 2: 6位PWM, 3: 10位位PWM
PCA3_PWM(wide); //PWM宽度 0: 8位PWM, 1: 7位PWM, 2: 6位PWM, 3: 10位位PWM
PWM0_OUT_0(); //初始输出0
PWM1_OUT_0(); //初始输出0
PWM2_OUT_0(); //初始输出0
PWM3_OUT_0(); //初始输出0
// PPCA = 1; //高优先级中断
// CMOD |= 0x01; //允许PCA计数器溢出中断
CR = 1;
}
//========================================================================
// 函数: void PwmOutContinue(u8 ch, u8 level)
// 描述: 设置PWM连续输出电平(高或低).
// 参数: ch: PCA序号, 0~3对应 PCA0 ~ PCA3
// level: 连续输出的电平,0为低电平, 1为高电平.
// 返回: none.
// 版本: V1.0, 2018-5-10
//========================================================================
void PwmOutContinue(u8 ch, u8 level)
{
if(ch == 0)
{
if(level == 0) PWM0_OUT_0();
else PWM0_OUT_1();
}
else if(ch == 1)
{
if(level == 0) PWM1_OUT_0();
else PWM1_OUT_1();
}
else if(ch == 2)
{
if(level == 0) PWM2_OUT_0();
else PWM2_OUT_1();
}
else if(ch == 3)
{
if(level == 0) PWM3_OUT_0();
else PWM3_OUT_1();
}
}
//========================================================================
// 函数: void UpdatePwm(u8 ch, u16 pwm_value)
// 描述: 更新PWM值.
// 参数: ch: PCA序号, 0~3对应 PCA0 ~ PCA3
// pwm_value: pwm值, 这个值是输出低电平的时间.
// 返回: none.
// 版本: V1.0, 2018-5-10
//========================================================================
void UpdatePwm(u8 ch, u16 pwm_value)
{
if(ch == 0)
{
PCA_PWM0 = (PCA_PWM0 & ~0x32) | (u8)((pwm_value >> 4) & 0x30);
CCAP0H = (u8)pwm_value;
// PWM0_NORMAL();
}
else if(ch == 1)
{
PCA_PWM1 = (PCA_PWM1 & ~0x32) | (u8)((pwm_value >> 4) & 0x30);
CCAP1H = (u8)pwm_value;
// PWM1_NORMAL();
}
else if(ch == 2)
{
PCA_PWM2 = (PCA_PWM2 & ~0x32) | (u8)((pwm_value >> 4) & 0x30);
CCAP2H = (u8)pwm_value;
// PWM2_NORMAL();
}
else if(ch == 3)
{
PCA_PWM3 = (PCA_PWM3 & ~0x32) | (u8)((pwm_value >> 4) & 0x30);
CCAP3H = (u8)pwm_value;
// PWM3_NORMAL();
}
}
|