c51单片机学习笔记一

目录

前言

单片机基础知识

单片机最小系统

GPIO

GPIO结构与工作原理

P0 端口

P1 端口

P2 端口

P3 端口

实验部分

点亮LED实验

LED 闪烁实验

LED 流水灯实验

蜂鸣器实验

静态数码管实验

动态数码管实验

74HC245

74H138

总结


前言

基于普中单片机对51单片机进行学习

注:本篇笔记主要参考了普中单片机开发文档

单片机基础知识

单片机
51 单片机是对所有兼容 Intel 8031 指令系统的单片机的统称。
功能:用于控制,通过串口可以和 WFIF/GPS/蓝牙等模块实现无线控制,通过 AD 接口可以采集光敏/烟雾传感器/可燃气体传感器等模拟信号.
常见产品有: 智能手环,无人机,平衡车、扫地机、移动 POST 机,机器人等
组成:
单片机主要由以下部分组成:CPU(进行运算、控制)、 RAM(数据存储),ROM(程序存储)、输入/输出设备(串行口、并行输出口 )等
其内部资源如下:
·8 位 CPU
·4kbytes 程序存储器(ROM) (52 为 8K)
·128bytes 的数据存储器(RAM)
(52 有 256bytes 的 RAM)
·32 条 I/O 口线
·111 条指令,大部分为单字节指令
·21 个专用寄存器
·2 个可编程定时/计数器
·5 个中断源,2 个优先级(52 有 6 个)
·一个全双工串行通信口
·外部数据存储器寻址空间为 64kB
·外部程序存储器寻址空间为 64kB
·逻辑操作位寻址功能
·双列直插 40PinDIP 封装
·单一+5V 电源供电
各部分作用:
CPU:由运算和控制逻辑组成,同时还包括中断系统和部分外部特殊功能寄
存器;
RAM:用以存放可以读写的数据,如运算的中间结果、最终结果以及欲显示
的数据;
ROM:用以存放程序、一些原始数据和表格;
I/O 口:四个 8 位并行 I/O 口,既可用作输入,也可用作输出
T/C:两个定时/记数器,既可以工作在定时模式,也可以工作在计数模式;
五个中断源的中断控制系统;
一个全双工 UART(通用异步接收发送器)的串行 I/O 口,用于实现单片机之
间或单片机与微机之间的串行通信;
片内振荡器和时钟产生电路,石英晶体和微调电容需要外接
总线(BUS):是单片机各部件之间传送信息的公共通道。单片机中有内部总线和外部总线两类,内部总线是 CPU 内部之间的连线,外部总线是指 CPU 与其它 部件之间的连线;外部总线有三种: 数据总线 DB(Data Bus),地址总线 AB (Address Bus)和控制总线 CBControl Bus)。
c51单片机学习笔记一_第1张图片

 

寻找芯片引脚方法:
在芯片上找到一个凹进去的小圆坑,或是用颜色标记的一个小标记(圆点或三
角或其他小图形),这个小圆坑或者小标记所对应的引脚就是这个芯片的第 1
28 脚,然后逆时针方向数下去,即 1 到最后一个引脚。
c51单片机学习笔记一_第2张图片

 

