关于STC8A8K64D4芯片PCA_PWM功能的一些见解(输出1kHz sin波形)
二齐
STC8A8K64D4芯片是目前STC公司产出的8A系列最新的8位单片机MCU。其中囊括了STC8A8K64S4A12芯片的全部功能,改进了关于PWM,比较器,I/O中断等硬件功能。新增的库函数比较好用。但是对于PCA应用,以我个人的状态来说,库函数应用比较不理想,下面文章仅对寄存器使用进行说明。
**一、**PCA硬件结构
其中PCA计数器时钟主要来源于系统时钟和T0定时器,外部中断时钟入口暂时没用。16位计数器的计数位数取决于定义的PWM位数。
如果定义为8位PWM,则仅使用CL8位数据,CH数据不更新;如果定位为10位PWM,则使用CL8位,CH2位满足10位定时的要求,其他类似。CCON主要控制的是PCA计时器启停(CR位)和中断状态标志。CMOD主要决定中断状态和引脚选择状态。
**二、**寄存器结构
如上图所示,PCA模块共4个,分别作用于不同的输出管脚。我们首先定义CCON和CMOD寄存器(当然了,在这之前请先定义系统时钟、GPIO管脚状态)。完成后对使用的PCA管脚进行设置。我这里使用的是PCA0管脚。
CCAPMn寄存器主要控制PCA工作模式,我们如果要产生1k正弦波,需要对占空比进行实时更新,来达到调整输出电压的效果,因此需要使用中断(中断问题后续讲解)。
如上图,再次对PCA_PWM寄存器进行设置,这里重点设置PWM位数,其中的拓展数据值先不写。
完成后即可对CR位进行置1操作,启动寄存器。
**三。**关于中断
PCA工作在PWM模式下的中断操作很神奇。目前我的处理方式为,先对sin正弦波进行取值,可在网络上搜索相关内容。取值完成后,当PCA0产生中断后,先将CCAPH的存储值写入CCAPL,再将sin正弦波的取点值写入CCAPH,进行更新。
当设置为上升沿中断时,效果是可以的。(8位模式下,输出正弦波频率为PCA时钟频率/256/点数),下降沿中断可能存在问题。因为在对PCA计数值进行比较时,当CL小于CCAPL时输出低电平,高于CCAPL时,输出高电平,此时产生上升沿,这时对CCAP进行更新,有一定的时间完成,但是如果进行下降沿中断,那么在CL溢出时,产生下降沿中断,进入中断服务程序后,同时也会进行更新CCAP,我们再进行操作可能引起问题(目前没出现问题),可能是隐患。当设定边沿中断时,上升沿、下降沿都会产生中断,频率翻倍。
总结如下:PCA使用时,会调用系统时钟,系统时钟存在一定误差,因此可能和预想设定的频率有一定差异,建议多测试,找到最好的结果。如果大家有什么好的意见,请及时交流,共同进步。
代码附下:
#include "config.h"
#include "STC8A_GPIO.h"
u8 code T_sin[]={
0x80,0x88,0x90,0x99,0xa1,0xa9,0xb1,0xb9,
0xc0,0xc7,0xce,0xd5,0xdb,0xe0,0xe6,0xeb,
0xef,0xf3,0xf6,0xf9,0xfb,0xfd,0xfe,0xfe,
0xfe,0xfe,0xfd,0xfb,0xf9,0xf6,0xf3,0xef,
0xeb,0xe6,0xe0,0xdb,0xd5,0xce,0xc7,0xc0,
0xb9,0xb1,0xa9,0xa1,0x99,0x90,0x88,0x80,
0x77,0x6f,0x66,0x5e,0x56,0x4e,0x46,0x3f,
0x38,0x31,0x2a,0x24,0x1f,0x19,0x14,0x10,
0x0c,0x09,0x06,0x04,0x02,0x01,0x01,0x01,
0x01,0x02,0x04,0x06,0x09,0x0c,0x10,0x14,
0x19,0x1f,0x24,0x2a,0x31,0x38,0x3f,0x46,
0x4e,0x56,0x5e,0x66,0x6f,0x77,
};
u8 i;
int main()
{
P1_MODE_IO_PU(GPIO_Pin_7);
CCON = 0x00;
CMOD = 0x08; //ϵͳʱÖÓ
CL = 0x00;
CH = 0x00;
CCAPM0 = 0x63;
PCA_PWM0 = (0x00<<6);
CCAP0L = 0x00;
CCAP0H = 0x80;
CR = 1;
EA = 1;
while(1);
}
void PCA_interrupt(void) interrupt PCA_VECTOR
{
if(CCF0)
{
CCF0 = 0;
CCAP0L = CCAP0H;
CCAP0H = T_sin[i];
i++;
if(i==94) i=0;
}
if(CF)CF = 0;
}
版权声明:本文为CSDN博主「二齐95」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/q1109/article/details/121909910
关于STC8A8K64D4芯片PCA_PWM功能的一些见解(输出1kHz sin波形)
二齐
STC8A8K64D4芯片是目前STC公司产出的8A系列最新的8位单片机MCU。其中囊括了STC8A8K64S4A12芯片的全部功能,改进了关于PWM,比较器,I/O中断等硬件功能。新增的库函数比较好用。但是对于PCA应用,以我个人的状态来说,库函数应用比较不理想,下面文章仅对寄存器使用进行说明。
**一、**PCA硬件结构
其中PCA计数器时钟主要来源于系统时钟和T0定时器,外部中断时钟入口暂时没用。16位计数器的计数位数取决于定义的PWM位数。
如果定义为8位PWM,则仅使用CL8位数据,CH数据不更新;如果定位为10位PWM,则使用CL8位,CH2位满足10位定时的要求,其他类似。CCON主要控制的是PCA计时器启停(CR位)和中断状态标志。CMOD主要决定中断状态和引脚选择状态。
**二、**寄存器结构
如上图所示,PCA模块共4个,分别作用于不同的输出管脚。我们首先定义CCON和CMOD寄存器(当然了,在这之前请先定义系统时钟、GPIO管脚状态)。完成后对使用的PCA管脚进行设置。我这里使用的是PCA0管脚。
CCAPMn寄存器主要控制PCA工作模式,我们如果要产生1k正弦波,需要对占空比进行实时更新,来达到调整输出电压的效果,因此需要使用中断(中断问题后续讲解)。
如上图,再次对PCA_PWM寄存器进行设置,这里重点设置PWM位数,其中的拓展数据值先不写。
完成后即可对CR位进行置1操作,启动寄存器。
**三。**关于中断
PCA工作在PWM模式下的中断操作很神奇。目前我的处理方式为,先对sin正弦波进行取值,可在网络上搜索相关内容。取值完成后,当PCA0产生中断后,先将CCAPH的存储值写入CCAPL,再将sin正弦波的取点值写入CCAPH,进行更新。
当设置为上升沿中断时,效果是可以的。(8位模式下,输出正弦波频率为PCA时钟频率/256/点数),下降沿中断可能存在问题。因为在对PCA计数值进行比较时,当CL小于CCAPL时输出低电平,高于CCAPL时,输出高电平,此时产生上升沿,这时对CCAP进行更新,有一定的时间完成,但是如果进行下降沿中断,那么在CL溢出时,产生下降沿中断,进入中断服务程序后,同时也会进行更新CCAP,我们再进行操作可能引起问题(目前没出现问题),可能是隐患。当设定边沿中断时,上升沿、下降沿都会产生中断,频率翻倍。
总结如下:PCA使用时,会调用系统时钟,系统时钟存在一定误差,因此可能和预想设定的频率有一定差异,建议多测试,找到最好的结果。如果大家有什么好的意见,请及时交流,共同进步。
代码附下:
#include "config.h"
#include "STC8A_GPIO.h"
u8 code T_sin[]={
0x80,0x88,0x90,0x99,0xa1,0xa9,0xb1,0xb9,
0xc0,0xc7,0xce,0xd5,0xdb,0xe0,0xe6,0xeb,
0xef,0xf3,0xf6,0xf9,0xfb,0xfd,0xfe,0xfe,
0xfe,0xfe,0xfd,0xfb,0xf9,0xf6,0xf3,0xef,
0xeb,0xe6,0xe0,0xdb,0xd5,0xce,0xc7,0xc0,
0xb9,0xb1,0xa9,0xa1,0x99,0x90,0x88,0x80,
0x77,0x6f,0x66,0x5e,0x56,0x4e,0x46,0x3f,
0x38,0x31,0x2a,0x24,0x1f,0x19,0x14,0x10,
0x0c,0x09,0x06,0x04,0x02,0x01,0x01,0x01,
0x01,0x02,0x04,0x06,0x09,0x0c,0x10,0x14,
0x19,0x1f,0x24,0x2a,0x31,0x38,0x3f,0x46,
0x4e,0x56,0x5e,0x66,0x6f,0x77,
};
u8 i;
int main()
{
P1_MODE_IO_PU(GPIO_Pin_7);
CCON = 0x00;
CMOD = 0x08; //ϵͳʱÖÓ
CL = 0x00;
CH = 0x00;
CCAPM0 = 0x63;
PCA_PWM0 = (0x00<<6);
CCAP0L = 0x00;
CCAP0H = 0x80;
CR = 1;
EA = 1;
while(1);
}
void PCA_interrupt(void) interrupt PCA_VECTOR
{
if(CCF0)
{
CCF0 = 0;
CCAP0L = CCAP0H;
CCAP0H = T_sin[i];
i++;
if(i==94) i=0;
}
if(CF)CF = 0;
}
版权声明:本文为CSDN博主「二齐95」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/q1109/article/details/121909910
暂无评论