嵌入式笔记--51单片机--江科大

1 单片机介绍

1.1 芯片名称

STC 89C52RC 40I-PDIP 0707
➢ STC: 公司名, AT(ATM), P(飞利浦), W(华邦), S(西门子), I(英特尔);
➢ 8: 80C51内核;
➢ 9: RAM型号, 9(Flash E2P-RAM), 0(Mark RAM), 7(EP-RAM);
➢ C: CMOS工艺, LV、 LE(低压产品), S(可串行化编程);
➢ 5: 固定;
➢ 2: 2X4KB, ROM;
➢ RC: 512B大小RAM, RD++(1080B);
➢ 40: 晶振频率40MHZ;
➢ I: I(工业级-40~85℃)、 C(商业级0~70℃)、 A(汽车-40~125℃)、 M(军品-55~150℃);
➢ PDIP: 封装形式, PDIP 双列直插式)、 PLCC(带引线的塑料封装)、 QFP/PFP(方形扁平式)、PGA(插针网格阵列)、 BGA(球栅阵列);
➢ 0707: 07年第07周;  

1.2 电平特性

➢ CMOS/TTL: 5V、 3.3V、 2.5V、 1.8V;
➢ STC89C52: TTL电平,高电平5V,低电平0V;
➢ RS-232: 计算机串口,高电平-12V,低电平12V;
➢ MAX232: 实现计算机串口电平与单片机电平转换;
➢ TTL特点: 使用最多, 对于电源要求不高、热损耗低; 直接与集成电路相连不需要价格昂贵的线路驱动; 能够实现数据高速传输; 但是并行数据传输不能超过10英尺,由于并行接口不对称对可靠性有影响;
➢ CMOS特点: 输入端不能悬空,会导致逻辑混乱;电源电压可在大范围变化,不如TTL严格;

1.3 芯片引脚

➢ 第一类:电源与时钟引脚 - VCC(40)、 GND(20)、 XTAL1(19)、 XTAL2(18);
➢ 第二类:编程控制引脚 – RST/VPD(9)、 𝑃𝑆𝐸𝑁(29)、 ATL/PROG(30)、 𝐸𝐴/𝑉𝑃𝑃(31);
➢ 第三类: IO引脚 – P1(1~8)、 P3(10~17)、 P2(21~28)、 P0(32~39);
➢ VCC、 GND: 外接电源,需要使用滤波器过滤信号;
➢ XTAL1、 XTAL2:时钟引脚,外部时钟, XTAL2接地, XTAL1接输入信号,片内振荡,XTAL1输入信号, XTAL2输出信号,外接 电容10~30PF,保证程序能够执行到下一行,外加电容是为了获得交流信号,使其起振;
➢ RST/VPD: 第一功能复位计数器PC=0000H,连续输入两个机器周期以上的高电平有效,第二功能提供临时高电平,备用电源,防止数据丢失;
➢ 𝑷𝑺𝑬𝑵: 程序存储器允许输出控制端,低电平有效,低电平读取外部ROM,一机器周期两个脉冲,与外部ROM的OE口相连;
➢ ATL/PROG: 扩展外部RAM时, ALE控制P0口的输出低8位地址送锁存器,低电平有效;PROG为编程脉冲的输入端 ;
➢ 𝑬𝑨/𝑽𝑷𝑷: 高电平先读内部,再读外部,低电平只读外部ROM;

1.4 最小系统

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iyNRKssl-1688306214837)(E:\Notes\1. 技术\1. STC89C52RC\images\最小系统.bmp)]

1.5 数据类型和头文件

➢ #include<reg52.h> 头文件比51多一个T2定时器;
➢ <regx52.h>头文件中也定义了特殊功能位 P1_0 = P1^0
➢ srf: 8位特殊功能寄存器声明;
➢ srf16: 16位特殊功能寄存器声明;
➢ sbit:特殊功能位声明;
➢ bit:位变量声明;
➢ short / unsigned short int 2;
➢ Int / unsigned int 2;
➢ long / unsigned long int 4;
➢ float 4 ;
➢ double 8;
➢ char / unsigned char 1;

2 点亮LED

2.1 LED结构原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mdqz1XeK-1688306214838)(E:\Notes\1. 技术\1. STC89C52RC\images\LED原理.bmp)]