各引脚功能
按其功能类别可分为四类:
①电源引脚。如 VCC、GND
②时钟引脚。如 XTAL1、XTAL2
③编程控制引脚。如 RST、PSEN、ALE/PROG、EA/Vpp。(此处了解即可)
④I/O 口引脚。如 P0、P1、P2、P3,4 组 8 位 I/O 口。
VCC(40 脚)、GND(20 脚):电源引脚,不同型号单片机接入对应电压,常压为+5V,低压为+3.3V,大家在使用时要查看其芯片所要求的电压。
XTAL1(19 脚)、XTAL2(18 脚):外接时钟引脚。XTAL1 为片内振荡电路的输入端,XTAL2 为片内振荡电路的输出端。
RST(9 脚):复位引脚。当输入连续两个机器周期以上高电平时为有效,用来完成单片机的复位初始化操作,即单片机从头开始执行程序。
PSEN(29 脚):程序存储器允许输出控制端。
ALE/PROG(30 脚)
EA/Vpp(31 脚):EA 接高电平时,单片机读取内部程序存储器。当扩展有
外部 ROM 时,当读取完内部 ROM 后自动读取外部 ROM。EA 接低电平时,单片机直
接读取外部 ROM。我们没有外扩 ROM,并且需要单片机直接读取内部程序存储器,
因此 EA/Vpp 脚直接接高电平
P0 口( 39 脚~32 脚):双向 8 位三态 I/O 口,每个口可独立控制。51 单片机 P0 口内部没有上拉电阻,若输出高 时为高阻态,不能正常输出高电平,因此该组 I/O 口在使用时务必要外接上拉电 阻,一般我们选择接入 10K 欧上拉电阻
P1 口(1 脚~8 脚) :准双向 8 位 I/O 口,每个口可独立控制,内部自带上拉电阻,这种接口输出没有高阻态,输入也不能锁存,故不是真正的双向 I/O 口。 “准双向”是因为该口在作为输入使用前,要先向该口进行写 1 操作,然后单片机内部才可正确读出外部信号,也就是要使其先有个“准”备的过程,所以才称为准双向口。
P2 口( 21 脚~28 脚) :准双向 8 位 I/O 口,每个口可独立控制,内部自带上
拉电阻,与 P1 口相似
P3 口( 10 脚~17 脚) :准双向 8 位 I/O 口,每个口可独立控制,内部自带上
拉电阻。作为第一功能使用时就当做普通 I/O 口,与 P1 口相似。作为第二功能
使用时,各引脚的定义如下:
c51单片机学习笔记一_第3张图片

 

单片机最小系统

能使 51 单片机工作的最简单基础的电路统称为 51 单片机最小系统。
由以下几部分组成:
(1)晶振电路:提供时钟给单片机工作,犹如人的心脏
(2)复位电路:提供系统复位操作,运行不正常或死机时可用
(3)电源电路:对单片机进行供电
(4)下载电路:使系统能够更新程序
注:前面三部分即可让单片机正常运行,但无法更新程序。

GPIO

GPIO(general purpose intput output)是通用输入输出端口的简称,可以通过软件来控制其输入和输出。gpio引脚通过与外部设备连接起来,实现与外部通讯,控制与数据采集功能。

c51单片机学习笔记一_第4张图片

 

51 单片机引脚可以分为这么几大类:

(1)电源引脚:引脚图中的 VCC、 GND 都属于电源引脚。

(2)晶振引脚:引脚图中的 XTAL1、XTAL2 都属于晶振引脚。

(3)复位引脚:引脚图中的 RST/VPD 属于复位引脚,不做其他功能使用。

(4)下载引脚:51 单片机的串口功能引脚(TXD、RXD)可以作为下载引脚使用。

(5) GPIO 引脚:引脚图中带有 Px.x 等字样的均属于 GPIO 引脚,4 组,P0、P1、P2、P3,每组为 8 个 IO。同一时刻,每个引脚只能使用该引脚的一个功能。

GPIO结构与工作原理

c51单片机学习笔记一_第5张图片

 

P0 端口

P0 端口由锁存器、输入缓冲器、切换开关、一个非门、一个与非门及场效应管驱动电路构成。
标号为 P0.x 引脚的图标,也就是说 P0.x 引脚可以是 P0.0 到 P0.7 的任何一位。
①输入缓冲器
在 P0 口中,有两个三态的缓冲器,要读取 D 锁存器输出端 Q 的数据,那就得使读锁存器的这个缓冲器的三态控制端(上图中标号为‘读锁存器’端)有效。要读取 P0.x 引脚上的数据,也要使标号为‘读引脚’的这个三态缓冲器的控制端有效。
②D 锁存器
D 端是数据输入端,CP(CLK)是控制端(也就是时序控制信号输入端),Q 是输出端,Q 非是反向输出端。
③多路开关
P0 口可以作为通用的输入输出端口(即 I/O)使用,当多路开关与下面接通时,P0 口是作为普通的 I/O 口使用的,当多路开关是与上面接通时,P0 口是作为‘地 址/数据’总线使用的。
④场效应管输出驱动
P0 口的输出是由两个 MOS 管组成的推拉式结构,也就是 说,这两个 MOS 管一次只能导通一个,当 V1 导通时,V2 就截止,当 V2 导通时, V1 截止。
⑤与非门、非门
1)作为 I/O 端口输出使用时的工作原理
工作流程:当写锁存器信号 CP 有效,数据总线的信号→锁存器的输入端→D 锁存器的反向输出 Q 非端→多路开关→V2 管的栅极→V2 的漏极到输出端 P0.X
c51单片机学习笔记一_第6张图片

 

