【单片机数码管显示程序设计入门秘籍】:从零基础到实战应用,轻松掌握数码管显示技术
发布时间: 2024-07-08 03:43:16 阅读量: 76 订阅数: 27
![【单片机数码管显示程序设计入门秘籍】:从零基础到实战应用,轻松掌握数码管显示技术](https://img-blog.csdnimg.cn/2021100612145210.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAbTBfNTEzNTE2NTc=,size_20,color_FFFFFF,t_70,g_se,x_16)
# 1. 单片机数码管显示基础**
数码管是一种常见的电子显示器件,广泛应用于各种电子设备中。它由七个独立的发光二极管(LED)组成,可以显示数字0到9。
要使用单片机控制数码管显示,需要了解其工作原理和驱动方式。数码管的每个LED对应一个段,通过控制各个段的通断状态,可以组合出不同的数字。单片机通过I/O口输出高低电平,控制数码管驱动电路,从而实现数字显示。
# 2. 数码管显示编程技巧
### 2.1 数码管驱动原理
#### 2.1.1 数码管的结构和工作原理
数码管是一种电子显示器件,由多个发光二极管(LED)组成,可以显示数字或其他符号。常见的数码管有七段数码管、八段数码管和点阵数码管。
七段数码管由七个发光二极管组成,分别称为 a、b、c、d、e、f 和 g。通过控制这七个发光二极管的亮灭,可以显示数字 0 到 9。
八段数码管在七段数码管的基础上增加了一个小数点发光二极管,可以显示数字 0 到 9 和小数点。
点阵数码管由多个发光二极管组成一个矩阵,可以显示数字、字母和其他符号。
#### 2.1.2 数码管驱动电路设计
数码管驱动电路的作用是为数码管提供合适的电压和电流,使其正常发光。常见的数码管驱动电路有共阳极驱动电路和共阴极驱动电路。
共阳极驱动电路中,数码管的阳极端连接到电源正极,阴极端通过限流电阻连接到单片机的 I/O 口。当单片机 I/O 口输出高电平时,对应的数码管段发光。
共阴极驱动电路中,数码管的阴极端连接到电源负极,阳极端通过限流电阻连接到单片机的 I/O 口。当单片机 I/O 口输出低电平时,对应的数码管段发光。
### 2.2 数码管显示控制
#### 2.2.1 单片机 I/O 口控制数码管
单片机可以通过 I/O 口直接控制数码管的显示。对于共阳极驱动电路,单片机 I/O 口输出高电平时,对应的数码管段发光;对于共阴极驱动电路,单片机 I/O 口输出低电平时,对应的数码管段发光。
```c
// 共阳极驱动电路
void display_digit(uint8_t digit) {
switch (digit) {
case 0:
PORTB = 0b11111100;
break;
case 1:
PORTB = 0b01100000;
break;
// ...
}
}
// 共阴极驱动电路
void display_digit(uint8_t digit) {
switch (digit) {
case 0:
PORTB = 0b00000011;
break;
case 1:
PORTB = 0b10011111;
break;
// ...
}
}
```
#### 2.2.2 多路复用技术实现多位数码管显示
当需要显示多位数字时,可以使用多路复用技术。多路复用技术是将多个数码管共用一个驱动电路,通过时分复用方式逐个显示数字。
```c
// 多路复用显示三位数码管
void display_digits(uint8_t digit1, uint8_t digit2, uint8_t digit3) {
static uint8_t current_digit = 0;
switch (current_digit) {
case 0:
PORTB = 0b11111100;
PORTC = digit1;
break;
case 1:
PORTB = 0b11111011;
PORTC = digit2;
break;
case 2:
PORTB = 0b11110111;
PORTC = digit3;
break;
}
current_digit = (current_digit + 1) % 3;
}
```
# 3. 数码管显示实践应用
### 3.1 数字时钟设计
#### 3.1.1 时钟电路设计
数字时钟的时钟电路主要由晶振、电容和电阻组成,其作用是为单片机提供稳定的时基信号。常用的晶振频率为 32.768KHz,通过电容和电阻与单片机相连。
#### 3.1.2 单片机时钟程序实现
单片机时钟程序主要负责读取晶振信号,并将其转换为单片机内部可用的时钟信号。通常使用单片机内置的定时器/计数器模块来实现时钟功能。
```c
// 初始化时钟
void init_clock() {
// 设置晶振频率为 32.768KHz
RCC_OscInitTypeDef osc_init;
osc_init.OscillatorType = RCC_OSCILLATORTYPE_HSE;
osc_init.HSEState = RCC_HSE_ON;
osc_init.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInit(&osc_init);
// 设置时钟为晶振时钟
RCC_ClocksTypeDef clocks;
RCC_GetClocksFreq(&clocks);
RCC_SYSCLKConfig(RCC_SYSCLKSOURCE_HSE);
}
```
### 3.2 温度显示系统
#### 3.2.1 温度传感器选型
温度传感器主要有热敏电阻、热电偶、红外温度传感器等。数字时钟中常使用热敏电阻,其阻值随温度变化而变化。
#### 3.2.2 单片机温度采集和显示程序
单片机温度采集和显示程序主要包括以下步骤:
1. 初始化 ADC 模块,配置 ADC 通道和采样时间。
2. 读取热敏电阻的阻值,并将其转换为温度值。
3. 将温度值显示在数码管上。
```c
// 初始化 ADC 模块
void init_adc() {
// 设置 ADC 时钟为 PCLK2
RCC_ADCCLKConfig(RCC_ADCCLK_PCLK2_DIV6);
// 使能 ADC 时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
// 初始化 ADC
ADC_InitTypeDef adc_init;
adc_init.ADC_Mode = ADC_Mode_Independent;
adc_init.ADC_ScanConvMode = DISABLE;
adc_init.ADC_ContinuousConvMode = DISABLE;
adc_init.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
adc_init.ADC_DataAlign = ADC_DataAlign_Right;
adc_init.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &adc_init);
// 使能 ADC
ADC_Cmd(ADC1, ENABLE);
}
// 读取热敏电阻阻值
uint16_t read_thermistor() {
// 设置 ADC 通道为热敏电阻通道
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5);
// 启动 ADC 转换
ADC_SoftwareStartConv(ADC1);
// 等待 ADC 转换完成
while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
// 读取 ADC 转换结果
return ADC_GetConversionValue(ADC1);
}
// 将热敏电阻阻值转换为温度值
float convert_thermistor_to_temperature(uint16_t thermistor_value) {
// 根据热敏电阻的特性曲线计算温度
float temperature = 25.0 + (100.0 - 25.0) / (log(100000.0 / thermistor_value) / log(10));
return temperature;
}
```
# 4. 数码管显示进阶应用**
**4.1 动态数码管显示**
**4.1.1 扫描显示原理**
动态数码管显示是一种通过快速扫描多个数码管来实现多位数码管显示的方法。其原理是将多个数码管连接到一个单片机的I/O口上,然后通过程序控制I/O口的输出,依次点亮不同的数码管。由于扫描速度非常快,人眼无法分辨出单个数码管的闪烁,从而实现多位数码管的连续显示。
**4.1.2 动态数码管显示程序实现**
```c
#include <reg51.h>
// 数码管段选端口
#define SEGMENT_PORT P2
// 数码管位选端口
#define DIGIT_PORT P1
// 数码管段选码表
const unsigned char segmentCode[] = {
0x3f, // 0
0x06, // 1
0x5b, // 2
0x4f, // 3
0x66, // 4
0x6d, // 5
0x7d, // 6
0x07, // 7
0x7f, // 8
0x6f // 9
};
// 数码管位选码表
const unsigned char digitCode[] = {
0xfe, // 第一位
0xfd, // 第二位
0xfb, // 第三位
0xf7 // 第四位
};
void main() {
unsigned char digit = 0; // 当前显示的数码管位
unsigned char segment = 0; // 当前显示的数码管段
while (1) {
// 循环显示每个数码管位
for (digit = 0; digit < 4; digit++) {
// 选择当前数码管位
DIGIT_PORT = digitCode[digit];
// 循环显示每个数码管段
for (segment = 0; segment < 7; segment++) {
// 选择当前数码管段
SEGMENT_PORT = segmentCode[segment];
// 延时,控制显示时间
for (unsigned int i = 0; i < 1000; i++) {
// 空循环,延时
}
}
}
}
}
```
**代码逻辑分析:**
* 主函数`main()`中,循环显示每个数码管位和数码管段。
* 循环变量`digit`表示当前显示的数码管位,`segment`表示当前显示的数码管段。
* 通过`DIGIT_PORT`和`SEGMENT_PORT`选择当前数码管位和段。
* 循环延时控制显示时间,使人眼无法分辨出单个数码管的闪烁。
**4.2 数码管矩阵显示**
**4.2.1 数码管矩阵的结构和驱动方式**
数码管矩阵是一种由多个数码管排列成矩阵形式的显示器。其结构通常为m行n列,每个数码管代表一个显示单元。驱动数码管矩阵时,需要使用行选和列选技术。行选是指选择要显示的数码管行,列选是指选择要显示的数码管列。通过逐行逐列扫描,可以实现整个数码管矩阵的显示。
**4.2.2 数码管矩阵显示程序设计**
```c
#include <reg51.h>
// 数码管矩阵行选端口
#define ROW_PORT P2
// 数码管矩阵列选端口
#define COL_PORT P1
// 数码管段选码表
const unsigned char segmentCode[] = {
0x3f, // 0
0x06, // 1
0x5b, // 2
0x4f, // 3
0x66, // 4
0x6d, // 5
0x7d, // 6
0x07, // 7
0x7f, // 8
0x6f // 9
};
void main() {
unsigned char row = 0; // 当前显示的行
unsigned char col = 0; // 当前显示的列
unsigned char segment = 0; // 当前显示的数码管段
while (1) {
// 循环显示每行
for (row = 0; row < 4; row++) {
// 选择当前行
ROW_PORT = ~(1 << row);
// 循环显示每列
for (col = 0; col < 8; col++) {
// 选择当前列
COL_PORT = ~(1 << col);
// 循环显示每个数码管段
for (segment = 0; segment < 7; segment++) {
// 选择当前数码管段
SEGMENT_PORT = segmentCode[segment];
// 延时,控制显示时间
for (unsigned int i = 0; i < 1000; i++) {
// 空循环,延时
}
}
}
}
}
}
```
**代码逻辑分析:**
* 主函数`main()`中,循环显示每行和每列。
* 循环变量`row`表示当前显示的行,`col`表示当前显示的列,`segment`表示当前显示的数码管段。
* 通过`ROW_PORT`和`COL_PORT`选择当前行和列。
* 循环延时控制显示时间,使人眼无法分辨出单个数码管的闪烁。
# 5. 单片机数码管显示实战**
**5.1 数码管显示仪表设计**
**5.1.1 仪表硬件电路设计**
仪表电路主要由单片机、数码管、驱动电路和电源部分组成。单片机负责控制数码管显示内容和驱动电路。驱动电路负责放大单片机的输出信号,驱动数码管显示。电源部分为整个电路供电。
**5.1.2 单片机仪表程序开发**
仪表程序主要负责从传感器采集数据,并根据数据控制数码管显示。程序流程如下:
```mermaid
sequenceDiagram
participant MCU as MCU
participant Sensor as Sensor
MCU->Sensor: Request data
Sensor->MCU: Send data
MCU->Display: Display data
```
**5.2 数码管显示控制系统**
**5.2.1 控制系统硬件设计**
控制系统硬件电路主要由单片机、数码管、输入设备和输出设备组成。单片机负责控制数码管显示内容和输入设备。输入设备用于接收用户输入,输出设备用于显示控制结果。
**5.2.2 单片机控制程序实现**
控制程序主要负责接收用户输入,并根据输入控制数码管显示和输出设备。程序流程如下:
```python
while True:
input = get_input()
if input == 'A':
display_value(1)
output_value(1)
elif input == 'B':
display_value(2)
output_value(2)
else:
display_value(0)
output_value(0)
```
0
0