2.1 代码实现

bsp_delay.h

#ifndef BSP_DELAY_H__
#define BSP_DELAY_H__
#include <REGX52.H>
#include <intrins.h>
/*延迟Xms*/
void Delay(unsigned int ms);
#endif

bsp_delay.c

#include "bsp_delay.h"

void Delay(unsigned int ms){
	unsigned char i, j;
	while(ms--){
		_nop_();
		i = 2;
		j = 199;
		do
		{
			while (--j);
		} while (--i);
	}
}

bsp_led.h

#ifndef BSP_LED_H__
#define BSP_LED_H__
#include <REGX52.H>
#include "bsp_delay.h"
#include <intrins.h>
/*引脚配置*/
#define LED_Port P2

/*点亮LED*/
#define LED_Pin_0  0xff   // 全部熄灭
#define LED_Pin_1  0xfe   // 点了第1个
#define LED_Pin_2  0xfd   // 点亮第2个
#define LED_Pin_3  0xfb	  // 点亮第3个
#define LED_Pin_4  0xf7   // 点亮第4个
#define LED_Pin_5  0xef   // 点了第5个
#define LED_Pin_6  0xdf   // 点亮第6个
#define LED_Pin_7  0xbf	  // 点亮第7个
#define LED_Pin_8  0x7f   // 点亮第8个
#define LED_Pin_9  0x00   // 全部点亮

/*点亮熄灭宏*/
#define ON  1
#define OFF 0
#define LED(X,LED_Pin)    if(X) \
								LED_Port = LED_Pin; \
						  else \
								LED_Port = 0xff;
/*实现流水灯*/
void LED_Water(void);
#endif

bsp_led.c

#include "bsp_led.h"
void LED_Water(void){
	LED_Port = LED_Pin_1;
	while(1){
		Delay(500);
		LED_Port = _crol_(LED_Port,1);
	}
}

main.c

#include <REGX52.H>
#include "bsp_led.h"

void main(void){
#if 0
	LED_Water();
#endif
	while(1){
		LED(ON,LED_Pin_1);
	}
}

3 独立按键

3.1 独立按键

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vAGsvqVE-1688306214838)(E:\Notes\1. 技术\1. STC89C52RC\images\独立按键原理.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IPKQuutZ-1688306214839)(E:\Notes\1. 技术\1. STC89C52RC\images\独立按键开发板.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fo7Hormr-1688306214839)(E:\Notes\1. 技术\1. STC89C52RC\images\按键消除抖动.bmp)]

3.2 代码实现

bsp_skey.h

#ifndef BSP_SKEY_H__
#define BSP_SKEY_H__
#include <REGX52.H>
#include "bsp_delay.h"

/*
	获取按键值,1、2、3、4
*/

unsigned char Key_Scan(void);
#endif

bsp_skey.c

#include "bsp_skey.h"

unsigned char Key_Scan(void){
	if(P3_1 == 0){
		Delay(20); // 消除抖动
		while(P3_1 == 0); // 保证到松开
		Delay(20); // 消除抖动
		return 1;
	}
	if(P3_0 == 0){
		Delay(20); 
		while(P3_0 == 0);
		Delay(20);
		return 2;
	}
	if(P3_2 == 0){
		Delay(20);
		while(P3_2 == 0);
		Delay(20); 
		return 3;
	}
	if(P3_3 == 0){
		Delay(20);
		while(P3_3 == 0);
		Delay(20); 
		return 4;
	}
	return 0;
}

main.c

#include <REGX52.H>
#include "bsp_led.h"
#include "bsp_skey.h"
#define uint8_t unsigned char

void main(void){
	/*
		按键点亮对于的灯
	*/
	uint8_t keyNum = 0;
	while(1){
		keyNum = Key_Scan();
		if(keyNum){
			LED(ON,_crol_(LED_Pin_1,keyNum - 1));
		}
	}
}

4 点亮数码管

