任务十设计说明2
一、 电路仿真图
程序设计
#include <reg51.h>
#include <stdio.h>
Unsignedcharcode screen[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x98,0xbf}; //0~9,'-'
unsigned char code keymap[]={1,2,3,4,5,6,7,8,9,10,0,11};
unsigned char GRAM[8];
#define KeyPort P3
#define SegData P0
#define SegCS P2
voiddelay_ms(unsigned intms){
unsigned char i, j;
for(;ms>0;ms--) {
i = 2;
j = 239;
do{
while (--j);
} while (--i);}}
signed char KeyScan(void){
unsigned char i,j;
KeyPort=0xf0;
if((KeyPort&0xf0)!=0xf0) {
KeyPort=0xff;
for(j=0;j<3;j++){
键盘刷 KeyPort=~(0x08>>j);
for(i=0;i<4;i++){
if((~KeyPort)&(0x10<<i)){
return i*3+j;}} } }
else{
return -1;}
return -1;}
voidUpdateGRAM(unsigned char keyval){
unsigned char i;
for(i=0;i<7;i++) {
GRAM[i]=GRAM[i+1]; }
GRAM[7]=screen[keymap[keyval]];}
voidInitGRAM(void){
unsigned char i;
for(i=0;i<8;i++){
GRAM[i]=screen[10];}}
voidFlash_Scr(void){
unsigned char i;
for(i=0;i<8;i++){
SegData=GRAM[i];
SegCS=1<<i;
delay_ms(1);
SegCS=0x00;}}
void main(void) {
unsigned char key,PressFlag=0;
// Write your code here
InitGRAM();
while (1){
Flash_Scr();
key=KeyScan();
if(PressFlag==0){
if((key>=0)&&(key<=10)){
PressFlag=1;
UpdateGRAM(key);}
else if(key==11){
InitGRAM();}}
else{
if(key==-1){
PressFlag=0;}} } }
二、 设计说明
本设计包含一个矩阵键盘和一个八位数码管。单片机同时负责扫描键盘和控制数码管显示。由于数码管采用动态扫描,因此数码管和键盘均需要实时控制,所以对于单片机来说,两个任务交替进行。由于要显示八位数字,因此单片机内部设置一个八字节数组用于充当显存,保存输入过的数字。每当输入新的数字就把这个显存向前移位一格然后填入新的数字并显示到数码管上。 三、 遇到的问题及解决方案
1. 数码管显示方向相反,输入新的数字时,新数字从左侧进入显示区。解决方法为改变数码管显示函数中位选信号的移位方向。
2. 按键按下时数码管不显示,松开后才正常显示。原因是按下按键时程序等待按键松开,此时数码管没有刷新,因此无显示。解决方法为设置按键按下标志位,有新按键按下时置位该标志位,然后不等待松键立刻去刷新数码管,以后遇到标志位处于置位状态是就检测按键是否松开,直到某次检测到按键松开时复位标志位。这样就保证了无论如何程序都不会卡死在某个地方导致数码管得不到刷新。