请教一下PWMB产生正弦波的问题 | 已解决
程序抄的是这个帖子第一个50hz的
产生正弦波的几种方法,有高速的,也有硬件超级简单的,波形发生器
https://www.stcaimcu.com/forum.php?mod=viewthread&tid=3593
(出处: 国芯技术交流网站)
使用的是8051U,PWMA P10口输出正常,可以看到占空比的变化,但是使用PWMB 切换到P50口,输出不正常了,1是波形不正常,2是占空比不会变化。
请教各位老师帮我看看,是什么地方的问题
P10口输出波形
P50口输出波形
P50口相关电路图
代码如下
#include "../comm/AI8051U.h"//包含此头文件后,不需要再包含"reg51.h"头文件
#include "usb.h" //USB调试及复位所需头文件
#include "T_SineTable.h"
#include "stdio.h"
#define MAIN_Fosc 35000000L //定义主时钟
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#"; //设置自动复位到ISP区的用户接口命令
//P3.2口按键复位所需变量
bit Key_Flag;
u16 Key_cnt;
u16 PWMB_Duty;
u8 PWMB_Index=0; //SPWM查表索引
u16 PWMA_Duty;
u8 PWMA_Index=0; //SPWM查表索引
void sys_init();
void delay_ms(u8 ms);
void KeyResetScan(void);
//输出正弦波频率 = 35000000 / 175 / 200 = 1000 HZ.
// 0xAF
//
//pwm
void pwmA_Init()
{
PWMA_Duty = 1220;
PWMA_CCER1 = 0x00; //写 CCMRx 前必须先清零 CCxE 关闭通道
PWMA_CCER2 = 0x00;
PWMA_CCMR1 = 0x68; //通道模式配置
PWMA_CCER1 = 0x01; //配置通道输出使能和极性
//PWMA_ARRH = 0x09; //设置周期时间
//PWMA_ARRL = 0x60;
PWMA_ARRH = 0x00; //设置周期时间1k
PWMA_ARRL = 0xAE;
PWMA_CCR1H = (u8)(PWMA_Duty >> 8); //设置占空比时间
PWMA_CCR1L = (u8)(PWMA_Duty);
//PWMA_DTR = 0x0C; //设置死区时间
PWMA_ENO = 0x00;
PWMA_ENO |= 1; //使能输出
//PWMA_ENO |= 2; //使能输出
//高级PWM输出脚会自动设置为推挽输出模式
PWMA_PS = 0x00;//高级 PWM 通道输出脚选择位
PWMA_PS |= 0; //选择 PWM1_1 通道
PWMA_BKR = 0x80; //使能主输出
PWMA_IER = 0x01; //使能中断
PWMA_CR1 |= 0x81; //使能ARR预装载,开始计时
}
void PWMA_ISR() interrupt PWMA_VECTOR
{
if(PWMA_SR1 & 0X01)
{
PWMA_SR1 &=~0X01;
PWMA_Duty = T_SinTable;
if(++PWMA_Index >= 200) PWMA_Index = 0;
PWMA_CCR1H = (u8)(PWMA_Duty >> 8); //设置占空比时间
PWMA_CCR1L = (u8)(PWMA_Duty);
}
PWMA_SR1 = 0;
}
//输出正弦波频率 = 35000000 / 175 / 200 = 1000 HZ.
// 0xAF
//
//pwm
void pwmB_Init()
{
PWMB_Duty = T_SinTable;
PWMB_CCER1 = 0x00; //写 CCMRx 前必须先清零 CCxE 关闭通道
PWMB_CCER2 = 0x00;
PWMB_CCMR1 = 0x68; //通道模式配置
PWMB_CCER1 = 0x01; //配置通道输出使能和极性
PWMB_ARRH = 0x00; //设置周期时间1k
PWMB_ARRL = 0xAE;
PWMB_CCR5H = (u8)(PWMB_Duty >> 8); //设置占空比时间
PWMB_CCR5L = (u8)(PWMB_Duty);
PWMB_ENO = 0x00;
PWMB_ENO |= 1; //使能输出
//PWMA_ENO |= 2; //使能输出
//高级PWM输出脚会自动设置为推挽输出模式
PWMB_PS = 0x03;//高级 PWM 通道输出脚选择位 P5.0
PWMB_BKR = 0x80; //使能主输出
PWMB_IER = 0x43; //使能中断
PWMB_CR1 |= 0x81; //使能ARR预装载,开始计时
}
void PWMB_ISR() interrupt PWMB_VECTOR
{
if(PWMB_SR1 & 0x01)
{
PWMB_SR1 &=~0X01;
PWMB_Duty = T_SinTable;
if(++PWMB_Index >= 200) PWMB_Index = 0;
PWMB_CCR5H = (u8)(PWMB_Duty >> 8); //设置占空比时间
PWMB_CCR5L = (u8)(PWMB_Duty);
}
PWMB_SR1 = 0;
}
void main()
{
sys_init();
IRC48MCR = 0x80;
while (!(IRC48MCR & 0x01));
USBCLK = 0x00;
USBCON = 0x90;
usb_init(); //USB CDC 接口配置
EUSB=1; //使能USB中断
EA = 1;
while (DeviceState != DEVSTATE_CONFIGURED); //等待USB完成配置
pwmB_Init();
pwmA_Init();
while (1)
{
delay_ms(1);
KeyResetScan(); //长按P3.2口按键触发软件复位,进入USB下载模式,不需要此功能可删除本行代码
if (bUsbOutReady)
{
USB_SendData(UsbOutBuffer,OutNumber); //发送数据缓冲区,长度
usb_OUT_done();
}
}
}
void sys_init()
{
WTST = 0;//设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
EAXFR = 1; //扩展寄存器(XFR)访问使能
CKCON = 0; //提高访问XRAM速度
P0M1 = 0x00; P0M0 = 0x00; //设置为准双向口
P1M1 = 0x00; P1M0 = 0x00; //设置为准双向口
P2M1 = 0x00; P2M0 = 0x00; //设置为准双向口
P3M1 = 0x00; P3M0 = 0x00; //设置为准双向口
P4M1 = 0x00; P4M0 = 0x00; //设置为准双向口
P5M1 = 0x00; P5M0 = 0x00; //设置为准双向口
P6M1 = 0x00; P6M0 = 0x00; //设置为准双向口
P7M1 = 0x00; P7M0 = 0x00; //设置为准双向口
P3M0 &= ~0x03;
P3M1 |= 0x03;
}
PWMB_IER不要使能触发中断,不要允许捕获/比较5中断,仅允许更新中断 DebugLab 发表于 2024-9-26 16:17
PWMB_IER不要使能触发中断,不要允许捕获/比较5中断,仅允许更新中断
感谢,可以了,之前中断号错了,以为是这里的问题,就改了,后来忘记改回来了
页:
[1]