C51单片机学习笔记3

前言:

从前面的学习中,新增了定时器模块,现在有延时函数,数码管显示,按键检测(包括矩阵键盘和独立按键),定时器模块
定时器模块如下:

#include <REGX52.H>
//定时器0配置
void Timer0_Init(void)		//1毫秒@11.0592MHz
{
	TMOD &= 0xF0;			//设置定时器模式
	TMOD |= 0x01;			//设置定时器模式
	TL0 = 0x66;				//设置定时初始值
	TH0 = 0xFC;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
	ET0=1; 
	EA=1;
	PT0=0;
}
/*void Timer0_Routine() interrupt 1
{
	static unsigned int T0count; 
	TL0 = 0x66;
	TH0 = 0xFC;
	T0count++;
	if(T0count>=){   
		T0count=0;
		}
}
*/



//定时器1配置
void Timer1_Init(void)		//1毫秒@11.0592MHz
{
	TMOD &= 0x0F;			//设置定时器模式
	TMOD |= 0x10;			//设置定时器模式
	TL1 = 0x66;				//设置定时初始值
	TH1 = 0xFC;				//设置定时初始值
	TF1 = 0;				//清除TF1标志
	TR1 = 1;				//定时器1开始计时
	ET1=1; 
	EA=1;
	PT0=0;
}

/*
void Timer1_Routine() interrupt 3
{
	static unsigned int T1count;
	TL1 = 0x66;				
	TH1 = 0xFC;				
	T1count++;
	if(T1count>=){
		}
	}
*/

一.串口

1.串口介绍

串口是一种应用十分广泛的通讯接口,串口成本低、容易使用、通信线路简单,可实现两个设备的互相通信。
单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信,极大的扩展了单片机的应用范围,增强了单片机系统的硬件实力。
51单片机内部自带UART(Universal Asynchronous Receiver Transmitter,通用异步收发器),可实现单片机的串口通信。

2.硬件电路

简单双向串口通信有两根通信线(发送端TXD和接收端RXD)
TXD与RXD要交叉连接
当只需单向的数据传输时,可以直接一根通信线
当电平标准不一致时,需要加电平转换芯片
在这里插入图片描述

3.电平标准

电平标准是数据1和数据0的表达方式,是传输线缆中人为规定的电压与数据的对应关系,串口常用的电平标准有如下三种:

TTL电平:+5V表示1,0V表示0
RS232电平:-3 ~ -15V表示1,+3 ~ +15V表示0
RS485电平:两线压差+2 ~ +6V表示1,-2 ~ -6V表示0(差分信号)

4.接口及引脚定义

在这里插入图片描述

5.相关术语

全双工:通信双方可以在同一时刻互相传输数据
半双工:通信双方可以互相传输数据,但必须分时复用一根数据线
单工:通信只能有一方发送到另一方,不能反向传输

异步:通信双方各自约定通信速率
同步:通信双方靠一根时钟线来约定通信速率

总线:连接各个设备的数据传输线路(类似于一条马路,把路边各住户连接起来,使住户可以相互交流)

6.UART

STC89C52有1个UART
STC89C52的UART有四种工作模式:
模式0:同步移位寄存器
模式1:8位UART,波特率可变(常用)
模式2:9位UART,波特率固定
模式3:9位UART,波特率可变
在这里插入图片描述

7.串口参数及时序图

波特率:串口通信的速率(发送和接收各数据位的间隔时间)
检验位:用于数据验证
停止位:用于数据帧间隔
在这里插入图片描述

8.串口模式图

在这里插入图片描述

SBUF:串口数据缓存寄存器,物理上是两个独立的寄存器,但占用相同的地址。写操作时,写入的是发送寄存器,读操作时,读出的是接收寄存器

9.串口相关寄存器

在这里插入图片描述

10.配置相关寄存器

void Uart1_Init(void)	//4800bps@11.0592MHz
{
	PCON |= 0x80;		//使能波特率倍速位SMOD
	SCON = 0x40;		//8位数据,可变波特率
	TMOD &= 0x0F;		//设置定时器模式
	TMOD |= 0x20;		//设置定时器模式
	TL1 = 0xF4;			//设置定时初始值
	TH1 = 0xF4;			//设置定时重载值
	ET1 = 0;			//禁止定时器中断
	TR1 = 1;			//定时器1开始计时
}

可以在stc-isp中计算波特率,生成代码

void Uart1_SendByte(unsigned char Byte){
	SBUF=Byte;
	while(TI==0);
	TI=0;
}

通过串口发送完后TI自动置1,需要用软件复位
在循环中使用串口的时候,有可能会出现错误,解决方案是加一个延时函数

11.串口的模块化

把初始化和串口发送字符的函数放进模块即可

12.电脑通过串口控制单片机LED

1 串口初始化和发送的时候有差距,需要有中断,这需要将REN置0,并且加上中断相关的寄存器设置

