51单片机学习代码 基础实验1
第9章 点亮第一个LED灯
9.4.1点亮第一个LED
本章所要实现的功能是:点亮 D1 指示灯,即让 P2.0 管脚输出一个低电平。
完成后可再控制 D1 指示灯闪烁,即间隔一段时间点亮和熄灭 D1 指示灯。
我们直接复制前面创建好的工程模板,在此模板基础上进行程序开发。为了
能够与开发攻略教程对应,将复制过来的模板文件夹重新命名为“2-点亮第一个
LED”。打开工程直接在 main.c 源文件内进行编程,main.c 内代码如下:
#include "reg52.h"
sbit LED1=P2^0; //将 P2.0 管脚定义为 LED1
/****************************************************************
***************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*****************************************************************
**************/
void main()
{
LED1=0; //LED1 端口设置为低电平
while(1)
{
}
}
9.4.2 LED 闪烁实验
/**************************************************************************************
深圳市普中科技有限公司(PRECHIN 普中)
技术支持:www.prechin.net
PRECHIN
普中
实验名称:LED闪烁实验
接线说明:
实验现象:下载程序后“LED模块”的D1指示灯闪烁
注意事项:
***************************************************************************************/
#include "reg52.h"
typedef unsigned int u16; //对系统默认数据类型进行重定义
typedef unsigned char u8;
sbit LED1=P2^0; //将P2.0管脚定义为LED1
/*******************************************************************************
* 函 数 名 : delay_10us
* 函数功能 : 延时函数,ten_us=1时,大约延时10us
* 输 入 : ten_us
* 输 出 : 无
*******************************************************************************/
void delay_10us(u16 ten_us)
{
while(ten_us--);
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
while(1)
{
LED1=0; //点亮
delay_10us(50000); //大约延时450ms
LED1=1; //熄灭
delay_10us(50000);
}
}
9.4.3 LED 流水灯实验
如果要实现 LED 流水灯,只需循环让 D1-D8 指示灯逐个点亮。同样本实验也
需要延时,这个在前面已介绍,这里就不多说。要实现循环点亮,可以使用最容
易理解的方法:点亮 D1 且把 D2-D8 熄灭,延时一段时间后再点亮 D2 且把 D1、
D3-D8 熄灭,延时一段时间后再点亮 D3 且把 D1-D2、D4-D8 熄灭,如此循环,这
样就可以很简单的实现 LED 流水灯实验,当然我们不推荐此种方法。在前面我们
学习了 C 语言相关的基础知识,里面有移位以及循环语句操作,根据流水灯实现
原理,即 IO 口由低往高或者由高往低逐个输出低电平特点,那么我们可以将移
位操作以及循环结合进来
/**************************************************************************************
深圳市普中科技有限公司(PRECHIN 普中)
技术支持:www.prechin.net
PRECHIN
普中
实验名称:LED流水灯实验
接线说明:
实验现象:下载程序后“LED模块”的D1-D8指示左右点亮
注意事项:
***************************************************************************************/
#include "reg52.h"
#include "intrins.h"
typedef unsigned int u16; //对系统默认数据类型进行重定义
typedef unsigned char u8;
#define LED_PORT P2 //使用宏定义P2端口
/*******************************************************************************
* 函 数 名 : delay_10us
* 函数功能 : 延时函数,ten_us=1时,大约延时10us
* 输 入 : ten_us
* 输 出 : 无
*******************************************************************************/
void delay_10us(u16 ten_us)
{
while(ten_us--);
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
u8 i=0;
LED_PORT=~0x01;
delay_10us(50000);
while(1)
{
//方法1:使用移位+循环实现流水灯
// for(i=0;i<8;i++)
// {
// LED_PORT=~(0x01<<i); //将1右移i位,然后取反将结果赋值到LED_PORT
// delay_10us(50000);
// }
//方法2:使用循环+_crol_或_cror_函数实现流水灯
for(i=0;i<7;i++) //将led左移一位
{
LED_PORT=_crol_(LED_PORT,1);
delay_10us(50000);
}
for(i=0;i<7;i++) //将led右移一位
{
LED_PORT=_cror_(LED_PORT,1);
delay_10us(50000);
}
}
}
第10章 蜂鸣器实验
蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计
算机、 打印机、 复印机、 报警器、 电子玩具、 汽车电子设备、 电话机、 定
时器等电子产品中作发声器件。蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两
种类型。
压电式蜂鸣器主要由多谐振荡器、压电蜂鸣片、阻抗匹配器及共鸣箱、外壳
等组成。多谐振荡器由晶体管或集成电路构成,当接通电源后(1.5~15V 直流工
作电压),多谐振荡器起振,输出 1.5~5kHZ 的音频信号,阻抗匹配器推动压电
蜂鸣片发声。
电磁式蜂鸣器由振荡器、电磁线圈、磁铁、振动膜片及外壳等组成。接通电
源后,振荡器产生的音频信号电流通过电磁线圈,使电磁线圈产生磁场,振动膜
片在电磁线圈和磁铁的相互作用下,周期性地振动发声。
其实一句话就可概括它们之间的区别,想要压电式蜂鸣器发声,需提供一定
频率的脉冲信号;想要电磁式蜂鸣器发声,只需提供电源即可。
我们开发板上使用的蜂鸣器是无源蜂鸣器,属于压电式蜂鸣器类型。这里说
的有源和无源,并不是指电源的意思,而是指蜂鸣器内部是否含有振荡电路,有
源蜂鸣器内部自带振荡电路,只需提供电源即可发声,而无源蜂鸣器则需提供一
定频率的脉冲信号才能发声,频率大小通常在 1.5-5KHz 之间。
对于无源蜂鸣器,如果改变频率就可以调节蜂鸣器音调,产生各种不同音色、
音调的声音。如果改变输出电平的高低电平占空比,则可以改变蜂鸣器的声音大
小。
对于有源蜂鸣器,通常内部已经固定了频率,对于调节频率或占空比可能改
变不了蜂鸣器的音调和音量,当然也有的有源蜂鸣器可以实现和无源蜂鸣器一样。
/**************************************************************************************
深圳市普中科技有限公司(PRECHIN 普中)
技术支持:www.prechin.net
PRECHIN
普中
实验名称:蜂鸣器实验
接线说明:
实验现象:下载程序后蜂鸣器发出声音,一段时间后关闭
注意事项:
***************************************************************************************/
#include "reg52.h"
typedef unsigned int u16; //对系统默认数据类型进行重定义
typedef unsigned char u8;
// 关键修改:把P2^5改成蜂鸣器的真实引脚(这里用P1^5,若不对可换P3^7)
sbit BEEP=P1^5; //将P1.5管脚定义为BEEP(普中开发板蜂鸣器常用引脚)
/*******************************************************************************
* 函 数 名 : delay_10us
* 函数功能 : 延时函数,ten_us=1时,大约延时10us
* 输 入 : ten_us
* 输 出 : 无
*******************************************************************************/
void delay_10us(u16 ten_us)
{
while(ten_us--);
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
u16 i=2000;
while(1)
{
while(i--)//循环2000次
{
BEEP=!BEEP;//产生一定频率的脉冲信号
delay_10us(100);
}
i=0;//清零
BEEP=0;//关闭蜂鸣器
}
}
蜂蜜器演奏小星星
/**************************************************************************************
深圳市普中科技有限公司(PRECHIN 普中)
实验名称:蜂鸣器演奏《一闪一闪亮晶晶》(精准节奏版)
接线说明:蜂鸣器接P1.5引脚
实验现象:下载程序后蜂鸣器按标准4/4拍演奏《一闪一闪亮晶晶》
***************************************************************************************/
#include "reg52.h"
// 数据类型重定义
typedef unsigned int u16;
typedef unsigned char u8;
// 蜂鸣器引脚定义(确认是P1.5)
sbit BEEP = P1^5;
// 1. 定义C调各音符频率(Hz),0=休止符
#define DO 523 // 1
#define RE 587 // 2
#define MI 659 // 3
#define FA 698 // 4
#define SOL 784 // 5
#define LA 880 // 6
#define SI 988 // 7
#define REST 0 // 休止符
// 2. 定义节奏(4/4拍,1拍=300ms,可调整BASE_BEAT改变整体速度)
#define BASE_BEAT 300 // 基础拍长(ms),数值越大节奏越慢,越小越快
#define BEAT_1 BASE_BEAT // 1拍
#define BEAT_2 BASE_BEAT*2 // 2拍
#define BEAT_HALF BASE_BEAT/2 // 半拍(备用)
/*******************************************************************************
* 函数名:delay_us
* 功能:微秒级精准延时(适配11.0592MHz晶振)
*******************************************************************************/
void delay_us(u16 us)
{
u16 i;
for(i=0; i<us; i++)
{
// 11.0592MHz晶振,该循环≈1us
;
}
}
/*******************************************************************************
* 函数名:beep_note
* 功能:播放指定频率和时长的音符,精准控制节奏
*******************************************************************************/
void beep_note(u16 freq, u16 time_ms)
{
u16 cycle, count;
if(freq == 0) // 休止符:静音
{
BEEP = 0;
delay_us(time_ms * 1000); // 延时对应时长
return;
}
// 计算方波周期(1/频率),转换为微秒
cycle = 1000000 / freq;
// 计算需要翻转的次数(总时长 / 周期)
count = (time_ms * 1000) / cycle;
// 产生指定频率的方波,持续指定时长
for(; count>0; count--)
{
BEEP = 1;
delay_us(cycle / 2); // 高电平半周期
BEEP = 0;
delay_us(cycle / 2); // 低电平半周期
}
// 音符间微小间隔,避免粘连(提升听感)
delay_us(5000);
}
/*******************************************************************************
* 函数名:main
* 功能:按标准4/4拍演奏《一闪一闪亮晶晶》
*******************************************************************************/
void main()
{
while(1)
{
// 第一段:1 1 5 5 6 6 5 - (1拍 1拍 1拍 1拍 | 1拍 1拍 2拍)
beep_note(DO, BEAT_1);
beep_note(DO, BEAT_1);
beep_note(SOL, BEAT_1);
beep_note(SOL, BEAT_1);
beep_note(LA, BEAT_1);
beep_note(LA, BEAT_1);
beep_note(SOL, BEAT_2);
delay_us(1000000);
// 第二段:4 4 3 3 2 2 1 - (1拍 1拍 1拍 1拍 | 1拍 1拍 2拍)
beep_note(FA, BEAT_1);
beep_note(FA, BEAT_1);
beep_note(MI, BEAT_1);
beep_note(MI, BEAT_1);
beep_note(RE, BEAT_1);
beep_note(RE, BEAT_1);
beep_note(DO, BEAT_2);
delay_us(1000000);
// 第三段:5 5 4 4 3 3 2 - (1拍 1拍 1拍 1拍 | 1拍 1拍 2拍)
beep_note(SOL, BEAT_1);
beep_note(SOL, BEAT_1);
beep_note(FA, BEAT_1);
beep_note(FA, BEAT_1);
beep_note(MI, BEAT_1);
beep_note(MI, BEAT_1);
beep_note(RE, BEAT_1);
delay_us(1000000);
// 第四段:5 5 4 4 3 3 2 - (1拍 1拍 1拍 1拍 | 1拍 1拍 2拍)
beep_note(SOL, BEAT_1);
beep_note(SOL, BEAT_1);
beep_note(FA, BEAT_1);
beep_note(FA, BEAT_1);
beep_note(MI, BEAT_1);
beep_note(MI, BEAT_1);
beep_note(RE, BEAT_2);
delay_us(1000000);
// 第五段:1 1 5 5 6 6 5 - (1拍 1拍 1拍 1拍 | 1拍 1拍 2拍)
beep_note(DO, BEAT_1);
beep_note(DO, BEAT_1);
beep_note(SOL, BEAT_1);
beep_note(SOL, BEAT_1);
beep_note(LA, BEAT_1);
beep_note(LA, BEAT_1);
beep_note(SOL, BEAT_2);
delay_us(1000000);
// 第六段:4 4 3 3 2 2 1 - (1拍 1拍 1拍 1拍 | 1拍 1拍 2拍)
beep_note(FA, BEAT_1);
beep_note(FA, BEAT_1);
beep_note(MI, BEAT_1);
beep_note(MI, BEAT_1);
beep_note(RE, BEAT_1);
beep_note(RE, BEAT_1);
beep_note(DO, BEAT_2);
// 演奏完一遍,暂停3秒再重复(可删除)
delay_us(3000000);
}
}
蜂鸣器演奏小星星,配合LED灯亮
/**************************************************************************************
深圳市普中科技有限公司(PRECHIN 普中)
实验名称:蜂鸣器演奏《一闪一闪亮晶晶》+LED同步闪烁(精准节奏版)
接线说明:蜂鸣器接P1.5引脚,LED1-LED8接P2.0-P2.7引脚
实验现象:下载程序后蜂鸣器按标准4/4拍演奏,对应音符触发不同LED灯亮
***************************************************************************************/
#include "reg52.h"
// 数据类型重定义
typedef unsigned int u16;
typedef unsigned char u8;
// 蜂鸣器引脚定义(确认是P1.5)
sbit BEEP = P1^5;
// LED引脚定义(P2.0-P2.7对应D1-D8)
sbit LED1 = P2^0;
sbit LED2 = P2^1;
sbit LED3 = P2^2;
sbit LED4 = P2^3;
sbit LED5 = P2^4;
sbit LED6 = P2^5;
sbit LED7 = P2^6;
sbit LED8 = P2^7;
// 1. 定义C调各音符频率(Hz),0=休止符
#define DO 523 // 1 对应LED1
#define RE 587 // 2 对应LED2
#define MI 659 // 3 对应LED3
#define FA 698 // 4 对应LED4
#define SOL 784 // 5 对应LED5
#define LA 880 // 6 对应LED6
#define SI 988 // 7 对应LED7
#define REST 0 // 休止符 对应LED8
// 2. 定义节奏(4/4拍,1拍=300ms,可调整BASE_BEAT改变整体速度)
#define BASE_BEAT 300 // 基础拍长(ms),数值越大节奏越慢,越小越快
#define BEAT_1 BASE_BEAT // 1拍
#define BEAT_2 BASE_BEAT*2 // 2拍
#define BEAT_HALF BASE_BEAT/2 // 半拍(备用)
/*******************************************************************************
* 函数名:delay_us
* 功能:微秒级精准延时(适配11.0592MHz晶振)
*******************************************************************************/
void delay_us(u16 us)
{
u16 i;
for(i=0; i<us; i++)
{
// 11.0592MHz晶振,该循环≈1us
;
}
}
/*******************************************************************************
* 函数名:led_control
* 功能:根据音符控制对应LED亮,其他LED灭
* 参数:note - 音符频率值(DO/RE/MI等)
*******************************************************************************/
void led_control(u16 note)
{
// 先关闭所有LED(共阳/共阴都兼容,根据硬件调整高低电平)
LED1 = 1;
LED2 = 1;
LED3 = 1;
LED4 = 1;
LED5 = 1;
LED6 = 1;
LED7 = 1;
LED8 = 1;
// 不同音符对应不同LED亮
switch(note)
{
case DO: LED1 = 0; break; // DO(1) -> LED1亮
case RE: LED2 = 0; break; // RE(2) -> LED2亮
case MI: LED3 = 0; break; // MI(3) -> LED3亮
case FA: LED4 = 0; break; // FA(4) -> LED4亮
case SOL: LED5 = 0; break; // SOL(5) -> LED5亮
case LA: LED6 = 0; break; // LA(6) -> LED6亮
case SI: LED7 = 0; break; // SI(7) -> LED7亮
case REST: LED8 = 0; break; // 休止符 -> LED8亮
default: break; // 默认关闭所有LED
}
}
/*******************************************************************************
* 函数名:beep_note
* 功能:播放指定频率和时长的音符,同步控制对应LED亮,精准控制节奏
*******************************************************************************/
void beep_note(u16 freq, u16 time_ms)
{
u16 cycle, count;
// 先控制对应LED亮起
led_control(freq);
if(freq == 0) // 休止符:静音
{
BEEP = 0;
delay_us(time_ms * 1000); // 延时对应时长
return;
}
// 计算方波周期(1/频率),转换为微秒
cycle = 1000000 / freq;
// 计算需要翻转的次数(总时长 / 周期)
count = (time_ms * 1000) / cycle;
// 产生指定频率的方波,持续指定时长
for(; count>0; count--)
{
BEEP = 1;
delay_us(cycle / 2); // 高电平半周期
BEEP = 0;
delay_us(cycle / 2); // 低电平半周期
}
// 音符间微小间隔,避免粘连(提升听感)
delay_us(5000);
}
/*******************************************************************************
* 函数名:main
* 功能:按标准4/4拍演奏《一闪一闪亮晶晶》,同步控制LED闪烁
*******************************************************************************/
void main()
{
// 初始化:关闭所有LED
LED1 = 1;
LED2 = 1;
LED3 = 1;
LED4 = 1;
LED5 = 1;
LED6 = 1;
LED7 = 1;
LED8 = 1;
while(1)
{
// 第一段:1 1 5 5 6 6 5 - (1拍 1拍 1拍 1拍 | 1拍 1拍 2拍)
beep_note(DO, BEAT_1);
beep_note(DO, BEAT_1);
beep_note(SOL, BEAT_1);
beep_note(SOL, BEAT_1);
beep_note(LA, BEAT_1);
beep_note(LA, BEAT_1);
beep_note(SOL, BEAT_2);
delay_us(1000000);
// 第二段:4 4 3 3 2 2 1 - (1拍 1拍 1拍 1拍 | 1拍 1拍 2拍)
beep_note(FA, BEAT_1);
beep_note(FA, BEAT_1);
beep_note(MI, BEAT_1);
beep_note(MI, BEAT_1);
beep_note(RE, BEAT_1);
beep_note(RE, BEAT_1);
beep_note(DO, BEAT_2);
delay_us(1000000);
// 第三段:5 5 4 4 3 3 2 - (1拍 1拍 1拍 1拍 | 1拍 1拍 2拍)
beep_note(SOL, BEAT_1);
beep_note(SOL, BEAT_1);
beep_note(FA, BEAT_1);
beep_note(FA, BEAT_1);
beep_note(MI, BEAT_1);
beep_note(MI, BEAT_1);
beep_note(RE, BEAT_1);
delay_us(1000000);
// 第四段:5 5 4 4 3 3 2 - (1拍 1拍 1拍 1拍 | 1拍 1拍 2拍)
beep_note(SOL, BEAT_1);
beep_note(SOL, BEAT_1);
beep_note(FA, BEAT_1);
beep_note(FA, BEAT_1);
beep_note(MI, BEAT_1);
beep_note(MI, BEAT_1);
beep_note(RE, BEAT_2);
delay_us(1000000);
// 第五段:1 1 5 5 6 6 5 - (1拍 1拍 1拍 1拍 | 1拍 1拍 2拍)
beep_note(DO, BEAT_1);
beep_note(DO, BEAT_1);
beep_note(SOL, BEAT_1);
beep_note(SOL, BEAT_1);
beep_note(LA, BEAT_1);
beep_note(LA, BEAT_1);
beep_note(SOL, BEAT_2);
delay_us(1000000);
// 第六段:4 4 3 3 2 2 1 - (1拍 1拍 1拍 1拍 | 1拍 1拍 2拍)
beep_note(FA, BEAT_1);
beep_note(FA, BEAT_1);
beep_note(MI, BEAT_1);
beep_note(MI, BEAT_1);
beep_note(RE, BEAT_1);
beep_note(RE, BEAT_1);
beep_note(DO, BEAT_2);
// 关闭所有LED,演奏完一遍暂停3秒再重复
LED1 = 1;LED2 = 1;LED3 = 1;LED4 = 1;
LED5 = 1;LED6 = 1;LED7 = 1;LED8 = 1;
delay_us(3000000);
}
}
第 11 章 静态数码实验
数码管显示单个数字
/**************************************************************************************
深圳市普中科技有限公司(PRECHIN 普中)
技术支持:www.prechin.net
PRECHIN
普中
实验名称:静态数码管实验
接线说明:
实验现象:下载程序后“数码管模块”最左边数码管显示数字0
注意事项:
***************************************************************************************/
#include "reg52.h"
typedef unsigned int u16; //对系统默认数据类型进行重定义
typedef unsigned char u8;
#define SMG_A_DP_PORT P0 //使用宏定义数码管段码口
//共阴极数码管显示0~F的段码数据
u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
SMG_A_DP_PORT=gsmg_code[0];//将数组第1个数据赋值给数码管段选口
while(1)
{
}
}
数码管显示日期 20260301
/**************************************************************************************
深圳市普中科技有限公司(PRECHIN 普中)
实验名称:8位数码管精准显示20260101(先解决显示顺序)
接线说明:
数码管段码口:P0
数码管位码口:P2.2(LSA)、P2.3(LSB)、P2.4(LSC)
实验现象:数码管从左到右稳定显示 2 0 2 6 0 1 0 1
***************************************************************************************/
#include "reg52.h"
typedef unsigned int u16;
typedef unsigned char u8;
typedef unsigned long u32;
#define SMG_A_DP_PORT P0
// 数码管位选定义(通用8位数码管位选,适配普中开发板)
sbit LSA = P2^2;
sbit LSB = P2^3;
sbit LSC = P2^4;
// 共阴极数码管 0~9 段码(标准值,确认硬件是共阴/共阳)
u8 code gsmg_code[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
// 固定显示20260101(先不计数,只保证显示正确)
u32 count_num = 20260101;
/*******************************************************************************
* 函数名:delay_us
* 功能:数码管扫描短延时(消影)
*******************************************************************************/
void delay_us(u16 t)
{
while(t--);
}
/*******************************************************************************
* 函数名:select_bit
* 功能:精准选择数码管物理位置(从左到右:第1位~第8位)
* 参数:bit_num - 物理位置(1=最左,8=最右)
*******************************************************************************/
void select_bit(u8 bit_num)
{
// 先关闭所有位选,防止串位
LSA = 1;
LSB = 1;
LSC = 1;
// 普中开发板8位数码管位选映射(实测验证)
switch(bit_num)
{
case 1: LSC=0; LSB=0; LSA=0; break; // 第1位(最左)
case 2: LSC=0; LSB=0; LSA=1; break; // 第2位
case 3: LSC=0; LSB=1; LSA=0; break; // 第3位
case 4: LSC=0; LSB=1; LSA=1; break; // 第4位
case 5: LSC=1; LSB=0; LSA=0; break; // 第5位
case 6: LSC=1; LSB=0; LSA=1; break; // 第6位
case 7: LSC=1; LSB=1; LSA=0; break; // 第7位
case 8: LSC=1; LSB=1; LSA=1; break; // 第8位(最右)
}
}
/*******************************************************************************
* 函数名:smg_show_correct
* 功能:强制显示20260101,每一位精准对应
*******************************************************************************/
void smg_show_correct(void)
{
// 第1位(最左):显示2
select_bit(1);
SMG_A_DP_PORT = gsmg_code[2];
delay_us(300);
SMG_A_DP_PORT = 0x00;
// 第2位:显示0
select_bit(2);
SMG_A_DP_PORT = gsmg_code[0];
delay_us(300);
SMG_A_DP_PORT = 0x00;
// 第3位:显示2
select_bit(3);
SMG_A_DP_PORT = gsmg_code[2];
delay_us(300);
SMG_A_DP_PORT = 0x00;
// 第4位:显示6
select_bit(4);
SMG_A_DP_PORT = gsmg_code[6];
delay_us(300);
SMG_A_DP_PORT = 0x00;
// 第5位:显示0
select_bit(5);
SMG_A_DP_PORT = gsmg_code[0];
delay_us(300);
SMG_A_DP_PORT = 0x00;
// 第6位:显示1
select_bit(6);
SMG_A_DP_PORT = gsmg_code[1];
delay_us(300);
SMG_A_DP_PORT = 0x00;
// 第7位:显示0
select_bit(7);
SMG_A_DP_PORT = gsmg_code[0];
delay_us(300);
SMG_A_DP_PORT = 0x00;
// 第8位(最右):显示1
select_bit(8);
SMG_A_DP_PORT = gsmg_code[1];
delay_us(300);
SMG_A_DP_PORT = 0x00;
}
/*******************************************************************************
* 主函数:只循环显示20260101,不计数
*******************************************************************************/
void main(void)
{
while(1)
{
// 无限循环刷新,保证显示稳定不闪
smg_show_correct();
}
}
第 12 章 动态数码管实验
通过前面内容的介绍我们知道,要使单片机能控制开发板上 2 位一体的共阴
数码管显示,仅靠单片机 IO 口来驱动是不行的,这里就需要增加外部驱动芯片,
PRECHIN
普中
www.prechin.net
142
开发板上使用的是 74HC245 芯片。2 个 4 位一体的共阴数码管的位选线有 8 根,
直接让单片机 IO 口控制是没有任何问题的,但考虑到 51 单片机 IO 口资源的限
制,通常我们会使用一种 IO 扩展芯片,比如 74HC138、74HC164、74HC595 芯片
等,只需要很少的单片机 IO 口就可以扩展出 8 个控制口,通过级联方式甚至可
扩展出更多的控制口(这个在后面 LED 点阵实验章节中会有详细介绍)。我们开
发板上使用的是 74HC138 译码器芯片,只需单片机 3 个 IO 口就可以实现 8 个位
选管脚的控制,节省了芯片的 IO 资源。
/**************************************************************************************
深圳市普中科技有限公司(PRECHIN 普中)
技术支持:www.prechin.net
PRECHIN
普中
实验名称:动态数码管实验
接线说明:
实验现象:下载程序后“数码管模块”显示01234567
注意事项:
***************************************************************************************/
#include "reg52.h"
typedef unsigned int u16; //对系统默认数据类型进行重定义
typedef unsigned char u8;
#define SMG_A_DP_PORT P0 //使用宏定义数码管段码口
//定义数码管位选信号控制脚
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
//共阴极数码管显示0~F的段码数据
u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
/*******************************************************************************
* 函 数 名 : delay_10us
* 函数功能 : 延时函数,ten_us=1时,大约延时10us
* 输 入 : ten_us
* 输 出 : 无
*******************************************************************************/
void delay_10us(u16 ten_us)
{
while(ten_us--);
}
/*******************************************************************************
* 函 数 名 : smg_display
* 函数功能 : 动态数码管显示
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void smg_display(void)
{
u8 i=0;
for(i=0;i<8;i++)
{
switch(i)//位选
{
case 0: LSC=1;LSB=1;LSA=1;break;
case 1: LSC=1;LSB=1;LSA=0;break;
case 2: LSC=1;LSB=0;LSA=1;break;
case 3: LSC=1;LSB=0;LSA=0;break;
case 4: LSC=0;LSB=1;LSA=1;break;
case 5: LSC=0;LSB=1;LSA=0;break;
case 6: LSC=0;LSB=0;LSA=1;break;
case 7: LSC=0;LSB=0;LSA=0;break;
}
SMG_A_DP_PORT=gsmg_code[i];//传送段选数据
delay_10us(100);//延时一段时间,等待显示稳定
SMG_A_DP_PORT=0x00;//消音
}
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
while(1)
{
smg_display();
}
}
显示20251231
/**************************************************************************************
深圳市普中科技有限公司(PRECHIN 普中)
技术支持:www.prechin.net
实验名称:动态数码管实验
接线说明:
实验现象:下载程序后“数码管模块”稳定显示20251231
注意事项:
***************************************************************************************/
#include "reg52.h"
typedef unsigned int u16; //对系统默认数据类型进行重定义
typedef unsigned char u8;
#define SMG_A_DP_PORT P0 //使用宏定义数码管段码口
//定义数码管位选信号控制脚
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
//共阴极数码管显示0~F的段码数据
u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
// 定义要显示的数字数组:2 0 2 5 1 2 3 1(对应8位数码管从左到右)
u8 display_num[8] = {2,0,2,5,1,2,3,1};
/*******************************************************************************
* 函 数 名 : delay_10us
* 函数功能 : 延时函数,ten_us=1时,大约延时10us
* 输 入 : ten_us
* 输 出 : 无
*******************************************************************************/
void delay_10us(u16 ten_us)
{
while(ten_us--);
}
/*******************************************************************************
* 函 数 名 : smg_display
* 函数功能 : 动态数码管显示20251231
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void smg_display(void)
{
u8 i=0;
for(i=0;i<8;i++)
{
switch(i)//位选(沿用普中标准位选逻辑)
{
case 0: LSC=1;LSB=1;LSA=1;break; // 第1位(最左)
case 1: LSC=1;LSB=1;LSA=0;break; // 第2位
case 2: LSC=1;LSB=0;LSA=1;break; // 第3位
case 3: LSC=1;LSB=0;LSA=0;break; // 第4位
case 4: LSC=0;LSB=1;LSA=1;break; // 第5位
case 5: LSC=0;LSB=1;LSA=0;break; // 第6位
case 6: LSC=0;LSB=0;LSA=1;break; // 第7位
case 7: LSC=0;LSB=0;LSA=0;break; // 第8位(最右)
}
// 关键修改:不再显示i,而是显示自定义的display_num[i]
SMG_A_DP_PORT=gsmg_code[display_num[i]];//传送20251231的段选数据
delay_10us(100);//延时一段时间,等待显示稳定
SMG_A_DP_PORT=0x00;//消影(原代码“消音”是笔误,修正注释)
}
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
while(1)
{
smg_display();//循环刷新,保证显示稳定不闪
}
}
第 13 章 独立按键实验
更多推荐


所有评论(0)