欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
PIC單片機PWM電機速度控制源碼-實用C語言程序設計與典型實例
[打印本頁]
作者:
likanghei
時間:
2018-5-19 11:27
標題:
PIC單片機PWM電機速度控制源碼-實用C語言程序設計與典型實例
與PIC單片機實用C語言程序設計與典型實例書籍配套的光盤實例,包括原理圖和C語言程序文件,希望對大家有所幫助!
0.jpg
(90.54 KB, 下載次數: 134)
下載附件
2018-5-20 02:38 上傳
單片機源程序如下:
#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;//選擇內部8MHz的主振蕩器
OSCTUNE=0x40;//使能4xPLL--->Fosc=32MHz
}
void PIC_PortDir_Initize(void)
{
ADCON1=0x0F;//RA和RE端口全為數字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位的定時/計數器
T0CONbits.T0CS=0;//選擇內部CLKO時鐘源作為定時
T0CONbits.PSA=0;//選擇預分頻器
T0CONbits.T0PS2=1;//預分頻比為1:256
T0CONbits.T0PS1=1;
T0CONbits.T0PS0=1;
TMR0H=(65536-31250)/256;//先寫高字節
TMR0L=(65536-31250)%256;//再寫低字節
T0CONbits.TMR0ON=1;//開始定時工作
}
void PIC_TMR1_Initize(void)
{
//此處TMR1的預分頻比為1:1
T1CONbits.RD16=1;//允許一次性讀寫16位
T1CONbits.TMR1CS=1;//選擇外部時鐘源,TMR1用作外部計數
TMR1H=0;//TMR1數據寄存器清0
TMR1L=0;
T1CONbits.TMR1ON=1;//允許TMR1開始工作
}
void PIC_TMR3_Initize(void)
{
//此處TMR1的預分頻比為1:8
T3CONbits.T3CKPS1=1;
T3CONbits.T3CKPS0=1;
T3CONbits.RD16=1;//允許一次性讀寫16位
T3CONbits.TMR3CS=0;//選擇內部時鐘源,TMR3用作內部計數
TMR3H=0;//TMR3數據寄存器清0
TMR3L=0;
T3CONbits.TMR3ON=1;//允許TMR3開始工作
}
void PIC_Interrupt_Initize(void)
{
INTCONbits.TMR0IF=0;//TMR0溢出標志位清0
INTCONbits.TMR0IE=1;//TMR0溢出中斷允許
PIR1bits.TMR1IF=0;//TMR1溢出標志位清0
PIE1bits.TMR1IE=1;//TMR1溢出中斷允許
IPR1bits.TMR1IP=0;//低優先級
PIR2bits.TMR3IF=0;//TMR1溢出標志位清0
PIE2bits.TMR3IE=1;//TMR1溢出中斷允許
IPR2bits.TMR3IP=0;//低優先級
INTCONbits.INT0IF=0;//清INT0中斷標志位
//INTCONbits.INT0IE=1;//INT0中斷允許
INTCON2bits.RBPU=0;//允許內部弱上拉
INTCON2bits.INTEDG0=1;//上邊沿觸發中斷
RCONbits.IPEN=1;//允許中斷優先級位
INTCONbits.GIE=1;//CPU全局中斷使能允許
INTCONbits.PEIE=1;//CPU第二梯隊中斷使能允許
}
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設置為PWM模式
CCP2CON=0x0F;//CCP2設置為PWM模式
T2CON=0x03;//TMR2的預分頻為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);//高優先級中斷函數聲明
#pragma code high_vector_section=0x8
void high_vector (void)
{
_asm goto PIC18F_High_isr _endasm
}
void SystemInterruptISR(void);//低優先級中斷函數聲明
#pragma code low_vector=0x18//低中斷優先級
void low_interrupt(void)
{
_asm goto SystemInterruptISR _endasm
}
#pragma code
//-------------------------------------------------------------------
void main(void)
{
unsigned long temp;
unsigned char i;
OSCillator_Initize();//CPU系統時鐘初始化內部時鐘源8MHz,經過4xPLL
PIC_PortDir_Initize();//PIC單片機的使用到的I/O口方向初始化
PIC_TMR0_Initize();//PIC單片機的TMR0定時器初始化為內部定時方式
PIC_TMR1_Initize();//PIC單片機的TMR1定時器初始化為外部計數方式
PIC_TMR3_Initize();
PIC_CCPForPWM_Initize();
PIC_Interrupt_Initize();
initize_lcd();
while(1)
{
if(0==RUNSTOPKEY)//判斷啟動按鍵是否按下
{
if(0==RunStopKeyFlag)//檢測啟動按鍵是否成功按下標志
{
RunStopKeyCounter++;//軟件計數器,用于按鍵去抖動
if(4000==RunStopKeyCounter)//按鍵去抖動延時到
{
RunStopKeyCounter=0;//清軟計數器為0
if(0==RUNSTOPKEY)//再判斷啟動按鍵是否真得按下
{
RunStopKeyFlag=1;//置啟動按鍵成功按下標志為1
if(0==MotorRunStatus)//如果電機是處理停止狀態
{//則啟動電機運轉
MotorRunStatus=1;//同時置電機狀態為1
LCDBuffer_0[0]='R';//LCD顯示屏上顯示"RUN"
LCDBuffer_0[1]='U';
LCDBuffer_0[2]='N';
LCDBuffer_0[3]=' ';
LCDBuffer_0[4]=' ';
temp=MotorPWMData;//讀取設置電機速度的變量
temp<<=1;//轉換成占空比送到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)//根據電機運轉的方向
{//來設置電機是正轉還是反轉,并在LCD上顯示
CCPR1L=0;
CCPR2L=0;
CCPR1L=MotorPWMData;//使RC1引腳輸出PWM信號
LCDBuffer_0[13]='+';//表示電機正轉
}
else
{
CCPR2L=0;
CCPR1L=0;
CCPR2L=MotorPWMData;//使RC2引腳輸出PWM信號
LCDBuffer_0[13]='-';//表示電機反轉
}
}
else//如果電機是在運轉中,則這時按下該鍵可以停止電機運轉
{
MotorRunStatus=0;//置電機運動狀態為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;//清啟動按鍵上次成功按下標志
RunStopKeyCounter=0;//消抖動延時計數器清0
}
}
}
if(0==DIRKEY)//判斷電機運轉方向切換鍵是否按下
{
if(0==DirKeyFlag)//判斷方向切換鍵的標志是否成功
{
DirKeyCounter++;//去抖動計數器加1
if(4000==DirKeyCounter)//去抖動延時時間到
{
DirKeyCounter=0;//計數器清0
if(0==DIRKEY)//判斷是否真得按下
{
DirKeyFlag=1;//置成功按下標志成立
if(0==MotorDirection)//電機是正轉方向嗎?
{
MotorDirection=1;//置反向運轉方向狀態
LCDBuffer_0[13]='-';//LCD顯示屏顯示"-"
CCPR2L=0;
CCPR1L=0;
CCPR2L=MotorPWMData;//啟動RC2輸出PWM信號
}
else
{
MotorDirection=0;//置正向運轉方向狀態
LCDBuffer_0[13]='+';//LCD顯示屏上顯示"+"
CCPR1L=0;
CCPR2L=0;
CCPR1L=MotorPWMData;//啟運RC1輸出PWM信號
}
lcd_displaystr(0,0,LCDBuffer_0);//將字符串送到LCD上顯示
}
}
}
}
else
{
if(1==DIRKEY)//等待按鍵釋放
{
if(1==DirKeyFlag)//如果上次按鍵按下標志成功,則
{
DirKeyFlag=0;//清按鍵按下標志
DirKeyCounter=0;//清計數器為0
}
}
}
if(0==PWMKEY)//判斷電機速度調節鍵是否按下
{
if(0==PWMKeyFlag)//判斷按鍵按下標志是否為0
{
PWMKeyCounter++;//去抖動計數器加1
if(4000==PWMKeyCounter)//支抖動延時時間到
{
PWMKeyCounter=0;//清計數器為0
if(0==PWMKEY)//再判斷電機速度調節鍵是否真得按下
{
PWMKeyFlag=1;//置本次按鍵按下標志成功
temp=MotorPWMData;//讀取PWM變量的內容
temp<<=1;//將其轉換成0-100之間的占空比
temp/5;
temp++;//占空比加1
if(100==temp)temp=0;//到100歸0
LCDBuffer_0[5]=(temp/10)+0x30;//送到LCD緩沖區
LCDBuffer_0[6]=(temp%10)+0x30;
temp*=5;//再將其轉換成0-250之間的PWM數據
temp>>=1;
MotorPWMData=temp;//裝入PWM變量中
if(0==MotorDirection)//如果電機方向是正轉
{
LCDBuffer_0[13]='+';//LCD上顯示"+"
CCPR1L=0;
CCPR2L=0;
CCPR1L=MotorPWMData;//PWM變量內容送到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;//清按鍵按下標志
PWMKeyCounter=0;//計數器清0
}
}
if((1==FreqFlag)&&(0==CycleFlag))//1S的測頻標志成立
{
FreqFlag=0;//清測頻標志
temp=MyTMR1.HighCounter;//讀取經過測頻的計數脈沖
temp<<=16;
temp|=MyTMR1.LowCounter;
//電機速度小于1000RPM,切換到測周法
if(temp<1000)
{
INTCONbits.INT0IE=1;//允許INT0中斷允許
INTCONbits.INT0IF=0;//清INT0中斷標志位
MyTMR3.ChangeFlag=0;//清測周所用變量標志位
}
else//否則就用測頻法計算電機速度
{
INTCONbits.INT0IE=0;//禁止INT0中斷允許
INTCONbits.INT0IF=0;//清INT0中斷標志位
//將測量的結果顯示在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使用的相關變量
MyTMR1.LowCounter=0;
T1CONbits.TMR1ON=1;
lcd_displaystr(1,0,LCDBuffer_1);//將測量的結果送到LCD上顯示
}
}
if((1==CycleFlag)&&(0==FreqFlag))
{
CycleFlag=0;
temp=MyTMR3.HighCounter;
temp<<=16;
temp|=MyTMR3.LowCounter;
temp=1000000/temp;
//將測量的結果顯示在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);//將測量的結果送到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;//如果標志為1,則置0
MyTMR3.LowCounter=TMR3L;//讀取TMR3寄存器的內容
MyTMR3.LowCounter=TMR3H;
MyTMR3.LowCounter<<=8;
MyTMR3.LowCounter|=TMR3L;
FreqFlag=0;
CycleFlag=1;
}
else
{
MyTMR3.ChangeFlag=1;//如果標志為0,則置1
MyTMR3.HighCounter=0;//清相關變量
MyTMR3.LowCounter=0;
}
}
if(1==INTCONbits.TMR0IF)//定時1S時間到
{
INTCONbits.TMR0IF=0;//TMR0溢出標志位清0
TMR0H=(65536-31250)/256;//先寫高字節
TMR0L=(65536-31250)%256;//再寫低字節
T1CONbits.TMR1ON=0;//TMR1計數器停止工作
MyTMR1.LowCounter=TMR1L;
MyTMR1.LowCounter=TMR1H;
MyTMR1.LowCounter<<=8;
MyTMR1.LowCounter|=TMR1L;
CycleFlag=0;
FreqFlag=1;
}
}
//-------------------------------------------------------------------
//---低優先中斷服務程序函數
#pragma interruptlow SystemInterruptISR
void SystemInterruptISR(void)
{
if(1==PIR1bits.TMR1IF)//如果TMR1溢出
{
PIR1bits.TMR1IF=0;//清TMR1溢出標志位
MyTMR1.HighCounter++;//TMR1軟計數器加1
}
if(1==PIR2bits.TMR3IF)//如果TMR3溢出
{
PIR2bits.TMR3IF=0;//清TMR3溢出標志位
MyTMR3.HighCounter++;//TMR3軟計數器加1
}
}
復制代碼
0.jpg
(7.54 KB, 下載次數: 112)
下載附件
2018-5-20 02:39 上傳
所有資料51hei提供下載:
PIC單片機實用C語言程序設計與典型實例(光盤).rar
(327.06 KB, 下載次數: 221)
2018-5-19 11:24 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
作者:
jzyjsjt
時間:
2019-6-18 14:56
感謝樓主分享!
作者:
石進良
時間:
2019-8-23 21:50
感謝樓主分享!
作者:
石進良
時間:
2019-8-23 21:51
感謝樓主分享!
作者:
qxdqx
時間:
2019-12-22 10:37
太好啦謝謝分享!
作者:
xxhei
時間:
2020-4-7 11:21
謝謝 手下了
作者:
花語993715
時間:
2020-5-6 11:31
感謝樓主分享
作者:
jackyjing
時間:
2020-6-4 15:39
感謝樓主分享!
作者:
liesnake
時間:
2021-5-14 15:41
如果有pcb文件就完美了。
作者:
清心閣閣主
時間:
2021-5-17 16:30
不錯 不錯 很好的資料 感謝分享!。。。。。。。。。!
歡迎光臨 (http://www.raoushi.com/bbs/)
Powered by Discuz! X3.1