📄 keydisplay.c
字号:
//ICC-AVR application builder : 2007-6-29 下午 09:31:04
// Target : M16
// Crystal: 1.0000Mhz
//maker:diyixiaozhu
//jianpanshaomiaofangshi:xunhuanshaomiao循环扫描且可以实现显示小数点
//并可加入其他功能
#include <iom16v.h>
#include <macros.h>
#define uchar unsigned char
#define uint unsigned int
#define clk0 PORTB|=0x02//时钟宏定义port2接clk
#define clk1 PORTB&=~0x02
#define data1 PORTB|=0x01//数字宏定义port1接data
#define data0 PORTB&=~0x01
uchar table[10]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09};//数字编码
uchar table1[10]={0x02,0x9e,0x24,0x0c,0x98,0x48,0x40,0x1e,0x00,0x08};//带点编码
uchar pata[4]={0,0,0,0};//显存
uchar pata1[4]={0,0,0,0};//存储前面已显示过的数据加上带显示的数据以
uchar pata2[4]={0,0,0,0};//测试用存储up函数处理国的数据 //送该显示函数显示
void port_init(void)//端口初始化
{
PORTA = 0x00;
DDRA = 0x00;
PORTB = 0x00;
DDRB = 0x00;
PORTC = 0x00; //m103 output only
DDRC = 0x00;
PORTD = 0x00;
DDRD = 0x00;
}
/*//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up//此处留作中断用
CLI(); //disable all interrupts
port_init();
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x00; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}*/
void delay(uint n)//ms延时函数
{uint i,j;
for(i=0;i<n;i++)
{
for(j=0;j<1000;j++){;}
}
}
uint keypressed(void)
{ uchar t;
DDRA=0x0f;// 输出模式
PORTA=0xf0;//第四位对应行线,高四位对应列
//DDRA=0x00;//设置为输入
PINA=PINA&0xf0;
if(PINA!=0xf0)
{
return 1;
}
else
return 0;
}
uint keyscan(void)
{
uchar a1,a2,a;
uint j=0;
if(keypressed()==1)//如有键按下,查询键值
{
PORTA=0xf0;//扫描第一次,取列输入
DDRA=0x0f;
a1=PINA;
a1=PINA;
a1=a1&0xf0;
PORTA=0x0f;//扫描第一次,取行输入
DDRA=0xf0;
a2=PINA;
a2=PINA;
a2=a2&0x0f;
a=a1|a2;
}
switch(a)//译码
{
case 0xee:j=0;break;//根据返回值确定按键编码安高四位为列
case 0xde:j=1;break;
case 0xbe:j=2;break;
case 0x7e:j=10;break;//up jian
case 0xed:j=3;break;
case 0xdd:j=4;break;
case 0xbd:j=5;break;
// case 0x7d:j=8;break;//down jian
case 0xeb:j=6;break;
case 0xdb:j=7;break;
case 0xbb:j=8;break;
// case 0x7b:j=12;break;//setup jian
case 0xe7:j=9;break;
case 0xd7:j=14;break;//xiaoshudian jian
case 0xb7:j=15;break;//cancel jian
case 0x77:j=16;break;//enter jian
default:break;
}
return j;
}
uint hex_to_int(uchar data)//此函数实现反查十六进制数编码对应的十进制数
{
uint n;
switch(data)
{
case 0x03:n=0;break;
case 0x9f:n=1;break;
case 0x25:n=2;break;
case 0x0d:n=3;break;
case 0x99:n=4;break;
case 0x49:n=5;break;
case 0x41:n=6;break;
case 0x1f:n=7;break;
case 0x01:n=8;break;
case 0x09:n=9;break;
case 0xff:n=0;break;//高位未显示,已经复位0xff,guyinggaizhuanweiling
default:break;
}
return n;
}
void up(uchar data[]) //此函数实现按键up的功能这里站设为加一
//但是不能够对含小数的数进行操作
{
uint i,j;
/* if(data[0]&0x01==0)//若前面含有小数点则不可以操作
;
else
{*/
j=hex_to_int(data[0]);//取其代表的十进制数
if(j<9)//第一位数小于十
data[0]=table[j+1];//加一显示
else//大于十进位
{
data[0]=table[0];//低位清零
j=hex_to_int(data[1]);//在判断高位
if(j<9)
data[1]=table[j+1];
else
{
data[1]=table[0];
j=hex_to_int(data[2]);
if(j<9)
data[2]=table[j+1];
else
{
data[2]=table[0];
j=hex_to_int(data[3]);
if(j<9)
data[3]=table[j+1];
else
;//已无法再向上进位
}
}
}
// }
}
void neirong1(uint n)//此法优于上面的列表法
{
uint ge,shi,bai,qian;
ge=n%10;//取n的各位个位
shi=n/10%10;//十位
bai=n/100%10;//百位
qian=n/1000;//千位
pata[0]=table[ge];//数字查表为该字符编码
pata[1]=table[shi];
pata[2]=table[bai];
pata[3]=table[qian];
}
void display(uchar p[]) //数字显示程序...不含显示小数点且不累集
{
uint i,j;
for(j=0;j<4;j++)
{for(i=0;i<8;i++)//八位全部显示完毕
{
if(p[j]&0x01)
data1;
else
data0;
clk0;//产生时钟脉冲
clk1;
p[j]=p[j]>>1;//右移以便取下一位
}
}
}
//*该函数实现输入数据缓存*//
void shujuhuancun(uint key0,uint key2)//key2为前一键值,key1为按键编码
{
uchar i,j;
uint key1,n=0,k,temp;//n为现实前面是否有小数点
// temp2=temp1;
key1=key0;//取键值
if(key1!=14)//若不是小数点
{
if(key1==0||key1==1||key1==2||key1==3||key1==4||key1==5||key1==6||key1==7
||key1==8||key1==9)
//若是数字0-9则移位
{
for(j=3;j>0;j--)
pata1[j]=pata1[j-1];//循环右移
pata1[0]=table[key1];//按键编码付给pata1[0]
}
else
;//此处可以添加除0-9以外的其他按键实现功能
}
else
{
// if(temp2)
//;
//else
for(k=3;k>0;)//此循环实现判断前面是否已经有超过一个的小书点
{
temp=pata1[k]&0x01;
if(temp==0)
{
n=1; break;
}
else
{
n=0;
k--;
}
}
if(n==0)
{
if((pata1[0]&0x01)==0)//若前一个数有小数点则无效
//h位是低电平有效
;
else
pata1[0]=table1[key2];//按键编码付给pata1[0]且键值变为带小数点.
//也解决了如果按下的键不是小数点但前一键
//值示小数点
}
else
;
}
for(j=3;j>=0;j--)//此循环功能很重要,他将高位的不带点零元素质1而不显示
{
if(pata1[j]|0x00!=0)
break ;//高位有非零数即可停止检查
else
pata1[j]=0xff;//否则置位为不显示
}
for(j=0;j<4;j++)
{
pata[j]=pata1[j];}
}
//此函数实现统计pata1中的非零元数的个数
uint tongji(uchar t[])
{
uint geshu=0,i;
for(i=0;i<4;)
{
if((t[i]|0x00)!=0)//证明非零
{ geshu++;i++;}
else
i++;
}
return geshu;
}
uint panduan(uchar t[])//此函数判断高三位是否已经含有小数点
{
uint n,r;
for(r=1;r<4;)
{
if(t[r]&0x01==0)
{
n=1; break;
}
else
{
r++;n=0;
}
}
return n;
}
void qingling(uchar data[])//清除前一次寄存值
{
uint i;
for(i=0;i<4;i++)
data[i]=0xff;
}
void zhuanyi(uchar data[])//测试用
{ uint i;
for(i=0;i<4;i++)
{
pata2[i]=data[i];
}
}
void main()
{
static uint key3=0;static uint key=0;
uchar t;//t为测试用
uint n=0;//n为pata1中有的非零元数个数
port_init();
DDRB=0xff;
PORTB=0xff;
PORTB=0x00;
neirong1(key);
display(pata);
while(1)
{
key3=key;//key2记录前一编码即键值以便于查找加点编码
if(keypressed()==1)//有键按下
{
key=keyscan();//开始扫描
delay(25);//键盘去抖
if(key==14)
{ //则显示小数点但不存入pata1
shujuhuancun(key,key3);
display(pata);
}
else
if(key==15)//若是cancel 键则清除屏幕
{
neirong1(0);//
display(pata);//显示零
qingling(pata1);//消除前一次寄存值,也可以说只要调用
//pata1就可以显示前面操作过的数据
}
else
if(key==10)//ruoshi anjian up
{
up(pata1);
zhuanyi(pata1);//测试用
display(pata2);//原为pata1
}
else
//留作其他按键功能扩展
{
shujuhuancun(key,key3);
display(pata);
}
}
else
;//此处留作函数实现其他功能的接口
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -