如何使PIC18F24Q10上的 PWM 功能正常工作?



我是使用PIC微控制器和MPLAB的新手。我给自己买了几PIC18F24Q10芯片,慢慢弄清楚如何使用一些不同的功能。我目前被难倒的一件事是PWM。我一直在试图弄清楚如何让PWM在芯片上工作,但没有运气。它不会发出任何类型的 pwm 信号。我的最终目标是让它驱动伺服器,但现在我只是把它连接到一个 LED 以确保它工作。

我在下面发布了我的代码。如果有人能为我快速浏览一下,并让我知道是否有任何错误,我将不胜感激。就像我说的,我对此很陌生,所以我提前为我的草率编码风格道歉。我在周期和占空比内加载到 CCPR2 寄存器和 T2PR 中的值只是我一直在更改和试验的随机值。我主要只是想在我深入研究设置PWM功能以运行伺服之前使其工作,这是我的最终目标。


#include <xc.h>
#include <stdlib.h>
// CONFIG1L
#pragma config FEXTOSC = ECH    // External Oscillator mode Selection bits (EC (external clock) above 8 MHz; PFM set to high power)
# pragma config RSTOSC = HFINTOSC_64MHZ// Power-up default value for COSC bits (HFINTOSC with HFFRQ = 64 MHz and CDIV = 1:1)
// CONFIG1H
#pragma config CLKOUTEN = OFF   // Clock Out Enable bit (CLKOUT function is disabled)
#pragma config CSWEN = ON       // Clock Switch Enable bit (Writing to NOSC and NDIV is allowed)
#pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor enabled)
// CONFIG2L
#pragma config MCLRE = EXTMCLR  // Master Clear Enable bit (MCLR pin (RE3) is MCLR)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (Power up timer disabled)
#pragma config LPBOREN = OFF    // Low-power BOR enable bit (Low power BOR is disabled)
#pragma config BOREN = SBORDIS  // Brown-out Reset Enable bits (Brown-out Reset enabled , SBOREN bit is ignored)
// CONFIG2H
#pragma config BORV = VBOR_190  // Brown Out Reset Voltage selection bits (Brown-out Reset Voltage (VBOR) set to 1.90V)
#pragma config ZCD = OFF        // ZCD Disable bit (ZCD disabled. ZCD can be enabled by setting the ZCDSEN bit of ZCDCON)
#pragma config PPS1WAY = OFF     // PPSLOCK bit One-Way Set Enable bit (PPSLOCK bit can be cleared and set only once; PPS registers remain locked after one clear/set cycle)
#pragma config STVREN = ON      // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config XINST = OFF      // Extended Instruction Set Enable bit (Extended Instruction Set and Indexed Addressing Mode disabled)
// CONFIG3L
#pragma config WDTCPS = WDTCPS_31// WDT Period Select bits (Divider ratio 1:65536; software control of WDTPS)
#pragma config WDTE = OFF        // WDT operating mode (WDT always enabled)
// CONFIG3H
#pragma config WDTCWS = WDTCWS_7// WDT Window Select bits (window always open (100%); software control; keyed access not required)
#pragma config WDTCCS = SC      // WDT input clock selector (Software Control)
// CONFIG4L
#pragma config WRT0 = OFF       // Write Protection Block 0 (Block 0 (000800-001FFFh) not write-protected)
#pragma config WRT1 = OFF       // Write Protection Block 1 (Block 1 (002000-003FFFh) not write-protected)
// CONFIG4H
#pragma config WRTC = OFF       // Configuration Register Write Protection bit (Configuration registers (300000-30000Bh) not write-protected)
#pragma config WRTB = OFF       // Boot Block Write Protection bit (Boot Block (000000-0007FFh) not write-protected)
#pragma config WRTD = OFF       // Data EEPROM Write Protection bit (Data EEPROM not write-protected)
#pragma config SCANE = ON       // Scanner Enable bit (Scanner module is available for use, SCANMD bit can control the module)
#pragma config LVP = ON         // Low Voltage Programming Enable bit (Low voltage programming enabled. MCLR/VPP pin function is MCLR. MCLRE configuration bit is ignored)
// CONFIG5L
#pragma config CP = OFF         // UserNVM Program Memory Code Protection bit (UserNVM code protection disabled)
#pragma config CPD = OFF        // DataNVM Memory Code Protection bit (DataNVM code protection disabled)
// CONFIG5H
// CONFIG6L
#pragma config EBTR0 = OFF      // Table Read Protection Block 0 (Block 0 (000800-001FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF      // Table Read Protection Block 1 (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks)
// CONFIG6H
#pragma config EBTRB = OFF      // Boot Block Table Read Protection bit (Boot Block (000000-0007FFh) not protected from table reads executed in other blocks)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.


#define _XTAL_FREQ 8000000

void PWM_Init()            /* Initialize PWM */
{

TRISC1=0;  // Set CCP2 pin as output for PWM out 
T2ON=0;
T2PR = 0xff; 
CCP2CON = 0b00001100; 
CCPR2 = 60; // load duty cycle value 
TMR2IF=0;
T2CLKCONbits.CS = 0b0001;
T2CONbits.CKPS = 0b10; // prescale value of 1:4. 
T2ON = 1; 

}
int main()
{

OSCFRQbits.HFFRQ = 0b0011; // set clock to 8Mhz
ANSELC = 0b00000000;
PWM_Init();

while(1)
{

}
return 0;
} 

我将 LED 连接到引脚 RC1,它对应于 CCP2。芯片的RSTOSC位设置为64MHz内部振荡器,然后我在配置HFFRQ位的主要功能中将其降低到8MHZ。我想知道问题是否与时钟设置有关,但老实说,我对芯片的时钟结构缺乏了解,无法确定。

提前感谢您的帮助,如果您需要更多详细信息,请告诉我。

我有一个答案给你,但它伴随着一个考验和磨难的传奇。

您的答案是您的代码没有启用 CCP2 功能块。

困难在于,当 CCP2 配置为 PWM 并设置 CCP2 使能位时,模拟器崩溃。

此代码应初始化一个实际部分:

/*
* Initialize CCP2 for PWM output on RC1
* Set period to (FOSC/(4*T2_prescale*256)), (8000000/4096)= 1953.125 Hz
* Set duty cycle to 50%
*/
void PWM_Init(void)         /* Initialize PWM */
{
T2CON   = 0;            // Stop TIMER2
CCP2CON = 0;            // Stop PWM2
LATCbits.LATC1 = 0;
TRISCbits.TRISC1 = 0;   // Set CCP2 pin as output for PWM out
ANSELCbits.ANSELC1 = 0; // Make RC1 a digital GPIO

T2CLKCON = 0x01;        // Select FOSC/4 as TIMER2 clock source
T2PR     = 0xFF; 
CCP2CON  = 0b00001100; 
CCPR2    = 511;         // load 50% duty cycle value 
TMR2IF   = 0;
T2CONbits.CKPS = 0b10;  // prescale value of 1:4.
T2ON     = 1;
RC1PPS   = 0x06;        // Assign PWM2 output to RC1
CCP2CONbits.CCP2EN = 1;
Nop();  /* when the simulation stops here the simulator is broken */
}

我的问题是我确实有一个PIC18F27Q10来测试此代码,所以我的代码仍然可能有问题。我确实尝试初始化所有内容,因此请在您的控制器上尝试一下。

MPLAB 代码配置器 (MCC( 设置相同的内容,只是散布在多个源文件中。

最新更新