?? zong.c
字號:
#include <AT89X52.h>
#define fosc 6
#define time0 4150 //定時器0定時規則,定時長度為time0*2.5us.理論上應該是:定時長度=65536-time0*fosc/12(us)
#define uchar unsigned char
//在此程序內將一直進行鍵盤掃描、中斷、顯示、按命令進行相應電機的控制與測速
void work(void);
//獲得鍵碼,注意返回的鍵碼是八位,其中高四位中哪一位為1表示該列的鍵按下
//同理低四位表示行,通過行與列確定哪個鍵按下
uchar getchar(void);
//鍵盤掃描程序,程序負責對有沒有按鍵的判斷,如果有將調用上程序判斷是哪個鍵按下,并得到相應的鍵值(字母)
uchar scankey(void);
//延時程序
void delay(int t);
//輸出PWM波的初始化程序
void PWM(void);
//控制電機正轉程序
void zhengzhuan(void);
//控制電機反轉程序
void fanzhuan(void);
//控制電機加速程序
void jiasu(void);
//控制電機減速程序
void jiansu(void);
//控制電機停止程序
void stop(void);
uchar out[4]; //該變量負責保存要輸出的四位數的每個位上的數值
unsigned int count; //保存計算轉速的變量
uchar roop = 100; //該變量將與定時器0的中斷控制每次計算轉速的時間周期
unsigned int t; //計算中斷時間的中間變量
unsigned int t2; //計算中斷時間的中間變量
//uchar p2; //
int c_out = 0; //用于保存要輸出的轉速的值
uchar sellect[4]={1,2,4,8}; //數碼管的選通信號
int led_n; //數碼管編號
unsigned int time3 = 1500; //產生PWM定時特點,定時長度為time3*2us
unsigned int time4 = 3500; //用于產生PWM0。--注:這樣的數據定時的PWM波的頻率是100Hz
uchar t2_1; //以下四個定時用的中間變量
uchar t2_0;
uchar t0_1;
uchar t0_0;
bit flag = 1; //用于判斷PWM是處于1還是0
sbit p20 = P2^0; //以下四個是與四個端口關聯的變量
sbit p21 = P2^1;
sbit p22 = P2^2;
sbit p23 = P2^3;
//延時,可以通過參數t改變延時的時間長度
void delay(int t)
{
int i;
while(t--)
{
for(i=0;i<62;i++);
}
}
//PWM波的初始化程序,主要是進行定時器2的定時時間的初始化
void PWM(void)
{
p20 = 1; //p20口輸出PWM波,初始時輸出高電平,且標志flag為1,表時現在輸出的是高電平
flag = 1;
t2 = 65536 - time3;
t2_1 = t2 / 256 - 1;
t2_0 = t2 % 256;
T2CON = 0x01; //選擇16位捕獲模式,exen2為0,作為普通定時器使用
T2MOD = 0x00;
TH2 = t2_1;
TL2 = t2_0;
ET2 = 1;
EA = 1;
TR2 = 1;
}
void work()
{
uchar key;
int temp[4];
uchar s = 0;
key = scankey();//進行鍵盤掃描,當按下A鍵時系統啟動,相當于開關
if(key=='A')
{
//中斷與定時器初始化
IT0 = 1; //外部中斷使用下降沿方式
EX0 = 1;
t = 65536 - time0 * fosc /12;
t0_1 = t / 256 - 1;
t0_0 = t % 256;
TMOD = 0x01;
TH0 = t0_1; //定時器0用于記錄轉速,定時10ms
TL0 = t0_0;
EA = 1;
ET0 = 1;
TR0 = 1;
led_n = 0;//初始時選通第一個LED
while(1) //死循環,讓系統一直處于工作狀態
{
if(!roop)//1s記錄一次轉速
{
p23 = !p23;
temp[s] = count;//臨時變量用于記錄上一個記速周期內的轉速值
s++;//用于數字濾波
if(s == 4)//當S為4,即到了4秒時,輸出經過求平均的轉速
{
c_out = (temp[0] + temp[1] + temp[2] + temp[3]) / 4;//求平均
s = 0;
}
out[0] = (c_out / 1000);//取出千位數
out[1] = ((c_out % 1000) / 100);//取出百位數
out[2] = ((c_out % 100) / 10);//取出十位數
out[3] = (c_out % 10);//取出個數數
count = 0;//轉速計數清0
roop = 100;//進入下一個計時
}
key = scankey();//掃描控制信息
switch(key)
{
case 'C'://C為電機正轉控制鍵
zhengzhuan();
break;
case 'D'://D為電機反轉控制鍵
fanzhuan();
break;
case 'E'://E為電機加速控制鍵
jiasu();
break;
case 'F'://F為電機減速控制鍵
jiansu();
break;
case 'B'://B為電機停止控制鍵
stop();
break;
default:
break;
}
}
}
}
//關于正轉與反轉,要與連線結合。實現這些功能要輸出三組信號
//一個是全能信號,由p20口輸出,這個使能信號是個PWM信號,這樣就可通過控制PWM占空比實現調速
//p21,p22口輸出正轉與反轉的控制信號,與電機控制芯片L298的兩個對應的控制入口相連
void zhengzhuan(void)
{
p20 = 1;
p21 = 1;
p22 = 0;
flag = 1;
PWM();
}
void fanzhuan(void)
{
p20 = 1;
p21 = 0;
p22 = 1;
flag = 1;
PWM();
}
//加速與減速是通過改變輸出高電平與低電平的時間長度來達到改變占空比的目的
void jiasu(void)
{
if(time3 < 4500)
{
time3 = time3 + 500;
delay(50); //為了解決不會一下加到最大的問題,在每次加速后加一個延時,減速同理
PWM();
}
if(time4 > 500)
{
time4 = time4 - 500;
delay(50);
PWM();
}
}
void jiansu(void)
{
if(time3 > 500)
{
time3 = time3 -500;
delay(50);
PWM();
}
if(time4 < 4500)
{
time4 = time4 + 500;
delay(50);
PWM();
}
}
//電機停止,控制電機的信號全清0,同時PWM的占空比調整為初始值
void stop(void)
{
P2 = 0x00;
time3 = 1500;
time4 = 3500;
}
uchar getkey()
{
uchar scancode, tmpcode;
if((P1 & 0xf0) == 0xf0)
return 0;
scancode = 0xfe;//行掃描碼
while((scancode & 0x10) != 0)
{
P1 = scancode;
if((P1 & 0xf0) != 0xf0)
{
tmpcode = (P1 & 0xf0) | 0x0f;
return ((~scancode) + (~tmpcode));//列碼+行碼=鍵植(鍵值形式:高4位行碼,低4位列碼,哪一位為1說明該行/列按下
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -