51单片机——实验5:定时器与LCD显示

目录

一、实验任务

二、实验目的及原理

三、实验中使用的仪器与材料

四、实验方案、步骤及原始记录(数据、图表、计算等)

1.任务一:定时器产生周期为1s的方波控制LED灯亮灭,间隔1s

2.任务二:在LCD上分行显示学号和姓名拼音

3.任务三:利用定时器设计秒表并用LCD显示,同时显示自己的学号和姓名拼音

五、实验结果及分析、实验过程中遇到问题及处理过程说明

六、实验总结及心得体会


一、实验任务

  1. 定时器产生周期为1s的方波控制LED灯亮灭,间隔1s;
  2. 在LCD上分行显示学号和姓名拼音;
  3. 利用定时器设计秒表并用LCD显示,同时显示自己的学号和姓名拼音。

二、实验目的及原理

1.实验目的:掌握定时器原理并会编程;掌握LCD显示原理并会编程。

2.实验原理:定时器通过控制计数个数来精确控制时间;LCD是利用液晶经过处理后能改变光线通过方向的特性,从而达到白底黑子或黑底白字显示的目的。

三、实验中使用的仪器与材料

Keil、PZ-ISP、普中科技51单片机、数码管、发光二极管、独立按键、定时器、LCD

四、实验方案、步骤及原始记录(数据、图表、计算等)

1.任务一:定时器产生周期为1s的方波控制LED灯亮灭,间隔1s

(1)用keil编写程序,输出.hex文件

/*
  定时原理:位+1-->1个机器周期x秒
	          定时T--->n(T/x)个机器周期
						一般晶振为12MHZ,则x为1us,定时1s则n=10^6;
						然而16位计数器最多计65536个,所以可以将1秒分为20个50ms,则计50000位则溢出,n+1--->n=20
						要想计50000位就溢出,初值可设为(65536-50000),然而这个数字太大,得用两个8位计数器显示
						高8位=(65536-50000)/256,低八位=(65536-50000)%256
*/
#include<reg52.h>
sbit D1 = P2^0;

void main()
{
  //step1:TMOD确定工作方式
	TMOD = 0x01; //定时器0工作方式1
	
	//step2:计算初值(与定的时间有关,每隔50ms溢出)
  TH0 = (65536 - 50000)/256;//高四位初值
  TL0 = (65536 - 50000)%256;//低四位初值
	
	//step3:打开需要的中断
  EA = 1; 	   //开总允许中断
  ET0 = 1;	   //开启T0溢出中断
	
	//step4:打开定时器
  TR0 = 1;	   //开启定时器
	
  while(1);
}

void ET0_ISR(void) interrupt 1	   //定时0中断
{ 
  static unsigned int cnt = 0;	

  //初值重赋	
  TH0 = (65536-50000)/256;
  TL0 = (65536-50000)%256;
	
  cnt++;//溢出一次,+1 
  if(cnt >= 20)					 //当为1秒时D1灯状态改变
  {
    cnt = 0;
	  D1 =~D1;  //取反改变灯的状态
  }
}

(2)将输出的hex文件烧录到开发板上

2.任务二:在LCD上分行显示学号和姓名拼音

(1)用keil编写程序,输出.hex文件

#include<reg52.h>
sbit LCD_RS=P2^6; //命令/数据选择
sbit LCD_RW=P2^5; //读写口
sbit LCD_EN=P2^7; //锁存控制
#define uchar unsigned char 

int pow(int x,uchar y)
{
	int mi=1; 
	for(;y>0;y--)
	{
		mi*=x;
	}
	return mi;
}

//延迟函数定义
void delay()
{
	uchar i,j;
	for(i=1;i>0;i--)
	for(j=239;j>0;j--);
}

//向LCD写指令
void LCD_write_cmd(uchar command)
{
	LCD_RS=0; //选择指令寄存器---写的是指令
	LCD_RW=0; //写--状态
	P0=command; //写入命令--将指令赋给8位数据总线
	LCD_EN=1;  //使能信号1
	delay();  //等待写入,如果时间太短,会导致液晶无法显示
	LCD_EN=0; //使能信号从1->0 下降沿有效 LCD执行写入命令
	delay();
}

