链接:
基本框架
建立工程模板 - 编写底层函数Key,Seg
.c 编写底层函数
.h 声明底层函数
Key_Read(); Seg_Disp()
Key.c
#include <Key.h>
unsigned char Key_Read()
{
unsigned char temp = 0;
if(P3_4 == 0) temp = 1;
if(P3_5 == 0) temp = 2;
if(P3_6 == 0) temp = 3;
if(P3_7 == 0) temp = 4;
return temp;
}
Key.h
#include <REGX52.H>
unsigned char Key_Read();
Seg.c
#include "Seg.h"
unsigned char Seg_Dula[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};
unsigned char Seg_Wela[] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
void Seg_Disp(unsigned char wela,dula)
{
P0 = 0x00;
P2_6 = 1;
P2_6 = 0;
P0 = Seg_Wela[wela];
P2_7 = 1;
P2_7 = 0;
P0 = Seg_Dula[dula];
P2_6 = 1;
P2_6 = 0;
}
Seg.h
#include <REGX52.H>
void Seg_Disp(unsigned char wela,dula);
Main:
1.头文件
2.变量声明
3.Key_Proc()
4.Seg_Proc()
5.Led_Proc()
6.Timer0Init() 定时器0中断初始化函数,通过stc生成
7.Server 定时器0中断服务函数
8.Main
#include <REGX52.H>
#include <Key.h>
#include <Seg.h>
unsigned char Key_Val,Key_Down,Key_Old;
unsigned char Key_Slow_Down;
unsigned char Seg_Buf[6] = {10,10,10,10,10,10};
unsigned char Seg_Pos;
unsigned int Seg_Slow_Down;
void Key_Proc()
{
if(Key_Slow_Down) return;
Key_Slow_Down = 1;
Key_Val = Key_Read();
Key_Down = Key_Val & (Key_Old ^ Key_Val);
Key_Old = Key_Val;
}
void Seg_Proc()
{
if(Seg_Slow_Down) return;
Seg_Slow_Down = 1;
}
void Led_Proc()
{
}
void Timer0Init(void)
{
TMOD &= 0xF0;
TMOD |= 0x01;
TL0 = 0x18;
TH0 = 0xFC;
TF0 = 0;
TR0 = 1;
ET0 = 1;
EA = 1;
}
void Timer0Server() interrupt 1
{
TL0 = 0x18;
TH0 = 0xFC;
if(++Key_Slow_Down == 10) Key_Slow_Down = 0;
if(++Seg_Slow_Down == 500) Seg_Slow_Down = 0;
if(++Seg_Pos == 6) Seg_Pos = 0;
Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos]);
}
void main()
{
Timer0Init();
while (1)
{
Key_Proc();
Seg_Proc();
Led_Proc();
}
}
减速代码
有时候比如温度传感器接收到信息再处理转化的周期是750ms,但是一般main函数执行一遍的速度是20ms。这样,上一次的数据还没处理好下一次的数据就又来了。
unsigned char Key_Slow_Down;
unsigned char Seg_Pos;
unsigned int Seg_Slow_Down;
void Timer0Server() interrupt 1
{
TL0 = 0x18;
TH0 = 0xFC;
if(++Key_Slow_Down == 10) Key_Slow_Down = 0;
if(++Seg_Slow_Down == 500) Seg_Slow_Down = 0;
if(++Seg_Pos == 6) Seg_Pos = 0;
Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos]);
}
蜂鸣器
初赛模拟题
对应代码
Driver中的底层不用变,就在main.c中编写即可。
以下为完整代码。
#include <REGX52.H>
#include "Key.h"
#include "Seg.h"
unsigned char Key_Slow_Down;
unsigned int Seg_Slow_Down;
unsigned char Key_Val,Key_Down,Key_Old;
unsigned char Seg_Pos;
unsigned char Seg_Buf[6] = {10,10,10,10,10,10};
unsigned char Seg_Mode;
unsigned int Timer_1000ms;
unsigned char Time_Count = 30;
bit System_Flag;
unsigned char Set_Dat[3] = {15,30,60};
unsigned char Set_Dat_Index = 1;
unsigned int Timer_500ms;
bit Seg_Flag;
void Key_Proc()
{
if(Key_Slow_Down) return;
Key_Slow_Down = 1;
Key_Val = Key_Read();
Key_Down = Key_Val & (Key_Val ^ Key_Old);
Key_Old = Key_Val;
switch(Key_Down)
{
case 1:
if(Seg_Mode==0)
System_Flag = 1;
break;
case 3:
if(Seg_Mode ==1)
Time_Count = Set_Dat[Set_Dat_Index];
Seg_Mode ^= 1;
break;
case 4:
if(Seg_Mode == 1)
{
if(++Set_Dat_Index == 3)
Set_Dat_Index = 0;
}
break;
case 2:
if(Seg_Mode == 0)
{
Time_Count = Set_Dat[Set_Dat_Index];
}
break;
}
}
void Seg_Proc()
{
if(Seg_Slow_Down) return;
Seg_Slow_Down = 1;
Seg_Buf[0] = Seg_Mode+1;
if(Seg_Mode == 0)
{
Seg_Buf[4] = Time_Count/10%10;
Seg_Buf[5] = Time_Count%10;
}
else
{
if(Seg_Flag == 1)
{
Seg_Buf[4] = Set_Dat[Set_Dat_Index]/10%10;
Seg_Buf[5] = Set_Dat[Set_Dat_Index]%10;
}
else
{
Seg_Buf[4] = 10;
Seg_Buf[5] = 10;
}
}
}
void Led_Proc()
{
if(Time_Count ==0 )
{
P1 = 0x00;
P2_3 = 0;
}
else
{
P1 = 0xff;
P2_3=1;
}
}
void Timer0Init(void)
{
TMOD &= 0xF0;
TMOD |= 0x01;
TL0 = 0x18;
TH0 = 0xFC;
TF0 = 0;
TR0 = 1;
ET0 = 1;
EA = 1;
}
void Time0Server() interrupt 1
{
TL0 = 0x18;
TH0 = 0xFC;
if(++Key_Slow_Down == 10) Key_Slow_Down = 0;
if(++Seg_Slow_Down == 500) Seg_Slow_Down = 0;
if(++Seg_Pos == 6) Seg_Pos = 0;
Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos]);
if(System_Flag == 1)
{
if(++Timer_1000ms == 1000)
{
Timer_1000ms = 0;
Time_Count--;
if(Time_Count == 255)
{
Time_Count = 0;
}
}
}
if(++Timer_500ms == 500)
{
Timer_500ms = 0;
Seg_Flag ^= 1;
}
}
void main()
{
Timer0Init();
while(1)
{
Key_Proc();
Seg_Proc();
Led_Proc();
}
}
这里的显示-设置模式是通过Seg_Mode的0,1来改变
unsigned char Seg_Mode;
用数组来存储要切换的数据
unsigned char Set_Dat[3] = {15,30,60};
这个打通了两种模式的数据
Time_Count = Set_Dat[Set_Dat_Index];