4.1 数码管原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iF0voolz-1688306214839)(E:\Notes\1. 技术\1. STC89C52RC\images\数码管驱动方式.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oleAbQsP-1688306214840)(E:\Notes\1. 技术\1. STC89C52RC\images\数码管原理图1.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p25l8iaz-1688306214841)(E:\Notes\1. 技术\1. STC89C52RC\images\数码管原理图1.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fV5Y2x2h-1688306214841)(E:\Notes\1. 技术\1. STC89C52RC\images\点亮数码管TX.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KTqlhzDI-1688306214841)(E:\Notes\1. 技术\1. STC89C52RC\images\数码管动态显示TX.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TfzuI65l-1688306214842)(E:\Notes\1. 技术\1. STC89C52RC\images\数码管循环TX.bmp)]

4.2 代码实现

bsp_nixie.h

#ifndef BSP_NIXIE_H__
#define BSP_NIXIE_H__
#include <REGX52.H>
#include "bsp_delay.h"
#define A0 P2_2
#define A1 P2_3
#define A2 P2_4
#define NIXIE_PORT P0
static unsigned char code Nixie_Table[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
// 点了第x个数码管,显示y
void Nixie(unsigned char x,y);
#endif

bsp_nixie.c

#include "bsp_nixie.h"
extern unsigned char code Nixie_Table[10];
void Nixie(unsigned char x,y){
	// 先段选
	switch(x){
		case 8: A0 = 0; A1 = 0; A2 = 0; break;
		case 7: A0 = 1; A1 = 0; A2 = 0; break;
		case 6: A0 = 0; A1 = 1; A2 = 0; break;
		case 5: A0 = 1; A1 = 1; A2 = 0; break;
		case 4: A0 = 0; A1 = 0; A2 = 1; break;
		case 3: A0 = 1; A1 = 0; A2 = 1; break;
		case 2: A0 = 0; A1 = 1; A2 = 1; break;
		case 1: A0 = 1; A1 = 1; A2 = 1; break;
	}
	// 位选
	NIXIE_PORT = Nixie_Table[y];
	Delay(1); // 消影
	NIXIE_PORT = 0x00; // 显示一会再取消
}

main.c

#include <REGX52.H>
#include "bsp_led.h"
#include "bsp_skey.h"
#include "bsp_nixie.h"
#define uint8_t unsigned char

void main(void){
	/*
		点亮显示123
	*/
	while(1){
		Nixie(1,1);
		Nixie(2,2);
		Nixie(3,3);
	}
}

5 矩阵键盘

5.1 矩阵键盘原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3d0LDtAK-1688306214842)(E:\Notes\1. 技术\1. STC89C52RC\images\矩阵键盘原理图.bmp)]

5.2 代码实现

bsp_matrix.h

#ifndef BSP_MATRIX_H__
#define BSP_MATRIX_H__
#include <REGX52.H>
#include "bsp_delay.h"
// 扫描按键
unsigned char Matrix_Scan(void);
#endif

bsp_matrix.c

#include "bsp_matrix.h"
unsigned char Matrix_Scan(void){
	/*
		扫描矩阵键盘
		1. 先将一行置0;
		2. 再扫描当前行;
		3. 为0则按下;
	*/
	unsigned char KeyNum = 0;
	P1 = 0xff; 
	P1_7 = 0;
	if(P1_3 == 0){Delay(20); while(P1_3 == 0); Delay(20); KeyNum = 1;}
	if(P1_2 == 0){Delay(20); while(P1_2 == 0); Delay(20); KeyNum = 2;}
	if(P1_1 == 0){Delay(20); while(P1_1 == 0); Delay(20); KeyNum = 3;}
	if(P1_0 == 0){Delay(20); while(P1_0 == 0); Delay(20); KeyNum = 4;}
	P1 = 0xff; 
	P1_6 = 0;
	if(P1_3 == 0){Delay(20); while(P1_3 == 0); Delay(20); KeyNum = 5;}
	if(P1_2 == 0){Delay(20); while(P1_2 == 0); Delay(20); KeyNum = 6;}
	if(P1_1 == 0){Delay(20); while(P1_1 == 0); Delay(20); KeyNum = 7;}
	if(P1_0 == 0){Delay(20); while(P1_0 == 0); Delay(20); KeyNum = 8;}
	P1 = 0xff; 
	P1_5 = 0;
	if(P1_3 == 0){Delay(20); while(P1_3 == 0); Delay(20); KeyNum = 9;}
	if(P1_2 == 0){Delay(20); while(P1_2 == 0); Delay(20); KeyNum = 10;}
	if(P1_1 == 0){Delay(20); while(P1_1 == 0); Delay(20); KeyNum = 11;}
	if(P1_0 == 0){Delay(20); while(P1_0 == 0); Delay(20); KeyNum = 12;}
	P1 = 0xff; 
	P1_4 = 0;
	if(P1_3 == 0){Delay(20); while(P1_3 == 0); Delay(20); KeyNum = 13;}
	if(P1_2 == 0){Delay(20); while(P1_2 == 0); Delay(20); KeyNum = 14;}
	if(P1_1 == 0){Delay(20); while(P1_1 == 0); Delay(20); KeyNum = 15;}
	if(P1_0 == 0){Delay(20); while(P1_0 == 0); Delay(20); KeyNum = 16;}
	P1 = 0xff; 
	return KeyNum;
}