void Uart1_Init(void)	
{
	PCON |= 0x80;		//使能波特率倍速位SMOD
	SCON = 0x50;		//8位数据,可变波特率
	TMOD &= 0x0F;		//设置定时器模式
	TMOD |= 0x20;		//设置定时器模式
	TL1 = 0xF4;			//设置定时初始值
	TH1 = 0xF4;			//设置定时重载值
	ET1 = 0;			//禁止定时器中断
	TR1 = 1;			//定时器1开始计时
	EA=1;
	ES=1;
}

并且定义中断函数

void Uart_Routine() interrupt 4
{
	// EI与RI占用同一个通道,发送和接受都会触发这个中断函数,因此需要此判断
	if(RI==1){
		P2=~SBUF;
		RI=0;
	}

}

在这里插入图片描述
在中断函数中加入Uart1_SendByte函数即可向电脑返回数据

13.波特率的计算

在这里插入图片描述
在这里插入图片描述

定时器溢出率= 定时器时钟频率 / (12 × (2^SM1) × (256 - TL1))
在STC89C52RC中
溢出率=11.0592/(12*(2^0)*(256-0xF4))=0.0768
SMOD=1
波特率=溢出率/16=0.0048MHz=4800Hz

14.数据显示模式

HEX模式/十六进制模式/二进制模式:以原始数据的形式显示
文本模式/字符模式:以原始数据编码(ASCLL码)后的形式显示

二.点阵屏

1.介绍

LED点阵屏由若干个独立的LED组成,LED以矩阵的形式排列,以灯珠亮灭来显示文字、图片、视频等。LED点阵屏广泛应用于各种公共场合,如汽车报站器、广告屏以及公告牌等

LED点阵屏分类

按颜色:单色、双色、全彩
按像素:8*8、16*16等(大规模的LED点阵通常由很多个小点阵拼接而成)

2.点阵屏的显示原理

LED点阵屏的结构类似于数码管,只不过是数码管把每一列的像素以“8”字型排列而已
LED点阵屏与数码管一样,有共阴和共阳两种接法,不同的接法对应的电路结构不同
LED点阵屏需要进行逐行或逐列扫描,才能使所有LED同时显示
在这里插入图片描述
单色(引脚乱序排序):
在这里插入图片描述
双色:
在这里插入图片描述

3.74HC595

74HC595是串行输入并行输出的移位寄存器,可用3根线输入串行数据,8根线输出并行数据,多片级联后,可输出16位、24位、32位等,常用于IO口扩展
其对应原理图如下:
在这里插入图片描述

扩展出D0~D7口,而后开发板点阵屏引脚对应关系如下:
在这里插入图片描述

4.C51的sfr、sbit

sfr(special function register):特殊功能寄存器声明
例:sfr P0 = 0x80;
声明P0口寄存器,物理地址为0x80
sbit(special bit):特殊位声明
例:sbit P0_1 = 0x81; 或 sbit P0_1 = P0^1;
声明P0寄存器的第1位
可位寻址/不可位寻址:在单片机系统中,操作任意寄存器或者某一位的数据时,必须给出其物理地址,又因为一个寄存器里有8位,所以位的数量是寄存器数量的8倍,单片机无法对所有位进行编码,故每8个寄存器中,只有一个是可以位寻址的。对不可位寻址的寄存器,若要只操作其中一位而不影响其它位时,可用“&=”、“|=”、“^=”的方法进行位操作

5.LED点阵屏显示图形

首先定义74HC595的函数

void _74HC595_WriteByte(unsigned char Byte)
{
	unsigned char i;
	for(i=0;i<8;i++){
		SER_=Byte&(0x80>>i);  //读位
		SRCLK_=1;  //移位
		SRCLK_=0;
	}
	RCLK_=1;  //锁存
	RCLK_=0;
}

然后在主函数中要提前将SRCLK_,RCLK_置零
点阵屏显示函数

void MatrixLED_ShowColumn(unsigned char column,Data){
	_74HC595_WriteByte(Data);
	P0=~(0x80>>column);
}

其中74HC595控制显示每一列的LED,P0口控制显示的列
同数码管一样,点阵屏也需要消影,否则会影响旁边LED的显示
在原基础上加

	Delay(1);
	MATRIX_LED_PORT=0xFF;

6.用动画显示Hello!

#include <REGX52.H>
#include "Delay.h"
#include "MatrixLED.h"
#include "Timer.h"

unsigned char code Animation[]={  //用code可以减少占用内存,但不可更改
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  //防止影响观感
	0xFF,0x08,0x08,0xFF,0x00,0x0E,0x15,0x15,
	0x15,0x09,0x00,0xFE,0x01,0x01,0x02,0x00,
	0xFE,0x01,0x01,0x02,0x00,0x00,0x0E,0x11,
	0x11,0x11,0x0E,0x00,0xFD,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  //防止影响观感
};

unsigned char i,offset;
void main(){
	Matrix_Init();
	Timer0_Init();
	while(1){
		for(i=0;i<8;i++){
			MatrixLED_Show(i,Animation[i+offset]);
		}

	}
}

void Timer0_Routine() interrupt 1
{
	static unsigned int T0count; 
	TL0 = 0x66;
	TH0 = 0xFC;
	T0count++;
	if(T0count>=100){   
		T0count=0;
		offset++;
		if(offset>40)
			offset=0;
		}
}

