题目要求:
根据题目要求本次涉及到了数码管显示、LED、NE555测量频率、PCF8091模块、独立按键
数码管显示:共有三个界面要显示。周期界面我理解为 (也来自于NE555)
LED显示:
这个模块与S7的长短按键关系十分密切。其中S7长短按键的用法参考了小蜜蜂老师的定时器方法https://blog.csdn.net/ohy3686/article/details/82927113
unsigned char count_7 = 0;//用于定时器计时
unsigned char K_7 = 0;//当开关按下后变为1开关断开后变为0
unsigned char K_7_flag = 0;//用于长按键循环
void key()
{
if(S7 == 0)
{
delay(10);
if(S7 == 0)
{
K_7 = 1;
while(S7 == 0)
{
Display();
}
K_7 = 0;
if(count_7 > 5) //按键长按
{
K_7_flag++;
if(K_7_flag > 1)
{
K_7_flag = 0;
}
}
else //按键短按
{
temp_1_stay = temp_1;//保存当前采集到的频率数据
}
count_7 = 0; //按键计数值清零
}
}
}
//定时器
void InitTimer() //定时器1定时,定时器0计数
{
TMOD = 0x16;
TH0 = 0xff;
TL0 = 0xff;
TH1 = (65536-50000)/256;
TL1 = (65536-50000)%256;
EA = 1;
ET0 = 1;
ET1 = 1;
TR0 = 1;
TR1 = 1;
}
void Timer1() interrupt 3
{
TH1 = (65536-50000)/256;
TL1 = (65536-50000)%256;
count_t++;//测量频率用
if(count_t == 20)
{
temp_1 = count_f;
temp_2 = 100000/count_f;
count_t = 0;
count_f = 0;
}
if(K_7 != 0)
{
count_7++;
}
}
//S7长按键的功能判断在main函数中
PCF8091 :
涉及到光敏电阻、电位器的电压AD转换结果的显示问题。需要把0~255转换为0~5V内的电压显示
unsigned char i;//选择通道变量
unsigned char date;//存放得到的数据
//==================================电压
void ad_read()
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(i);
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0x91);
IIC_Stop();
date = IIC_RecByte();
IIC_SendAck(0);
}
在电压显示:
void work()
{
ad_read();
temp_3 = date*(50000/255)/100;//此时数码管显示两位小数的0~5v电压
a = 0xc1;//1100 0001
b = 0xbf;//1011 1111
c = SMG[i];
d = 0xff;
e = 0xff;
f = SMG_Point[temp_3/100];
g = SMG[(temp_3/10)%10];
h = SMG[temp_3%10];
}
//abcdefgh对于数码管的8位显示内容
主函数:
长按键循环功能判断尝试了很多方法。如果只是简单的在key函数中判断K_7_flag对应的是关灯还是显示,这样得到的结果虽然能实现长按后关灯再长按后开灯,但是LED灯不再具有实时显示的功能。最终尝试放入主函数中的while(1)后完成了题目要求。
void main()
{
InitSystem();
InitTimer();
while(1)
{
key();
Work();
Display();
if(K_7_flag == 1)//长按键循环功能判断
{
stat_LED = 0xff;
InitHC138(4);
P0 = stat_LED;
}
else
{
LED ();//只有将判断放入while(1)中LED才能实时显示
}
}
}
如果有更简单的方法欢迎大家提出。