guo123456 发表于 2025-4-20 18:07:28

8H3K48S2用PWMB输出占空比可调一直无法输出

论坛的兄台帮忙看看:
问题描述:
8H3K48S2用PWMB输出(使用PWMB 5-3引脚,中断更新占空比值)占空比可调一直无法输出

代码如下:

#include "stc8h.h"
#include "intrins.h"
#include "stdio.h"
#include "math.h"

typedef unsigned char       u8;
typedef unsigned int       u16;
typedef unsigned long      u32;

   
sbit PWM_OUTPUT_PIN = P0^0;


#define MAIN_FOSC                   40000000UL

#define PWM_DUTY_OUTPUT             8000   // pwm freq = 40000000 / 8000 = 5000 Hz
#define PWM_HIGH_MIN_OUTPUT         24       // 4000*0.6% = 18
#define PWM_HIGH_MAX_OUTPUT         ((PWM_DUTY_OUTPUT)-(PWM_HIGH_MIN_OUTPUT))
#define PCA_N_OUTPUT                P00      // PWM channel PWM5-3#

u16 CCAP5_TEMP, PWMB_5_HIGH, PWMB_5_LOW;
u16 PWMB_5_duty_value;
u16 PWM_OUTPUT_DUTY;
//************ end of the PCA define

//****************** others defined
bit T0_450MS_flag = 0;


void Config_PCA_OUTPUT();
void PWMn_update_OUTPUT(u8 PCA_ID_OUTPUT, u16 PWM_OUTPUT_DATA);

void Config_TMR0();





//**********************config the tmr0

void Config_TMR0()
{
AUXR |= 0X80;
      TMOD &= 0XF0;
      
      TL0 = 0XC0;         // 1 ms for timer T0 AT 40 000 000 HZ
      TH0 = 0X63;
      
      TF0 = 0X00;
      ET0 = 0X01;            
      PT0 = 0X01;         // set the t0 interrupt as the 1st one
      TR0 = 0X01;         // start the T0
      ET0 = 0X01;      
}


//************************ set the pwm for output

void PWMn_update_OUTPUT(u8 PCA_ID_OUTPUT, u16 PWM_OUTPUT_DATA)
{
if(PWM_OUTPUT_DATA > PWM_HIGH_MAX_OUTPUT)
      { PWM_OUTPUT_DATA = PWM_HIGH_MAX_OUTPUT; }
if(PWM_OUTPUT_DATA < PWM_HIGH_MIN_OUTPUT)
      { PWM_OUTPUT_DATA = PWM_HIGH_MIN_OUTPUT; }

if(PCA_ID_OUTPUT == PCA_N_OUTPUT)
      {
          PWMB_5_HIGH = PWM_OUTPUT_DATA;
          PWMB_5_LOW= (PWM_DUTY_OUTPUT)-PWM_OUTPUT_DATA;

      }
}



//************************ set the pwm

void    Config_PCA_OUTPUT(void)
{
//P_SW2 |= 0X80;         // ENABLE P_SW2 SFR
      PWMB_PSCR = 0X0000;      
      PWMB_DTR= 0X00;
      
      PWMB_PS &= 0XFF;         // BIT 1=1 BIT 0=0 FOR P0.0 FOR PWMB-53BIN 1111 1110
      PWMB_PS |= 0X02;
      
      PWMB_CCER1 = 0X00;       // CLEAN
      PWMB_CCER2 = 0X00;
      PWMB_SR1   = 0X00;
      PWMB_SR2   = 0X00;
      PWMB_ENO   = 0X00;
      PWMB_PS    = 0X00;
      PWMB_IER   = 0X00;
      
      PWMB_CCMR1 = 0X68;       // CC5 for pwm output, start pre-load
      PWMB_CCER1 = 0X01;      // BIT 1 = 0 , BIT0 = 1 ENABLE CC5HIGH IS WORKING
      PWMB_ARR = 8000;      // freq = 5000 hz ,5000 = 40000000 / 8000
      
      PWMB_ENO = 0X01;         // BIN 0000 0001 , FOR BIT 0 SET 1
      PWMB_EGR = 0X01;   // ? 0X03
      PWMB_BKR = 0X80;
      PWMB_IER = 0X01;   // ? 0X03
      PWMB_CR1 = 0X81;
      
}


