給你個數碼管的測速程序:
#include<reg52.h>
#include<stdio.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define THC0 0xf8 //0xf9
#define TLC0 0x30 //2ms //0x0f
unsigned char code Duan[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//共陽極數碼管,0-9段碼表
unsigned char Data_Buffer[8]={0,0,0,0,0,0,0,0}; //轉速及定值顯示緩存
uchar i=0,n,Bit;
sbit led1=P2^0; //轉速千位顯數碼管位驅動端口
sbit led2=P2^2; //轉速百位顯數碼管位驅動端口
sbit led3=P2^4; //轉速個位顯數碼管位驅動端口
sbit led4=P2^6; //轉速十位顯數碼管位驅動端口
static uchar bdata ke; //可位尋址的狀態寄存器
sbit aj=ke^0; //按鍵處理標志位
sbit k1=P3^3; //功能按鍵
sbit k2=P3^4; //定值加按鍵
sbit k3=P3^5; //定值加按鍵
sbit PWM_FC=P2^7; //PWM調速輸出端
uchar T0_H = 0,T0_L = 0,T1_H=0,T1_L=0; //用來裝計算出的初值
uchar flag=1;// pwm輸出標志,0為輸出低電平,1為輸出高電平
int out=0;
uint Inpluse=0,num=0; //脈沖計數
uint PWMTime=100; //脈沖寬度
unsigned char arry[];
void SendString(uint ch);
void PIDControl();
void SystemInit();
void PWMOUT();
void SetSpeed();
void SegRefre();
void delay(i); //延時函數
/**************主函數************/
void main()
{
SystemInit(); //單片機初始化
while(1)
{
SetSpeed(); //按鍵處理程序
SegRefre(); //顯示處理
}
}
void SystemInit()
{
TMOD=0X11; //t0,t1為16位
TH0=THC0;
TL0=TLC0;
T0_H = (65535-300)/256; //PWM=1時給定高位初值
T0_L = (65535-300)%256; //PWM=1時給定低位初值
T1_H = (65535-(1000-300))/256; //PWM=0時給定高位初值
T1_L = (65535-(1000-300))%256; //PWM=0時給定低位初值
ET1=1;
ET0=1;
TR0=1;
TR1=1;
EX0=1; //中斷0用來測量轉速
IT0=1;
EA=1;
out=300; //開總中斷
// n=30;
}
void SetSpeed()
{
if (k2==0) //增加轉速定值按鍵按下時,每次增加定值100轉/分
{
while(!k2); //再次進行按鍵按下判斷
delay(40); //延時
out+=50; //增加定值100轉/分
if(out>1000) //定值最大值為9900轉/分
{
out=1000; //定值=9900轉/分
}
T0_H = (65535-out)/256; //PWM=1高位初值計算
T0_L = (65535-out)%256; //PWM=1低位初值計算
T1_H = (65535-(1000-out))/256; //PWM=0高位初值計算
T1_L = (65535-(1000-out))%256; //PWM=0低位初值計算
}
if (k3==0) //減小轉速定值按鍵按下時,每次增減定值100轉/分
{
while(!k3); //再次進行按鍵按下判斷
delay(40); //延時
out-=50; //減小定值100轉/分
if(out<100) //定值最小值為200轉/分
{
out=100; //定值=200轉/分
}
T0_H = (65535-out)/256; //PWM=1高位初值計算
T0_L = (65535-out)%256; //PWM=1低位初值計算
T1_H = (65535-(1000-out))/256; //PWM=0高位初值計算
T1_L = (65535-(1000-out))%256; //PWM=0低位初值計算
}
SegRefre(); //顯示刷新
}
void SegRefre() //顯示刷新
{
Data_Buffer[0]=num/1000; //轉速千位顯示轉換處理
Data_Buffer[1]=num%1000/100; //轉速百位顯示轉換處理
Data_Buffer[2]=num%100/10; //轉速十位顯示轉換處理
Data_Buffer[3]=num%10; //轉速個位顯示轉換處理
}
void int0() interrupt 0 //進行轉速脈沖計數外部中斷處理
{
Inpluse++; //轉速脈沖加1
}
void t0() interrupt 1 //2毫秒中斷一次
{
static unsigned int time=0;
TH0=THC0;
TL0=TLC0;
time++; //轉速測量周期
if(time>250) //0.5秒獲取一次轉速數據,進行一次PID處理。
{
time=0;
num=Inpluse*2; //碼盤數n num=Inpluse*60/n
Inpluse=0;
}
led1=1; //停止顯示
led2=1; //停止顯示
led3=1; //停止顯示
led4=1; //停止顯示
Bit++;
if(Bit>4) Bit=0;
P0=Duan[Data_Buffer[Bit]]; //獲取顯示數據段碼
switch(Bit)
{
case 0:led1=0;break; //數碼管千位顯示
case 1:led2=0;break; //數碼管百位顯示
case 2:led3=0;break; //數碼管十位顯示
case 3:led4=0;break; //數碼管個位顯示
}
}
void timer_1() interrupt 3 //PWM調速中斷處理程序
{
if(flag)
{
TH1 = T0_H; //通的初值高位
TL1 = T0_L; //通的初值低位
PWM_FC= 1; //PWM輸出=1
flag= 0;
}
else
{
TH1 = T1_H; //斷的初值高位
TL1 = T1_L; //斷的初值低位
PWM_FC= 0; //PWM輸出=0
flag= 1;
}
}
void delay(i) //延時函數
{
while(--i);
} |