PIC16F1575无CCP模块的PWM控制问题求助
PIC16F1575无CCP模块下PWM输出故障排查求助
控制PIC16F1575单片机的PWM信号时遇到问题:网上多数教程涉及CCP模块,但这款单片机无该模块。自行编写代码尝试实现PWM输出,测量后无任何PWM信号输出,求帮助。
原代码
#include "config.h" #define _XTAL_FREQ 16000000 //short pwmModule = PWM1CONbits.OUT; //Global variable for pin select void main( void ){ // <editor-fold default="collapsed" desc="Oscillator Register"> //Configure the oscillator block(16MHz) OSCCONbits.SPLLEN = 0b0; //ignored due to config OSCCONbits.IRCF = 0b1111; //16MHz OSCCONbits.SCS = 0b00; //sets clock determined by config OSCTUNEbits.TUN = 0b000000; //sets factory calibrated oscillator // </editor-fold> // <editor-fold default="collapsed" desc="PWM Register"> PWM1CONbits.EN = 0b1; //enable PWM bit PWM1CONbits.POL = 0b0; //polarity not inverted PWM1CONbits.MODE = 0b00; //standard mode PWM1CONbits.OE = 0b1; // PWM1CLKCONbits.PS = 0b001; //divide clock by 2 for source pwm 16M/2 PWM1CLKCONbits.CS = 0b01; //use high frequency internal oscillator PWM1OFCONbits.OFM = 0b00; //independant run mode // </editor-fold> // <editor-fold default="collapsed" desc="I/O Configurations"> //Configure the pins as output TRISCbits.TRISC0 = 0; TRISCbits.TRISC1 = 0; TRISAbits.TRISA4 = 0; TRISAbits.TRISA5 = 0; //Clear the output pins LATCbits.LATC0 = 0; LATCbits.LATC1 = 0; LATAbits.LATA4 = 0; LATAbits.LATA5 = 0; //Configure the pins as input TRISAbits.TRISA2 = 1; //Configure the inputs pins as digital ANSELAbits.ANSA2 = 0; // </editor-fold> while(1){ LATCbits.LATC0 = PWM1CONbits.OUT; } return; }
问题分析
- 未配置PWM核心参数:代码仅开启了PWM模块和时钟,但未设置
PWM1PR(周期寄存器)和PWM1DCH/PWM1DCL(占空比寄存器),没有这两个参数,PWM模块无法生成有效波形。 - 引脚映射缺失:PIC16F1575的PWM1输出需要通过
PWM1OFCONbits.OFSEL选择对应引脚,原代码未配置该参数,导致PWM信号无法映射到RC0引脚。 - 手动赋值引脚错误:while循环中手动将
PWM1CONbits.OUT赋值给LATC0完全多余,PWM模块会自动驱动映射后的引脚,手动赋值反而可能干扰输出。 - 振荡器配置冲突:
OSCCONbits.SCS = 0b00表示使用外部时钟,但PWM1CLKCONbits.CS = 0b01选择内部高频振荡器,两者冲突,需统一时钟源配置。
修正后的代码示例
#include "config.h" #define _XTAL_FREQ 16000000 void main( void ){ // 振荡器配置:使用16MHz内部振荡器 OSCCONbits.IRCF = 0b1111; // 16MHz内部时钟 OSCCONbits.SCS = 0b01; // 选择内部振荡器作为系统时钟 OSCTUNEbits.TUN = 0b000000; // 工厂校准值 // PWM模块配置:先关闭再配置 PWM1CONbits.EN = 0b0; PWM1CONbits.POL = 0b0; // 输出极性不翻转 PWM1CONbits.MODE = 0b00; // 标准PWM模式 PWM1CONbits.OE = 0b1; // 使能PWM输出 // PWM时钟配置:16MHz / 2 = 8MHz PWM1CLKCONbits.PS = 0b001; // 预分频器2分频 PWM1CLKCONbits.CS = 0b01; // 选择内部高频振荡器作为PWM时钟源 // 引脚映射:将PWM1输出映射到RC0引脚(OFSEL=00对应RC0) PWM1OFCONbits.OFSEL = 0b00; PWM1OFCONbits.OFM = 0b00; // 独立运行模式 // 设置PWM周期:8MHz / 1000 = 8kHz PWM频率 PWM1PR = 999; // 周期值 = (时钟频率 / 目标频率) - 1 // 设置占空比:50%占空比 PWM1DCH = (999 / 2) >> 2; // 高8位 PWM1DCL = ((999 / 2) & 0x03) << 6; // 低2位 PWM1CONbits.EN = 0b1; // 配置完成后开启PWM // I/O配置:RC0设为输出(PWM模块自动控制) TRISCbits.TRISC0 = 0; // 保留其他I/O配置 TRISCbits.TRISC1 = 0; TRISAbits.TRISA4 = 0; TRISAbits.TRISA5 = 0; LATCbits.LATC1 = 0; LATAbits.LATA4 = 0; LATAbits.LATA5 = 0; TRISAbits.TRISA2 = 1; ANSELAbits.ANSA2 = 0; while(1){ // 无需手动操作PWM引脚,模块自动运行 } return; }
内容的提问来源于stack exchange,提问作者BiscuitBoy
相关产品推荐
相关产品推荐