//************************* the main

void main()
{      
      P1M0 |= 0XFC;            // P1^0, P1^1 as high resister model   FOR ADC
      P1M1 |= 0X03;            // M1 = 0, M0 = 0 is quasi-bidirection model                        
                                 // M1 = 0, M0 = 1 is push pull model
                           // M1 = 1, M0 = 0 is high resister model
                                 // M1 = 1, M0 = 1 is open drain model
      P0M0 |= 0XFF;            // P1^0, P1^1 as open drain model,others as pull-push model
      P0M1 |= 0X00;
      
      P2M0 |= 0X38;            // P1^0, P1^1 as open drain model,others as pull-push model
      P2M1 |= 0X38;
      
      P3M0 |= 0XFF;            // P3 as pull-push modelBIN 1111 1111
      P3M1 |= 0X00;            //M1 = 0, M0 = 1 is pull-push model
               
      
      P_SW2 |= 0X80;         // ENABLE P_SW2 SFR
      

      Config_PCA_OUTPUT();

      Config_TMR0();      

      PWMn_update_OUTPUT(PCA_N_OUTPUT, PWMB_5_duty_value);

      ET0 = 1;
      EA= 1;
      
      while(1)
      {               
                if(T0_450MS_flag == 1)
                {
                  T0_450MS_flag = 0;         
                  PWMB_5_duty_value += 200;         
                  PWMn_update_OUTPUT(PCA_N_OUTPUT, PWMB_5_duty_value);                        
      }      
      }
               
      }

// ************* the tmr0 interrupt250ms for 1 time adc scan

void TMR0_isr() interrupt 1
{
static u16 tmr0_cnt = 0;
      tmr0_cnt++;
      if(tmr0_cnt >= 800)
      {
         tmr0_cnt   = 0;
         T0_450MS_flag = 1;
}
}

//************* the uart 1# interupt



//************************ the PWMB5 3# interrupt

void PCA_Handler (void) interrupt 27
{
PWMB_SR1 = 0X00;
      
if(PWMB_SR1 & 0X02)   
      {
                PWMB_SR1 &= ~0X02;
                if(PWM_OUTPUT_PIN == 1)
                { CCAP5_TEMP += PWMB_5_HIGH;}
                else
                { CCAP5_TEMP += PWMB_5_LOW;}

                PWMB_CCR5L = (u8)CCAP5_TEMP;
                PWMB_CCR5H = (u8)(CCAP5_TEMP >> 8);      
}
}



国芯人工智能 发表于 2025-4-20 18:08:00

在分析您提供的代码和问题描述时,我们注意到您在使用STC8H3K48S2微控制器的PWMB模块时遇到了占空比无法输出的问题。以下是对该问题的详细分析和可能的解决方案。

问题分析

1. 引脚配置:您将PWM输出引脚配置为P0^0,但在代码中并未看到对该引脚的初始化配置。确保在使用PWMB模块之前,已经正确配置了相关引脚为PWM输出模式。

2. PWMB模块配置:您提到使用的是PWMB 5-3引脚,但代码中并未明确配置PWMB模块的相关寄存器。PWMB模块的配置包括时钟源选择、计数器模式、PWM模式等,这些都需要通过寄存器进行设置。

3. 占空比更新:您提到通过中断更新占空比值,但代码中并未看到中断服务程序的实现。确保中断服务程序正确更新了占空比寄存器,并且在中断中进行了必要的寄存器操作。

4. 时钟频率:您定义了主时钟频率为40MHz,但未看到对PWMB模块时钟源的配置。PWMB模块的时钟源需要根据主时钟频率进行适当的配置,以确保PWM输出频率符合预期。

