沉浸式学习51单片机(5)--单片机定时器与串口通信

一.作者小课堂

(一)蜂鸣器介绍

1.简介

蜂鸣器是一种一体化结构的电子讯响器,它采用直流电压供电,被广泛应用于各种电子产品中,如计算机、打印机、复印机、报警器、电子玩具、汽车电子设备、电话机和定时器等,作为发声器件。

2.分类

蜂鸣器主要分为压电式蜂鸣器电磁式蜂鸣器两种类型。压电式蜂鸣器主要由多谐振荡器、压电蜂鸣片、阻抗匹配器及共鸣箱、外壳等组成。当接通电源后,多谐振荡器起振,输出音频信号,阻抗匹配器推动压电蜂鸣片发声。压电蜂鸣片通常由锆钛酸铅或铌镁酸铅压电陶瓷材料制成,两面镀有银电极,并与黄铜片或不锈钢片粘合。

3.组成

电磁式蜂鸣器则由振荡器、电磁线圈、磁铁、振动膜片及外壳等组成。当振荡器产生的音频信号电流通过电磁线圈时,会产生磁场,使振动膜片在电磁线圈和磁铁的相互作用下周期性地振动发声。

4.工作原理

蜂鸣器的工作原理主要基于压电效应或电磁效应。其详细介绍如下:

  • 压电式蜂鸣器。主要由压电陶瓷片和金属片组成,当压电陶瓷片两端施加电压时,由于逆压电效应,陶瓷片会产生机械变形,进而带动金属片振动发出声音。压电式蜂鸣器的结构简单、体积小巧、功耗低。
  • 电磁式蜂鸣器。由振荡器、电磁线圈、磁铁和振动膜片等组成,当电流通过电磁线圈时,会产生磁场,振动膜片在磁铁的相互作用下周期性地振动发声。

此外,蜂鸣器还有有源蜂鸣器和无源蜂鸣器之分,有源蜂鸣器内部集成有振荡电路,可以持续发出声音,而无源蜂鸣器则需要外部振荡电路才能连续发声。

(二)数码管介绍

数码管是一种由多个发光二极管(LED)组成的显示设备,这些LED通常以七段或八段的形式排列,用于显示数字、字母、符号等信息。

1.数码管的种类包括:

①LED数码管。这是最常见的类型,由多个并联的LED组成,可以是共阳或共阴结构,即所有LED的阳极或阴极连接在一起,其他端分别连接到相应的显示数据信号。
②辉光管(Nixie tube)。这是一种较老的数码管技术,使用玻璃管和内部充填的气体来显示数字和字母,它们通常包含多个阴极,每个阴极代表一个数字或字母,通过给特定的阴极施加电压来显示相应的数字或字母。

2.数码管的应用:

数码管广泛应用于各种电子设备中,如手表、计算器、家用电器、汽车仪表盘等,它们可以显示数字、字母、符号,甚至可以播放视频和动画。随着技术的发展,数码管的设计和功能也在不断进步,例如,通过使用更高亮度的LED和使用更先进的驱动技术,可以提高数码管的显示效果和可靠性。

(三)LCD介绍

液晶显示屏(LCD,Liquid Crystal Display)是一种平面显示器技术,具有多种优点,包括低耗电量、体积小、辐射低,因此被广泛应用于电视机、计算机等电子产品中。LCD的工作原理是利用液晶分子的电光效应,在电场的作用下改变液晶分子的排列,从而影响光线的通过,显示出不同的图像。

1.LCD的结构

LCD的结构主要包括两片平行的玻璃基板,中间填充有液态晶体。这两片玻璃基板上印有电极和过滤器,用以控制光线的通过。与传统的CRT显示器相比,LCD具有更小的体积、更薄的厚度、更低的功耗和没有辐射的特点。

2.LCD的局限性

然而,LCD也有其局限性,如需要背光源来发光,在强光下可能难以看清屏幕。此外,LCD的响应速度相对较慢,这限制了其在高速动态图像显示中的应用。
为了改进这些缺点,研究人员开发出了TFT-LCD(薄膜晶体管液晶显示器),它通过改进背光技术和提高液晶分子的响应速度,显著提高了LCD的性能。

