1.系统功能
1.1可测0~5V的8路输入电压值;
1.2在LED数码管上轮流显示;
1.3单路选择显示;
2.系统硬件设计
2.1 单片机采用PIC16F877
2.2 键盘为4×4行列式键盘,按键设有10个数字键0……9,和5个功能键依次是:各通道轮流显示键、单通道显示键、向左滚动显示键、显示启动/停止键、回车键。
2.3有3位LED管,左边1位用于指示显示通道,右边2位显示电压值,保留到小数点后面1位。
3系统软件设计
3.1键盘管理程序(包括键扫描、键处理程序);
3.2LED动态显示程序;
3.3各通道轮流显示,共显示8个通道,每通道显示1s;
3.4 单通道显示,仅显示指定通道电压,并保持到其他功能键按下。
仿真原理图如下
单片机源程序如下:
//作者:云树阿云
#include #include #define uchar unsigned char #define uint unsigned int __CONFIG(0x3b32);//状态字 uchar table[]={0x00,0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};//数码管显示字符表 uchar channel[]={0x41,0x49,0x51,0x59,0x61,0x69,0x71,0x79};//代表8个通道被按下的状态表 uchar key_num;//按键标志位 uchar disp_num;//通道标志位 uchar left_num; uchar loop_num; uint volval=0;//电压值 uint enter=0;//回车被按下标志位 uint on_off=0;//开机标志位 uint loop_disp=0;//循环显示标志位 uint single_disp=0;//单通道显示标志位 uint left_move=0;//左移显示标志位 uint a;//用于显示的换算位 uint b;//用于显示的换算位 uint c;//用于显示的换算位 uint d;//用于左移显示的转移中间值 uchar e=2; uchar onkey_num; void delay(uint x)//延时程序 {uint times,num; for(times=x;times>0;times--) for(num=110;num>0;num--); } void display(uint i,uint j)//显示程序 { a=i/10;//通过电压值和通道值算出需要显示的值 b=i-a*10;//通过电压值和通道值算出需要显示的值 a=a+10;//为电压第一位加上小数点 c=j; if(enter==0) {a=-1; b=-1; //c=-1; } TRISD=0x00;//设置输出端口 TRISB=0x00;//设置输出端口 delay(1);//延时 RB0=0;//选择需要亮起的数码管 RB1=1; RB2=1; PORTD=table[c+1];//输出需要显示的数字 delay(1);//延时 RB0=1;//选择需要亮起的数码管 RB1=0; RB2=1; PORTD=table[a+1]; delay(1);//延时 RB0=1;//选择需要亮起的数码管 RB1=1; RB2=0; PORTD=table[b+1];//输出需要显示的数字 } void getab(uint i,uint j)//左移显示时获得当前的a,b,c值 { a=i/10; b=i-a*10; a=a+10; c=j; } void leftdisplay()//左移显示模式的显示程序,类似显示程序 { TRISD=0x00; TRISB=0x00; delay(1); RB0=0; RB1=1; RB2=1; PORTD=table[c+1]; delay(1); RB0=1; RB1=0; RB2=1; PORTD=table[a+1]; delay(1); RB0=1; RB1=1; RB2=0; PORTD=table[b+1]; } void leftmove()//实现左移显示的程序(交换abc) { if(left_num==8) { left_num=0; ADCON0=channel[0]; uint adval; GO=1; while(GO) adval=ADRESH; adval=adval<<8|ADRESL; volval=adval/20; a=-1; b=volval/10; b=b+10; c=left_num; } else{ //disp_num++; ADCON0=channel[left_num]; uint adval; GO=1; while(GO) adval=ADRESH; adval=adval<<8|ADRESL; volval=adval/20; a=-1; b=volval/10; b=b+10; c=left_num; } } void scan()//扫描程序获得key_num { TRISC=0xf0;//C端口高四位输出,低四位输入 PORTC=0xfe;//首先扫描第一列 key_num=PORTC;//读取C端口低四位,获得key_num key_num=key_num&0xf0;//判断低四位是否有1存在 if (key_num!=0xf0)//如果低四位有1(第一行有键被按下) { delay(10);//去抖动 key_num=PORTC;//重新读取 key_num=key_num&0xf0;//得到低四位中为1的位,其他位置0 if (key_num!=0xf0) { key_num=key_num|0x0e;//加上高四位中被扫描的值,获得代表被按下键的值:key_num } } else//其他列依次判断 { PORTC=0xfd; key_num=PORTC; key_num=key_num&0xf0; if (key_num!=0xf0) { delay(10); key_num=PORTC; key_num=key_num&0xf0; if (key_num!=0xf0) { key_num=key_num|0x0d; } } else { PORTC=0xfb; key_num=PORTC; key_num=key_num&0xf0; if (key_num!=0xf0) { delay(10); key_num=PORTC; key_num=key_num&0xf0; if (key_num!=0xf0) { key_num=key_num|0x0b; } } else { PORTC=0xf7; key_num=PORTC; key_num=key_num&0xf0; if (key_num!=0xf0) { delay(10); key_num=PORTC; key_num=key_num&0xf0; if (key_num!=0xf0) { key_num=key_num|0x07; } } } } } } void switched()//根据key_num改变相应标志位 { switch(key_num) {case 0xee:disp_num=7;enter=0;break;//通道选择 case 0xed:disp_num=4;enter=0;break;//通道选择 case 0xeb:disp_num=1;enter=0;break;//通道选择 case 0xe7:if(onkey_num!=key_num){on_off=!on_off;enter=0;}break; //on_off=1; break;//开机 //case 0xde:disp_num=7;enter=0;break;//通道选择 case 0xdd:disp_num=5;enter=0;break;//通道选择 case 0xdb:disp_num=2;enter=0;break;//通道选择 case 0xd7:disp_num=0;enter=0;break;//通道选择 //case 0xbe:disp_num=7;enter=0;break;//通道选择 case 0xbd:disp_num=6;enter=0;break;//通道选择 case 0xbb:disp_num=3;enter=0;break;//通道选择 case 0xb7:enter=1;break;//回车键 case 0x7e:loop_disp=1;single_disp=0;left_move=0;enter=0;break;//循环显示功能 case 0x7d:loop_disp=0;single_disp=1;left_move=0;enter=0;break;//单通道显示功能 case 0x7b:loop_disp=0;single_disp=0;left_move=1;enter=0;break;//左移显示功能 //case 0x77:on_off=0;break;//关机 } } void measure()//AD转化程序&完成相应功能
上一篇:PIC18F452+Proteus双机通信 串口通信 键盘更改波特率源程序
下一篇:PIC16F877A流水灯Proteus仿真程序
推荐阅读最新更新时间:2024-11-09 09:26