最后这一讲没什么知识点讲解,我们将前面的七讲内容集合成最后完整的function文件,以便后面大家弄乱了这两个文件的内容好过来这里复制粘贴回去。
1.function.c最终代码#include
#include
u8 code LedChar[16]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};//数码管状态值初始化
u8 LedBuff[6]={0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};//初始化数码管显示缓存区
void delay_ms(u16 x)
{
u16 i,j;
if(x==1000)
{
for(i=0;i<19601;i++)//延时1s
{
for(j=5;j>0;j--);
}
}
else while(x--)for(j=115;j>0;j--);
}
void LED_Init()
{
P1|=0x0E;//让P1.1,P1.2,P1.3强制输出1
P1&=0xEE;//让P1.0和P1.4强制输出0
}
void KEY_Init()
{
P2=0X7F;//让P2.7输出低电平,其他输出高电平,这样就可以使能4个按键了
}
u8 KEY_Scan(u8 mode,u16 TIMES)
{
static u8 key_up=1; //按键松开标志
static u16 times;
if(mode)key_up=1; //如果mode等于1,支持连按
if(key_up&&(KEY4==0||KEY8==0||KEY12==0||KEY16==0))//只要在key_up等于1时,其中一个按键被按下就可以进入执行代码
{
times++; //记录进入低电平的时间
if(times>=TIMES)//抖动的时间已经过去
{
times=0;
key_up=0;
if(KEY4==0)return 4;
else if(KEY8==0)return 8;
else if(KEY12==0)return 12;
else if(KEY16==0)return 16;
}
}
else if(KEY4==1&&KEY8==1&&KEY12==1&&KEY16==1)key_up=1;
return 0;// 无按键按下
}
void SEG_Scan()
{
static u8 i = 0;
P0 = 0xFF; //端口状态全部熄灭数码管里的LED达到刷新作用
P1 = (P1 & 0xF8) | i; //i等于0时,就是“ADDR2=0; ADDR1=0; ADDR0=0;”,i等于1时,就是“ADDR2=0; ADDR1=0; ADDR0=1;”,以此类推
P0 = LedBuff[i]; //6个缓冲区的值轮流赋给P0
i++;
if(i>=6)i=0; //让i在0~5之间循环变化
}
void ShowNumber(u32 num)
{
char i;//取值范围-128~127
u8 buf[6];
for (i=0; i<6; i++) //把长整型数转换为6位十进制的数组
{
buf[i] = num % 10;
num = num / 10; //舍掉个位数,重新装载
}
for (i=5; i>=1; i--) //从最高位起,遇到0填充不显示的代码,遇到非0则退出循环
{
if (buf[i] == 0)
LedBuff[i] = 0xFF;
else
break;
}
for ( ; i>=0; i--) //剩余低位都如实转换为数码管显示字符
{
LedBuff[i] = LedChar[buf[i]];
}
}
2.function.h最终代码#ifndef __FUNCTION_H__
#define __FUNCTION_H__
sbit BEEP = P1^6;
sbit KEY4 = P2^3;
sbit KEY8 = P2^2;
sbit KEY12 = P2^1;
sbit KEY16 = P2^0;
sbit LED2 = P0^0;
sbit LED3 = P0^1;
sbit LED4 = P0^2;
sbit LED5 = P0^3;
sbit LED6 = P0^4;
sbit LED7 = P0^5;
sbit LED8 = P0^6;
sbit LED9 = P0^7;
typedef unsigned char u8; //对数据类型进行声明定义
typedef unsigned int u16;
typedef unsigned long u32;
extern u8 LedBuff[6]; //对数码管缓存区进行外部声明
extern u8 code LedChar[16];//对数码管真值表进行外部声明
//只要在“function.c”文件中封装有的函数都需要在头文件中声明一下
void delay_ms(u16 x);
void LED_Init();
void KEY_Init();
u8 KEY_Scan(u8 mode,u16 TIMES);
void SEG_Scan();
void ShowNumber(u32 num);
#endif
3.本讲的main.c测试代码#include
#include
void main()
{
u8 key;//用来读取按键动作的返回值
u8 beep_ok=0;//定义标志蜂鸣器允许鸣叫的变量,为1时可以鸣叫,为0时不能鸣叫
u8 x;
u32 NUM=10086;
LED_Init();//初始化LED硬件模块
KEY_Init();//初始化按键模块
ShowNumber(NUM);//更新数码管缓存区内容
while(1)
{
SEG_Scan();
key=KEY_Scan(0,700); //不支持连按模式,判断阈值为700
if(key==4){NUM++;ShowNumber(NUM);} //K4使NUM自加
if(key==12){NUM--;ShowNumber(NUM);} //K12使NUM自减
if(key==8)beep_ok=1; //K8开启蜂鸣器鸣叫
if(key==16)beep_ok=0; //K16关闭蜂鸣器鸣叫
if(beep_ok==1)
{
x++;
}
else x=0;
if(x>=3)
{
x=0;
BEEP=!BEEP;
}
}
}