蓝桥杯单片机——数码管、LED、蜂鸣器、继电器

前言

因为开发板上的外设较多所以引脚复用是不可避免的,这块开发板使用的方案是4片74HC573锁存器,加一片74HC138译码器芯片和一片双输入的与非门芯片。锁存器的输入端接了单片机的P0口,使能信号由与非门芯片控制,而与非门芯的输入一路接了138译码器,另一路接了统一接到了单片机的P42号引脚。138译码器的ABC对应单片机的引脚为P25、P26、P27。

  .............直接上代码吧

锁存器使能函数

/****************************************************************
* 函 数 名       : hc138_init
* 函数功能		 : 使能选中的锁存器
* 参数           : 使能n锁存器
* 返回值         : 无
******************************************************************/
void hc138_init(unsigned char n)
{
	switch(n)
	{
		//led灯	
		case 4:
			P2=(P2&0x1f)|0x80;
			break;
		
		//蜂鸣器,继电器		
		case 5:
			P2=(P2&0x1f)|0xa0;
			break;

		//数码管的位选
		case 6:
			P2=(P2&0x1f)|0xc0;
			break;
		
		//数码管的段选
		case 7:
			P2=(P2&0x1f)|0xe0;
			break;
		
		//失能所用锁存器
		default:P2=(P2&0x1f);
		  break;
	}
}

数码管

/*****数码管数组*****/
unsigned char code smg_dm[]=
		{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,//0-9不带点
		 0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,//0-9带点
		 0xff
		};
	
/******延迟函数*****/
void delay_ms(unsigned int z)
{
	unsigned int i,j;
	for(i=z;i>0;i--)
	  for(j=800;j>0;j--);
}
	
/*****控制数码管位选与段选*****/
void smg_SetOne(unsigned char pos,unsigned char value)
{
    P0=0x01<<(pos-1);//位选
	hc138_init(6);//使能锁存器,更新输出电平
	hc138_init(0);//失能锁存器,锁存输出电平
	
	P0=smg_dm[value];//段选
	hc138_init(7);
    hc138_init(0);
	delay_ms(2);//延时
	
    P0=0;//熄灭数码管所有的位与段码,即消隐
	hc138_init(6);
	hc138_init(0);
	P0=0xff;
	hc138_init(7);
    hc138_init(0);	
}

/***** 应用 *****/
void main(void)
{
	char i=0;
	while(1)
	{
		for(i=0;i<8;i++)
		   smg_SetOne(i+1,i);//动态扫描显示12345678
	}
}

led灯

unsigned char LED_State =0xff;//保存LED灯的状态

/****  初始化LED,LED全灭  ******/
void LED_Init(void)
{	
	P0=0xff;
	hc138_init(4);
    hc138_init(0);
}

/****整体控制  dat:led灯的状态(对应位1灭,0亮)  ******/
void LED_SetEntierty(unsigned char dat)
{
	P0 = dat;
	hc138_init(4);//使能led灯锁存器
	hc138_init(0);//失能锁存器
	LED_State  = dat;
}

/****按位控制  num:要操作led灯的位,bat:led灯的状态(0灭,1亮)  ******/
void LED_SetOne(unsigned char num,bit dat)
{
	if(dat==0)    LED_State  |=  0x01<<(num-1);
	else          LED_State  &= ~(0x01<<(num-1));
    LED_SetEntierty(LED_State);
}

/****  应用 ******/
void main(void)
{
	char i=0,j=0;
	LED_Init();//熄灭所有led
	
	delay_ms(1500);
	
	LED_SetEntierty(0Xaa);//间隔点亮led
	while(1)
	{
		LED_SetOne(1,1); //LED1以0.2s频率闪烁
		delay_ms(200);
		LED_SetOne(1,0);
		delay_ms(200);
	}
}

蜂鸣器、继电器

