|
與PIC單片機(jī)實(shí)用C語言程序設(shè)計(jì)與典型實(shí)例書籍配套的光盤實(shí)例,包括原理圖和C語言程序文件,希望對大家有所幫助!
0.jpg (90.54 KB, 下載次數(shù): 134)
下載附件
2018-5-20 02:38 上傳
單片機(jī)源程序如下:
- #include <p18cxxx.h>
- #include "16x2LCDDriver.h"
- unsigned char LCDBuffer_0[]={"STOP 00% DIR +"};
- unsigned char LCDBuffer_1[]={"Get Spd 0000 RPM"};
- struct TMR1COUNTER_STRUCT
- {
- unsigned char HighCounter;
- unsigned int LowCounter;
- unsigned char ChangeFlag;
- };
- struct TMR1COUNTER_STRUCT MyTMR1,MyTMR3,GetTMR1,GetTMR3;
- void OSCillator_Initize(void)
- {
- OSCCON=0x70;//選擇內(nèi)部8MHz的主振蕩器
- OSCTUNE=0x40;//使能4xPLL--->Fosc=32MHz
- }
- void PIC_PortDir_Initize(void)
- {
- ADCON1=0x0F;//RA和RE端口全為數(shù)字IO口
- TRISD=0x00;//RD端口置輸出方向
- TRISE=0x00;//RE端口置輸出方向
- TRISCbits.TRISC1=0;
- TRISCbits.TRISC2=0;
- TRISCbits.TRISC3=0;
- }
- void PIC_TMR0_Initize(void)
- {
- T0CONbits.TMR0ON=0;//TMR0停止工作
- T0CONbits.T08BIT=0;//選擇16位的定時(shí)/計(jì)數(shù)器
- T0CONbits.T0CS=0;//選擇內(nèi)部CLKO時(shí)鐘源作為定時(shí)
- T0CONbits.PSA=0;//選擇預(yù)分頻器
- T0CONbits.T0PS2=1;//預(yù)分頻比為1:256
- T0CONbits.T0PS1=1;
- T0CONbits.T0PS0=1;
- TMR0H=(65536-31250)/256;//先寫高字節(jié)
- TMR0L=(65536-31250)%256;//再寫低字節(jié)
- T0CONbits.TMR0ON=1;//開始定時(shí)工作
- }
- void PIC_TMR1_Initize(void)
- {
- //此處TMR1的預(yù)分頻比為1:1
- T1CONbits.RD16=1;//允許一次性讀寫16位
- T1CONbits.TMR1CS=1;//選擇外部時(shí)鐘源,TMR1用作外部計(jì)數(shù)
- TMR1H=0;//TMR1數(shù)據(jù)寄存器清0
- TMR1L=0;
- T1CONbits.TMR1ON=1;//允許TMR1開始工作
- }
- void PIC_TMR3_Initize(void)
- {
- //此處TMR1的預(yù)分頻比為1:8
- T3CONbits.T3CKPS1=1;
- T3CONbits.T3CKPS0=1;
- T3CONbits.RD16=1;//允許一次性讀寫16位
- T3CONbits.TMR3CS=0;//選擇內(nèi)部時(shí)鐘源,TMR3用作內(nèi)部計(jì)數(shù)
- TMR3H=0;//TMR3數(shù)據(jù)寄存器清0
- TMR3L=0;
- T3CONbits.TMR3ON=1;//允許TMR3開始工作
- }
- void PIC_Interrupt_Initize(void)
- {
- INTCONbits.TMR0IF=0;//TMR0溢出標(biāo)志位清0
- INTCONbits.TMR0IE=1;//TMR0溢出中斷允許
-
- PIR1bits.TMR1IF=0;//TMR1溢出標(biāo)志位清0
- PIE1bits.TMR1IE=1;//TMR1溢出中斷允許
- IPR1bits.TMR1IP=0;//低優(yōu)先級
-
- PIR2bits.TMR3IF=0;//TMR1溢出標(biāo)志位清0
- PIE2bits.TMR3IE=1;//TMR1溢出中斷允許
- IPR2bits.TMR3IP=0;//低優(yōu)先級
-
- INTCONbits.INT0IF=0;//清INT0中斷標(biāo)志位
- //INTCONbits.INT0IE=1;//INT0中斷允許
- INTCON2bits.RBPU=0;//允許內(nèi)部弱上拉
- INTCON2bits.INTEDG0=1;//上邊沿觸發(fā)中斷
-
- RCONbits.IPEN=1;//允許中斷優(yōu)先級位
- INTCONbits.GIE=1;//CPU全局中斷使能允許
- INTCONbits.PEIE=1;//CPU第二梯隊(duì)中斷使能允許
- }
- void PIC_CCPForPWM_Initize(void)
- {
- TRISCbits.TRISC1=0;//RC1置輸出方向
- TRISCbits.TRISC2=0;//RC2置輸出方向
- LATCbits.LATC1=0;//RC1引腳輸出為0
- LATCbits.LATC2=0;//RC2引腳輸出為0
- CCP1CON=0x0F;//CCP1設(shè)置為PWM模式
- CCP2CON=0x0F;//CCP2設(shè)置為PWM模式
- T2CON=0x03;//TMR2的預(yù)分頻為1:16
- T2CONbits.TMR2ON=1;//TMR2開始工作
- PR2=249;//PWM周期為2000Hz,FOSC=32MHz
- CCPR1L=0;//PWM1的占空比為0
- CCPR2L=0;//PWM2的占空比為0
- }
- unsigned char CycleFlag;
- unsigned char FreqFlag;
- #define RUNSTOPKEY PORTBbits.RB3
- #define PWMKEY PORTBbits.RB4
- #define DIRKEY PORTBbits.RB5
- unsigned char MotorRunStatus;
- unsigned char MotorDirection;
- unsigned char MotorPWMData;
- unsigned char RunStopKeyFlag;
- unsigned int RunStopKeyCounter;
- unsigned char DirKeyFlag;
- unsigned int DirKeyCounter;
- unsigned char PWMKeyFlag;
- unsigned int PWMKeyCounter;
- void SystemVariant_Initize(void)
- {
- MotorPWMData=0;
- }
- void Motor_Control(unsigned char Direction,
- unsigned char Speed)
- {
- switch(Direction)
- {
- case 0:
- CCPR1L=0;
- CCPR2L=0;
- CCPR1L=Speed;
- break;
- case 1:
- CCPR2L=0;
- CCPR1L=0;
- CCPR2L=Speed;
- break;
- }
- }
- //-------------------------------------------------------------------
- void PIC18F_High_isr(void);//高優(yōu)先級中斷函數(shù)聲明
- #pragma code high_vector_section=0x8
- void high_vector (void)
- {
- _asm goto PIC18F_High_isr _endasm
- }
- void SystemInterruptISR(void);//低優(yōu)先級中斷函數(shù)聲明
- #pragma code low_vector=0x18//低中斷優(yōu)先級
- void low_interrupt(void)
- {
- _asm goto SystemInterruptISR _endasm
- }
- #pragma code
- //-------------------------------------------------------------------
- void main(void)
- {
- unsigned long temp;
- unsigned char i;
-
- OSCillator_Initize();//CPU系統(tǒng)時(shí)鐘初始化內(nèi)部時(shí)鐘源8MHz,經(jīng)過4xPLL
- PIC_PortDir_Initize();//PIC單片機(jī)的使用到的I/O口方向初始化
- PIC_TMR0_Initize();//PIC單片機(jī)的TMR0定時(shí)器初始化為內(nèi)部定時(shí)方式
- PIC_TMR1_Initize();//PIC單片機(jī)的TMR1定時(shí)器初始化為外部計(jì)數(shù)方式
- PIC_TMR3_Initize();
- PIC_CCPForPWM_Initize();
- PIC_Interrupt_Initize();
- initize_lcd();
-
- while(1)
- {
- if(0==RUNSTOPKEY)//判斷啟動(dòng)按鍵是否按下
- {
- if(0==RunStopKeyFlag)//檢測啟動(dòng)按鍵是否成功按下標(biāo)志
- {
- RunStopKeyCounter++;//軟件計(jì)數(shù)器,用于按鍵去抖動(dòng)
- if(4000==RunStopKeyCounter)//按鍵去抖動(dòng)延時(shí)到
- {
- RunStopKeyCounter=0;//清軟計(jì)數(shù)器為0
- if(0==RUNSTOPKEY)//再判斷啟動(dòng)按鍵是否真得按下
- {
- RunStopKeyFlag=1;//置啟動(dòng)按鍵成功按下標(biāo)志為1
- if(0==MotorRunStatus)//如果電機(jī)是處理停止?fàn)顟B(tài)
- {//則啟動(dòng)電機(jī)運(yùn)轉(zhuǎn)
- MotorRunStatus=1;//同時(shí)置電機(jī)狀態(tài)為1
- LCDBuffer_0[0]='R';//LCD顯示屏上顯示"RUN"
- LCDBuffer_0[1]='U';
- LCDBuffer_0[2]='N';
- LCDBuffer_0[3]=' ';
- LCDBuffer_0[4]=' ';
- temp=MotorPWMData;//讀取設(shè)置電機(jī)速度的變量
- temp<<=1;//轉(zhuǎn)換成占空比送到LCD上顯示
- temp/=5;
- LCDBuffer_0[5]=(temp/10)+0x30;
- LCDBuffer_0[6]=(temp%10)+0x30;
- LCDBuffer_0[7]='%';
- LCDBuffer_0[8]=' ';
- LCDBuffer_0[9]='D';
- LCDBuffer_0[10]='I';
- LCDBuffer_0[11]='R';
- LCDBuffer_0[12]=' ';
- if(0==MotorDirection)//根據(jù)電機(jī)運(yùn)轉(zhuǎn)的方向
- {//來設(shè)置電機(jī)是正轉(zhuǎn)還是反轉(zhuǎn),并在LCD上顯示
- CCPR1L=0;
- CCPR2L=0;
- CCPR1L=MotorPWMData;//使RC1引腳輸出PWM信號
- LCDBuffer_0[13]='+';//表示電機(jī)正轉(zhuǎn)
- }
- else
- {
- CCPR2L=0;
- CCPR1L=0;
- CCPR2L=MotorPWMData;//使RC2引腳輸出PWM信號
- LCDBuffer_0[13]='-';//表示電機(jī)反轉(zhuǎn)
- }
- }
- else//如果電機(jī)是在運(yùn)轉(zhuǎn)中,則這時(shí)按下該鍵可以停止電機(jī)運(yùn)轉(zhuǎn)
- {
- MotorRunStatus=0;//置電機(jī)運(yùn)動(dòng)狀態(tài)為0
- LCDBuffer_0[0]='S';//LCD屏上顯示"STOP"
- LCDBuffer_0[1]='T';
- LCDBuffer_0[2]='O';
- LCDBuffer_0[3]='P';
- LCDBuffer_0[4]=' ';
- LCDBuffer_0[5]='0';
- LCDBuffer_0[6]='0';
- CCPR1L=0;//RC1和RC2引腳不輸出PWM信號
- CCPR2L=0;
- }
- lcd_displaystr(0,0,LCDBuffer_0);//將字符串送到LCD上顯示
- }
- }
- }
- }
- else
- {
- if(1==RUNSTOPKEY)//等待按鍵釋放處理過程
- {
- if(1==RunStopKeyFlag)
- {
- RunStopKeyFlag=0;//清啟動(dòng)按鍵上次成功按下標(biāo)志
- RunStopKeyCounter=0;//消抖動(dòng)延時(shí)計(jì)數(shù)器清0
- }
- }
- }
-
- if(0==DIRKEY)//判斷電機(jī)運(yùn)轉(zhuǎn)方向切換鍵是否按下
- {
- if(0==DirKeyFlag)//判斷方向切換鍵的標(biāo)志是否成功
- {
- DirKeyCounter++;//去抖動(dòng)計(jì)數(shù)器加1
- if(4000==DirKeyCounter)//去抖動(dòng)延時(shí)時(shí)間到
- {
- DirKeyCounter=0;//計(jì)數(shù)器清0
- if(0==DIRKEY)//判斷是否真得按下
- {
- DirKeyFlag=1;//置成功按下標(biāo)志成立
- if(0==MotorDirection)//電機(jī)是正轉(zhuǎn)方向嗎?
- {
- MotorDirection=1;//置反向運(yùn)轉(zhuǎn)方向狀態(tài)
- LCDBuffer_0[13]='-';//LCD顯示屏顯示"-"
- CCPR2L=0;
- CCPR1L=0;
- CCPR2L=MotorPWMData;//啟動(dòng)RC2輸出PWM信號
- }
- else
- {
- MotorDirection=0;//置正向運(yùn)轉(zhuǎn)方向狀態(tài)
- LCDBuffer_0[13]='+';//LCD顯示屏上顯示"+"
- CCPR1L=0;
- CCPR2L=0;
- CCPR1L=MotorPWMData;//啟運(yùn)RC1輸出PWM信號
- }
- lcd_displaystr(0,0,LCDBuffer_0);//將字符串送到LCD上顯示
- }
- }
- }
- }
- else
- {
- if(1==DIRKEY)//等待按鍵釋放
- {
- if(1==DirKeyFlag)//如果上次按鍵按下標(biāo)志成功,則
- {
- DirKeyFlag=0;//清按鍵按下標(biāo)志
- DirKeyCounter=0;//清計(jì)數(shù)器為0
- }
- }
- }
-
- if(0==PWMKEY)//判斷電機(jī)速度調(diào)節(jié)鍵是否按下
- {
- if(0==PWMKeyFlag)//判斷按鍵按下標(biāo)志是否為0
- {
- PWMKeyCounter++;//去抖動(dòng)計(jì)數(shù)器加1
- if(4000==PWMKeyCounter)//支抖動(dòng)延時(shí)時(shí)間到
- {
- PWMKeyCounter=0;//清計(jì)數(shù)器為0
- if(0==PWMKEY)//再判斷電機(jī)速度調(diào)節(jié)鍵是否真得按下
- {
- PWMKeyFlag=1;//置本次按鍵按下標(biāo)志成功
- temp=MotorPWMData;//讀取PWM變量的內(nèi)容
- temp<<=1;//將其轉(zhuǎn)換成0-100之間的占空比
- temp/5;
- temp++;//占空比加1
- if(100==temp)temp=0;//到100歸0
- LCDBuffer_0[5]=(temp/10)+0x30;//送到LCD緩沖區(qū)
- LCDBuffer_0[6]=(temp%10)+0x30;
- temp*=5;//再將其轉(zhuǎn)換成0-250之間的PWM數(shù)據(jù)
- temp>>=1;
- MotorPWMData=temp;//裝入PWM變量中
- if(0==MotorDirection)//如果電機(jī)方向是正轉(zhuǎn)
- {
- LCDBuffer_0[13]='+';//LCD上顯示"+"
- CCPR1L=0;
- CCPR2L=0;
- CCPR1L=MotorPWMData;//PWM變量內(nèi)容送到CCP1
- }
- else
- {
- LCDBuffer_0[13]='-';
- CCPR2L=0;
- CCPR1L=0;
- CCPR2L=MotorPWMData;//PWM變量送到CCP2
- }
- lcd_displaystr(0,0,LCDBuffer_0);//將字符串送到LCD上顯示
- }
- }
- }
- }
- else
- {
- if(1==PWMKeyFlag)//等待按鍵釋放
- {
- PWMKeyFlag=0;//清按鍵按下標(biāo)志
- PWMKeyCounter=0;//計(jì)數(shù)器清0
- }
- }
-
- if((1==FreqFlag)&&(0==CycleFlag))//1S的測頻標(biāo)志成立
- {
- FreqFlag=0;//清測頻標(biāo)志
- temp=MyTMR1.HighCounter;//讀取經(jīng)過測頻的計(jì)數(shù)脈沖
- temp<<=16;
- temp|=MyTMR1.LowCounter;
- //電機(jī)速度小于1000RPM,切換到測周法
- if(temp<1000)
- {
- INTCONbits.INT0IE=1;//允許INT0中斷允許
- INTCONbits.INT0IF=0;//清INT0中斷標(biāo)志位
- MyTMR3.ChangeFlag=0;//清測周所用變量標(biāo)志位
- }
- else//否則就用測頻法計(jì)算電機(jī)速度
- {
- INTCONbits.INT0IE=0;//禁止INT0中斷允許
- INTCONbits.INT0IF=0;//清INT0中斷標(biāo)志位
- //將測量的結(jié)果顯示在LCD顯示屏上
- for(i=8;i<12;i++)LCDBuffer_1[i]=0x30;
- i=11;
- while(temp)
- {
- LCDBuffer_1[i]=(temp%10)+0x30;
- temp/=10;
- i--;
- }
- MyTMR1.HighCounter=0;//清TMR1使用的相關(guān)變量
- MyTMR1.LowCounter=0;
- T1CONbits.TMR1ON=1;
- lcd_displaystr(1,0,LCDBuffer_1);//將測量的結(jié)果送到LCD上顯示
- }
- }
-
- if((1==CycleFlag)&&(0==FreqFlag))
- {
- CycleFlag=0;
- temp=MyTMR3.HighCounter;
- temp<<=16;
- temp|=MyTMR3.LowCounter;
- temp=1000000/temp;
- //將測量的結(jié)果顯示在LCD顯示屏上
- for(i=8;i<12;i++)LCDBuffer_1[i]=0x30;
- i=11;
- while(temp)
- {
- LCDBuffer_1[i]=(temp%10)+0x30;
- temp/=10;
- i--;
- }
- MyTMR3.HighCounter=0;
- MyTMR3.LowCounter=0;
- T1CONbits.TMR1ON=1;
- lcd_displaystr(1,0,LCDBuffer_1);//將測量的結(jié)果送到LCD上顯示
- }
- }
- }
- //-------------------------------------------------------------------
- #pragma interrupt PIC18F_High_isr
- void PIC18F_High_isr(void)
- {
- unsigned long temp;
-
- if(1==INTCONbits.INT0IF)
- {
- INTCONbits.INT0IF=0;
- if(MyTMR3.ChangeFlag)
- {
- INTCONbits.INT0IE=0;
- MyTMR3.ChangeFlag=0;//如果標(biāo)志為1,則置0
- MyTMR3.LowCounter=TMR3L;//讀取TMR3寄存器的內(nèi)容
- MyTMR3.LowCounter=TMR3H;
- MyTMR3.LowCounter<<=8;
- MyTMR3.LowCounter|=TMR3L;
- FreqFlag=0;
- CycleFlag=1;
- }
- else
- {
- MyTMR3.ChangeFlag=1;//如果標(biāo)志為0,則置1
- MyTMR3.HighCounter=0;//清相關(guān)變量
- MyTMR3.LowCounter=0;
- }
- }
-
- if(1==INTCONbits.TMR0IF)//定時(shí)1S時(shí)間到
- {
- INTCONbits.TMR0IF=0;//TMR0溢出標(biāo)志位清0
- TMR0H=(65536-31250)/256;//先寫高字節(jié)
- TMR0L=(65536-31250)%256;//再寫低字節(jié)
-
- T1CONbits.TMR1ON=0;//TMR1計(jì)數(shù)器停止工作
- MyTMR1.LowCounter=TMR1L;
- MyTMR1.LowCounter=TMR1H;
- MyTMR1.LowCounter<<=8;
- MyTMR1.LowCounter|=TMR1L;
- CycleFlag=0;
- FreqFlag=1;
- }
- }
- //-------------------------------------------------------------------
- //---低優(yōu)先中斷服務(wù)程序函數(shù)
- #pragma interruptlow SystemInterruptISR
- void SystemInterruptISR(void)
- {
- if(1==PIR1bits.TMR1IF)//如果TMR1溢出
- {
- PIR1bits.TMR1IF=0;//清TMR1溢出標(biāo)志位
- MyTMR1.HighCounter++;//TMR1軟計(jì)數(shù)器加1
- }
-
- if(1==PIR2bits.TMR3IF)//如果TMR3溢出
- {
- PIR2bits.TMR3IF=0;//清TMR3溢出標(biāo)志位
- MyTMR3.HighCounter++;//TMR3軟計(jì)數(shù)器加1
- }
- }
復(fù)制代碼
0.jpg (7.54 KB, 下載次數(shù): 112)
下載附件
2018-5-20 02:39 上傳
所有資料51hei提供下載:
PIC單片機(jī)實(shí)用C語言程序設(shè)計(jì)與典型實(shí)例(光盤).rar
(327.06 KB, 下載次數(shù): 221)
2018-5-19 11:24 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
|