单片机软件工程(一)--FIFO设计
FIFO设计:在单片机的程序设计过程 中,通常为了防止数据的丢失,利用FIFO来缓冲高速与低速设备的差异,这样可以保证数据在传输的过程中不会丢失。
程序设计如下:
/*********************************************************************************************
/*********************************************************************************************
说明: 按键的设计:利用FIFO队列来进行数据的缓冲,这样CPU不直接操作硬件,而是通过键盘缓冲区来
获取键盘的值。这样,可以将前台与后台程序隔离开来。消除了按键扫描与读键之间的时间关联性
/*********************************************************************************************/
/**********************************************************************************************/
#include<reg51.h> //常用的头文件
#include <intrins.h> //51基本运算(包括_nop_空函数)
//#include<dispy.h> //模块接口 :display()扫描,send_dat(uint dat)显示数据,前者放在定时器里面,后者放在后台
#define uchar unsigned char
#define ulong unsigned long
#define uint unsigned int
#define size 4
void key_buffer(uchar key);
uchar key_get();
sbit KEY1_IN=P3^7;
sbit KEY2_IN=P3^6;
sbit dula=P2^6; //控制数码管位选的使能
sbit wela=P2^7; //控制数码管段选的使能,低电平位选中
//sbit KEY2_IN=P3^6;
//sbit KEY3_IN=P3^7;
uchar P_key1=255; //存放按键前一次状态的变量
uchar N_key1=255; // 存放下一次按键的状态,通过定时器中断(10ms)的扫描便可以确定是否被按下
uchar key_max=0;
uchar key_min=0;
uchar count=0; //定义FIFO的头指针,尾指针,与指针计数
uchar key_inbuff[size]; //定义FIFO的容量
static uchar temp;
uchar P_key2=255; //存放按键前一次状态的变量
uchar N_key2=255; // 存放下一次按键的状态,通过定时器中断(10ms)的扫描便可以确定是否被按下
//uchar P_key3=255; //存放按键前一次状态的变量
//uchar N_key3=255; // 存放下一次按键的状态,通过定时器中断(10ms)的扫描便可以确定是否被按下
unsigned char code table[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};//数码管数据
/**********************按键1扫描***************************************************************/
void key_scan() //放在10ms的中断函数里面执行
{
P_key1=N_key1; //每扫描一次,则把下一次的状态给当前(即把后一次的给前一次)
N_key1=KEY1_IN; //按键此时的状态给N_key
P_key2=N_key2; //每扫描一次,则把下一次的状态给当前(即把后一次的给前一次)
N_key2=KEY2_IN; //按键此时的状态给N_key
// P_key3=N_key3; //每扫描一次,则把下一次的状态给当前(即把后一次的给前一次)
// N_key3=KEY3_IN; //按键此时的状态给N_key
if((P_key1!=0)&&(N_key1==0)) //表示按键被按下
key_buffer(0x01); //可以代表键值,可也以用此表征键被按下
if((P_key2!=0)&&(N_key2==0)) //表示按键被按下
key_buffer(0x02); //可以代表键值,可也以用此表征键被按下
}
/**********************按键2扫描***************************************************************/
/***********************将键值数据压入FIFO****************************************************/
void key_buffer(uchar key) // 设计一FIFO,将键值压入FIFO
{
if (count>=size) return;
EA=0; //防止数据被 中断
count++; //按键次数递增
key_inbuff[key_max] =key; //压入FIFO
if (++key_max>=size) //如果越界,而从头部追加新的数据
{
key_max=0;
}
EA=1;
}
/**********************************************************************************************/
void delayms(uint z) //ms级延时函数
{ uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/**********************************************************************************************/
void display(uchar a) //第一个数码管亮 位选
{
wela=0;
P0=0xfe;
wela=1;
wela=0;
dula=0;
P0=table[a]; //显示最高位
dula=1;
dula=0;
delayms(2);
}
/**********************************************************************************************/
uchar key_get(void) // 从FIFO里面取出键值
{
uchar key;
if(count==0) return(0); //如果没数据,返回0
EA=0;
count--;
key=key_inbuff[key_min];
if (++key_min>=size)
{
key_min=0;
}
EA=1;
return(key);
}
/**********************************************************************************************/
/**********************************************************************************************/
void timer_init(void)
{
TMOD=0x10;
TH1=(65536-15000)/256; //时间为1ms
TL1=(65536-15000)%256;
EA=1;
ET1=1;
TR1=1;
}
/**********************************************************************************************/
void main()
{
uchar i ;
timer_init();
while(1)
{
temp= key_get(); //获取键值
if(temp==0x01) //按键进行处理
{
i++;
if(i==9)
i=0;
display(i);
}
if (temp==0x02)
{
display(5);
}
}
}
/**********************************************************************************************/
void time1(void)interrupt 3 //以每15ms对按键进行扫描
{
TH1=(65536-15000)/256;
TL1=(65536-15000)%256;
key_scan();
}
/**********************************************************************************************/
/**********************************************************************************************/
/**********************************************************************************************/
/**********************************************************************************************/
/**********************************************************************************************/
原文地址http://li19910722.blog.163.com/blog/static/136856822201141814614750/