二.实践出真知

(一)驱动蜂鸣器鸣叫

1.实验要求

利用T1的中断控制P1.7引脚输出频率为1kHz方波音频信号,驱动蜂鸣器发声。系统时钟为12MHz。方波音频信号周期1ms,因此T1的定时中断时间为0.5 ms,进入中断服务程序后,对P1.7求反。
先计算T1初值,系统时钟为12MHz,则机器周期为1µs。1kHz音频信号周期为1ms,要定时计数的脉冲数为a。则T1初值:

      TH1=(65 536 −a) /256;	
      TL1=(65 536 −a) %256

2.代码

#include<reg51.h>  			//包含头文件
sbit sound=P1^7;  			//将sound位定义为P1.7脚
#define f1(a) (65536-a)/256		//定义装入定时器高8位时间常数
#define f2(a) (65536-a)%256    		//定义装入定时器低8位时间常数
unsigned int i=500; 
unsigned int j=0; 
void main(void)
{
	 	EA=1;                  		//开总中断.
  		ET1=1;                		//允许定时器T1中断         .
   		TMOD=0x10; 			//TMOD=0001 000B,使用T1的方式1定时    	TH1=f1(i);      			//给T1高8位赋初值.
   		TL1=f2(i);      			//给T1低8位赋初值.
   		TR1=1;                 		//启动T1
   		while(1)  
{              				//循环等待
     	i=460; 
      	while(j<2000);
      	j=0;
      	i=360; 
      	while(j<2000);
      	j=0;
    }
 }
 
void T1(void) interrupt 3 using 0	//定时器T1中断函数
{
    	TR1= 0;                 	//关闭T1
   	sound=~sound; 			//P1.7输出求反
    	TH1=f1(i);   			//T1的高8位重新赋初值.
    	TL1=f2(i);   			//T1的低8位重新赋初值.
j++;				
    	TR1=1;                 	//启动定时器T1
}

3.实验结果

(二)LED数码管秒表的制作

1.实验要求

用2位数码管显示计时时间,最小计时单位为“百毫秒”,计时范围0.1~9.9s。当第1次按一下计时功能键时,秒表开始计时并显示;第2次按一下计时功能键时,停止计时,将计时的时间值送到数码管显示;如果计时到9.9s,将重新开始从0计时;第3次按一下计时功能键,秒表清0。再次按一下计时功能键,则重复上述计时过程。

2.代码

#include<reg51.h>
typedef unsigned int uint;	 //定义无符号整形和字符型
typedef unsigned char uchar;
 
