请教关于30F2010的PWM模块占空比和死区的问题

2020-02-10 08:38发布

我将PWM模块设为自由运行模式,PWM1H/L设为互补输出模式,PTPER寄存器设为0x3FF。当PDC1=0x1FF时,PWM1H占空比(应该是值高电平时间占总周期比例吧)为3/4,当PDC1=0x5FF时,占空比却为1/4,当PDC1=0x7FF时,占空比为0。那个二倍关系我是知道的,但为什么占空比与PDC是倒过来的呢?

另外30F系列中的DTCON2寄存器是指定单元A和单元B的死区在哪里插入的,但是2010里没有这个寄存器,单元A和单元B都应该是在什么位置插入呢?

还有发现C30的头文件和函数有一些bugs,均在程序中说明了,大家看是不是这样。

我的MPLAB版本是8.0,C30版本是3.10。

以下是我的程序:

#ifndef __dsPIC30F2010__
#define __dsPIC30F2010__
#endif
#include <p30fxxxx.h>
#include <uart.h>
#include <pwm.h>
#define FCY   29491200 //晶振7.3728MHz,PLL×16,FCY=FOSC/4=29.4912MHz
#define BOUDRATE 9600  //串口波特率
//uart.h中对于30F2010没有定义以下两个备用IO选择位,这里补上
#define UART_ALTRX_ALTTX        0xFFE7  /*Communication through ALT pins*/
#define UART_RX_TX              0xFBE7  /*Communication through the normal pins*/

_FOSC(XT_PLL16 & CSW_FSCM_OFF);
_FWDT(WDT_OFF);
_FBORPOR(PBOR_ON & BORV_20 & PWRT_64 & MCLR_EN & RST_PWMPIN & PWMxH_ACT_HI & PWMxL_ACT_HI);
_FGS(CODE_PROT_OFF & GWRP_OFF);
_FICD( 0xFFFF );
/*  头文件中对于FICD的常量定义有问题
实际上0xFFFF对应Use PGC/EMUC and PGD/EMUD
0xFFFE对应Use EMUC1 and EMUC1
0xFFFD对应Use EMUC2 and EMUC2
0xFFFC对应Use EMUC3 and EMUC3 */
// 串口发送中断服务程序
void __attribute__((__interrupt__, __auto_psv__)) _U1TXInterrupt(void)
{   
   IFS0bits.U1TXIF = 0;
}

// 串口接受中断服务程序
void __attribute__((__interrupt__, __auto_psv__)) _U1RXInterrupt(void)
{
    IFS0bits.U1RXIF = 0;
}
// 电机控制PWM中断服务程序
void __attribute__((__interrupt__, __auto_psv__)) _PWMInterrupt(void)
{
IFS2bits.PWMIF = 0;
//WriteUART1('b');
}

int main(void)
{
unsigned int reg_U1BRG;  //串口1波特率分频比寄存器设置
unsigned int reg_U1MOD;  //串口1模式寄存器设置
unsigned int reg_U1STA;  //串口1状态和控制寄存器设置
unsigned int reg_PEPER;  //PWM时基周期寄存器
unsigned int reg_PTCON;  //PWM时基控制寄存器
unsigned int reg_SEVTCMP; //PWM特殊事件比较寄存器
unsigned int reg_PWMCON1; //PWM控制寄存器1  
unsigned int reg_PWMCON2; //PWM控制寄存器2  
unsigned int reg_PDC1;  //PWM占空比寄存器1
char get;

// 以下配置串口
CloseUART1();
//设置串口的中断
ConfigIntUART1(UART_RX_INT_EN & UART_RX_INT_PR6 &
     UART_TX_INT_EN & UART_TX_INT_PR2);

/* 模式寄存器设置: 串口打开,空闲模式时打开,使用备用IO口,
       禁止启动位唤醒,禁止环回模式,
       使能自动波特率检测,无奇偶校验8位数据,
       1停止位 */
reg_U1MOD = UART_EN & UART_IDLE_CON & UART_ALTRX_ALTTX &  
                UART_DIS_WAKE & UART_DIS_LOOPBACK  &
                UART_EN_ABAUD & UART_NO_PAR_8BIT  &
                UART_1STOPBIT;
/* 状态和控制寄存器设置: 缓冲区空时产生中断,TX不拉低,
        发送使能,接受缓冲器3/4满时产生中断
        禁止地址字符检测,清零接受溢出状态位 */
    reg_U1STA = UART_INT_TX_BUF_EMPTY & UART_TX_PIN_NORMAL &
                UART_TX_ENABLE & UART_INT_RX_3_4_FUL &
                UART_ADR_DETECT_DIS & UART_RX_OVERRUN_CLEAR;
// 波特率分频比设置,波特率9600
reg_U1BRG = FCY / BOUDRATE / 16 - 1;
    OpenUART1(reg_U1MOD, reg_U1STA, reg_U1BRG);

// 以下配置电机控制PWM
/* 中断设置: PWM中断打开,优先级1,故障输入A中断关闭 */
    ConfigIntMCPWM( PWM_INT_EN & PWM_FLTA_DIS_INT & PWM_INT_PR1
               & PWM_FLTA_INT_PR0 );
/* 各寄存器设置 */
reg_PEPER = 0x3FF; //PWM频率 = 7.3728 * 4 / 1024 = 28.8KHz
reg_PDC1 = 0x7FF; //占空比50%
    reg_SEVTCMP = 0x0; //特殊事件比较寄存器匹配值为0
/* 时基控制寄存器设置: 时基打开,空闲模式时打开,1:1后分频,
       1:1预分频,自由运行模式 */
    reg_PTCON = (PWM_EN & PWM_IDLE_CON & PWM_OP_SCALE1 &
    PWM_IPCLK_SCALE1 & PWM_MOD_FREE); //此处示例程序有错
/* 控制寄存器1:PWM1H/L为互补输出模式,其他引脚禁止 */
    reg_PWMCON1 = (PWM_MOD1_COMP & PWM_PDIS3H & PWM_PDIS2H &
       PWM_PEN1H &PWM_PDIS3L & PWM_PDIS2L & PWM_PEN1L);
/* 控制寄存器2:特殊事件触发器输出后分频比1:1,
     输出改写与PWM时基同步,
     使能从占空比和周期缓冲寄存器的更新 */
    reg_PWMCON2 = (PWM_SEVOPS1 & PWM_OSYNC_PWM & PWM_UEN);
/* 设置PWM1的占空比,使能从占空比和周期缓冲寄存器的更新 */
SetDCMCPWM(1,reg_PDC1,0);
    OpenMCPWM(reg_PEPER, reg_SEVTCMP, reg_PTCON, reg_PWMCON1, reg_PWMCON2);
/* 按照头文件和例子文件里给定的方式,
    PWM更新禁止位(UDIS 控制位,PWMCON2<0>)重复设置了两遍 */


while(1)
{
  if (DataRdyUART1()) //缓冲区中有接受到的字符
  {
   get = (unsigned char)ReadUART1();
   WriteUART1((unsigned int)get);
   WriteUART1((unsigned int)PTMRbits.PTDIR);
  }
  /*
  WriteUART1((PTMR >> 8) & 0x007F);
  WriteUART1(PTMR & 0x00FF);
  WriteUART1(0x00FF);
  delay_nus(500);
  */
}
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
3条回答
tiancaigao7
2020-02-10 12:15
你说的向哪里插入死区时间的问题指针对于有8个pwm输出的芯片,也就是6010A,想2010这样的芯片没有这个功能。统一都是在发生匹配事件的时刻插入一段无效状态。

一周热门 更多>