1.模块化编程
模板参考:C盘 零基础入门资源包 协会第四次培训
User-用户名(main)
Driver-底层(固定)
建立工程模板--编写底层函数 Key Seg
.c编写底层函数
.h声明底层函数 .c 和.h 建议成双成对设置 每一个.c都要引用它的头文件.h
在.c中写完,在.h中声明
Key_Read() 按键底层
具体内容:
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; }
//逻辑还是较为简单的
Seg_Disp() 数码管底层
具体内容:

用到单片机引脚时要包含头文件<REGX52.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};//数码管位码储存数组
Main函数框架
1.头文件声明
2.变量声明区
3.按键处理函数 Key_Proc //Proc是函数的简写
4.信息显示 Seg_Proc
5.Led的显示Led_Proc()
6.定时器零的初始化Timer0Init()
在isp中生成

7.定时器中断服务函数 Server

底层可背
8.主函数main
//头文件声明区 #include <REGX52.H> #include <Seg.h> #include <Key.h>
//变量声明区 unsigned char Key_Slow_Down;//按键减速专用变量 unsigned char Key_Val,Key_Down,Key_Old;//按键扫描专用变量 unsigned int Seg_Slow_Down;//数码管减速专用变量 unsigned char Seg_Pos;//数码管扫描变量 unsigned char Seg_Buf[6]={1,2,3,4,5,6};//数码管显示数据存放数组 unsigned char Seg_Mode; //数码管显示界面 0代表显示 1代表设置 <如果要多模式显示就要用到此变量>
//按键处理函数 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;//辅助扫描变量 switch(Key_Down) { } }
//信息处理函数 void Seg_Proc() { if(Seg_Slow_Down) return; Seg_Slow_Down=1;//数码管减速程序
} //其他显示函数 void Led_Proc() {
} //定时器零初始化函数 void Timer0_Init(void) //1毫秒@12.000MHz { TMOD &= 0xF0; //设置定时器模式 TMOD |= 0x01; //设置定时器模式 TL0 = 0x18; //设置定时初始值 TH0 = 0xFC; //设置定时初始值 TF0 = 0; //清除TF0标志 TR0 = 1; //定时器0开始计时 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]); }
//main void main() { Timer0_Init(); while(1) { Key_Proc(); Seg_Proc(); Led_Proc();
}
}
关于蜂鸣器


buzzer连接的是P2_3引脚 0灭 1亮

仿真中FM 点 变蓝了就是响了 红色就是没响
要显示多种界面时 在信息处理函数中写代码

显示多种界面时先往变量声明区写一个

题目中要求中间三位数是熄灭的 故把Seg_Buf[6]里的数全改为10
模式标识倒计时界面要显示 1 设置时要为2 而我们所定义的变量是0/1 为显示正确,故要定义数码管第一位显示1/2 也就是Seg_Buf[0]=Seg_Mode+1
实现倒计时
先定义两个变量

初值是三十 故声明变量时将Time_Count 初始化为30

然后将1000ms标志位变量放到中断函数中去
题目中还要求第5 6 位显示出倒计时 故写上系统计时变量 并使其开始递减 同时改变显示数组里的第五六位,将倒计时显示出来
代码如下:

倒计时已写好,现在开始写按键功能

先定义一个标志位
题中按键一定义的是开始 那么在按键一按下的时候开始计时

涉及到按键,故在按键处理函数中进行修改

由于题目中要求按下1时开始 故使当Key_Down=1 时令系统标志位为1
即使其开始
题目中还要求按键1 和 2仅仅在显示中 有效 故在设置界面不能使其生效
于是在Key_Down = 1 后再加一个限制条件

但此时只写了按下1代表它走,但没限制没按1时不走
在定时器0中断服务函数中进行修改

现在开始写按键三 切换(注意等号前面有个取反符号^)

然后开始写4按键 要求在15 30 60 来回切换 故初始化一个数组如下


利用改变第二个变量从而改变模式,即将第二个变量作为第一个数组的索引值,由于 题目最开始为30,故使索引值为1,即数组第二位
现在开始写设置界面下的代码,使最后两位显示设置的值(信息处理函数中写)

此时代码与显示界面下大同小异,但这里要显示的是设置值,故只需将Time_Count改为刚刚定义的数组其中的值,并加上索引值以确定输出哪一个
现在界面已设置完成,正式开始写按键四(按键处理函数)按键四仅在设置界面有效,故还需要加上限制条件

由于设置界面设置好的值还要保存到显示界面,故可以在按键处理函数的切换键中写一些代码更新切换后显示界面的值,即:

再看题,还有个按键二(复位)没写
逻辑很简单,按一下按键二就要让Time_Count回到原位(Seg_Dat[Seg_Dat_Index]),且按键二只在显示界面生效,所以:


他要倒计时为零时所有LED点亮,复位后熄灭,就是让Time_Count为0时P0=0x00,LED显示属于其他显示函数,故在其他显示函数中修改:

前面讲过蜂鸣器连接的是P2_3引脚,所以想要使其使能则使P2_3引脚获得低电平,除要求倒计时为0时所有灯点亮,蜂鸣器使能,还要求复位后所有灯灭,蜂鸣器停止,其实可以理解为只要倒计时不为零就让灯灭,蜂鸣器停止,故可写出上述代码
但仿真运行过后发现倒计时变为零后继续变为55,这是因为我们只让其一直--,而并未增加限制条件,使其到零后继续减,unsigned char中是没有负数的(0-255),故自动使其变为255,此时让255参与运算,打印出了55,所以,代码要进行以下优化(定时器中断服务函数)


要求一秒为周期进行闪烁即为要求500ms灯灭500ms灯亮

定时器中断服务函数中:

由于其要求的是设置界面下后两位闪烁,因此要在设置界面下去写,前面写了每500ms Seg_Flag异或取1(等于1时取0,不等于1 时取1),已设置1s为周期,只需要设置一个500ms内亮,另一个500ms内灭即可

1476

被折叠的 条评论
为什么被折叠?