uchar led[] ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar led1[] = {0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
uchar second; //秒数
uchar key; //按键次数
uint t; //用来计数,每500,代表0.1s
 
sbit keyif = P3^7;	//按键接口
void delay(){ //延时函数,用于消除抖动
	uchar i,j;
	for(i=0;i<255;i++){
		for(j=0;j<100;j++);
	}
}
 
void init(void) //初始化
{
	TMOD = 0x01;  //0000 0010 使用方式二
	second = 0; //秒数初始化为0
	EA = 1;	 //总中断,定时器0中断允许
	ET0 = 1;  //允许定时器0中断
	key = 0; //按键次数初始化为0
	t = 0; //计数初始化为0
}
 
void main(){
	init();
	P0 = led1[second/10];
	P2 = led[second%10];
	while(1){
		if(keyif == 0){
			delay();//消除抖动	 
			if(keyif == 0){		  
				key++;
			switch(key){
				   case 1: //按一次,计时器开始
				   		TH0 =  0xee;
						TL0 = 0x00;
						TR0 = 1;			   		
				   		break;
				   case 2:	//按两次,暂停定时器
				   		t = 0; 
				   		TR0 = 0;
				   		break;
				   case 3: //按三次,停止计时,数据清零
				   		key = 0;
						second = 0;
						P0 = led1[0];
						P2 = led[0];
				   		break;
					}
				while(keyif == 0);  //若一直按下,使其停留			
			}
		}
	}
}
 
void timer() interrupt 1
{
	TR0 = 0; //停止计时
	t++;
	if(t ==20){
		second++;
		P0 = led1[second/10];
		P2 = led[second%10];
		t = 0;
	}
	if(second == 99){ //当计数到9.9秒,重新开始计时
		second = 0;
		key = 2; //相当于重新开始计时
	}
	TR0 = 1; //继续启动计时器		
}

3.实验结果

(三)使用定时器实现一个LCD显示时钟

1.实验要求

使用定时器实现一个LCD显示时钟。采用LCD1602.最小计时单位是秒,如何获得1s的定时?可将T0定时时间定为50ms,采用中断方式进行溢出次数累计,满20次,则秒计数变量second加1;若秒计满60,则分计数变量minute加1,同时将秒计数变量second清0;若分钟计满60,则小时计数变量hour加1;若小时计数变量满24,则将小时计数变量hour清0。

2.代码

#include<reg51.h>
#include<lcd1602.h>
#define uchar unsigned char
#define uint unsigned int
uchar int_time;				//定义中断次数计数变量
uchar second;				//秒计数变量
uchar minute;				//分钟计数变量
uchar hour;				//小时计数变量
uchar code date[]="  H.I.T. CHINA  ";	//LCD第1行显示的内容
uchar code time[]=" TIME  23:59:55 ";	//LCD第2行显示的内容
uchar second=55,minute=59,hour=23;
 
void clock_init()
{
	uchar i,j;
	for(i=0;i<16;i++)
	{
		write_data(date[i]);
	}
write_com(0x80+0x40);
for(j=0;j<16;j++)
	{
		write_data(time[j]);
	}
}
 
void clock_write( uint s, uint m, uint h)
{
	write_sfm(0x47,h);
	write_sfm(0x4a,m);
	write_sfm(0x4d,s);
}
 
void main()
{
	init1602();		//LCD初始化
	clock_init();		//时钟初始化
TMOD=0x01;			 //设置定时器T0为方式1定时
EA=1;            			// 总中断开 
ET0=1; 				// 允许T0中断 
TH0=(65536-46483)/256;	//给T0装初值
TL0=(65536-46483)%256;
TR0=1;
int_time=0;			//中断次数、秒、分、时单元清0
second=55;
minute=59;
hour=23;
while(1)
{
	clock_write(second ,minute, hour);
}
}
void  T0_interserve(void)  interrupt 1  using 1 	//T0中断服务子程序
{	
	int_time++;				//中断次数加1
 	if(int_time==20) 			//若中断次数计满20次
 	{ 
		int_time=0; 			//中断次数变量清0
 		second++;			//秒计数变量加 1
 	}
 	if(second==60)			//若计满60s
 	{ 
	second=0; 				//秒计数变量清0
 	minute ++;				//分计数变量加 1
 	}
if(minute==60)			//若计满60分
{ 	
	minute=0;		//分计数变量清0
	hour ++;		//小时计数变量加1
}
if(hour==24)
{ 	
	hour=0;			//小时计数计满24,将小时计数变量清0
}
TH0=(65536-46083)/256;		//定时器T0重新赋值
TL0=(65536-46083)%256;
}

3.实验结果

(四)两单片机实现串口通信

1.实验要求

在实物实验时,如果不能找到两个普中单片机,用笔记本电脑的串口助手程序代替其中一个单片机,实现课件上描述的主要功能。甲、乙两单片机进行 方式3(或方式2)串行通信。甲机把控制8个流水灯点亮的数据发送给乙机并点亮其P1口的8个LED。方式3比方式1多了1个可编程位TB8,该位一般作奇偶校验位。乙机接收到的8位二进制数据有可能出错,需进行奇偶校验,其方法是将乙机的RB8和PSW的奇偶校验位P进行比较,如果相同,接收数据;否则拒绝接收。我们使用了一个虚拟终端来观察甲机串口发出的数据。

2.代码

甲:
//甲机发送
#include <REGX52.H>
 
sbit T_P=PSW^0;
unsigned char code Tab[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//流水灯程序
void Send(unsigned char dat)
{
	TB8=T_P;
	SBUF=dat;
	while(TI==0);
	TI=0;
}
void Delay(unsigned char xms)		//@11.0592MHz
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 199;
		do
		{
			while (--j);
		} while (--i);
	}
}
 
