关于STC8A8K64D4芯片PCA_PWM功能的一些见解(输出1kHz sin波形)

关于STC8A8K64D4芯片PCA_PWM功能的一些见解(输出1kHz sin波形)

二齐

STC8A8K64D4芯片是目前STC公司产出的8A系列最新的8位单片机MCU。其中囊括了STC8A8K64S4A12芯片的全部功能,改进了关于PWM,比较器,I/O中断等硬件功能。新增的库函数比较好用。但是对于PCA应用,以我个人的状态来说,库函数应用比较不理想,下面文章仅对寄存器使用进行说明。

**一、**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结构图
其中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

二齐95

我还没有学会写个人说明!

暂无评论

相关推荐

基于8051单片机实现电子时钟+数字秒表设计

概述 电子时钟是一种利用数字电路来显示秒、分、时的计时装置,与传统的机械钟相比,它具有走时准确、显 示直观、无机械传动装置等优点,因而得到广泛应用。随着人们生活环境的不断改善和美化,在许

CC2530 常用寄存器

一、端口初始化相关寄存器 代码示例:用按键1和按键2分别控制D4和D6灯 点我跳转 二、INT相关寄存器 代码示例:利用key1,key2来产生中断控制D3,D5灯,key1,key2为下降沿触