eiaydxyb 发表于 2026-3-26 17:23:54

STC8H1K08-SOP16的硬件PWM怎么用呢?

STC8H1K08-SOP16的硬件PWM怎么用呢?

乘风飞扬 发表于 2026-3-26 19:02:02

可参考8H实验箱例程包里面的PWM例子:
23-高级PWM1-PWM2-PWM3-PWM4,驱动P6口呼吸灯实验程序
24-高级PWM5-PWM6-PWM7-PWM8输出测试程序
    PWMA_CCER1 = 0x00; //写 CCMRx 前必须先清零 CCxE 关闭通道
    PWMA_CCER2 = 0x00;
    PWMA_CCMR1 = 0x60; //通道模式配置
    PWMA_CCMR2 = 0x60;
    PWMA_CCMR3 = 0x60;
    PWMA_CCMR4 = 0x60;
    PWMA_CCER1 = 0x55; //配置通道输出使能和极性
    PWMA_CCER2 = 0x55;

    PWMA_CCMR1 |= 0x08; //开启PWMA_CCRx预装载功能(需要CCxE=1才可写)
    PWMA_CCMR2 |= 0x08;
    PWMA_CCMR3 |= 0x08;
    PWMA_CCMR4 |= 0x08;

    PWMA_ARRH = (u8)(PWM_PERIOD >> 8); //设置周期时间
    PWMA_ARRL = (u8)PWM_PERIOD;

    PWMA_ENO = 0x00;
    PWMA_ENO |= ENO1P; //使能输出
    PWMA_ENO |= ENO1N; //使能输出
    PWMA_ENO |= ENO2P; //使能输出
    PWMA_ENO |= ENO2N; //使能输出
    PWMA_ENO |= ENO3P; //使能输出
    PWMA_ENO |= ENO3N; //使能输出
    PWMA_ENO |= ENO4P; //使能输出
    PWMA_ENO |= ENO4N; //使能输出

    PWMA_PS = 0x00;//高级 PWM 通道输出脚选择位
    PWMA_PS |= PWM1_3; //选择 PWM1_3 通道
    PWMA_PS |= PWM2_3; //选择 PWM2_3 通道
    PWMA_PS |= PWM3_3; //选择 PWM3_3 通道
    PWMA_PS |= PWM4_3; //选择 PWM4_3 通道

    PWMA_BKR = 0x80; //使能主输出
    PWMA_CR1 |= 0x01; //开始计时

实验箱例程包下载页面:https://www.stcai.com/syx

eiaydxyb 发表于 2026-3-27 11:35:32

乘风飞扬 发表于 2026-3-26 19:02
可参考8H实验箱例程包里面的PWM例子:
23-高级PWM1-PWM2-PWM3-PWM4,驱动P6口呼吸灯实验程序
24-高级PWM5-P ...

没有单个片内外设的视频教学吗?

乘风飞扬 发表于 2026-3-27 15:30:08

eiaydxyb 发表于 2026-3-27 11:35
没有单个片内外设的视频教学吗?

论坛教学视频栏目里面有PWM以及其它外设的教学视频
https://www.stcaimcu.com/x7ree_v-x7ree_v.html?fenlei=4

eiaydxyb 发表于 2026-3-27 17:17:02

乘风飞扬 发表于 2026-3-26 19:02
可参考8H实验箱例程包里面的PWM例子:
23-高级PWM1-PWM2-PWM3-PWM4,驱动P6口呼吸灯实验程序
24-高级PWM5-P ...

帮忙看一下,这个是串口没有初始化好吗?P35接的是LED灯。现在灯不亮。串口数据是接收433解码芯片出来的四个字节,只有第三个字节是不一样的。
#include <STC8G.H>
unsigned char buf;
unsigned char cnt = 0;

// 标准唯一正确串口初始化 11.0592 9600
void UART_Init(void)
{
    SCON = 0x50;
    TMOD = 0x20;
    TH1 = 0xFD; TL1 = 0xFD;
    TR1 = 1;
    ES = 1; EA = 1;
}

void UART_ISR() interrupt 4
{
    if(RI){RI=0; if(cnt<4)buf=SBUF;}
}