(2)作为 I/O 端口输入使用时的工作原理
读引脚
读芯片引脚上的数据,读引脚数时,读引脚缓冲器打开(即三态缓冲器的控制端要有效),通过内部数据总线输入
c51单片机学习笔记一_第7张图片

 

读锁存器
c51单片机学习笔记一_第8张图片

 

P1 端口

仅作为数据输入/输出端口使用
c51单片机学习笔记一_第9张图片

 

P2 端口

功能上兼有 P0 端口和 P1 端口的特点。是动态的 I/O 端口。用来周期性地输出从外存中取指令的地址(高 8 位地址)
c51单片机学习笔记一_第10张图片

 

P3 端口

和 Pl 端口的结构相似,区别仅在于 P3 端口的各端口线有两种功能选择。
c51单片机学习笔记一_第11张图片

 

重点
①P0 口是漏极开路,要使其输出高电平,必须外接上拉电阻,通常选择
4.7K~10K 阻值。
②P0、P1、P2 几乎都用作普通 I/O 口使用,既可作为输入,又可作为输出。
③P3 口既可用作普通 I/O 口,又可作为第二功能使用,比如串口、外部中
断、计数器等。

实验部分

点亮LED实验

LED
LED 即发光二极管。它具有单向导电性,通过 5mA 左右电流即可发光,电流越大,其亮度越强,但若电流过大,会烧毁二极管,一般控制在 3 mA-20mA。
发光二极管正极又称阳极,负极又称阴极,电流只能从阳极流向阴极。
直插式发光二极管长脚为阳极,短脚为阴极。贴片式发光二极管正面的一端有彩色标记,通常有
标记的一端为阴极。
硬件电路图
c51单片机学习笔记一_第12张图片

 

实现功能:点亮 D1 指示灯。
原理:LED 采用共阳接法,D1-D8 对应单片机的 P20-P27 。则让D1发光则应让P20输出低电平。
代码

#include "reg52.h"//引入头文件

sbit LED1=P2^0;	//将P2.0管脚定义为LED1

/*******************************************************************************
* 函 数 名       : main
* 函数功能		 : 主函数
* 输    入       : 无
* 输    出    	 : 无
*******************************************************************************/
void main()
{
	LED1=0;	//LED1端口设置为低电平
	while(1)
	{
		
	}		
}

解析:首先将 51 单片机的头文件包含进来,然后使用 sbit 关键字来定义 P2.0 管脚,定义好后即可使用 LED1 来替代 P2.0 口的操作。主函数首先让 LED1 为低电平,即 P2.0 口输出为低电平,D1 指示灯即点亮,然后进入 while 循环,单片机此时一直在 while 内循环操作。

编译结果里面的几个数据的意义:
code:表示程序所占用 FLASH 的大小。
data:数据储存器内部 RAM 占用大小。
xdata:数据储存器外部 RAM 占用大小。
注: 程序的大小不是.hex 文件的大小,而是编译后的 code 和 data 之和。

LED 闪烁实验

实现的功能: 间隔一段时间点亮和熄灭 D1 指示灯
原理:通过控制输出高低电平来达到熄灭和点亮的效果
代码
​

#include "reg52.h"

typedef unsigned int u16;	//对系统默认数据类型进行重定义
typedef unsigned char u8;

sbit LED1=P2^0;	//将P2.0管脚定义为LED1


void delay_10us(u16 ten_us)//延时函数
{
	while(ten_us--);	
}

void main()
{	
	while(1)
	{
		LED1=0;	//点亮
		delay_10us(50000); //大约延时450ms
		LED1=1;	//熄灭
		delay_10us(50000); 	
	}		
}

​
解析:首先将 51 单片机的头文件包含进来,然后使用 sbit 关键字来定义 P2.0 管脚,在主函数中通过循环来让led1不断输出高低电平并用延时函数延时来达到闪烁效果。