main.c

#include <REGX52.H>
#include "bsp_led.h"
#include "bsp_skey.h"
#include "bsp_nixie.h"
#include "bsp_matrix.h"
#define uint8_t unsigned char

void main(void){
	/*
		显示按键值
	*/
	unsigned char KeyNum = 0;
	unsigned char Num = 0;
	
	while(1){
		KeyNum = Matrix_Scan();
		if(KeyNum){
			Num = KeyNum;
		}
		Nixie(1,Num/10);
		Nixie(2,Num%10);
	}
}

6 LED点阵屏

6.1 LED点阵屏原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Kq4IAsiQ-1688306214842)(E:\Notes\1. 技术\1. STC89C52RC\images\点阵屏原理介绍.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Pr6d30Gm-1688306214843)(E:\Notes\1. 技术\1. STC89C52RC\images\点阵屏显示原理.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EgjJ6VZj-1688306214843)(E:\Notes\1. 技术\1. STC89C52RC\images\点阵屏显示原理1.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3zN3c9SO-1688306214843)(E:\Notes\1. 技术\1. STC89C52RC\images\74HC595原理.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uUNdVKuk-1688306214843)(E:\Notes\1. 技术\1. STC89C52RC\images\74HC595原理图.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8tLNFgPc-1688306214844)(E:\Notes\1. 技术\1. STC89C52RC\images\点阵屏显示原理1.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LSTzHmxb-1688306214844)(E:\Notes\1. 技术\1. STC89C52RC\images\取字模.bmp)]

6.2 代码实现

bsp_matrixled.h

#ifndef BSP_MATRIXLED_H__
#define BSP_MATRIXLED_H__
#include <REGX52.H>
#include "bsp_delay.h"
/*74HC595模块*/
// 引脚配置
#define HC595_SER    P3_4    // 串行输入
#define HC595_SRCLK  P3_6	 // 下降沿数据位移
#define HC595_RCLK   P3_5	 // 下降沿数据输出
// 写入数据
void HC595_WriteData(unsigned char Data);
/*点阵屏显示*/
void Matrix_ShowColumn(unsigned char Column,Data);
/*图像变换显示*/
static unsigned char code PictureTable[16] = {0x23,0x45,0x51,0x89,0x89,0x51,0x45,0x23,0x80,0x98,0xD4,0xF3,0xF3,0xD4,0x98,0x80};
void Matrix_LED(void);
#endif

bsp_matrixled.c

#include "bsp_matrixled.h"
extern unsigned char code PictureTable[16];
void HC595_WriteData(unsigned char Data){
	unsigned char i = 0;
	for(;i < 8;i++){
		HC595_SER = Data & (0x80 >> i); // 取第i位
		HC595_SRCLK = 1;
		HC595_SRCLK = 0;
	}
	HC595_RCLK = 1;
	HC595_RCLK = 0;
}
void Matrix_ShowColumn(unsigned char Column,Data){
	HC595_WriteData(Data);
	P0 = ~(0x80 >> Column);
	Delay(1); // 消除闪烁
	P0 = 0xff;
}

void Matrix_LED(void){
	unsigned char Data = 0;
	unsigned char Column = 0;
	unsigned char i = 0;
	while(1){
		for(Column = 0;Column < 8;Column++){
			Matrix_ShowColumn(Column,PictureTable[Data + Column]);
		}
		Delay(500);
		Data = (Data + 8) % 16;
	}
}

main.c