void main(void)
{
P3M0 = 0x20; P3M1 = 0x00;
        P35 = 0;   // 上电强制熄灭,彻底解决常亮
    UART_Init();

    while(1)
    {
      if(cnt == 4)
      {
            if(buf==0x24 && buf==0x94 && buf==0x02)
            {
                switch(buf)
                {
                  case 0x01: P35=0; break;
                  case 0x03: P35=1; break;
                  case 0x07: P35=0; break;
                  case 0x0A: P35=1; break;
                  case 0x0D: P35=0; break;
                }
            }
            cnt = 0;
      }
    }
}

乘风飞扬 发表于 2026-3-27 17:28:41

串口初始化代码可使用ISP软件的工具生成

eiaydxyb 发表于 2026-3-27 18:03:30

乘风飞扬 发表于 2026-3-27 17:28
串口初始化代码可使用ISP软件的工具生成

P35是控制LED灯的。按这个来初始化了。P35一样没有输出,串口接收不到数据。
即使直接把P35置1置0,都没有亮。哪里出问题了?
#include <STC8G.H>
typedef unsigned char u8;

// 你的固定指令
#define CMD_ON   0x01   //全亮100%
#define CMD_OFF    0x03   //灭0%
#define CMD_MODE10x07   //20%微亮
#define CMD_MODE20x0A   //灭
#define CMD_MODE30x0D   //全亮100%

u8 buf;
u8 idx = 0;

//===== 极简软件PWM全局变量 =====
u8 duty = 0;    //占空比 0~100
u8 cnt= 0;

void Delay1000ms(void)        //@11.0592MHz
{
        unsigned char data i, j, k;

        _nop_();
        _nop_();
        i = 43;
        j = 6;
        k = 203;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}

//===== T0中断做PWM 1kHz 不卡串口 =====
void Timer0_Init(void)
{
    TMOD |= 0x01;
    TH0 = 0xF8; TL0 = 0xF8;
    ET0 = 1; TR0 = 1;
}
void T0_ISR(void) interrupt 1
{
    TH0 = 0xF8; TL0 = 0xF8;
    cnt++;
    if(cnt >= 100) cnt = 0;
    P35 = (cnt < duty) ? 0 : 1; //低电平点亮LED
}

//===== 串口最简稳配置 9600 11.0592 =====
void Uart1_Init(void)        //9600bps@11.0592MHz
{
        SCON = 0x50;                //8位数据,可变波特率
        AUXR |= 0x40;                //定时器时钟1T模式
        AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
        TMOD &= 0x0F;                //设置定时器模式
        TL1 = 0xE0;                        //设置定时初始值
        TH1 = 0xFE;                        //设置定时初始值
        ET1 = 0;                        //禁止定时器中断
        TR1 = 1;                        //定时器1开始计时
}
void UartISR(void) interrupt 4
{
    if(RI)
    {
      RI = 0;
      if(idx < 4) buf = SBUF;
    }
}

void main(void)
{
    P3M0 = 0x20; P3M1 = 0x00;
                P35 = 0;
    Timer0_Init();
    Uart1_Init();

    while(1)
    {
      if(idx == 4)
      {
            //校验帧头尾:24 94 xx 02
            if(buf==0x24 && buf==0x94 && buf==0x01)
            {
                switch(buf)
                {
                  case CMD_OFF:   P35=0;//duty = 0;break;   //关灯
                  case CMD_ON:    P35=1;//duty = 100;break;   //全亮
                  case CMD_MODE1: duty = 20; break;   //20%微亮
                  case CMD_MODE2: duty = 0;break;
                  case CMD_MODE3: duty = 100;break;
                }
            }
            idx = 0;
      }
//                                Delay1000ms();//以下用于测试
//                                P35=1;
//                                Delay1000ms();
//                                P35=0;                               
    }
}

乘风飞扬 发表于 2026-3-27 18:41:55

写个接收串口命令开关灯的例子,供参考

eiaydxyb 发表于 2026-4-3 15:17:18

定时器2怎么关闭?

神农鼎 发表于 2026-4-3 15:28:06


页: [1] 2
查看完整版本: STC8H1K08-SOP16的硬件PWM怎么用呢?