#include <STC15F2K60S2.H>
#include "ds1302.h"
#include "iic.h"
float f_jz=0;//校准参数
unsigned int f_cx=2000;//超限参数
unsigned char state=0,state_cs=0,state_huixian=0;//数码管界面切换标志位
float f=0;//频率
float voltage_out;//输出电压
bit led_sign=0;//频率界面下的led闪烁标志位
unsigned int f_max=0;
unsigned char hour,minute,second;//时间
unsigned char hour_last,minute_last,second_last;//最大频率发生时间
unsigned char smg_clk=0,key_clk=0,vol_clk=0;
unsigned char smg[8] = {16,16,16,16,16,16,16,16};
unsigned char dot[8] = {0,0,0,0,0,0,0,0};
unsigned char led[8] = {0,0,0,0,0,0,0,0};
unsigned char position=0;
code unsigned char duanma[] =
{
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0x88, //A
0x83, //b
0xc6, //C
0xa1, //d
0x86, //E
0x8e, //F
0xff, //空白 16
0xc7, //L 17
0x8c, //P 18
0xbf, //横杠 19
0x89 //H
};
//锁存器选择函数
void suocunqi(unsigned char channel,unsigned char dat)
{
P2 = (P2 & 0x1f) | 0x00;
P0 = dat;
switch(channel)
{
case 4:P2 = (P2 & 0x1f) | 0x80;break;
case 5:P2 = (P2 & 0x1f) | 0xa0;break;
case 6:P2 = (P2 & 0x1f) | 0xc0;break;
case 7:P2 = (P2 & 0x1f) | 0xe0;break;
}
P2 = (P2 & 0x1f) | 0x00;
}
//系统初始化函数
void system_init()
{
suocunqi(4,0xff);
suocunqi(5,0x00);
suocunqi(7,0xff);
}
//数码管位选函数
void smg_bit(unsigned char *smg,unsigned char *dot)
{
suocunqi(7,0xff);
suocunqi(6,0x01<<position);
if(dot[position])
suocunqi(7,duanma[smg[position]]&0x7f);
else
suocunqi(7,duanma[smg[position]]);
}
//led位选函数
void led_bit(unsigned char *led)
{
static unsigned char temp_led = 0xff;
if(led[position])
temp_led &= ~(0x01<<position);
else
temp_led |= 0x01<<position;
suocunqi(4,temp_led);
}
//定时器扫描函数
void timer_init()
{
AUXR &= 0xBF; //定时器1时钟12T模式
AUXR &= 0x7F; //定时器0时钟12T模式
TMOD = 0x04;
TH0 = 0xff;
TL0 = 0xff;
TH1 = (65536 - 1000)/256;
TL1 = (65536 - 1000)%256;
TF0=TF1=0;
EA=1;
ET1=ET0=1;
TR0=TR1=1;
}
unsigned int count_f=0,count_1=0,count_2;
void timer0() interrupt 1
{
count_f++;
}
void timer1() interrupt 3
{
if(++count_1==1000)
{
count_1=0;
f = count_f + f_jz;
if(f>f_max)
{
f_max = f;
hour_last = hour;
minute_last = minute;
second_last = second;
}
count_f=0;
}
}
void Timer5Init(void) //1毫秒@12.000MHz
{
AUXR &= 0xFB; //定时器时钟12T模式
T2L = 0x18; //设置定时初值
T2H = 0xFC; //设置定时初值
AUXR |= 0x10; //定时器2开始计时
IE2 |= 0x04;
EA = 1;
}
void timer2() interrupt 12
{
smg_clk++;//注意不超过100
key_clk++;
vol_clk++;
smg_bit(smg,dot);
if(position<=1) led_bit(led);
if(++position==8) position=0;
if(++count_2==200)
{
count_2=0;
led_sign^=1;
}
}
//电压输出函数
void wt_voltage()
{ unsigned char temp_vol;
if(vol_clk<6) return;
vol_clk=0;
if(f>=0)//频率数据正常
{
if(f>=f_cx) voltage_out=5.0;
else if(f>=500) voltage_out= (f-500)/(f_cx-500)*4+1;
else voltage_out = 1.0;
}
else voltage_out=0;
temp_vol = voltage_out*(255/5.0);
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x40);
I2CWaitAck();
I2CSendByte(temp_vol);
I2CWaitAck();
I2CStop();
}
//时间读取与初始化函数
void ds1302_init()
{
Write_Ds1302_Byte(0x8e,0x00);
Write_Ds1302_Byte(0x84,0x13);
Write_Ds1302_Byte(0x82,0x03);
Write_Ds1302_Byte(0x80,0x05);
Write_Ds1302_Byte(0x8e,0x80);
}
void rd_time()
{
hour = Read_Ds1302_Byte (0x85);
minute = Read_Ds1302_Byte (0x83);
second = Read_Ds1302_Byte (0x81);
}
//数码管显示函数
unsigned int temp_1;
void smg_display()
{
if(smg_clk<60) return;
smg_clk=0;
rd_time();//时间刷新
switch(state)
{
case 0://频率界面
temp_1 = f;
smg[0] = 15;
smg[1] = 16;
smg[2] = 16;
smg[3] = f>=0?temp_1>=10000?temp_1/10000%10:16:16;
smg[4] = f>=0?temp_1>=1000?temp_1/1000%10:16:16;
smg[5] = f>=0?temp_1>=100?temp_1/100%10:16:16;
smg[6] = f>=0?temp_1>=10?temp_1/10%10:16:17;
smg[7] = f>=0?temp_1%10:17;
break;
case 1://参数界面
switch(state_cs)
{
case 0://超限参数界面
temp_1 = f_cx;
smg[0] = 18;
smg[1] = 1;
smg[2] = 16;
smg[3] = 16;
smg[4] = temp_1>=1000?temp_1/1000%10:16;
smg[5] = temp_1>=100?temp_1/100%10:16;
smg[6] = temp_1>=10?temp_1/10%10:16;
smg[7] = temp_1%10;
break;
case 1://校准值参数界面
temp_1 = f_jz>=0?f_jz:-f_jz;
smg[0] = 18;
smg[1] = 2;
smg[2] = 16;
smg[3] = 16;
smg[4] = temp_1>=1000?(temp_1/1000%10):(f_jz<=-100?19:16);
smg[5] = temp_1>=100?temp_1/100%10:16;
smg[6] = temp_1>=10?temp_1/10%10:16;
smg[7] = temp_1%10;
break;
}
break;
case 2://时间界面
smg[0] = hour/16;
smg[1] = hour%16;
smg[2] = 19;
smg[3] = minute/16;
smg[4] = minute%16;
smg[5] = 19;
smg[6] = second/16;
smg[7] = second%16;
break;
case 3://回显界面
switch(state_huixian)
{
case 0://回显频率
temp_1 = f_max;
smg[0] = 20;
smg[1] = 15;
smg[2] = 16;
smg[3] = temp_1>=10000?temp_1/10000:16;
smg[4] = temp_1>=1000?temp_1/1000%10:16;
smg[5] = temp_1>=100?temp_1/100%10:16;
smg[6] = temp_1>=10?temp_1/10%10:16;
smg[7] = temp_1%10;
break;
case 1://回显时间
smg[0] = 20;
smg[1] = 10;
smg[2] = hour_last/16;
smg[3] = hour_last%16;
smg[4] = minute_last/16;
smg[5] = minute_last%16;
smg[6] = second_last/16;
smg[7] = second_last%16;
break;
}
break;
}
}
//按键扫描函数
unsigned char rd_key()
{
unsigned char key=0;
P32=0;P33=1;P44=P42=1;
if(P44==0) key=5;
if(P42==0) key=9;
P32=1;P33=0;P44=P42=1;
if(P44==0) key=4;
if(P42==0) key=8;
return key;
}
unsigned char key_new,key_old,key_down;
void key_proc()
{
if(key_clk<10) return;
key_clk=0;
key_new = rd_key();
key_down = key_new & (key_new ^ key_old);
key_old = key_new;
switch(key_down)
{
case 4:
if(++state==4) state=0;
if(state==1) state_cs=0;
if(state==3) state_huixian=0;
break;
case 5:
switch(state)
{
case 1:state_cs^=1;break;
case 3:state_huixian^=1;break;
}
break;
case 8:
if(state==1)//参数界面下有效
{
switch(state_cs)
{
case 0:if(f_cx<9000) f_cx+=1000;break;
case 1:if(f_jz<900) f_jz+=100;break;
}
}
break;
case 9:
if(state==1)//参数界面下有效
{
switch(state_cs)
{
case 0:if(f_cx>1000) f_cx-=1000;break;
case 1:if(f_jz>-900) f_jz-=100;break;
}
}
break;
}
}
//led控制函数
void led_control()
{
led[0] = (state==0&&led_sign==1)?1:0;
led[1] = ((f>f_cx&&led_sign==1) || f<0)?1:0;
}
void main()
{
system_init();
Timer5Init();
timer_init();
ds1302_init();
while(1)
{
smg_display();
wt_voltage();
key_proc();
led_control();
}
}
十五届蓝桥杯单片机-四川前五代码
最新推荐文章于 2024-07-18 19:36:20 发布
![](https://img-home.csdnimg.cn/images/20240711042549.png)