#include <REGX52.H>
#include "bsp_led.h"
#include "bsp_skey.h"
#include "bsp_nixie.h"
#include "bsp_matrix.h"
#include "bsp_matrixled.h"
#define uint8_t unsigned char

void main(void){
	/*
		点阵屏动态显示
	*/
	Matrix_LED();
}

7 LCD1602

7.1 LCD1602原理

  • LCD1602:字符型液晶显示器,可以显示ASCII码以及内置特殊字符。
  • 显示容量:16 x 2,每个字符是5 x 7点阵。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1LkJasgU-1688306214844)(E:\Notes\1. 技术\1. STC89C52RC\images\LCD1602原理图.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kQtOhZQG-1688306214845)(E:\Notes\1. 技术\1. STC89C52RC\images\LCD1602内部框图.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K1H9an6s-1688306214845)(E:\Notes\1. 技术\1. STC89C52RC\images\LCD1602存储器结构.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9gxlH7QL-1688306214845)(E:\Notes\1. 技术\1. STC89C52RC\images\LCD1602时序图.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qWxDkq0v-1688306214845)(E:\Notes\1. 技术\1. STC89C52RC\images\LCD1602指令集.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RQmEIPDc-1688306214845)(E:\Notes\1. 技术\1. STC89C52RC\images\LCD1602操作顺序.bmp)]

7.2 代码实现

bsp_lcd1602.h

#ifndef BSP_LCD1602_H__
#define BSP_LCD1602_H__
#include <REGX52.H>
#include "bsp_delay.h"

// 引脚配置
#define LCD1602_RS			P2_6
#define LCD1602_RW			P2_5
#define LCD1602_EN			P2_7
#define LCD1602_DataPort  	P0

// 写指令
void LCD1602_WriteCommand(unsigned char Command);
// 写数据
void LCD1602_WriteData(unsigned char Data);
// 初始化
void LCD1602_Init(void);
// 设置地址
void LCD1602_SetAddress(unsigned char Line,Column);
// 显示字符
void LCD1602_ShowChar(unsigned char Line,Column,Char);
// 显示字符串
void LCD1602_ShowString(unsigned char Line,Column,char String[]);
// 显示数字
void LCD1602_ShowNum(unsigned char Line,Column,unsigned int Num,unsigned char Len);
// 显示有符号数
void LCD1602_ShowSignedNum(unsigned char Line,Column,int Num,unsigned char Len);
// 显示二进制数字
void LCD1602_ShowBinNum(unsigned char Line,Column,unsigned int Num,unsigned char Len);
#endif

bsp_lcd1602.c

#include "bsp_lcd1602.h"