sbit Relay = P0^4;	 //继电器,为1时打开继电器,且上电默认值为1
sbit BUZZ = P0^6;	 //蜂鸣器,写1时打开,且上电默认值为1

bit Relay_State=0,BUZZ_State=0;//保存蜂鸣器、蜂鸣器的状态

/****  初始化关闭蜂鸣器、蜂鸣器  ******/
void Relay_BUZZ_Init(void)
{	
	Relay =0;
	BUZZ = 0;
	hc138_init(5);//使能锁存器
	hc138_init(0);//失能锁存器
}

/****  蜂鸣器 1打开,0关闭  ******/
void BUZZ_Set(char dat)
{
	BUZZ_State = dat;//更新蜂鸣器的状态 
	
    Relay = Relay_State;//输出更新后的电平
	BUZZ  = BUZZ_State; //输出更新后的电平
	
	hc138_init(5);//使能锁存器
	hc138_init(0);//失能锁存器	
}

/****  继电器 1打开,0关闭 ******/
void Relay_Set(char dat)
{
	Relay_State = dat;
	
    Relay = Relay_State;//输出更新后的电平
	BUZZ  = BUZZ_State; //输出更新后的电平
	
	hc138_init(5);//使能锁存器
	hc138_init(0);//失能锁存器	
}

/****  应用 ******/
void main(void)
{
	Relay_BUZZ_Init();//初始化关闭蜂鸣器、蜂鸣器
	
	while(1)
	{
		BUZZ_Set(1);//打开蜂鸣器
		delay_ms(1000);
		
		BUZZ_Set(0);//关闭蜂鸣器
		delay_ms(1000);
		
		Relay_Set(1);//打开继电器
		delay_ms(1000);
		
		Relay_Set(0);//关闭继电器
		delay_ms(1000);		
	}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
数码管是一种常见的数字显示器件,可以用于显示各种数字、字母等字符。在单片机应用中,数码管通常用于显示计数器、计时器、温度、湿度等实时数据。 数码管的种类有很多,包括共阳数码管、共阴数码管、共阳共阴混合数码管等。其中,共阳数码管是最常见的一种,也是本文所涉及的数码管类型。 单片机控制数码管的原理是通过对数码管的各个管脚进行控制,使其显示相应的数字或字符。数码管的控制方式有两种,即静态显示和动态显示。 静态显示是指将要显示的数字或字符的每一位分别输出到数码管的每个管脚上,然后使其保持不变,从而实现显示效果。静态显示的缺点是需要使用大量的I/O口,且不能灵活地改变显示内容。 动态显示是指将要显示的数字或字符的每一位依次输出到数码管的每个管脚上,并在短时间内快速切换下一个数字或字符,从而形成连续的显示效果。动态显示的优点是可以使用较少的I/O口,且可以灵活地改变显示内容。 以下是一个简单的动态显示数码管的实现示例: 1. 定义数码管的引脚 ```c #define DIG_PORT P2 // 数码管位选端口 #define DIG_COM 0x00 // 数码管位选端口初始值 #define LED_PORT P0 // 数码管段选端口 ``` 2. 定义数码管显示的数字或字符 ```c unsigned char code ledChar[] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f }; ``` 3. 实现数码管动态显示函数 ```c void display(unsigned char i) { unsigned char j, k; for (j = 0; j < 8; j++) { DIG_PORT = DIG_COM | (1 << j); // 选择数码管位(从左到右) for (k = 0; k < 100; k++); // 延时,视情况可调整 LED_PORT = ledChar[i]; // 显示数码管上的数字或字符 } } ``` 4. 调用数码管动态显示函数 ```c int main() { unsigned char i = 0; while (1) { display(i % 10); // 显示数字 i 的个位数 i++; } return 0; } ``` 以上就是一个简单的数码管动态显示的实现示例。需要注意的是,数码管的控制方式和具体实现方法可能因不同的硬件平台和编程语言而有所不同。因此,在具体应用中需要根据实际情况进行适当的调整和修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值