//向LCD写数据
void LCD_write_data(uchar Data)
{
	LCD_RS=1; //选择数据寄存器,写数据
	LCD_RW=0; //写操作
	P0=Data; //将数据赋给8位数据总线DB0-DB7,
	         //这里的P0为LCD上8位数据总线所连接的单片机IO端口
	LCD_EN=1; //使能端拉高
	delay();
	LCD_EN=0; //使能端拉低,下降沿有效,数据写入DDRAM
	delay();
}

//初始化
void LCD_Init()
{
	LCD_write_cmd(0x38); //指令--显示模式设置
	LCD_write_cmd(0x0c); //指令--显示光标开及光标设置
	LCD_write_cmd(0x06); //指令--显示光标移动设置
	LCD_write_cmd(0x01); // 指令--清屏
}

//LCD显示字符串
void LCD_dstr(uchar line,uchar column,uchar *str)
{
	if(line==1)
	{
		LCD_write_cmd(0x80|(column-1));
	}
	else
	{
		LCD_write_cmd(0x80|(column-1)+0x40);
	}
	while(*str!='\0')
	{
		LCD_write_data(*str++);
	}
}

//LCD显示整形数字
void LCD_dnum(uchar line,uchar column,int num,uchar length)
{
	uchar i;
	if(line==1)
	{
		LCD_write_cmd(0x80|(column-1));
	}
	else
	{
		LCD_write_cmd(0x80|(column-1)+0x40);
	}
	for(i=length;i>0;i--)
	{
		LCD_write_data('0'+num/pow(10,i-1)%10);
	}
}

//LCD显示字符
void LCD_dchar(uchar line,uchar column,uchar Char)
{
	if(line==1)
	{
		LCD_write_cmd(0x80|(column-1));
	}
	else
	{
		LCD_write_cmd(0x80|(column-1)+0x40);
	}
		LCD_write_data(Char);
}

void main()
{
	uchar *str1,*str2;
	uchar xuehao[]="2022210491";
	uchar xin[]="shidan";
	str1=&xuehao[0];
	str2=&xin[0];
	LCD_Init();
	LCD_dstr(1,1,str1);
	LCD_dstr(2,1,str2);
}

(2)将输出的hex文件烧录到开发板上

3.任务三:利用定时器设计秒表并用LCD显示,同时显示自己的学号和姓名拼音

(1)用keil编写程序,输出.hex文件

#include<reg52.h>
sbit LCD_RS=P2^6; //命令/数据选择
sbit LCD_RW=P2^5; //读写口
sbit LCD_EN=P2^7;  //锁存控制
#define uchar unsigned char
unsigned char m=4,n=5;

//延时函数
void delay7ms()
{
	long int i,j;
	for(i=0;i<1;i++)
	for(j=0;j<14;j++);
}

//x^y
int pow(int x,uchar y)
{
	int mi=1; 
	for(;y>0;y--)
	{
		mi*=x;
	}
	return mi;
}

//延时
void delay()
{
	uchar i,j;
	for(i=1;i>0;i--)
	for(j=250;j>0;j--);
}

//向LCD写指令
void LCD_write_cmd(uchar command)
{
	LCD_RS=0; //选择指令寄存器---写的是指令
	LCD_RW=0; //写--状态
	P0=command;  //写入命令--将指令赋给8位数据总线
	LCD_EN=1; //使能信号1
	delay(); //等待写入,如果时间太短,会导致液晶无法显示
	LCD_EN=0; //使能信号从1->0 下降沿有效 LCD执行写入命令
	delay();
}

//向LCD写数据
void LCD_write_data(uchar Data)
{
	LCD_RS=1; //选择数据寄存器,写数据
	LCD_RW=0; //写操作
	P0=Data; //将数据赋给8位数据总线DB0-DB7,
	         //这里的P0为LCD上8位数据总线所连接的单片机IO端口
	LCD_EN=1; //使能端拉高
	delay();
	LCD_EN=0; //使能端拉低,下降沿有效,数据写入DDRAM
	delay();
}