// 写指令
void LCD1602_WriteCommand(unsigned char Command){
	LCD1602_RS = 0;   // 1 数据 0 指令
	LCD1602_RW = 0;	  // 1 读   0 写
	LCD1602_DataPort = Command; // 将指令放在数据结口
	LCD1602_EN = 1;   // 高电平使能
	Delay(1);		  // 延迟1ms,需要一定时间
	LCD1602_EN = 0;	  // 下降延写入数据
	Delay(1);
}
// 写数据
void LCD1602_WriteData(unsigned char Data){
	LCD1602_RS = 1;
	LCD1602_RW = 0;
	LCD1602_DataPort = Data;
	LCD1602_EN = 1;
	Delay(1);
	LCD1602_EN = 0;
	Delay(1);
}
// 初始化
void LCD1602_Init(void){
	LCD1602_WriteCommand(0x38);   // 8位数据线,两行显示,5*7字符
	LCD1602_WriteCommand(0x0c);	  // 显示打开,光标关闭,闪烁关闭
	LCD1602_WriteCommand(0x06);	  // 数据输入和输出AC都会自加1,画面不动
	LCD1602_WriteCommand(0x00);	  // 清屏
}
// 设置地址
void LCD1602_SetAddress(unsigned char Line,Column){
	// 设置地址时,最高位需要为1
	if(Line == 1){
		LCD1602_WriteCommand(0x80 | (Column - 1 + 0x00)); // 0x00 将其最高行为1 
	}else if(Line == 2){
		LCD1602_WriteCommand(0x80 | (Column - 1 + 0x40)); // 0x40
	}
}
// 显示字符
void LCD1602_ShowChar(unsigned char Line,Column,Char){
	// 写地址
	LCD1602_SetAddress(Line,Column);
	// 写数据
	LCD1602_WriteData(Char);
}
// 显示字符串
void LCD1602_ShowString(unsigned char Line,Column,char String[]){
	unsigned char i = 0;
	LCD1602_SetAddress(Line,Column);
	for(;String[i] != '\0';i++){
		LCD1602_WriteData(String[i]);
	}
}
// 显示数字
int LCD1602_Pow(int x,y){
	// 获取X的Y次方
	unsigned char i = 0;
	int ret = 1;
	for(i = 0;i < y;i++){
		ret *= x;
	} 
	return ret;
}
void LCD1602_ShowNum(unsigned char Line,Column,unsigned int Num,unsigned char Len){
	unsigned char i = 0;
	LCD1602_SetAddress(Line,Column);
	for(i = Len;i > 0;i--){
		// 从最高位写到最低位
		LCD1602_WriteData(Num/LCD1602_Pow(10,i-1)%10 + '0');
	}
}
// 显示有符号数
void LCD1602_ShowSignedNum(unsigned char Line,Column,int Num,unsigned char Len){
	unsigned char i = 0;
	LCD1602_SetAddress(Line,Column);
	if(Num > 0){
		LCD1602_WriteData('+');
	}else if(Num < 0){
		LCD1602_WriteData('-');
		Num = -Num;
	}
	for(i = Len;i > 0;i--){
		LCD1602_WriteData(Num/LCD1602_Pow(10,i-1)%10 + '0');
	}
}
// 显示二进制数字
void LCD1602_ShowBinNum(unsigned char Line,Column,unsigned int Num,unsigned char Len){
	unsigned char i = 0;
	LCD1602_SetAddress(Line,Column);
	for(i = Len;i > 0; i-- ){
		LCD1602_WriteData(Num/LCD1602_Pow(2,i-1)%2 + '0');
	}
}

main.c

#include <REGX52.H>
#include "bsp_led.h"
#include "bsp_skey.h"
#include "bsp_nixie.h"
#include "bsp_matrix.h"
#include "bsp_matrixled.h"
#include "bsp_lcd1602.h"
#define uint8_t unsigned char

void main(void){
	LCD1602_Init();
	while(1){
		LCD1602_ShowChar(1,1,'A');
		LCD1602_ShowNum(1,2,123,3);
		LCD1602_ShowSignedNum(2,8,-666,3);
		LCD1602_ShowString(2,1,"hello");
		LCD1602_ShowBinNum(1,7,11,4);
	}
}

8 蜂鸣器

8.1 蜂鸣器原理

8.2 代码实现

9 定时器

9.1 定时器原理

  • 定时器:内部资源,T0、T1、T2三个定时器资源,其中T2为新增,主要用途定时或者延时。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WhKBoiW7-1688306214846)(E:\Notes\1. 技术\1. STC89C52RC\images\定时器框图.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I6V8TSWu-1688306214846)(E:\Notes\1. 技术\1. STC89C52RC\images\中断资源原理.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-86JOBY3a-1688306214846)(E:\Notes\1. 技术\1. STC89C52RC\images\中断优先级.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JmNjrzEJ-1688306214846)(E:\Notes\1. 技术\1. STC89C52RC\images\中断寄存器.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cgcDyztx-1688306214846)(E:\Notes\1. 技术\1. STC89C52RC\images\中断TMOD.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LPqFy8Yi-1688306214847)(E:\Notes\1. 技术\1. STC89C52RC\images\中断TCON.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zu8pXuKR-1688306214847)(E:\Notes\1. 技术\1. STC89C52RC\images\中断IE.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PVncERdr-1688306214847)(E:\Notes\1. 技术\1. STC89C52RC\images\中断IP.bmp)]

9.2 代码实现

9.2.1 LED闪烁

bsp_timer0.h

#ifndef BSP_TIMER0_H__
#define BSP_TIMER0_H__
#include <REGX52.H>
void Timer0_Init(void);
#endif

bps_timer0.c

#include "bsp_timer0.h"

void Timer0_Init(void){
	// 设置TMOD寄存器,16位计数器模式
	TMOD &= 0xf0; // 后四位清零
	TMOD |= 0x01; // 设置模式1
	// 设置计数大小
	TL0 = 0x66;		//设置定时初始值
	TH0 = 0xFC;		//设置定时初始值
	// 设置TCON寄存器
	TF0 = 0;
	// 打开TR0
	TR0 = 1;
	// 设置IE寄存器
	ET0 = 1;
	EA = 1;
	// 设置优先级
	PT0 = 1;
}

