找回密码
 立即注册
查看: 212|回复: 7

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

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2025-06-12 08:49:32
已绑定手机

3

主题

5

回帖

47

积分

新手上路

积分
47
发表于 2025-4-20 18:07:28 | 显示全部楼层 |阅读模式
论坛的兄台帮忙看看:
问题描述:
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-53  BIN 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 CC5  HIGH 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 model  BIN 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 interrupt  250ms 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);        
  }
}



回复

使用道具 举报 送花

3

主题

717

回帖

145

积分

等待验证会员

积分
145
发表于 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输出模式。例如:

  
  1. c
  2.    P0M1 &= ~(1  8) & 0xFF;  // 设置占空比高字节
  3.    PWMBCCR5L = PWMDUTYOUTPUT & 0xFF;  // 设置占空比低字节
复制代码

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

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

[本文内容由国芯人工智能辅助生成,仅供参考]
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:499
  • 最近打卡:2025-06-16 10:06:31
已绑定手机
已实名认证

112

主题

2391

回帖

6016

积分

版主

积分
6016
发表于 2025-4-21 09:28:03 | 显示全部楼层
有关io口模式配置部分代码不正确
在给1的时候时候,可以使用|=运算符号,但是给0的时候,需要使用&=运算符号
因为上电默认是高阻模式,我看了一下你这样配置,P0实际为开漏模式了,此时如果没有上拉电阻,确实是没有输出信号的。
建议通过stcisp的io口配置工具来设置端口模式,简单易用
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:444
  • 最近打卡:2025-06-16 09:26:42
已绑定手机

39

主题

2059

回帖

7070

积分

论坛元老

积分
7070
发表于 2025-4-21 09:54:21 | 显示全部楼层
截图202504210954175327.jpg
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2025-06-12 08:49:32
已绑定手机

3

主题

5

回帖

47

积分

新手上路

积分
47
发表于 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波不见更新

点评

你的这个操作仍然不正确,想要给某一个位赋1,需要使用 X |= (1  详情 回复 发表于 2025-4-21 10:14
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:499
  • 最近打卡:2025-06-16 10:06:31
已绑定手机
已实名认证

112

主题

2391

回帖

6016

积分

版主

积分
6016
发表于 2025-4-21 10:14:18 | 显示全部楼层
guo12*** 发表于 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; (直接用赋值)
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2025-06-12 08:49:32
已绑定手机

3

主题

5

回帖

47

积分

新手上路

积分
47
发表于 2025-4-21 10:26:53 | 显示全部楼层

大哥,
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(低电平)
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:444
  • 最近打卡:2025-06-16 09:26:42
已绑定手机

39

主题

2059

回帖

7070

积分

论坛元老

积分
7070
发表于 2025-4-21 10:31:02 | 显示全部楼层
guo12*** 发表于 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
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-6-16 18:21 , Processed in 0.125963 second(s), 98 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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