LED 流水灯实验

实现的功能:让D1-D8 指示灯逐个点亮
for循环实现
原理:点亮一个灯时,该位输出低电平,其余灯处于熄灭状态,即对应的位输出高电平。与移位结合使用
代码

#include "reg52.h"

typedef unsigned int u16;	//对系统默认数据类型进行重定义
typedef unsigned char u8;

#define LED_PORT	P2	//使用宏定义P2端口


void delay_10us(u16 ten_us)
{
	while(ten_us--);	
}


void main()
{	
   	u8 i=0;

	LED_PORT=~0x01;
	delay_10us(50000);
	while(1)
	{
		//方法1:使用移位+循环实现流水灯
		for(i=0;i<8;i++)
		{
			LED_PORT=~(0x01<
解析:进入 main 函数后首先定义一个变量 i,然后进入 while 循环,由于要实现 8
个 LED 从 D1->D8 循环点亮,因此可以使用 for 循环语句循环 8 次,每循环一次,
点亮的小灯向右移动一个,而 D1-D8 是连接到 P2.0-P2.7 的,因此输出的低电平
要左移一位,因此可以使用 LED_PORT=~(0x01<
119 增加 1 次,0x01 中的 1 就移动多少位,因为 1(高电平)不会让 LED 点亮,需要
取反后变为低电平 0 才能点亮,所以最后的结果需要取反后给 LED_PORT 口,并
且每次循环都要延时一段时间,这样才能分辨出来 LED 在流水。
左移右移实现
原理:相当于一个队列内循环移动,如果是左移,那么最高位就被移到最低位了,次高位变为最高位,依次类推。
代码
​

#include "reg52.h"
#include "intrins.h"

typedef unsigned int u16;	//对系统默认数据类型进行重定义
typedef unsigned char u8;

#define LED_PORT	P2	//使用宏定义P2端口


void delay_10us(u16 ten_us)
{
	while(ten_us--);	
}

void main()
{	
   	u8 i=0;

	LED_PORT=~0x01;
	delay_10us(50000);
	while(1)
	{
		
		//方法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);	
		}	
	}		
}

​
解析:进入 main 函数后首先定义一个变量 i,LED_PORT=~0x01,因为 LED 是低电平点亮,所以 0X01 取反后的结果是 0XFE,对应二进制数为 1111 1110,即最低位120为0,因此最开始的 D1 指示灯会点亮,然后进入 while 循环,使用 for 循环、_crol_和_cror_移位函数实现 LED 左右流水显示。
注:左移右移函数需要包含头文件  intrins.h

蜂鸣器实验

蜂鸣器是一种一体化结构的电子讯响器。主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。

有源蜂鸣器内部自带振荡电路,只需提供电源即可发声,而无源蜂鸣器则需提供一定频率的脉冲信号才能发声,频率大小通常在 1.5-5KHz 之间。

对于无源蜂鸣器,如果改变频率就可以调节蜂鸣器音调,产生各种不同音色,音调的声音。如果改变输出电平的高低电平占空比,则可以改变蜂鸣器的声音大小
硬件电路图
c51单片机学习笔记一_第13张图片

对应管脚为P25,使用ULN2003芯片驱动,相当于一个非门。当 P25 输出高电平,BEEP 则输出低电平;当 P25 输出低电平,BEEP 则输出高电平

实现功能: 蜂鸣器发出声音,一段时间后再关闭。
原理:通过变量和循环产生一定频率脉冲信号使蜂鸣器发声,后在关闭蜂鸣器引脚。
代码
#include "reg52.h"
typedef unsigned int u16; //对系统默认数据类型进行重定义
typedef unsigned char u8;
sbit BEEP=P2^5; //将 P2.5 管脚定义为 BEEP


void delay_10us(u16 ten_us)
{
    while(ten_us--);
}


void main()
{
    u16 i=2000;
    while(1)
    {
        while(i--)//循环 2000 次
        {
            BEEP=!BEEP;//产生一定频率的脉冲信号
            delay_10us(100);
        }
        i=0;//清零
        BEEP=0;//关闭蜂鸣器
    }
}
解析;首先将 51 单片机的头文件包含进来, 然后使用 sbit 关键字来定义 P2.5 管脚,定义好后即可使用 BEEP 来替代 P2.5口的操作。主函数进入 while 循环,在循环内再次套用了一 个 while 循环,只不过这里并非死循环,而是通过变量 i 值来决定何时退出,i 值初始化为 2000,即该循环会执行 2000 次,此循环内不断对 BEEP 取反,然后 延时一定时间,即 P2.5 间隔一定时间输出高低电平,这样就会产生脉冲信号控制蜂鸣器发出声音,当 i 值递减到 0 时则退出 while 循环,然后将 i 值清零,且将 BEEP 输出 0。若修改变量 i 的值可以改变蜂鸣器发声时间。
注:若要改变音调可以修改延时时间,但要注意频率不能太大或者太小,具体大
家可以试着调试。若要改变音量,可以修改 BEEP 输出高电平时间。

静态数码管实验

数码管是一种半导体发光器件,其基本单元是发光二极管。
按段数可分为七段数码管和八段数码管,八段数码管比七段数码管多一个发光二极管单元,也就是多一个小数点(DP)。按能显示多少个可分为 1 位、 2 位、 3 位、 4 位、 5 位、 6 位、7 位等数码管。按发光二极管单元连接方式可分为共阳极数码管和共阴极 数码管。
共阳数码管是指将所有发光二极管的阳极接到一起形成公共阳极(COM)的数
码管,共阳数码管在应用时应将公共极 COM 接到+5V,当某一字段发光二极管的
阴极为低电平时,相应字段就点亮,当某一字段的阴极为高电平时,相应字段就
不亮。
共阴数码管是指将所有发光二极管的阴极接到一起形成公共阴极(COM)的数
码管,共阴数码管在应用时应将公共极 COM 接到地线 GND 上,当某一字段发光
二极管的阳极为高电平时,相应字段就点亮,当某一字段的阳极为低电平时,相
应字段就不亮。
内部电路图
c51单片机学习笔记一_第14张图片
单位数码管都封装 10 个引脚,其中第 3 和 第 8 引脚是连接在一起的。而它们的公共端又可分为共阳极和共阴极。开发板上使用的是共阴极。
对共阴极数码来说,其 8 个发光二极管的阴极在数码管内部全部连接在一起, 所以称“共阴”,而它们的阳极是独立的,通常在设计电路时一般把阴极接地。 当我们给数码管的任意一个阳极加一个高电平时,对应的这个发光二极管就点亮了。如果想要显示出一个 8 字,并且把右下角的小数点也点亮的话,可以给 8 个阳极全部送高电平。

使用共阴数码管,需要注意增加单片机 IO 口驱动电流,因为共阴数码管是要靠单片机 IO 口输出电流来点亮的,但单片机 I/O 口难以输出稳定的、如此大的电流,所以数码管与单片机连接时需要加驱动电路,可以用上拉电阻的方 法或使用专门的数码管驱动芯片,比如 74HC573、74HC245。

c51单片机学习笔记一_第15张图片

 

①共阴数码管码表
c51单片机学习笔记一_第16张图片

 

②共阳数码管码表

c51单片机学习笔记一_第17张图片

规律:它们的数据正好是相互取反的值。比如
共阴数码管数字 0 段码:0x3f,其二进制是:0011 1111,取反后为:1100 0000,转换成 16 进制即为 0XC0。其他段码依此类推。
静态显示方式和动态显示方式。
静态显示
特点:每个数码管的段选必须接一个 8 位数据线来保持显示的字形码。
优点:占用 CPU 时间少,显示便于监测和控制。
缺点:硬件电路比较复杂,成本较高。
动态显示
特点:将所有数码管的段选线并联在一起,由位选线控制是哪一位数码管有效

 

硬件电路图
c51单片机学习笔记一_第18张图片

 c51单片机学习笔记一_第19张图片

 

实现的功能: 控制静态数码管显示数字 0
原理:通过38译码器控制led8的位选线有效,P0口控制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};

void main()
{
    SMG_A_DP_PORT=gsmg_code[0];//将数组第 1 个数据赋值给数码管段选口
    while(1)
    {
    }
}
解析:首先将 51 单片机的头文件包含进来,然后定义一个全局数组变量 gsmg_code 存放共阴数码管 0-F 段码数据。主函数功能也很简单,首先将数组的第 1 个数据赋值给SMG_A_DP_PORT,因为数组内定义的是共阴数码管段码,数组角标为0存储的就是第一个数据0X3F。然后进入while
循环,单片机此时一直在 while 内循环操作。当然该条语句也可以放在 while 循环语句内,同样会让静态数码管显示 0。

动态数码管实验

多位数码管,即两个或两个以上单个数码管并列集中在一起形成一体的数码管。
当多位一体时,它们内部的公共端是独立的,而负责显示什么数字的段线 (a-dp)全部是连接在一起的,独立的公共端可以控制多位一体中的哪一位数码管点亮,而连接在一起的段线可以控制这个能点亮数码管亮什么数字。公共端叫做“位选线”,连接在一起的段线叫做“段选线”。
动态显示,就是利用减少段选线,分开位选线,利用位选线不同时选择通断,改变段选数据来实现的。 比如在第一次选中第一位数码管时,给段选数据 0, 下一次位选中第二位数码管时显示 1。为了在显示 1 的时候,0 不会消失(当然实际上是消失了),必须在人肉眼观察不到的时间里再次点亮第一次点亮的 0。 而这时就需要记住,人的肉眼正常情况下只能分辨变化超过 24ms 间隔的运动。 也就是说,在下一次点亮 0 这个数字的时间差不得大于 24ms。
74HC245 74HC138 芯片介绍

74HC245

IO 扩展芯片。只需要很少的单片机 IO 口就可以扩展出 8 个控制口,通过级联方式甚至可扩展出更多的控制口。

c51单片机学习笔记一_第20张图片

 

c51单片机学习笔记一_第21张图片

 c51单片机学习笔记一_第22张图片

 给 OE 使能管脚低电平,DIR 管脚为高电平传输方向是 A->B 输出,DIR 为低电平传输方向是 B->A,至于输出高电平还是输出低电平取决于输入端的状态,如果输入为低电平,输出即为低;输入为高电平,输出即为高。如果 OE 使能管脚为高电平,不论 DIR 管脚是高还是低,输出是高组态。

74H138

译码器芯片

只需单片机 3 个 IO 口就可以实现 8 个位选管脚的控制
c51单片机学习笔记一_第23张图片

 c51单片机学习笔记一_第24张图片

 c51单片机学习笔记一_第25张图片

 E1、E2 使能管脚低电平,E3 管脚为高电平,至于哪个管脚输出有效电平(低电平),要看 A0,A1,A2 输入管脚的电平状态。如果 A0,A1,A2 都为低电平,则Y0 输出有效电平(低电平),其他管脚均输出高电平。如果 A0 为高电平,A1,A2 都为低电平,则 Y1 输出有效电平(低电平),其他管脚均输出高电平。

硬件电路图

c51单片机学习笔记一_第26张图片

c51单片机学习笔记一_第27张图片 

实现功能:控制动态数码管从左至右显示数字 0-7 

原理:通过控制38译码器选择哪一个led灯的位选线有效,p0端口控制led灯的段选线有效。动态扫描,利用二极管的余晖效应和人眼的识别呈现数字0-7.

代码:


#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};

void delay_10us(u16 ten_us)
{
    while(ten_us--);
}

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;//消音
    }
}

void main()
{
    while(1)
    {
    smg_display();
    }
}
解析:main.c 文件内代码非常少也很简单,首先将 51 单片机的头文件包含进来,
然后定义 38 译码器的控制引脚,并将共阴数码管 0-F 段码数据使用数组定义好。
主函数功能也很简单,直接进入 while 循环,在循环体内执行 smg_display()数
码管动态显示函数。该函数是根据动态数码管显示原理所编写,即选中所要显示
的那位数码管,然后发送在该位数码管上所要显示的段码数据,延时一定时间后
在将段选口清零即消隐(消除之前的显示),如此循环 8 次即可实现 8 位数码管
显示。
注:在动态扫描中要注意时间的控制,时间不要超过24ms.

总结

学习了单片机有关的基础知识,以及led,蜂鸣器,数码管等实验。

你可能感兴趣的:(单片机,学习,嵌入式硬件)