新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 按鍵控制PWM波程序

        按鍵控制PWM波程序

        作者: 時間:2016-11-13 來源:網絡 收藏
        //*******************************************************************************

        // Description: //通過按鍵改變PWM波的占空比,并用LCD1602
        // 顯示大致的占空比。按鍵短按一次加減1次,長按連續加減。
        // 此程序用于恒流電路的測試。
        //******************************************************************************
        //main.c

        本文引用地址:http://www.104case.com/article/201611/316418.htm

        #include
        #include
        #include"pwm.h"
        #include"key.h"
        #include"lcd1602.h"
        __CONFIG(0x3739);

        uchar Keyval = 0;

        /*------------------------*/
        void Init_port();
        void Key_Process();

        /*-------- 主函數--------*/
        void main(void)
        {

        INTCON =0x00; //關總中斷
        PIE1=0;
        Init_port();
        Init_LCD() ;
        Init_PWM();
        GIE=1; //開總中斷,使能所以高優先級中斷
        while(1)
        {
        Key_Process();
        }

        }

        /*============================================
        函數名稱:Init_port
        功 能:初始化I/O端口
        參 數:無
        返回值 :無
        ==============================================*/
        void Init_port()
        { OPTION=0;
        ADCON1=0X07; //設置A口為普通I/O口
        TRISA=0x00; //控制口A設為輸出狀態
        TRISD = 0X00; //數據口為輸出狀態
        PORTD = 0;
        TRISC = 0XF0; //設置RC0~RC3為輸CHU狀態,RC4~RC7為輸RU
        PORTC = 0;

        //定義按鍵端口
        TRISB=0X1F; //設置B口低5位為輸入

        }

        /*******************************************
        函數名稱:Key_Process
        功 能:根據按鍵值執行任務
        參 數:無
        返回值 :無
        ********************************************/
        void Key_Process()
        {
        static uchar CNT=0;
        static uchar CNT1=5;
        uchar keyvalue;


        keyvalue = Key_Scan();
        Keyval = 0;


        if(keyvalue == 1) //占空比加1%
        {
        CCPR1L += 0x02;
        CNT++;
        if(CNT>9)
        {
        CNT1++;
        CNT=0;
        }
        Disp1Char(8,0,CNT1+0x30);
        Disp1Char(9,0,CNT+0x30) ;

        }
        if(keyvalue == 2) //占空比減1%
        {
        CCPR1L -= 0x02;
        CNT--;
        Disp1Char(8,0,CNT1+0x30);
        Disp1Char(9,0,CNT+0x30) ;

        if(CNT==0)
        {
        CNT1--;
        CNT = 0x0a;
        }


        }


        }

        //key.h

        #include
        #include

        #define uchar unsigned char
        #define keyin (PORTB&0x1f)

        //------------------------------------------------
        //延時程序
        void delay40ms() //延時程序
        {
        int i,j; //定義整形變量
        for(i=10;i>0;i--)
        {
        for(j=1000;j>0;j--);
        }
        }

        //------------------------------------------------
        //按鍵掃描程序
        uchar Key_Scan()
        {
        extern uchar Keyval; //初始化按鍵掃描結果,無按鍵按下時的結果

        if( keyin != 0x1f )
        {
        delay40ms();
        if( keyin != 0x1f)
        {
        if(RB0==0) //判斷B0是否按下
        Keyval=1;
        if(RB1==0) //判斷B1是否按下
        Keyval=2;
        if(RB2==0) //判斷B2是否按下
        Keyval=3;
        if(RB3==0) //判斷B3是否按下
        Keyval=4;
        if(RB4==0) //判斷B4是否按下
        Keyval=5;
        }

        }

        return Keyval;
        }

        //pwm.h

        #include
        #include

        /*============================================
        函數名稱:Init_PWM
        功 能:初始化定時器A,產生PWM波
        參 數:無
        返回值 :無
        ==============================================*/
        void Init_PWM()
        {

        PR2=0xff; //PWM Period=(PR2+1)*4*Tosc*(TMR2前分頻值)
        //占空比50%
        CCPR1L=0x7f;
        CCP1CON = 0x2C; //CCP1模塊為PWM工作方式

        TRISC = 0xF0; //設置RC2為輸出
        T2CON = 0x04; //打開TMR2,且使其前分頻為1,同時開始輸出PWM波形
        CCP1IE =0; //CCP1中斷禁止
        }

        //lcd1602.h

        #include
        #include

        #define uint unsigned int
        #define uchar unsigned char

        //定義MCU與LCD的接口
        /**************宏定義***************/
        #define Busy 0x80
        #define CLR_RS RA1=0 //RS = RA1
        #define SET_RS RA1=1
        #define CLR_RW RA2=0 //RW = RA2
        #define SET_RW RA2=1
        #define CLR_EN RA3=0 //EN = RA3
        #define SET_EN RA3=1


        /*******************************************
        函數名稱:Delayus
        功 能:延時Nus
        參 數:無
        返回值 :無
        ********************************************/
        /*void Delayus(uint N)
        {
        while (N != 0)
        {
        N--;
        }
        }*/
        /*******************************************
        函數名稱:WaitForEnable
        功 能:等待1602液晶完成內部操作
        參 數:無
        返回值 :無
        ********************************************/
        void WaitForEnable(void)
        {
        TRISD=0XFF; //將PORTD口切換為輸入狀態

        CLR_RS;
        SET_RW;
        asm("nop");
        SET_EN;
        asm("nop");
        asm("nop");
        while((PORTD & Busy)!=0); //檢測忙標志
        CLR_EN;
        TRISD=0X00; //將PORTD口切換為輸出狀態
        }
        /*******************************************
        函數名稱:write_cmd
        功 能:向液晶模塊寫入命令
        參 數:com--命令,
        返回值 :無
        ********************************************/
        void write_cmd(unsigned char com)
        {
        WaitForEnable(); //等待液晶不忙
        CLR_RS ; //RS=0,RW=0,寫指令
        CLR_RW;
        asm("nop");
        PORTD = com;
        asm("nop");
        SET_EN ;
        asm("nop");
        asm("nop");
        CLR_EN;
        }

        /*******************************************
        函數名稱:write_data
        功 能:向液晶顯示的當前地址寫入顯示數據
        參 數:data--顯示字符數據
        返回值 :無
        ********************************************/
        void write_data(unsigned char data)
        {
        WaitForEnable(); //等待液晶不忙
        SET_RS; //RS=1,RW=0,寫數據
        CLR_RW;
        asm("nop");
        PORTD = data;
        asm("nop");
        SET_EN ; //產生負脈沖
        asm("nop");
        asm("nop");
        CLR_EN ;
        }

        /*============================================
        函數名稱:Init_LCD
        功 能:初始化液晶
        參 數:無
        返回值 :無
        ==============================================*/
        void Init_LCD()
        {

        write_cmd(0x38); //規定的復位操作
        asm("nop");
        asm("nop");
        write_cmd(0x38);
        asm("nop");
        asm("nop");
        write_cmd(0x38);
        asm("nop");
        asm("nop");

        write_cmd(0x38);//16×2顯示,5×7點陣,8位數據接口
        write_cmd(0x08);//關閉顯示
        write_cmd(0x01);//清屏,數據指針=0,所有顯示=0
        write_cmd(0x06);//讀或寫一個字符后地址指針加1 &光標加1,整屏顯示不移動
        write_cmd(0x0c);//開顯示, 關光標,光標所在位置的字符不閃爍

        }

        /*******************************************
        函數名稱:LocateXY
        功 能:向液晶寫入顯示字符位置的坐標信息
        參 數:x--位置的列坐標
        y--位置的行坐標
        返回值 :無
        ********************************************/
        void LocateXY(uchar x,uchar y)
        {
        uchar temp;

        temp = x&0x0f;
        y &= 0x01;
        if(y) temp |= 0x40; //如果在第2行
        temp |= 0x80;

        write_cmd(temp);
        }
        /*******************************************
        函數名稱:Disp1Char
        功 能:在某個位置顯示一個字符
        參 數:x--位置的列坐標
        y--位置的行坐標
        data--顯示的字符數據
        返回值 :無
        ********************************************/
        void Disp1Char(uchar x,uchar y,uchar data)
        {
        LocateXY( x, y );
        write_data( data );
        }

        /***********************************************
        函數名稱:DispStr
        功 能:讓液晶從某個位置起連續顯示一個字符串
        參 數:x--位置的列坐標
        y--位置的行坐標
        ptr--指向字符串存放位置的指針
        返回值 :無
        ***********************************************/
        void DispStr(uchar x,uchar y,uchar *ptr)
        {
        uchar *temp;
        uchar i,n = 0;

        temp = ptr;
        while(*ptr++ !=

        主站蜘蛛池模板: 来安县| 昌都县| 禄丰县| 伊宁县| 枣强县| 武隆县| 阿克陶县| 增城市| 比如县| 浑源县| 仙居县| 张家港市| 兰考县| 铜陵市| 固阳县| 贵南县| 竹北市| 江津市| 武义县| 阿图什市| 山东| 武威市| 云梦县| 喀喇沁旗| 临沧市| 静乐县| 沐川县| 吕梁市| 遂平县| 肃南| 平度市| 六盘水市| 安泽县| 武冈市| 岗巴县| 五峰| 广西| 宜兰县| 堆龙德庆县| 扶余县| 长岭县|