标题: pic16f1939单片机pwm XC编译器例子 [打印本页]

作者: king2007    时间: 2020-12-28 19:34
标题: pic16f1939单片机pwm XC编译器例子
LED5运行闪亮,LED0 渐亮渐暗

#include "xc.h"                     // 调用头文件

// CONFIG1
#pragma config FOSC = HS            // Oscillator Selection (HS Oscillator, High-speed crystal/resonator connected between OSC1 and OSC2 pins)
#pragma config WDTE = OFF           // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF          // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = ON           // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
#pragma config CP = OFF             // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF            // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = OFF          // Brown-out Reset Enable (Brown-out Reset disabled)
#pragma config CLKOUTEN = OFF       // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = ON            // Internal/External Switchover (Internal/External Switchover mode is enabled)
#pragma config FCMEN = ON           // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)

// CONFIG2
#pragma config WRT = OFF            // Flash Memory Self-Write Protection (Write protection off)
#pragma config VCAPEN = OFF         // Voltage Regulator Capacitor Enable (All VCAP pin functionality is disabled)
#pragma config PLLEN = OFF          // PLL Enable (4x PLL disabled)
#pragma config STVREN = ON          // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO            // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = OFF            // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)

//-------------------------------------------------------------------------------

#define _XTAL_FREQ      8000000L    //外部 8MHz

#define LED0  LATCbits.LATC2        //LED宏定义
#define LED1  LATCbits.LATC1
#define LED2  LATCbits.LATC0
#define LED3  LATAbits.LATA5
#define LED4  LATAbits.LATA3
#define LED5  LATAbits.LATA2

#define SCLK  LATBbits.LATB0        //74HC595时钟
#define SDAT  LATBbits.LATB1        //74HC595数据
#define SRCK  LATCbits.LATC5        //74HC595锁存

#define KEY0  PORTEbits.RE3         //KEY宏定义
#define KEY1  PORTBbits.RB5
#define KEY2  PORTBbits.RB4

//-------------------------------------------------------------------------------

#define TMR1HPRELOAD    0xF0        //定时器初值
#define TMR1LPRELOAD    0x9B

unsigned char TickClock  = 0;      //2.5mS 时基
unsigned char Tmr1conunt = 0;      //定时计数

//-------------------------------------------------------------------------------
//        TMR1定时器初始化
//-------------------------------------------------------------------------------
void TMR1_Init(void)
{           
        T1CONbits.TMR1CS = 0;   //TMR1时钟 FOSC/4         
        T1CONbits.T1CKPS = 1;   //输入分频比1:2
        TMR1H  = 0xF0;          //8MHz  4mS
        TMR1L  = 0x5F;
        TMR1IF = 0;             //清中断标志
        TMR1IE = 1;             //中断允许
}

//-------------------------------------------------------------------------------
//        中断程序
//-------------------------------------------------------------------------------
void interrupt SystemISR(void)
{
        if(TMR1IE & TMR1IF)              // TMR1中断
        {
                TMR1IF= 0;
                TMR1H = 0xF0;
                TMR1L = 0x5F;
                TickClock = 1;                 // 标志位
                Tmr1conunt ++;           // 计数
        }               
}

//-------------------------------------------------------------------------------
//        CCP1初始化
//-------------------------------------------------------------------------------
void CCP1_Init(void)
{
        CCP1CON = 0b00001100;         //CCP1 为PWM模式
        CCPTMRS0= 0b00000000;         //CCP1~4 时钟来源TMR2
        CCPTMRS1= 0b00000000;         //CCP5 以Timer2 作为定时器
        CCP1IE = 0;
        CCP1IF = 0;
        
        T2CON = 0b01001100;           // Postcaler 1:10, T2ON
        PR2 = 249;                    // PWM周期 = (PR2+1)*4*TOSC
                                      // TOSC = 1/FOSC
        CCPR1L = 0x00;                // 占空比 0
        
        TMR2IF = 0;
        TMR2IE = 0;
}        

//-------------------------------------------------------------------------------
//        CCP占空比程序
//-------------------------------------------------------------------------------
unsigned int  PWM_Duty = 0;      //PWM 占空比
unsigned char PWM_FLAG  = 0;     //渐变标志位
void Conver_CCPR1L(unsigned int Duty)         //PWM 占空比转换
{
        CCPR1L = (unsigned char)(Duty>>2);
        CCP1CON |= (unsigned char)((Duty&0x0003)<<4);
}

//-------------------------------------------------------------------------------
//        PWM控制LED部分
//-------------------------------------------------------------------------------
void PWM_LED(void)
{   
        if (TickClock == 1)             //2.5mS
        {
                TickClock = 0;
                if(PWM_FLAG == 1)       //PWM LED  渐暗   
                {
                        if(PWM_Duty != 0)  
                                PWM_Duty --;
                        else               
                                PWM_FLAG = 0;
                }
                else                    //PWM LED  渐亮
                {
                        if(PWM_Duty <1023)
                                PWM_Duty++;
                        else               
                                PWM_FLAG = 1;               
                }
                Conver_CCPR1L(PWM_Duty);                  
        }
}

//-------------------------------------------------------------------------------
//        系统初始化
//-------------------------------------------------------------------------------
void System_Init(void)
{
        ADCON1 = 0b10010011;            //Fosc/8 Vref = FVR
        ADCON0 = 0b00000001;            //ADON = 1 As AN0
        
        FVRCON = 0b10000011;            //Vref+ = 4.096V

        LATA  = 0b00000000;             //端口电平初始化
        LATB  = 0b00000000;
        LATC  = 0b00000000;
        LATD  = 0b00000000;
        LATE  = 0b00000000;
        
        TRISA  = 0b11000001;            //输入
        ANSELA = 0b00000001;            //RA0模拟 LED   
                  
        TRISB  = 0b00110000;            //RB4 RB5 mTouch
        ANSELB = 0b00110000;            //74HC164 CLK DAT

        TRISC  = 0b10011000;            //UART I2C
        
        TRISD  = 0b00000000;            //输出
        ANSELD = 0b00000000;            //数字I/O

        TRISE  = 0b00000000;            //输出
        ANSELE = 0b00000000;            //数字I/O
}

//-------------------------------------------------------------------------------
//        LED灯开机显示
//-------------------------------------------------------------------------------
void StartViewLED(void)
{
        LED0 = 1;                //LED0-LED5 亮
        LED1 = 1;
        LED2 = 1;
        LED3 = 1;
        LED4 = 1;
        LED5 = 1;
        __delay_ms(800);         //延时
        LED0 = 0;                //LED0-LED5 灭
        LED1 = 0;
        LED2 = 0;
        LED3 = 0;
        LED4 = 0;
        LED5 = 0;
        __delay_ms(50);          //延时
}
               
//-------------------------------------------------------------------------------
//        主程序部分
//-------------------------------------------------------------------------------
void main(void)
{
        System_Init();               //系统初始化
        StartViewLED();              //开机LED显示
        
        TMR1_Init();                 //TMR1初始化
        CCP1_Init();                 //CCP1初始化
        
        INTCONbits.PEIE = 1;         //外设中断
        INTCONbits.GIE  = 1;         //系统中断
        T1CONbits.TMR1ON= 1;         //TMR1使能
        while(1)
        {
                PWM_LED();                   //渐变
                if(Tmr1conunt > 199)         //500mS
                {
                        Tmr1conunt = 0;
                        LED5 = !LED5;        //运行灯
                }        
        }
}



作者: 465501297    时间: 2024-8-21 11:35
中断函数要改成:void __interrupt() isr(void)
不然会报错




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1