#if 0
void Timer0_Rountine(void) interrupt 1{
	static unsigned int i = 0;
	// 重置技术单元
	TH0 = 64536 /256; // 1000us
	TL0 = 64536 % 256 + 1;
	i++;
	if(i >= 500){
		// 500ms后翻转第一个灯
		P2_0 = ~P2_0;
		// 重置i
		i = 0;
	}
}
#endif

main.c

#include <REGX52.H>
#include "bsp_timer0.h"

void main(void){
	Timer0_Init();
	while(1){
		
	}
}

void Timer0_Rountine(void) interrupt 1{
	static unsigned int i = 0;
	// 重置技术单元
	TH0 = 64536 /256;
	TL0 = 64536 % 256 + 1;
	i++;
	if(i >= 500){
		// 500ms后翻转第一个灯
		P2_0 = ~P2_0;
		// 重置i
		i = 0;
	}
}
9.2.2 按键切换LED模式

main.c

#include <REGX52.H>
#include "bsp_skey.h"
#include "bsp_timer0.h"
#include <intrins.h>
static unsigned char mode = 0;
void main(void){
	unsigned char KeyNum = 0;
	Timer0_Init();
	P2 = 0xfe;
	while(1){
		KeyNum = Key_Scan();
		if(KeyNum){
			if(KeyNum == 1){ // 加1
				mode = (mode + 1) %2;
			}else if(KeyNum == 2){
				if(mode == 0){
					mode = 1;
				}else{
					mode --;
				}
			}
		}
	}
}

void Timer0_Rountine(void) interrupt 1{
	static unsigned int i = 0;
	// 重置技术单元
	TH0 = 64536 /256;
	TL0 = 64536 % 256 + 1;
	i++;
	if(i >= 1000){
		if(mode == 0){
			P2 = _crol_(P2,1); // 左移
		}else if(mode == 1){
			P2 = _cror_(P2,1); // 右移
		}
		i= 0;
	}
}
9.2.3 显示时分秒

main.c

#include <REGX52.H>
#include "LCD1602.h"
#include "bsp_timer0.h"

unsigned int Sec = 0;
unsigned int Minute = 0;
unsigned int Hour = 0;

void main(void){
	Timer0_Init();
	LCD_Init();
	while(1){
		LCD1602_ShowString(1,1,"Time: ");
		LCD1602_ShowNum(2,1,Hour,2);
		LCD1602_ShowChar(2,3,' ');
		LCD1602_ShowNum(2,4,Minute,2);
		LCD1602_ShowChar(2,6,' ');
		LCD1602_ShowNum(2,7,Sec,2);
	}
}

void Timer0_Rountine(void) interrupt 1{
	static unsigned int i = 0;
	// 重置技术单元
	TL0 = 0x66;		//设置定时初始值
	TH0 = 0xFC;		//设置定时初始值
	i++;
	if(i >= 1000){
		i= 0;
		Sec++;
		if(Sec >= 60){
			Sec = 0;
			Minute ++;
			if(Minute >= 60){
				Minute = 0;
				Hour ++;
				if(Hour >= 24){
					Hour = 0;
				}
			}
		}
	}
}

10 UART串口

10.1 UART串口原理

  • **UART:**通用异步收发器,两根通信线TXD、RXD交叉接线,电平不一致时加电平转换芯片。
  • **TTL电平:**0v – 0,5v – 1。
  • RS232电平:-3v~-15v – 1,3v~15v – 0。
  • **RS485电平:**两线压差,传输更远。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HwzIo7Uh-1688306214847)(E:\Notes\1. 技术\1. STC89C52RC\images\串口分类.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q7hLTGvW-1688306214847)(E:\Notes\1. 技术\1. STC89C52RC\images\通信术语.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i3PL8Bgo-1688306214848)(E:\Notes\1. 技术\1. STC89C52RC\images\UART原理图.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-avDGF29K-1688306214848)(E:\Notes\1. 技术\1. STC89C52RC\images\UART内部框图.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r8iPUwX6-1688306214848)(E:\Notes\1. 技术\1. STC89C52RC\images\UART相关寄存器.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cRIHHa8v-1688306214848)(E:\Notes\1. 技术\1. STC89C52RC\images\UART相关寄存器1.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7wTdPH32-1688306214848)(E:\Notes\1. 技术\1. STC89C52RC\images\UART相关寄存器2.bmp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3WG1DWzS-1688306214848)(E:\Notes\1. 技术\1. STC89C52RC\images\波特率计算.bmp)]

