【单片机基础】单片机数码管驱动函数(三极管驱动)

1、数码管电路原理图及原理

电路图(图一)
请添加图片描述

数码管显示原理(图二)
在这里插入图片描述
数码管根据内部连接不同,分为共阴极和共阳极。八段数码管内部有8颗LED组成,如果想要显示特定字形只需控制相应的LED亮起,其他LED熄灭即可。

数码管显示方式有两种:静态显示和动态显示

静态显示每个数码管端口都必须接上数据IO口来保持显示。当送入字形可一直保持,直到送入新字形为止。
优点:数码管显示无闪烁、亮度高、软件控制比较容易。
缺点:需要的硬件电路较多,如果数码管增多,当数码管全部被电量的时候,所需要的电流会增大,对电源的要求也随之增加。所以,大部分硬件设计中,很少采用静态显示的方式

动态显示:所有位的数码管段选线并联在一起,由位选线进行动态扫描,控制是哪一位数码管有效。所谓动态扫描显示就是轮流向各位数码管送出字形码和相应的位选,利用发光数码管的余晖和人眼视觉残留的作用,使人感觉好像各位数码管同时都在显示。

扩展:眼睛的另一个重要特性是视觉惰性,即光象一旦在视网膜上形成,视觉将会对这个光象的感觉维持一个有限的时间,这种生理现象叫做视觉暂留性,对于中等亮度的光刺激,视觉暂留时间约为0.05至0.2秒

优点:硬件简单(数码管越多,这个优势越明显),由于每个数码管只有一个被点亮,所以数码管消耗的电流较小。
缺点:数码管亮度不如静态显示的亮度高,如果刷新率低,会出现闪烁的现象。

2、数码管码表

//数码管码表,共阳极
unsigned char leddata[]={ 
 
                0xC0,  //"0"
                0xF9,  //"1"
                0xA4,  //"2"
                0xB0,  //"3"
                0x99,  //"4"
                0x92,  //"5"
                0x82,  //"6"
                0xF8,  //"7"
                0x80,  //"8"
                0x90,  //"9"
                0x88,  //"A"
                0x83,  //"B"
                0xC6,  //"C"
                0xA1,  //"D"
                0x86,  //"E"
                0x8E,  //"F"
                0x89,  //"H"
                0xC7,  //"L"
                0xC8,  //"n"
                0xC1,  //"u"
                0x8C,  //"P"
                0xA3,  //"o"
                0xBF,  //"-"
                0xFF,  //熄灭
                0xFF  //自定义
 
                         };

//数码管码表,共阴极
unsigned char leddata[]={ 
 
                0x3F,  //"0"
                0x06,  //"1"
                0x5B,  //"2"
                0x4F,  //"3"
                0x66,  //"4"
                0x6D,  //"5"
                0x7D,  //"6"
                0x07,  //"7"
                0x7F,  //"8"
                0x6F,  //"9"
                0x77,  //"A"
                0x7C,  //"B"
                0x39,  //"C"
                0x5E,  //"D"
                0x79,  //"E"
                0x71,  //"F"
                0x76,  //"H"
                0x38,  //"L"
                0x37,  //"n"
                0x3E,  //"u"
                0x73,  //"P"
                0x5C,  //"o"
                0x40,  //"-"
                0x00,  //熄灭
                0x00  //自定义
 
                         };

3、位选IO管脚定义

sbit smg1 = P2^0;
sbit smg2 = P2^1;
sbit smg3 = P2^2;
sbit smg4 = P2^3;

4、延时函数

//注意:必须包含<intrins.h>头文件才能使用
void Delay1ms()		//@11.0592MHz
{
	unsigned char i, j;

	_nop_();
	i = 2;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
}

void delay_ms(unsigned int time)
{
	unsigned int i;
	for(i=0; i<time; i++)
	{
		Delay1ms();
	}
}

5、动态显示一位数码管

//在数码管显示一位数字显示函数,
//unsigned char i 输入0-9以内的数字
void disply_one_digit(unsigned char i)
{
	P0 = leddata[i];
	smg4 = 0;
	delay_ms(5);
	smg4 = 1;
}

6、动态显示两位数码管

