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);
}
}
在分析您提供的代码和问题描述时,我们注意到您在使用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
[本文内容由国芯人工智能辅助生成,仅供参考] 有关io口模式配置部分代码不正确
在给1的时候时候,可以使用|=运算符号,但是给0的时候,需要使用&=运算符号
因为上电默认是高阻模式,我看了一下你这样配置,P0实际为开漏模式了,此时如果没有上拉电阻,确实是没有输出信号的。
建议通过stcisp的io口配置工具来设置端口模式,简单易用 王昱顺 发表于 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波不见更新 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; (直接用赋值) 乘风飞扬 发表于 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(低电平) 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]