单片机实现数码管显示小数
数码管(7段数码管)在嵌入式应用中广泛用于显示数字。通常,数码管只能显示整数,但我们可以通过控制其显示内容,使其显示小数部分。这个过程的关键是模拟小数点的显示,并正确地显示数字。
本项目将实现通过8051单片机控制一个数码管显示带小数的数字,例如 12.34
,通过合理分配数码管的显示位,实现小数的显示。
一、项目需求
- 数码管显示:通过数码管显示带小数的数字。
- 控制方式:通过单片机控制数码管的显示,支持两位整数和两位小数。
- 小数点显示:通过控制数码管的小数点位置来显示小数。
二、硬件设计
- 单片机:使用8051单片机(如AT89C51)。
- 数码管:使用两个共阴数码管显示带小数的数字。每个数码管显示一位数字,两个数码管依次显示整数和小数部分。
- 小数点:使用数码管的一个小数点(通常是共阴数码管的第8个段)来表示小数点的位置。
三、数码管显示原理
数码管通常由7个LED段和一个小数点段组成。每个数字的显示是通过控制不同段的亮灭来实现的。例如,数字0
对应的段码为0x3F
,数字1
对应的段码为0x06
,依此类推。
3.1 数码管段码定义
数字和小数点的段码(以共阴数码管为例)如下:
数字 | 段码 (0x3F) | 数字 | 段码 (0x3F) |
---|---|---|---|
0 | 0x3F | 1 | 0x06 |
2 | 0xB6 | 3 | 0x76 |
4 | 0xEE | 5 | 0x7A |
6 | 0xFA | 7 | 0x06 |
8 | 0xFE | 9 | 0x7E |
小数点 | 0x80 | - | - |
其中,0x80
用于点亮小数点。
3.2 显示流程
假设我们需要显示一个带两位小数的数字,如12.34
,可以通过以下方式控制数码管显示:
- 第一位数码管显示
1
。 - 第二位数码管显示
2
。 - 第三个数码管显示
.
(小数点)。 - 第四个数码管显示
3
。 - 第五个数码管显示
4
。
四、程序设计
4.1 数码管显示函数
在程序中,我们需要设计一个函数来显示数值和小数点。
- 由于数码管只能显示单个数字,因此我们必须将整数和小数部分分别处理。
- 控制显示时需要选择相应的数码管和小数点。
4.2 代码实现
#include <reg51.h> // 包含8051单片机的寄存器定义
// 数码管段码(共阴数码管)
unsigned char code digit_code[] = {
0x3F, // 0
0x06, // 1
0xB6, // 2
0x76, // 3
0xEE, // 4
0x7A, // 5
0xFA, // 6
0x06, // 7
0xFE, // 8
0x7E, // 9
};
// 定义数码管端口
#define DIGIT1 P0 // 个位数码管连接到P0口
#define DIGIT2 P1 // 十位数码管连接到P1口
#define DIGIT3 P2 // 小数点数码管连接到P2口
#define DIGIT4 P3 // 小数部分数码管连接到P3口
// 延时函数(用来调整数码管刷新时间)
void delay_ms(unsigned int ms) {
unsigned int i, j;
for (i = 0; i < ms; i++) {
for (j = 0; j < 120; j++) {
// 空循环,产生延时
}
}
}
// 数码管显示函数
void display_number(float number) {
unsigned char integer_part = (unsigned char)number; // 整数部分
unsigned char decimal_part = (unsigned char)((number - integer_part) * 100); // 小数部分
// 显示十位数
DIGIT1 = digit_code[integer_part / 10];
delay_ms(5); // 延时,避免闪烁
// 显示个位数
DIGIT2 = digit_code[integer_part % 10];
delay_ms(5); // 延时,避免闪烁
// 显示小数点
DIGIT3 = 0x80; // 点亮小数点
delay_ms(5); // 延时,避免闪烁
// 显示小数部分
DIGIT4 = digit_code[decimal_part / 10]; // 显示小数点后一位
delay_ms(5); // 延时,避免闪烁
// 显示小数部分第二位
DIGIT4 = digit_code[decimal_part % 10]; // 显示小数点后一位
delay_ms(5); // 延时,避免闪烁
}
// 主程序
void main() {
float number = 12.34; // 示例数字
while (1) {
display_number(number); // 显示数字
delay_ms(500); // 延时500ms,每秒更新一次
}
}
五、程序说明
数码管段码:
digit_code[]
数组定义了数字0-9
对应的数码管段码。
显示数字:
display_number(float number)
函数将传入的浮动数字分解为整数部分和小数部分,然后分别显示在相应的数码管上。- 整数部分通过
integer_part
存储,小数部分通过decimal_part
存储。每个数码管显示一位数字,同时使用0x80
来点亮小数点。
延时:
delay_ms()
函数用来控制数码管刷新时间,避免显示闪烁。
数码管控制:
- 每个数码管都通过
DIGIT1
、DIGIT2
等端口控制,数字显示时会通过这些端口传输相应的段码。
- 每个数码管都通过
小数点显示:
- 小数点通过控制小数点段(通常是
0x80
)来点亮,显示在小数部分和整数部分之间。
- 小数点通过控制小数点段(通常是
六、总结
通过8051单片机的控制,可以成功实现数码管显示带小数的数字。这个方案通过将整数和小数部分分开控制数码管,并利用小数点段显示小数部分,实现了对浮动数字的显示。通过调整delay_ms()
函数中的延时时间,可以实现合适的刷新速度,从而避免数码管闪烁的问题。
该方案适用于各种嵌入式应用,尤其是在需要显示带小数的数字时。通过增加更多的数码管或者使用动态显示技术,系统可以扩展以显示更多的数字位。