有帮助的话点个赞吧~
main.c
#include <STC15F2K60S2.H>
#include <intrins.h>
unsigned char code smg_duanma[10]={0xc0,0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90};
unsigned char smg[8];
unsigned int set_dist=30; //距离参数
bit busy;
typedef struct
{
unsigned char b1:1;
unsigned char b2:1;
unsigned char b3:1;
unsigned char b4:1;
unsigned char b5:1;
unsigned char b6:1;
unsigned char b7:1;
unsigned char b8:1;
}Bits;
typedef union
{
unsigned char Hex;
Bits B;
}HexToBit;
HexToBit led_ctrl;
//译码器选择
void vDevice_Process(unsigned char p2dat,unsigned char p0dat)
{
P0 = p0dat;
P2 = (P2&0x1f)|p2dat;
P2 = P2&0x1f;
}
void Timer2Init(void) //1毫秒@12.000MHz
{
AUXR |= 0x04; //定时器时钟1T模式
T2L = 0x20; //设置定时初值
T2H = 0xD1; //设置定时初值
AUXR |= 0x10; //定时器2开始计时
EA=1;
IE2=0x04;
}
void Timer0Init(void) //65535微秒@12.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL1 = 0x00; //设置定时初值
TH1 = 0x00; //设置定时初值
TF1 = 0; //清除TF1标志
TR1=1;
}
void UartInit(void) //9600bps@12.000MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器1时钟为Fosc,即1T
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设定定时器1为16位自动重装方式
TL1 = 0xC7; //设定定时初值
TH1 = 0xFE; //设定定时初值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
ES=1;
EA=1;
}
//超声波测量
//发送超声波
void vSend_Wave()
{
unsigned char i,j;
for (i=0;i<8;i++)
{
P10=1;
for(j=0;j<25;j++)
_nop_();
P10=0;
for(j=0;j<25;j++)
_nop_();
}
}
//获取距离
unsigned int vGet_distance()
{
unsigned int distance;
TL0=0;
TH0=0;
vSend_Wave();
TR0=1;
while((P11==1)&&(TF0==0));
TR0=0;
TF0=0;
distance = ((TH0<<8)|TL0)*0.017;
return distance;
}
//测量
unsigned int cnt_sonic;
unsigned int Distance;
void vSnoic_Process()
{
if(cnt_sonic>=100)
{
cnt_sonic=0;
Distance = vGet_distance();
}
}
//数码管操作
unsigned char mode_smg=0;
void vSMG_Process()
{
if(mode_smg==0)
{
smg[0] = 0xc1;
smg[1] = smg_duanma[1];
smg[2] = 0xff;
smg[3] = 0xff;
smg[4] = 0xff;
smg[5] = smg_duanma[Distance/100];
smg[6] = smg_duanma[Distance/10%10];
smg[7] = smg_duanma[Distance%10];
}
if(mode_smg==1)
{
smg[0] = 0xc1;
smg[1] = smg_duanma[2];
smg[2] = 0xff;
smg[3] = 0xff;
smg[4] = 0xff;
smg[5] = smg_duanma[set_dist/100];
smg[6] = smg_duanma[set_dist/10%10];
smg[7] = smg_duanma[set_dist%10];
}
}
//数码管显示
void vSMG_Show()
{
static unsigned char i;
vDevice_Process(0xc0, 0x00);
vDevice_Process(0xe0, smg[i]);
vDevice_Process(0xc0, 0x01<<i);
i = (i+1)%8;
}
//KBD扫描
unsigned char vScan_Keys()
{
unsigned char key_io=0xff;
P32=0;P33=0;
P34=1;P35=1;P42=1;P44=1;
if(P44==0) key_io = 0x70;
if(P42==0) key_io = 0xb0;
if(P35==0) key_io = 0xd0;
if(P34==0) key_io = 0xe0;
P32=1;P33=1;
P34=0;P35=0;P42=0;P44=0;
if(P33==0) key_io = key_io|0x07;
if(P32==0) key_io = key_io|0x0b;
return key_io;
}
//三行按键处理
unsigned char Trg, Cont;
void vThreeLins_Key()
{
unsigned char key_io;
unsigned char ReadData;
key_io=vScan_Keys();
ReadData=key_io^0xff;
Trg = ReadData&(ReadData^Cont);
Cont = ReadData;
}
//按键处理
unsigned int cnt_key;
bit flag_send=0; //串口发送标志位
void vKeys_Process()
{
if(cnt_key>=20)
{
cnt_key=0;
vThreeLins_Key();
if(Trg==0x88) //S4
{
mode_smg = (mode_smg+1)%2;
}
if(Trg==0x48) //S8
{
if(mode_smg==0)
{
set_dist = Distance;
}
}
if(Trg==0x28) //S12
{
if(mode_smg==1)
{
if(set_dist<=990) //判断 防止越界
set_dist = set_dist+10;
}
}
if(Trg==0x18) //S16
{
if(mode_smg==1)
{
if(set_dist>=10)
set_dist = set_dist-10;
}
}
if(Trg==0x44) //S9
{
flag_send=1;
}
}
}
/*----------------------------
发送串口数据
----------------------------*/
void SendData(unsigned char dat)
{
while (busy); //等待前面的数据发送完成
busy = 1;
SBUF = dat; //写数据到UART数据寄存器
}
/*----------------------------
发送字符串
----------------------------*/
void SendString(char *s)
{
while (*s) //检测字符串结束标志
{
SendData(*s++); //发送当前字符
}
}
//发送距离参数
void Send_dist()
{
if(flag_send==1)
{
flag_send=0;
SendString("Distance:");
SendData(Distance/100+'0');
SendData(Distance/10%10+'0');
SendData(Distance%10+'0');
SendString("cm");
}
}
//LED指示灯
bit flag_led=0;
void vLED_Process()
{
if(mode_smg==0)
{
led_ctrl.B.b1=0;
led_ctrl.B.b2=1;
}
if(mode_smg==1)
{
led_ctrl.B.b1=1;
led_ctrl.B.b2=0;
}
if(Distance>set_dist)
{
flag_led=1;
}
else
{
flag_led=0;
led_ctrl.B.b3=1;
}
vDevice_Process(0x80,led_ctrl.Hex);
}
//初始化
void System_init()
{
led_ctrl.Hex=0xff;
vDevice_Process(0x80,led_ctrl.Hex);
vDevice_Process(0xa0,0x00);
}
void main()
{
Timer2Init();
Timer0Init();
UartInit();
System_init();
while(1)
{
vSMG_Process();
vSnoic_Process();
vKeys_Process();
Send_dist();
}
}
unsigned int pwm_dat;
void Timer2() interrupt 12
{
cnt_sonic++;cnt_key++;pwm_dat++;
vSMG_Show();
vLED_Process();
if(flag_led==1)//闪烁
{
if(pwm_dat<200)
{
led_ctrl.B.b3=0;
}
else if(pwm_dat<400)
{
led_ctrl.B.b3=1;
}
else
{
pwm_dat=0;
}
vDevice_Process(0x80,led_ctrl.Hex);
}
}
/*----------------------------
UART 中断服务程序
-----------------------------*/
void Uart() interrupt 4 using 1
{
if (RI)
{
RI = 0; //清除RI位
}
if (TI)
{
TI = 0; //清除TI位
busy = 0; //清忙标志
}
}