解决方案

1. 引脚初始化:在代码中添加对P0^0引脚的初始化配置,将其设置为PWM输出模式。例如:

   c
   P0M1 &= ~(18) & 0xFF;// 设置占空比高字节
   PWMBCCR5L = PWMDUTYOUTPUT & 0xFF;// 设置占空比低字节

3. 中断服务程序:实现中断服务程序,更新占空比寄存器。例如:

   ```c
   void PWMBIRQHandler(void) interrupt PWMBVECTOR {
       PWMBCCR5H = (PWMB5dutyvalue >> 8) & 0xFF;// 更新占空比高字节
       PWMBCCR5L = PWMB5dutyvalue & 0xFF;// 更新占空比低字节
       PWMBSR1 &= ~(18) & 0xFF;// 更新占空比高字节
    PWMBCCR5L = PWMB5dutyvalue & 0xFF;// 更新占空比低字节
    PWMBSR1 &= ~(1

[本文内容由国芯人工智能辅助生成,仅供参考]

王昱顺 发表于 2025-4-21 09:28:03

有关io口模式配置部分代码不正确
在给1的时候时候,可以使用|=运算符号,但是给0的时候,需要使用&=运算符号
因为上电默认是高阻模式,我看了一下你这样配置,P0实际为开漏模式了,此时如果没有上拉电阻,确实是没有输出信号的。
建议通过stcisp的io口配置工具来设置端口模式,简单易用

乘风飞扬 发表于 2025-4-21 09:54:21

guo123456 发表于 2025-4-21 10:08:06

王昱顺 发表于 2025-4-21 09:28
有关io口模式配置部分代码不正确
在给1的时候时候,可以使用|=运算符号,但是给0的时候,需要使用&=运算符 ...

大哥,
1) 我刚刚把IO 口更新为(推挽) P0M0 |=0XFF; P0M1 &=0X00; 发现PWMB 5-3一直输出高电平3.3V, PWM波不见更新
2) 我刚刚把IO 口更新为(准双向) P0M0 &=0XFF; P0M1 &=0X00; 发现PWMB 5-3一直输出1V, PWM波不见更新

王昱顺 发表于 2025-4-21 10:14:18

guo123456 发表于 2025-4-21 10:08
大哥,
1) 我刚刚把IO 口更新为(推挽) P0M0 |=0XFF; P0M1 &=0X00; 发现PWMB 5-3一直输出高电平3.3V, ...

你的这个操作仍然不正确,想要给某一个位赋1,需要使用 X |= (1<<第几个位)
想要给某一个位赋0,需要使用 X &= ~(1<<第几个位)
所以你的P00设置为推挽模式应该是:   P0M0 = 0x01; P0M1 = 0xfe; (直接用赋值)

guo123456 发表于 2025-4-21 10:26:53

乘风飞扬 发表于 2025-4-21 09:54


大哥,
1) 我刚刚更新为PWMB_PS = 0X02; (去除了PWMB_PS &= , PWMB_PS |=)
      同时将IO口设置为推挽输出

PWMB-53口,一直输出0(低电平)


2) 将IO口设置为推挽输出, 直接写 PWMB_PS = 0X02;
      将PWMB_EGR 由0x01更新为 0X03 ; PWMB_IER 由0x01更新为 0X03;

PWMB-53口,一直输出0(低电平)

乘风飞扬 发表于 2025-4-21 10:31:02

guo123456 发表于 2025-4-21 10:26
大哥,
1) 我刚刚更新为PWMB_PS = 0X02; (去除了PWMB_PS &= , PWMB_PS |=)
      同时将IO口设置为推挽 ...

使用8H实验箱例程包里面的例子:24-高级PWM5-PWM6-PWM7-PWM8输出测试程序
进行测试,功能验证正常后再进行修改或者移植。
下载地址:https://www.stcai.com/syx
页: [1]
查看完整版本: 8H3K48S2用PWMB输出占空比可调一直无法输出