我将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);
*/
}
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
一周热门 更多>