大概就是在矩阵键盘输入4个数字到数码管上,然后数字再按照一定的规律进行动态变化。
可有偿代写,难度不大,stc89c52的板子
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit D1 = P2^0;
sbit D2 = P2^1;
sbit D3 = P2^2;
sbit D4 = P2^3;
uchar code num[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};
void delay(uint x)
{
uint i, j;
for(i=x; i>0; i--)
for(j=110; j>0; j--);
}
void display(uchar i, uchar n)
{
switch(i)
{
case 1:
D1 = 0; D2 = 1; D3 = 1; D4 = 1;
P0 = num[n%10];
break;
case 2:
D1 = 1; D2 = 0; D3 = 1; D4 = 1;
P0 = num[n/10%10];
break;
case 3:
D1 = 1; D2 = 1; D3 = 0; D4 = 1;
P0 = num[n/100%10];
break;
case 4:
D1 = 1; D2 = 1; D3 = 1; D4 = 0;
P0 = num[n/1000%10];
break;
default:
break;
}
}
void main()
{
uchar i, j, k, l, n1, n2, n3, n4;
P0 = 0;
while(1)
{
for(i=1; i<=4; i++)
{
for(j=0; j<10; j++)
{
for(k=0; k<10; k++)
{
for(l=0; l<10; l++)
{
n1 = num[j];
n2 = num[k];
n3 = num[l];
n4 = num[j];
display(1, n1);
delay(2);
display(2, n2);
delay(2);
display(3, n3);
delay(2);
display(4, n4);
delay(2);
}
}
}
}
}
}
这里使用了一个数组num来存储数字0到9的七段码值。在display函数中,根据传入的参数i来选择哪个数码管进行显示,根据传入的参数n来选择显示哪个数字。在main函数中,使用四层循环来遍历所有的数字组合,每次调用display函数来显示四个数字。由于循环比较多,因此需要设置一些延时来控制数码管的刷新速度。
以下是使用C语言编写的滚动显示数字的代码示例,适用于STC89C52单片机:
#include <reg52.h>
#define DISPLAY_DELAY 1
// 定义数码管段选和位选引脚
sbit digit1 = P1^0;
sbit digit2 = P1^1;
sbit digit3 = P1^2;
sbit digit4 = P1^3;
sbit segmentA = P2^4;
sbit segmentB = P2^5;
sbit segmentC = P2^6;
sbit segmentD = P2^7;
// 数码管段选码表
unsigned char code segmentCode[] = {
0x3F, // 0
0x06, // 1
0x5B, // 2
0x4F, // 3
0x66, // 4
0x6D, // 5
0x7D, // 6
0x07, // 7
0x7F, // 8
0x6F // 9
};
// 延时函数
void delay(unsigned int ms) {
unsigned int i, j;
for(i = 0; i < ms; i++) {
for(j = 0; j < 110; j++);
}
}
// 数码管显示函数
void displayNumber(unsigned int num) {
unsigned char i;
unsigned char digitValue[4];
// 分离数字的每一位
digitValue[0] = num % 10;
digitValue[1] = (num / 10) % 10;
digitValue[2] = (num / 100) % 10;
digitValue[3] = (num / 1000) % 10;
// 数码管滚动显示
for(i = 0; i < 4; i++) {
// 逐个位选,显示对应数字
digit1 = i == 0;
digit2 = i == 1;
digit3 = i == 2;
digit4 = i == 3;
// 设置段选,显示对应数字
P2 = segmentCode[digitValue[i]];
// 延时一段时间,控制滚动速度
delay(DISPLAY_DELAY);
}
}
void main() {
unsigned int inputNumber = 2761; // 输入的数字
unsigned int tempNumber;
unsigned char i;
while(1) {
tempNumber = inputNumber;
// 循环滚动显示数字
for(i = 0; i < 8; i++) {
displayNumber(tempNumber);
// 每次滚动将数字右移一位
tempNumber = (tempNumber / 10) + ((tempNumber % 10) * 1000);
// 延时一段时间,控制滚动速度
delay(DISPLAY_DELAY);
}
}
}
这段代码使用STC89C52单片机控制4位共阳数码管进行滚动显示输入的数字。你可以根据需要修改inputNumber
变量来输入不同的数字,并通过DISPLAY_DELAY
常量调整滚动速度。代码中包含详细的注释,以帮助理解每一行代码的作用和功能。请注意,该代码仅供参考,你可能需要根据自己的硬件接口和需求进行适当的修改和调整。
在这里的显示方式我们简单的归纳为这么几步:位选 段选 清零 位选 段选 清零
首先说明什么是扫描数码管,我们发现,数码管在构造时为了节省端口(单片机就40个引脚,不能全用来显示数码管吧,嘿嘿)把一排的数码管端口都共用了,所以为了同时显示四个数字,我们是不是得这样:
1,先在DIG1,DIG2,DIG3,DIG4,选一个
2,在端口用二进制代码或者十六进制代码显示我们想要显示的字符
3,最后将端口清零,就是全灭,因为端口是共用的,所以这样可以避免扫描过快时,第二个位置也显示相同的字符;
最后利用定时器以很快地速度重复这三个步骤,就可以实现数码管的扫描操作了
然后我们之前解释的显示方式就一一对应了即1就表示位选,2就表示段选,3,就表示清零。
#include<reg52.h>
#define DataPort P0
sbit we=P2^7;
sbit du=P2^6;
unsigned char code digit[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsigned char irtime;
bit irpro_ok,ir_ok;
unsigned char IRcode[4],IRdata[33];
void TIME0init(void)
{
TMOD=0x02;
TH0=0x00;
TL0=0x00;
ET0=1;
TR0=1;
}
void EX0init()
{
IT0=1;
EX0=1;
EA=1;
}
void TIME0_interrupt(void) interrupt 1 using 1
{
irtime++;
}
void EX0_interrupt(void) interrupt 0
{
static unsigned char i; //接收第几次红外信号处理
static bit startflag; //是否开始处理
if(startflag)
{
if(irtime>40&&irtime<60)
i=0;
IRdata[i]=irtime;
irtime=0;
i++;
if(i==33)
{
ir_ok=1;
startflag=0;
}
}
else
{
irtime=0;
startflag=1;
}
}
void Ir_work(void)
{
if (IRcode[0]==0x00&&IRcode[1]==0xFF)
{
switch(IRcode[2])//客户码:00FF
{
case 0x45:break;
case 0x46:break;
case 0x47:break;
case 0x44:break;
case 0x40:break;
case 0x43:break;
case 0x07:break;
case 0x15:break;
case 0xD9:break;
case 0x16:DataPort=digit[0];break;
case 0x19:break;
case 0x0D:break;
case 0x0C:DataPort=digit[1];break;
case 0x18:DataPort=digit[2];break;
case 0x5E:DataPort=digit[3];break;
case 0x08:DataPort=digit[4];break;
case 0x1C:DataPort=digit[5];break;
case 0x5A:DataPort=digit[6];break;
case 0x42:DataPort=digit[7];break;
case 0x52:DataPort=digit[8];break;
case 0x4A:DataPort=digit[9];break;
default:break;
}
}
}
void Ircodepro(void)
{
unsigned char i, j, k;
unsigned char cord,value;
k=1;
for(i=0;i<4;i++) //处理4个字节
{
for(j=1;j<=8;j++) //处理1个字节8位
{
cord=IRdata[k];
if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差
value|=0x80;
if(j<8)
{
value>>=1;
}
k++;
}
IRcode[i]=value;
value=0;
}
irpro_ok=1;//处理完毕标志位置1
}
void main(void)
{
EX0init();
TIME0init();
we=1;
DataPort=0xFE;
we=0;
du=1;
while(1)
{
if(ir_ok)
{
Ircodepro();
ir_ok=0;
}
if(irpro_ok)
{
Ir_work();
irpro_ok=0;
}
}
}
示例程序
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar KeySta[4] = {0xff, 0xff, 0xff, 0xff}; //初始化键盘状态
uchar KeyValue[16] = {
0xc, 0x9, 0x3, 0x1,
0xd, 0xa, 0x6, 0x2,
0xe, 0xb, 0x7, 0x4,
0xf, 0x0, 0x8, 0x5,
}; //键值映射表
uchar DispVal[4] = {0, 0, 0, 0}; //初始化数码管显示值
uchar DispPos = 0; //数码管显示位置
//延时函数
void Delay(uint i)
{
while(i--);
}
//矩阵键盘扫描函数
uchar KeyScan()
{
uchar i, j;
uchar keyvalue = 0xff;
for(i=0; i<4; i++)
{
P1 = 0x0f;
KeySta[i] = (P1 & 0xf0) | 0x0f;
for(j=0; j<4; j++)
{
if(KeySta[i] == KeyValue[i*4+j])
{
keyvalue = KeySta[i]; //获取键值
}
}
P1 = 0xf0;
KeySta[i] = (P1 & 0x0f) | 0xf0;
for(j=0; j<4; j++)
{
if(KeySta[i] == KeyValue[i*4+j])
{
keyvalue = KeySta[i]; //获取键值
}
}
}
return keyvalue;
}
//数码管扫描函数
void ScanDisp()
{
uchar i, j;
uint tmp;
uchar code disptable[] = { //数码管段选表
0xc0, 0xf9, 0xa4, 0xb0,
0x99, 0x92, 0x82, 0xf8,
0x80, 0x90, 0x88, 0x83,
0xc6, 0xa1, 0x86, 0x8e,
};
tmp = DispVal[DispPos]; //获取当前位置的数值
for(i=0; i<8; i++)
{
j = tmp % 10;
tmp /= 10;
P0 = 0xff;
P2 = disptable[j];
Delay(100); //延时一段时间,保证数码管显示稳定
P2 = 0x00;
Delay(100);
}
}
//主函数
void main()
{
while(1)
{
uchar keyvalue = KeyScan(); //获取键值
if(keyvalue != 0xff) //判断是否有按键按下
{
DispVal[DispPos] = keyvalue & 0x0f; //将键值添加到数码管显示值中
DispPos++; //更新显示位置
if(DispPos == 4)
{
DispPos = 0; //如果显示的位置超过4,则重新从位置0开始显示
}
}
ScanDisp(); //进行数码管扫描
}
}
电路图呢?
#include <reg51.h>
// 定义4位数码管的端口连接
sbit digit1 = P2^0;
sbit digit2 = P2^1;
sbit digit3 = P2^2;
sbit digit4 = P2^3;
// 定义4x4矩阵键盘的端口连接
sbit col1 = P0^0;
sbit col2 = P0^1;
sbit col3 = P0^2;
sbit col4 = P0^3;
sbit row1 = P0^4;
sbit row2 = P0^5;
sbit row3 = P0^6;
sbit row4 = P0^7;
// 数码管显示表
unsigned char code segTable[] = {
0xC0, // 0
0xF9, // 1
0xA4, // 2
0xB0, // 3
0x99, // 4
0x92, // 5
0x82, // 6
0xF8, // 7
0x80, // 8
0x90 // 9
};
// 延时函数
void delay(unsigned int count) {
unsigned int i, j;
for(i = 0; i < count; i++) {
for(j = 0; j < 120; j++) {}
}
}
// 读取键盘输入函数
unsigned char getKey() {
unsigned char key = 0xFF;
unsigned char col = 0xFF;
col1 = 0;
col2 = 1;
col3 = 1;
col4 = 1;
if(row1 == 0) {
key = 1;
col = 1;
}
else if(row2 == 0) {
key = 4;
col = 1;
}
else if(row3 == 0) {
key = 7;
col = 1;
}
else if(row4 == 0) {
key = 10;
col = 1;
}
col1 = 1;
col2 = 0;
col3 = 1;
col4 = 1;
if(row1 == 0) {
key = 2;
col = 2;
}
else if(row2 == 0) {
key = 5;
col = 2;
}
else if(row3 == 0) {
key = 8;
col = 2;
}
else if(row4 == 0) {
key = 0;
col = 2;
}
col1 = 1;
col2 = 1;
col3 = 0;
col4 = 1;
if(row1 == 0) {
key = 3;
col = 3;
}
else if(row2 == 0) {
key = 6;
col = 3;
}
else if(row3 == 0) {
key = 9;
col = 3;
}
else if(row4 == 0) {
key = 11;
col = 3;
}
col1 = 1;
col2 = 1;
col3 = 1;
col4 = 0;
if(row1 == 0) {
key = 12;
col = 4;
}
else if(row2 == 0) {
key = 13;
col = 4;
}
else if(row3 == 0) {
key = 14;
col = 4;
}
else if(row4 == 0) {
key = 15;
col = 4;
}
return (key + col - 1);
}
void main() {
unsigned char digit1Val = 0;
unsigned char digit2Val = 0;
unsigned char digit3Val = 0;
unsigned char digit4Val = 0;
while(1) {
unsigned char key = getKey();
if(key >= 1 && key <= 9) {
// 更新数码管的值
digit4Val = digit3Val;
digit3Val = digit2Val;
digit2Val = digit1Val;
digit1Val = key;
}
else if(key == 0) {
// 清空数码管的值
digit1Val = 0;
digit2Val = 0;
digit3Val = 0;
digit4Val = 0;
}
else if(key == 12) {
// 向左移动数码管的值
unsigned char temp = digit1Val;
digit1Val = digit2Val;
digit2Val = digit3Val;
digit3Val = digit4Val;
digit4Val = temp;
}
else if(key == 13) {
// 向右移动数码管的值
unsigned char temp = digit4Val;
digit4Val = digit3Val;
digit3Val = digit2Val;
digit2Val = digit1Val;
digit1Val = temp;
}
// 在数码管上显示值
digit1 = 1;
P1 = segTable[digit1Val];
digit1 = 0;
delay(5);
digit2 = 1;
P1 = segTable[digit2Val];
digit2 = 0;
delay(5);
digit3 = 1;
P1 = segTable[digit3Val];
digit3 = 0;
delay(5);
digit4 = 1;
P1 = segTable[digit4Val];
digit4 = 0;
delay(5);
}
}