三.DS1302时钟

1.介绍

DS1302是由美国DALLAS公司推出的具有涓细电流充电能力的低功耗实时时钟芯片。它可以对年、月、日、周、时、分、秒进行计时,且具有闰年补偿等多种功能
RTC(Real Time Clock):实时时钟,是一种集成电路,通常称为时钟芯片

优点:

相较于定时器,DS1302可以在断电的时候也能在后台工作,重新启动时可以正确显示时间,不会像定时器那样占用CPU
(可惜的是,此开发板并未接备用电池,没有掉电运行的功能)

2.引脚定义及应用电路

在这里插入图片描述

引脚名作用
VCC2主电源
VCC1备用电池
GND电源地
X1、X232.768KHz晶振
CE芯片使能
IO数据输入/输出
SCLK串行时钟

3.内部结构框图

在这里插入图片描述

4.寄存器定义

在这里插入图片描述

5.时序定义

在这里插入图片描述

6.BCD码

BCD码(Binary Coded Decimal‎),用4位二进制数来表示1位十进制数

例:0001 0011表示13,1000 0101表示85,0001 1010不合法

在十六进制中的体现:0x13表示13,0x85表示85,0x1A不合法

BCD码转十进制:DEC=BCD/16 * 10+BCD%16; (2位BCD)
十进制转BCD码:BCD=DEC/10 * 16+DEC%10; (2位BCD)
在DS1302中数据储存的形式是以BCD码储存的,因此需要对其进行运算转为十进制数,否则会显示错误

7.DS1302模块化

#include <REGX52.H>

sbit DS1302_SCLK=P3^6;
sbit DS1302_IO=P3^4;
sbit DS1302_CE=P3^5;

#define DS1302_SECOND		0x80
#define DS1302_MINUTE		0x82
#define DS1302_HOUR			0x84
#define DS1302_DATE			0x86
#define DS1302_MONTH		0x88
#define DS1302_YEAR			0x8C
#define DS1302_DAY			0x8A
#define DS1302_WP			0x8E

unsigned char DS1302_Time[]={23,12,12,19,28,55,2};
//年月日时分秒,星期,写保护
unsigned char DS1302_Parameter[]={DS1302_YEAR,DS1302_MONTH,DS1302_DATE,DS1302_HOUR,DS1302_MINUTE,DS1302_SECOND,DS1302_DAY,DS1302_WP};

/**
  * @brief DS1302初始化
  * @param 无
  * @retval 无
  */
void DS1302_Init(){DS1302_CE=0;DS1302_SCLK=0;}

/**
  * @brief 写入一个字节
  * @param Command 命令标识,用于判断写入的地址
		   Data 写入的字节
  * @retval 无
  */
void DS1302_WriteByte(unsigned char Command,unsigned char Data){
	unsigned char i;
	DS1302_CE=1;
	for(i=0;i<8;i++){
		DS1302_IO=Command&(0x01<<i);
		DS1302_SCLK=1;
		DS1302_SCLK=0;
	}
	for(i=0;i<8;i++){
		DS1302_IO=Data&(0x01<<i);
		DS1302_SCLK=1;
		DS1302_SCLK=0;
	}
	DS1302_CE=0;
}

/**
  * @brief 读取一个字节
  * @param Command命令标识
  * @retval 读取出的字节
  */
unsigned char DS1302_ReadByte(unsigned char Command){
	unsigned char i,Data=0x00;
	Command|=0x01;
	DS1302_CE=1;
	for(i=0;i<8;i++){
		DS1302_IO=Command&(0x01<<i);
		DS1302_SCLK=0;
		DS1302_SCLK=1;
	}
	for(i=0;i<8;i++){
		DS1302_SCLK=1;
		DS1302_SCLK=0;
		if(DS1302_IO){Data|=(0x01<<i);}
	}
	DS1302_CE=0;
	DS1302_IO=0;
	return Data;
}

/**
  * @brief	BCD码转换
	* @param	Mod 转为()进制 10为转换为十进制,16为转换为16进制
						Data 需要转换的数据
  * @retval	转换后的结果
  */
unsigned char BCD_Transform(unsigned char Mod,unsigned char Data){
	if(Mod==10){Data=Data/16*10+Data%16;}
	if(Mod==16){Data=Data/10*16+Data%10;}
	return Data;
}

/**
  * @brief 设置时间
  * @param 无
  * @retval 无
  */
void DS1302_SetTime(){
	unsigned char i;
	DS1302_WriteByte(DS1302_Parameter[7],0x00);
	for(i=0;i<7;i++){
		DS1302_WriteByte(DS1302_Parameter[i],BCD_Transform(16,DS1302_Time[i]));
	}
	DS1302_WriteByte(DS1302_Parameter[7],0x80);

}

/**
  * @brief 写入时间
  * @param 无
  * @retval 无
  */
void DS1302_ReadTime(){
	unsigned char i;
	for(i=0;i<7;i++){
		DS1302_Time[i]=BCD_Transform(10,DS1302_ReadByte(DS1302_Parameter[i]));
	}
}
  • 18
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值