给你个数码管的测速程序:
#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);
} |