找回密码
 立即注册
楼主: yangjq

手册写不清,调试搞昏头 !都是坑! STC8G单片机SFR地址的寄存器

[复制链接]
  • 打卡等级:以坛为家III
  • 打卡总天数:644
  • 最近打卡:2026-03-20 08:58:57
已绑定手机

52

主题

2488

回帖

8796

积分

论坛元老

积分
8796
发表于 2026-1-27 14:50:42 | 显示全部楼层
STC8G系列10位PCA型PWM占空比设置,PCA_PWMx的值要用一条指令写入,不能分多条指令去写(“读-修改-写”)。PWM在运行过程中,写入的高2位会先保存在内部的BUF里面,而没有真正写入寄存器,所以也无法读取刚才写入的高2位值。只有在写CCAPxH寄存器时,才将高2位真正写入PCA_PWMx,才能读取。
可以参考上面梁工提供的例子设置。
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:724
  • 最近打卡:2026-03-18 07:56:47
已绑定手机

97

主题

7244

回帖

1万

积分

超级版主

积分
13791
发表于 2026-1-27 15:27:32 | 显示全部楼层
yan*** 发表于 2026-1-27 11:04
问题就是  编译器产生的汇编代码     
ANL  PCA_PWM1  #0cf   
是否算写入了PCA_PWM1?

PCA_PWMx(高2位)有缓冲寄存器,写CCAPxH(低8位)时才会一并写入,硬件上保证原子操作,避免两个寄存器不同步导致写入错误的值
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2026-01-27 09:02:27
已绑定手机

5

主题

8

回帖

56

积分

注册会员

积分
56
发表于 2026-1-27 16:29:53 | 显示全部楼层
神*** 发表于 2026-1-27 12:10
陈工说:
能否提供完整的可以复现问题的简单测试项目程序?
上传上来,他帮您排查,您错在哪或KEIL-C51如 ...

完整代码已经在主贴了,我再贴一下也行
#include "stc8g.h"
#include <stdio.h>
#include <string.h>

void  PWMInit(void)
{
  CCON=0x00;       //CF:PCA计数器溢出可触发中断  CR:计数器启动,-,-,-,CCF2,CCF1,CCF0  后三位是PCA匹配或捕获标志,可触发中断
  CMOD=0x08;       //CIDL:空闲允许计数,- ,- ,-,CSPS[2:0] CCA时钟选择,ECF:计数溢出中断使能          CSPS: 0:SYSCLK/12,1:SYSCLK/2,2:T0溢出脉冲 3:ECI引脚 4:SYSCLK 5:SYSCLK/4 6:SYSCLK/6 7:SYSCLK/8   
        //位定义:-,ECOM:允许比较,CCAPP:上升沿捕获,CCAPN:下降沿捕获,MAT0:允许匹配,TOG0:允许高速脉冲输出,PWM0:PWM使能,ECCF0:允许捕获匹配中断
  CCAPM1=0x42;      
      //位定义:EBS[1:0]取值:0-3 对应8,7,6,10位PWM,XCCAPH[1:0]10位PWM高2位重载,XCCAPL[1:0]10PWM高2位比较,EPCnH最高位重载值,ECPL最高位比较值
  PCA_PWM1=0xc0;   //采用10位PWM
  PCA_PWM1|=0x3e;  //10bit,9bit置1  
  CCAP1H=0xff;
  CCAP1L=0xff;
  CR=1;            //PWM计数器开始计数(PWM开始输出)
}

void ChangePwm(unsigned int lumin)
{
unsigned char byteh,bytel;
lumin=1023-lumin;
bytel=lumin%256;
byteh=lumin/256;      //10位PWM的比较值高两位在PCA_PWM寄存器的第五位和第四位
byteh=byteh<<4;

PCA_PWM1&=(~0x30);    //先清除
PCA_PWM1|=byteh;
if(lumin==1023)  PCA_PWM1|=0x02;   //完全关闭
else PCA_PWM1&=(~0x02);
CCAP1H=bytel;
}

void main(void)
{
P3&=0xf3;
P5=0xff;

P3M0=0x0e;
P3M1=0x00;

P5M0=0x20;
P5M1=0x10;
PWMInit();
ChangePwm(900);
while(1);
}


回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:644
  • 最近打卡:2026-03-20 08:58:57
已绑定手机

52

主题

2488

回帖

8796

积分

论坛元老

积分
8796
发表于 2026-1-27 16:32:37 | 显示全部楼层
yan*** 发表于 2026-1-27 16:29
完整代码已经在主贴了,我再贴一下也行
#include "stc8g.h"
#include

PCA_PWMx的值用一条指令写入,像这样:
  1. void UpdatePcaPwm(u8 PCA_id, u16 pwm_value)
  2. {
  3.         if(PCA_id == PCA0)
  4.         {
  5.                 PCA_PWM0 = (PCA_PWM0 & ~0x32) | (u8)((pwm_value & 0x0300) >> 4) | (u8)((pwm_value & 0x0400) >> 9);
  6.                 CCAP0H = (u8)pwm_value;
  7.         }
  8.         else if(PCA_id == PCA1)
  9.         {
  10.                 PCA_PWM1 = (PCA_PWM1 & ~0x32) | (u8)((pwm_value & 0x0300) >> 4) | (u8)((pwm_value & 0x0400) >> 9);
  11.                 CCAP1H = (u8)pwm_value;
  12.         }
  13.         else if(PCA_id == PCA2)
  14.         {
  15.                 PCA_PWM2 = (PCA_PWM2 & ~0x32) | (u8)((pwm_value & 0x0300) >> 4) | (u8)((pwm_value & 0x0400) >> 9);
  16.                 CCAP2H = (u8)pwm_value;
  17.         }
  18. }
复制代码

官网8G-8H库函数例程包里面的“STC8G_PCA.c”文件,或者独立程序“30-PCA-3路硬件PWM模式呼吸灯程序-STC8G”例子可以参考。
库函数例程包下载页面:https://www.stcai.com/khs
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-3-22 03:27 , Processed in 0.102247 second(s), 56 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表