//在数码管显示两位数字显示函数,
//unsigned char i 输入0-99以内的数字
void disply_two_digit(unsigned char i)
{
	unsigned char shi,ge;
	shi = i / 10;
	ge = i % 10;
	
	P0 = leddata[ge];
	smg4 = 0;
	delay_ms(5);
	smg4 = 1;
	
	P0 = leddata[shi];
	smg3 = 0;
	delay_ms(5);
	smg3 = 1;
}

7、动态显示三位数码管

//在数码管显示三位数字显示函数,
//unsigned char i 输入0-999以内的数字
void disply_three_digit(unsigned int i)
{
	unsigned int ge,shi,bai;
	
	bai = i / 100;
	shi = i % 100 / 10;
	ge  = i % 10;
	
	P0 = leddata[ge];
	smg4 = 0;
	delay_ms(5);
	smg4 = 1;
	
	P0 = leddata[shi];
	smg3 = 0;
	delay_ms(5);
	smg3 = 1;
	
	P0 = leddata[bai];
	smg2 = 0;
	delay_ms(5);
	smg2 = 1;
}

8、动态显示四位数码管

//在数码管显示四位数字显示函数,
//unsigned char i 输入0-9999以内的数字
void disply_four_digit(unsigned int i)
{
	unsigned int ge,shi,bai,qian;
	
	qian = i / 1000 % 10;
	bai = i / 100 % 10;
	shi = i / 10 % 10;
	ge = i % 10;
	
	P0 = leddata[ge];
	smg4 = 0;
	delay_ms(5);
	smg4 = 1;
	
	P0 = leddata[shi];
	smg3 = 0;
	delay_ms(5);
	smg3 = 1;
	
	P0 = leddata[bai];
	smg2 = 0;
	delay_ms(5);
	smg2 = 1;
	
	P0 = leddata[qian];
	smg1 = 0;
	delay_ms(5);
	smg1 = 1;
}

9、主函数调用示例

void main()
{
	while(1)
	{
//		disply_one_digit(5);
//		
//		disply_two_digit(9);
//		
//		disply_three_digit(123);
		
		disply_four_digit(1234);
	}
}
  • 5
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,针对你的问题,SPI(Serial Peripheral Interface)是一种串行通信接口,常用于单片机控制外部器件。而数码管可以通过SPI总线来驱动显示。下面是一个简单的SPI驱动数码管的示例代码: ```c #include <avr/io.h> #include <util/delay.h> #define SS_PIN PB2 #define MOSI_PIN PB3 #define SCK_PIN PB5 void spi_init() { DDRB |= (1 << SS_PIN) | (1 << MOSI_PIN) | (1 << SCK_PIN); SPCR |= (1 << SPE) | (1 << MSTR) | (1 << SPR0); // enable SPI, set as master, set prescaler to 16 } void spi_write(uint8_t data) { SPDR = data; while (!(SPSR & (1 << SPIF))); // wait for transmission to complete } void display_number(uint8_t num) { uint8_t digits[4] = {0}; digits[0] = num % 10; digits[1] = (num / 10) % 10; digits[2] = (num / 100) % 10; digits[3] = (num / 1000) % 10; for (int i = 0; i < 4; i++) { PORTB &= ~(1 << SS_PIN); // select the display spi_write(1 << i); // set the digit position spi_write(digits[3 - i]); // send the digit value PORTB |= (1 << SS_PIN); // deselect the display _delay_ms(1); // delay to avoid ghosting } } int main() { spi_init(); while (1) { for (uint8_t i = 0; i < 10000; i++) { display_number(i); _delay_ms(10); } } return 0; } ``` 在这个示例代码中,我们使用AVR微控制器的SPI接口驱动了一个四位数码管。首先,我们需要初始化SPI总线,然后定义一个`display_number`函数用于显示一个数字。在`display_number`函数中,我们将输入的数字拆分成四个位,然后依次将每个位的值通过SPI接口发送给数码管。在主函数中,我们通过循环调用`display_number`函数来显示数字。需要注意的是,由于数码管的刷新速度较慢,所以我们需要在发送完每个数字后加上适当的延时,以避免出现“幽灵”数字。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小明n.n

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

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

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

打赏作者

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

抵扣说明:

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

余额充值