//初始化
void LCD_Init()
{
	LCD_write_cmd(0x38); //指令--显示模式设置
	LCD_write_cmd(0x0c); //指令--显示光标开及光标设置
	LCD_write_cmd(0x06); //指令--显示光标移动设置
	LCD_write_cmd(0x01); // 指令--清屏
}

//LCD显示字符串
void LCD_dstr(uchar line,uchar column,uchar *str)
{
	if(line==1)
	{
		LCD_write_cmd(0x80|(column-1));
	}
	else
	{
		LCD_write_cmd(0x80|(column-1)+0x40);
	}
	while(*str!='\0') 
	{
		LCD_write_data(*str++); //先写十位,再地址后移,写个位
	}
}

//LCD显示整形数字
void LCD_dnum(uchar line,uchar column,int num,uchar length)
{
	uchar i;
	if(line==1)
	{
		LCD_write_cmd(0x80|(column-1));
	}
	else
	{
		LCD_write_cmd(0x80|(column-1)+0x40);
	}
	for(i=length;i>0;i--)
	{
		LCD_write_data('0'+num/pow(10,i-1)%10);
	}
}

//LCD显示字符
void LCD_dchar(uchar line,uchar column,uchar Char)
{
	if(line==1)
	{
		LCD_write_cmd(0x80|(column-1));
	}
	else
	{
		LCD_write_cmd(0x80|(column-1)+0x40);
	}
		LCD_write_data(Char);
}


void main()
{
	unsigned int j;
	
	//step1:TMOD确定工作方式
	TMOD = 0x01; //定时器0工作方式1
	
	//step2:计算初值(与定的时间有关,每隔50ms溢出)
  TH0 = (65536 - 50000)/256;//高四位初值
  TL0 = (65536 - 50000)%256;//低四位初值
	
	//step3:打开需要的中断
  EA = 1; 	   //开总允许中断
  ET0 = 1;	   //开启T0溢出中断
	
	//step4:打开定时器
  TR0 = 1;	   //开启定时器
	
	while(1)
	{
		uchar *ge,*shi,*str2;
		
		for(j=0;j<50;j++) 
		{
			uchar xin[]=" 2022210491 sdd ";
			uchar Dig_code[]="0123456789"; //仅用于确定初始数字,与累加无关
			uchar Dig[2]="  ";
			Dig[1] = Dig_code[n];//个位 确立初始状态
			Dig[0] = Dig_code[m];//十位  比如Dig=14 那么它就先写4,再写
			shi=&Dig[0]; //取地址,ge取Dig[0]的地址
			ge=&Dig[1];
			str2=&xin[0];
			
	    LCD_Init();
			LCD_dstr(1,1,shi);
    	LCD_dstr(2,1,str2);
			}
	
	}
}

void ET0_ISR(void) interrupt 1	   //定时0中断
{ 
  static unsigned int cnt = 0;	

  //初值重赋	
  TH0 = (65536-50000)/256;
  TL0 = (65536-50000)%256;
	
  cnt++;//溢出一次,+1 
  if(cnt >= 20)					 //当为1秒时+1
  {
    cnt = 0;
	  n++;
		if(n>=10) 
		{
			m++; n=0;
		}
		if(m>=6) m=0;
  }
}

(2)将输出的hex文件烧录到开发板上

五、实验结果及分析、实验过程中遇到问题及处理过程说明

1.任务一结果

2.任务二结果

3.任务三结果

4.遇到的问题及处理过程

在任务三中烧录程序后发现秒表数字为倒着的,即个位在前,十位在后。查看程序,shi=&Dig[1],ge=&Dig[0],LED_dstr(1,1,ge)就表示先写个位,再写十位,故需要交换shi与ge,代码改成shi=&Dig[0],ge=&Dig[1],最终得到理想效果。

六、实验总结及心得体会

通过本次实验课,明白了定时器定时原理,LCD显示字符、字符串原理,并掌握了它们的编程方法。在编程过程中,要理清楚逻辑,可从一个简单的功能入手,逐步增加代码以实现更多的功能。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值