1、数码管的基本介绍
数码管显示的三步
- 清屏 (清除上一次显示内容)
- 段选 (输送断码值)
- 位选 (选择哪一位)
我们需要记住常见数码管断码值
共阴跟共阳取反即可转换
显示的数据 | 断码值(共阳) |
---|---|
0 | 0xc0 |
1 | 0xf9 |
2 | 0xa4 |
2 | 0xa4 |
3 | 0xb0 |
4 | 0x99 |
5 | 0x92 |
6 | 0x82 |
7 | 0xf8 |
8 | 0x80 |
9 | 0x90 |
A | 0x88 |
B | 0x83 |
C | 0xc6 |
D | 0xA1 |
E | 0x86 |
F | 0x8E |
H | 0x89 |
L | 0xC7 |
N | 0xC8 |
P | 0x8c |
U | 0xC1 |
- | 0xbf |
空格 | 0xff |
加小数点 | &= 0x7f |
0-9代码考试会给出
uchar dsp_code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//数码管段选
2、数码管的显示代码(第一套方案)
uchar dsp_code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar dsp_show[8]={0xff,0xff,0xff} //要显示的内容
void Time0_init(void)
{
AUXR |= 0x80;
TMOD &= 0xF0;
TL0 =0xCD;
TH0 = 0xD4;
TR0=1;
ET0=1;
EA= 1;
}
void Time0_isr() interrupt 1
{
static unchar dsp_com = 0; //静态全局变量
P0 = 0; //清屏 (清楚上一次显示内容)
P2=0xc0; //打开锁存器控制数码管位选
P2=0; //关闭锁存器
P0=dsp_Show[dsp_com];//段选的内容,即要显示的数字
P2 = 0xe0; //打开锁存器控制数码管段选
P2=0; //关闭锁存器
P0= 1<<dsp_com; //位选左移1位
P2 =0xc0; //打开锁存器控制数码管位选
P2=0; //关闭锁存器
if(++dsp_com == 8) //位选变量自加
{
dsp_com=0;
}
}
3、数码管的显示代码(第二套方案)
数码管显示处理函数
void Seg_Tran(unsigned char *seg_string, unsigned char *seg_buf)
{
unsigned char i = 0;
unsigned char j = 0;
unsigned char temp;
for(i = 0; i <= 7;i++,j++)
{
switch(seg_string[j])
{
case '0': temp = 0xc0; break;
case '1': temp = 0xf9; break;
case '2': temp = 0xa4; break;
case '3': temp = 0xb0; break;
case '4': temp = 0x99; break;
case '5': temp = 0x92; break;
case '6': temp = 0x82; break;
case '7': temp = 0xf8; break;
case '8': temp = 0x80; break;
case '9': temp = 0x90; break;
case 'A': temp = 0x88; break;
case 'B': temp = 0x83; break;
case 'C': temp = 0xc6; break;
case 'D': temp = 0xa1; break;
case 'E': temp = 0x86; break;
case 'F': temp = 0x8e; break;
case 'H': temp = 0x89; break;
case 'L': temp = 0xc7; break;
case 'N': temp = 0xc8; break;
case 'P': temp = 0x8c; break;
case 'U': temp = 0xc1; break;
case '-': temp = 0xbf; break;
case ' ': temp = 0xff; break;
default: temp = 0xff; break; //默认
}
if(seg_string[j+1] == '.')//判断小数点
{
temp &= 0x7f;
j++;
}
seg_buf[i] = temp;
}
}
显示函数
void Seg_Disp(unsigned char *seg_buf, unsigned char pos)
{
P0 = 1<<pos;
P2 = P2 & 0X1F | 0xc0;//位码选通
P2 &= 0X1F;
P0 = 0xff;
P2 = P2 & 0X1F | 0xe0;//段码选通,消隐
P2 &= 0X1F;
P0 = seg_buf[pos];
P2 = P2 & 0X1F | 0xe0;//段码选通
P2 &= 0X1F;
}
数码管处理函数
void Seg_Proc(void)
{
if(Seg_Slow_Down) return;
Seg_Slow_Down = 1;
/***用户自定义代码区↓***/
sprintf(seg_string,"%1d",(unsigned int)state_flag);
Seg_Tran(seg_string, seg_buf);
}
//在定时器中加入如下代码
Seg_Disp(seg_buf, pos);//用于数码管显示
if(++pos == 8) pos = 0;
4、数码管操作练习
习题1:让数码管显示28428
#include <STC15F2K60S2.H>
typedef unsigned char uchar;
typedef unsigned int uint;
uchar dsp_code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//数码管段选
uchar dsp_show[8]={0xff,0xff,0xff};
uint number = 28428;
void Time0_init(void)
{
AUXR |= 0x80;
TMOD &= 0xF0;
TL0 =0xCD;
TH0 = 0xD4;
TR0=1;
ET0=1;
EA= 1;
}
void Time0_isr() interrupt 1
{
static uchar dsp_com = 0; //静态全局变量
P0 = 0; //清屏 (清楚上一次显示内容)
P2=0xc0; //打开锁存器控制数码管位选
P2=0; //关闭锁存器
P0=dsp_show[dsp_com];//段选的内容,即要显示的数字
P2 = 0xe0; //打开锁存器控制数码管段选
P2=0; //关闭锁存器
P0= 1<<dsp_com; //位选左移1位
P2 =0xc0; //打开锁存器控制数码管位选
P2=0; //关闭锁存器
if(++dsp_com == 8) //位选变量自加
{
dsp_com=0;
}
}
void main()
{
P0=0xff;
P2=0x80;
P2=0x00;
P0=0x00;
P2=0xa0;
P2=0x00;
Time0_init();
dsp_show[3]= dsp_code[number/10000];
dsp_show[4]=dsp_code[number/1000%10];
dsp_show[5]=dsp_code[number/100%10];
dsp_show[6]= dsp_code[number/10%10];
dsp_show[7]=dsp_code[number%10];
while(1)
{
}
}
习题2:按下按键使数码管显示相应的矩阵按键值,且LED灯显示相应二进制值
#include <STC15F2K60S2.H>
typedef unsigned char uchar;
typedef unsigned int uint;
uchar dsp_code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//数码管段选
uchar dsp_show[8]={0xff,0xff,0xff,0xff,0xff,0xff};
uchar value,countkey;
void Time0_init(void)
{
AUXR |= 0x80;
TMOD &= 0xF0;
TL0 =0xCD;
TH0 = 0xD4;
TR0=1;
ET0=1;
EA= 1;
}
void Time0_isr() interrupt 1
{
static uchar dsp_com = 0; //静态全局变量
P0 = 0; P2=0xc0; P2=0;
P0=dsp_show[dsp_com];P2 = 0xe0; P2=0;
P0= 1<<dsp_com; P2 =0xc0; P2=0;
if(++dsp_com == 8) { dsp_com=0;}
countkey++;
}
void scan_key()
{
static uchar key_state=0;
uchar key_val=0, key_x=0, key_y=0;
//行扫描
P3=0x0f; P4=0x00;
if(!P30) key_x=3;
else if(!P31) key_x=2;
else if(!P32) key_x=1;
else if(!P33) key_x=0;
//X=3210 Y=4321 特别易记
//列扫描
P3=0xf0; P4=0xff;
if(!P34) key_y=4;
else if(!P35) key_y=3;
else if(!P42) key_y=2;
else if(!P44) key_y=1;
key_val=key_x+ key_y*4;//综合行、列扫描的结果,判断具体位置
switch(key_state)
{
case 0:
if(key_val!=0) key_state = 1; //第一次检测到有按键按下,状态为1
break;
case 1:
if(key_val==0) key_state=0;//第二次(10ms后)若检测到无按键按下,返回状态0
else
{
key_state = 2; //第二次(10ms 后)再次检测到有按键按下状态为2
value = key_val; ///将按键值传给需要显示的变量
switch(key_val)
{
case 4: P0=~0x04;P2=0x80;P2=0; break;//按下S4
case 5: P0=~0x05;P2=0x80;P2=0; break;//按下S5
case 6: P0=~0x06;P2=0x80;P2=0; break; //按下S6
case 7: P0=~0x07;P2=0x80;P2=0; break; //按下S7
case 8: P0=~0x08;P2=0x80;P2=0; break;//按下S8
case 9: P0=~0x09;P2=0x80;P2=0; break;//按下S9
case 10: P0=~0x0a;P2=0x80;P2=0; break;//按下S10
case 11: P0=~0x0b;P2=0x80;P2=0; break; //按下S11
case 12: P0=~0x0c;P2=0x80;P2=0; break;//按下S12
case 13: P0=~0x0d;P2=0x80;P2=0; break; //按下S13
case 14: P0=~0x0e;P2=0x80;P2=0; break;//按下S14
case 15: P0=~0x0f;P2=0x80;P2=0; break;//按下S15
case 16: P0=~0x10;P2=0x80;P2=0; break;//按下S16
case 17: P0=~0x11;P2=0x80;P2=0; break;//按下S17
case 18: P0=~0x12;P2=0x80;P2=0; break;//按下S18
case 19: P0=~0x13;P2=0x80;P2=0; break;//按下S19
}
}
case 2:if(key_val==0) key_state = 0;//第三次若检测到无按键按下,返回状态0。
}
}
void main()
{
P0=0xff;P2=0x80;P2=0x00;
P0=0x00;P2=0xa0;P2=0x00;
Time0_init();
while(1)
{
if(countkey>9)
{
countkey=0;
scan_key();
if(value >9)dsp_show[6] = dsp_code[value / 10];
else dsp_show[6]=0xff;
dsp_show[7] = dsp_code[value%10];
}
}
}