金沙滩51单片机数码、LED、点阵

在这里插入图片描述

								图1

一、数码管与LED

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

由上面三个图可得知六个数码管与八个LED一起受到U3(74HC138)的控制。
当我们让六个数码管同时亮时,采取的是动态扫描,即1ms进入一次中断进行扫描IO口,又因为一个数码管是由八个LED组成,所以要想数码管和LED同时亮,先用一个数组来暂存LED0~LED7的地址(unsigned char code Led[] = {0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F}),再用一个来暂存数码管的显示数值地址,同时扩大数码管与LED的缓冲区成LEDBuf[7]。
动态扫描思路如下
1、先定义一个静态变量i,用来改变扫描的索引。
2、定义变量之后紧接着写上P0=0xFF,此语句是为了消隐。
3、因为138受到P1.0~P1.2控制,也即受P1低3位控制,所以先使P1低3位清空,然后再改变P1低3位的状态。P1=(P1&0xF8)|i。
例:P1&0xF8 XXXXX000;假如此时i=2,也即010,现在(P1&0xF8)|i =xxxxx010,这样就改变了P1低三位的状态。0xF8=11111000
4、把缓冲区的数据送给P0,P0=LEDBuf[i],i的值递增到i=5即可。
5、这个函数(函数名随意)需要放到中断中,中断时间为1ms。
代码如下:

static unsigned char i = 0;
P0 = 0xFF;
P1 = (P1&0xF8)|i;
if(i==6)
	LEDBuf[6]=Led[cnt];//cnt为全局变量,控制点亮哪个LED
P0=LEDBuf[i];
if(i<6)
	i++;
else
	i=0;

二、点阵

在这里插入图片描述
在这里插入图片描述

由上图可知点阵也连到了P0口,并且受到U4(74HC138)的控制,由图1可知U4又受到ADDR3的控制,当ADDR3=0时有效。点阵是1ms进入中断进行扫描
点阵显示图案也是P0口进行动态扫描,时间为1ms扫描一次,先定义一个数组暂存显示图案的地址(unsigned char code Lattice[]),图案地址从取模软件获取
动态扫描思路:
只需把数码管与LED的扫描思路第4点改成把Lattice数组的数据送给P0,P0=Lattice[i],i的值递增到i=7即可,其他思路一样。
代码如下:

static unsigned char i = 0;
P0 = 0xFF; //消隐
P1 = (P1&0xF8)|i;
P0=Lattice[i];
if(i<8)
	i++;
else
	i=0;

三、数码管、LED、点阵

三者都连到了P0口,若想一起点亮,把他们放到同一个函数内进行扫描。
扫描思路:
1、先定义静态变量i,用来改变扫描索引。
2、当i<8时进行点阵扫描,打开U4,ADDR3=0;
3、当i>7时进行LED和数码管的扫描,打开U3,ADDR3=1;
4、当i>15时,i=0。
代码如下:

Static unsigned char i = 0;
P0 = 0xFF;//消隐
if(i>7)
{
	ADDR3 = 1;
	P1 = (P1&0xF8)|(i-8);
	if(i==14)
		LEDBuf[6]=Led[cnt];
	P0 =LEDBuf[i-8];
}
else
{
	ADDR3 = 0;
	P1 = (P1&0xF8)|i;
	P0=Lattice[i];
}
i++;
if(i>15)
	i=0;

注:以上扫描函数需要放到中断中

全部代码如下:

#include<reg52.h>

sbit ADDR3 = P1^3;
sbit ENLED = P1^4;

void ConfigTimer0(unsigned long ms);//定时多少毫秒
void ScanLattLed();//点阵扫描


unsigned char T0RH = 0;
unsigned char T0RL = 0;
unsigned char code Lattice[8] = {//心形字模表
	  0x99,0x00,0x00,0x00,0x81,0xC3,0xE7,0xFF
	};
unsigned char code LedChar[]={//数码管显示字符转换表
	0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
	0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
	};
unsigned char code Led[8] = {
	  0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F
	};
unsigned char LedBuff[]={
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
	};
bit flag1s = 0;//1s定时标志
unsigned char cnt = 0;//记录T0中断次数

void main()
{
    unsigned long sec = 0;
	ENLED = 0;
	EA = 1;
	ConfigTimer0(1);
	while(1)
	{
		if(flag1s == 1)		  
		{
			flag1s = 0;
			sec++;
			LedBuff[0] = LedChar[sec%10];
			LedBuff[1] = LedChar[sec/10%10];
			LedBuff[2] = LedChar[sec/100%10];
			LedBuff[3] = LedChar[sec/1000%10];
			LedBuff[4] = LedChar[sec/10000%10];
			LedBuff[5] = LedChar[sec/100000%10];	
		}
	}	
}
void ConfigTimer0(unsigned long ms)//定时多少毫秒
{
	unsigned long tmp;
	tmp = 11059200/12;
	tmp = (tmp*ms)/1000;
	tmp = 65536-tmp;
	tmp += 18;
	T0RH = (unsigned char)(tmp>>8);
	T0RL = (unsigned char)tmp;
	TMOD &= 0xF0;
	TMOD |= 0x01;
	TH0 = T0RH;
	TL0 = T0RL;
	ET0 = 1;
	TR0 = 1;
}
void ScanLattLed()
{
	static unsigned char i = 0;
	P0 = 0xFF;
	if(i>7)//扫描数码管与LED小灯
	{
		ADDR3 = 1;	
		P1 = (P1&0xF8)|(i-8);
		if(i==14)
			LedBuff[6]=Led[cnt];
		P0 = LedBuff[i-8];
	}
	else  //i<7时扫描点阵
	{
		ADDR3 = 0;      
		P1 = (P1&0xF8)|i;
		P0 = Lattice[i];
	}
	i++;	
	if(i>15)	
		i=0;
}
void InterruptTimer0() interrupt 1
{
	static unsigned long cut = 0;
	TH0 = 0xFC;
	TL0 = 0x67;
	cut++;
	if(cut>=1000)
	{
		cut=0;
		cnt++;
		flag1s=1;
		if(cnt>7)//cnt为LED数组索引
			cnt=0;	
	}
	ScanLattLed();//点阵、数码管、LED扫描
}
  • 4
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

点灯大师~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值