void main()
{
	unsigned char i;
	TMOD=0x20;
	SCON=0xc0;
	PCON&=0x7f;
	TH1=0xfd;
	TL1=0xfd;
	TR1=1;
	while(1)
	{
		for(i=0;i<8;i++)
		{
			Send(Tab[i]);
			Delay(200);//约200ms发送数据
		}
	}
}
乙:
//乙机接收
#include <REGX52.H>
sbit R_P=PSW^0;
 
unsigned char Receive()//接收一字节数据
{
	unsigned char dat;
	while(RI==0);//检测RI,RI=0,未接收完
	RI=0;					//接收数据完成RI手动清0
	ACC=SBUF;			//将接收缓冲器的数据存于ACC
	if(RB8=R_P) 	//只有偶检验成功才能往下执行,接收数据
	{
		dat=ACC;		//将ACC数据存于dat
		return dat;	//将接收的数据返回
	}
}
 
void main()
{
	TMOD=0x20;  //设置定时器为方式2,8位自动重载
	SCON=0xd0;	//串口为方式3,允许接收REN=1
	PCON&=0x7f;	//波特率不加倍
	TH1=0xfd;		//波特率9600
	TL1=0xfd;
	TR1=1;
	//REN=1;
	while(1)
	{
		 P2=Receive();	//将接收的数据送至P2口显示
	}
}

 3.实验结果

(五)实现“Hello C51"

1.实验要求

将单片机串口与笔记本电脑串口模块相连,单片机每隔2秒发送“Hello C51”,笔记本电脑用串口助手软件接收。 如果串口助手发送字符“0" 给单片机,则单片机停止发送; 如果单片机收到“1”,则继续每隔2秒发送“Hello C51”

2.代码

#include <REGX52.H>
#include "stdio.h"
unsigned char ch;
unsigned char Flag=1;
void Delay(unsigned int xms)		//@11.0592MHz
{
	unsigned char i, j;
 
	while(xms--)
	{
		i = 2;
		j = 199;
		do
		{
			while (--j);
		} while (--i);
	}
}
 
void UartInit(void)		//9600bps@11.0592MHz
{
	PCON &= 0x7F;		//波特率不倍速
	SCON = 0x50;		//8位数据,可变波特率
	TMOD &= 0x0F;		//清除定时器1模式位
	TMOD |= 0x20;		//设定定时器1为8位自动重装方式
	TL1 = 0xFD;		//设定定时初值
	TH1 = 0xFD;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
	EA=1;
	ES=1;
}
void UartSend()
{
		TI=1;
		puts("Hello C51");
		while(!TI);
		TI=0;
		Delay(2000);
}
 
void main()
{
	UartInit();
	while(1)
	{
		if(Flag==1)UartSend();
	}	
}
 
 
//串口中断函数模板
void UART_Routine()	interrupt 4 //串口中断
{
	if(RI==1)
	{
		RI=0;
		ch=SBUF;
		if(ch=='1')Flag=1;
		if(ch=='0')Flag=0;
	}
}

  • 19
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
51单片机串口通信与定时器有一定的关系。定时器可以提供精确的时序控制,而在串口通信中,定时器常常被用来生成波特率时钟,即串口通信的时钟信号。通过定时器的计数和溢出,可以实现精确的波特率设定,从而使得串口通信能够按照预定的速率进行数据传输。此外,定时器还可以用来检测接收数据的间隔时间,或者用来生成特定的时序信号,以实现串口通信的各种功能。所以可以说,定时器在51单片机串口通信中扮演着重要的角色。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [51--定时器/计数器,串口,中断的巧妙关系](https://blog.csdn.net/weixin_64473106/article/details/126725789)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [AutoLeaders控制组——51单片机学习笔记(定时器、串口通信)](https://blog.csdn.net/draw_future_TL/article/details/127914528)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值