10.2 代码实现

bsp_uart.h

#ifndef BSP_UART_H__
#define BSP_UART_H__
#include <REGX52.H>
void UART_Init(void);
void UART_SendByte(unsigned char Byte);
#endif

bsp_uart.c

#include "bsp_uart.h"

void UART_Init(void){
	// 设置8位重装模式
	TMOD &= 0x0f;
	TMOD |= 0x20;
	// 设置RS的相关寄存器
	PCON &= 0x7f; // 将SMOD清零波特率不加倍
	SCON = 0x50;  // REN = 1 SM0 = 0 SM1 = 1 
	// 设置计数单元
	TH1 = 0xfd;
	TL1 = 0xfd;
	// 关闭ET1中断
	ET1 = 0;
	TR1 = 1;
	// 打开串行中断
	EA = 1;
	ES = 1;
}

// 写
void UART_SendByte(unsigned char Byte){
	SBUF = Byte;
	while(TI == 0); // 发送时会产生TI中断标志
	TI = 0;    	// 最后将TI清零
}

// 中断
/*
void UART_Rountine(void) interrupt 4{  // 输入数据点亮LED
	if(RI == 1){
		// 开始接受
		P2 = SBUF; // led的值为SUBF
		UART_SendByte(SBUF); // 发送到接受端
		RI = 0; // 清零RI
	}
}
*/

main.c

#include <REGX52.H>
#include "bsp_lcd1602.h"
#include "bsp_uart.h"

void main(void){
	UART_Init();
	while(1){
		
	}
}

void UART_Rountine(void) interrupt 4{
	if(RI == 1){
		// 开始接受
		P2 = SBUF; // led的值为SUBF
		UART_SendByte(SBUF); // 发送到接受端
		RI = 0; // 清零RI
	}
}

11 DS1302时钟

11.1 DS1302时钟原理

11.2 代码实现

12 AT20C02存储器

12.1 AT20C02存储器

12.2 代码实现

13 DS18B20传感器

13.1 DS18B20传感器原理

13.2 代码实现

14 PWM驱动电机

14.1 PWM驱动电机原理

14.2 代码实现

15 数模转换

15.1 数模转换原理

15.2 代码实现

16 红外遥控

16.1 红外遥控原理

16.2 代码实现

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
普中51单片机A2开发板是一款智能控制开发板,采用51单片机作为控制核心。该开发板具有丰富的接口资源和强大的功能,适用于物联网、智能家居、机器人等多种应用场景。 该开发板的资料包括以下主要内容: 1. 主板设计资料:包括电路原理图、PCB设计文件、材料清单等。主板设计资料详细描述了开发板的硬件电路设计,包括各个接口的连接方式、电源部分设计等。这些资料对于理解开发板的硬件工作原理非常重要。 2. 软件开发资料:包括51单片机的开发环境、编程工具和普中提供的代码库等。开发环境通常包括集成开发环境(IDE)和编译器等,用于编写、调试、烧录代码。普中还提供了丰富的代码库,包含各种功能的例程,如LED控制、串口通信、温度传感器读取等。 3. 使用手册:详细介绍了开发板的功能、使用方法和注意事项等。手册中包括硬件连接示意图、软件调试步骤以及常见问题解答等内容,帮助用户快速上手和解决问题。 4. 实验教程:提供一系列实验教程,引导用户逐步学习开发板的各种功能和应用。实验教程通常包括实验目的、实验原理、实验步骤和实验结果等内容,用户可以跟随实验教程一步一步掌握开发板的使用。 通过阅读这些资料例程,用户可以了解开发板的硬件设计和软件开发过程,掌握开发板的各种功能和应用,进而进行自己的项目开发。同时,普中还提供了技术支持平台,用户可以在平台上提问和交流,获得更详细的技术指导和帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值