单片机综合实验报告.docx
- 文档编号:14836855
- 上传时间:2023-06-27
- 格式:DOCX
- 页数:32
- 大小:391.33KB
单片机综合实验报告.docx
《单片机综合实验报告.docx》由会员分享,可在线阅读,更多相关《单片机综合实验报告.docx(32页珍藏版)》请在冰点文库上搜索。
单片机综合实验报告
单片机综合实验报告
题目:
电子时钟(LCD显示)
班级:
姓名:
学号:
指导老师:
时间:
一、实验内容:
以AT89C51单片机为核心的时钟,在LCD显示器上显示当前的时间:
使用字符型LCD显示器显示当前时间。
显示格式为“时时:
分分:
秒秒”。
用4个功能键操作来设置当前时间,4个功能键接在P1.0~P1.3引脚上。
功能键K1~K4功能如下。
K1—进入设置现在的时间。
K2—设置小时。
K3—设置分钟。
K4—确认完成设置。
程序执行后工作指示灯LED闪动,表示程序开始执行,LCD显示“00:
00:
00”,然后开始计时。
二、实验电路及功能说明
本系统采用STC89C52单片机,DS1302时钟芯片及18B20温度传感器作为主要硬件进行设计开发,通过12864液晶显示器及键盘作为人机交互。
充分发挥了各部分的性能及特点,操作简单,界面简洁易懂。
实物系统实现了以下功能:
数字式时钟显示
起始时间设置
室温实时显示
全机热复位
显示器灰度可调
1)单片机电路
单片机电路采用STC89C51RC作为主控芯片,芯片内集成了通用8位中央处理器和ISPFlash存储单元,具有在系统可编程(ISP)特性,配合PC端的控制程序即可将用户的程序代码下载进单片机内部,指令集结构简单。
芯片外接11.05926MHz及两片0603封装20P贴片电容作为晶振电路,为单片机提供时钟信号。
2)复位电路
RST为单片机的复位引脚。
当连续输入两个机器周期以上高电时为有效,用来完成单片机的复位初始化操作,复位后程序计数器PC=0000H,即复位后将从程序储存器的0000H单元读取第一条指令代码。
系统采用上电复位:
加电后给RST一个高电平脉冲。
简单的措施是阻容串联,电容接电源、电阻接地、中间节点接RST。
加电瞬间,电容两侧电压差为0,两侧均为高,RST脚为高,随后C通过R放电使RST节点到0。
3)12864显示电路
12864是128*64点阵液晶模块的点阵数简称,内部集成字库,采用串行及并行两种通信方式与MCU通信。
本系统采用串行方式通信,通过改变V0端口电压改变背光对比度。
4)DS1302时钟电路
DS1302实时时钟芯片广泛应用于电话、传真、便携式仪器等产品领域.DS1302是一个实时时钟芯片,可以提供秒、分、小时、日期、月、年等信息,并且还有软年自动调整的能力,可以通过配置AM/PM来决定采用24小时格式还是12小时格式。
采用串行I/O通信方式,相对并行来说比较节省IO口的使用。
DS1302时钟芯片功耗低,它在工作电压2.0V的时候,工作电流小于300nA。
5)温度采集电路
温度采集电路DS18B20温度传感器,信号线采用4.7k电阻上拉。
6)独立键盘
设置4个按键组成独立键盘,共用10K对地限流电阻。
7)下载电路
下载电路外引P3.0(RXD)、P3.1(TXD),使用STC原厂烧录器下载程序。
8)供电电路
全机供电采取12V锂聚合物电池,它具有能量高、小型化、轻量化等特点,方便使用。
因MCU及外围电路工作电压为5V,故采用7805进行直流降压。
7805三端稳压IC来组成稳压电源所需的外围元件极少,电路内部还有过流、过热及调整管的保护电路,使用起来可靠、方便,而且价格便宜。
根据硬件电路设计规则,虽然整机采用直流供电,为了适应后期变压器供电可能引入的交流成分,在稳压芯片前设置了470uF/25V电解电容及104瓷片电容进行滤波,并在各个芯片供电输入前设置了瓷片电容用来滤除高频信号干扰。
三、实验程序流程图:
四、实验结果分析
经测试,系统程序运行稳定可靠,时间精度准确,整机掉电后,系统时间仍可维持正常计时。
人机交互界面简洁。
五、心得体会
在为期一个学期的单片机实验课程中,承蒙高林老师的耐心指导和讲解。
通过综合实验的开发加强了我动手能力。
在系统设计过程中得到了创新实践中心开发平台提供的硬件支持和开发环境,使我顺利完成了本次实践制作,在此一并表示感谢。
六、程序清单
主函数:
/*************************************************
带温度显示的数字时钟
白赫031140504
实验操作:
KEY1-进入设置KEY2-设置小时KEY3-设置分KEY4-确定
*************************************************/
#include
#include"led.h"
#include"key.h"
#include"18b20.h"
#include"lcd.h"
#include"ds1302.h"
voiddelay_ms(uintt);//延时nms
voidset(void);//设置时间
voidshow_time(void);//显示时间
voidmain(void)
{
uchari=0,key=0;
intt=0;//温度
LED_Init();
LCD_Init();//12864初始化
KEY_Init();//按键初始化
Ds1302_Init();//ds1302初始化
DS18B20_Init();//DS18B20初始化
//启动显示界面
LCD_writeString(0,1,"超级电子时钟");
LCD_writeString(2,0,"031140504");
LCD_writeString(2,5,"白赫");
LCD_writeChar(3);
LCD_writeString(3,3,"");
LCD_writeChar('D');LCD_writeChar('r');LCD_writeChar(':
');
LCD_writeString(3,5,"高林");
while
(1)
{
key=KEY_scan();//获取键值
if(key==1)//按下1键,进入设置
{
set();//进行时间设置
Ds1302_Write_Time();//更新时间参数
show_time();//显示时间
}
else//如果没有进入设置
{
Ds1302_Read_Time();//读取时间参数
show_time();//显示时间
delay_ms(50);//防止温度显示错位,加一个小延时
t=ReadTemperature();//读取温度
LCD_Wendu(t);//显示温度
}
delay_ms(50);
i++;
if(i>10)
{
LED=!
LED;//闪烁灯,指示程序正在运行
i=0;
}
}
}
/***********************************************
@函数名:
delay_ms()
@描述:
进行nms延时
@输入:
t-延时的时间
@返回:
void
************************************************/
voiddelay_ms(uintt)
{
uinti,j;
for(i=0;i for(j=0;j<115;j++); } /*********************************************** @函数名: set() @描述: 时间设置的主要部分 @输入: void @返回: void ************************************************/ voidset(void) { ucharkey_flag=1,key=0; while(key_flag)//按下1键,进入循环扫描,知道key4按下,key_flag置0才退出 { key=KEY_scan();//扫描按键 if(key! =0)//如果有键按下 { switch(key) { case2: //小时设置 { time[4]+=1; if(time[4]>23)//如果小时值大于23,则重新置为0 time[4]=0; LCD_writeNumber(1,1,time[4]);//显示小时值 }break; case3: //分钟设置 { time[5]+=1; if(time[5]>59)//如果分钟值大于59,则重新置为0 time[5]=0; LCD_writeNumber(1,3,time[5]);//显示分钟值 }break; case4: key_flag=0;break;//确定,key_flag置0,退出while(key_flag)循环 } } } } /*********************************************** @函数名: show_time() @描述: 显示时间的函数 @输入: void @返回: void ************************************************/ voidshow_time(void) { LCD_writeNumber(1,1,time[4]);//时 LCD_writeChar(''); LCD_writeChar(': '); LCD_writeNumber(1,3,time[5]);//分 LCD_writeChar(''); LCD_writeChar(': '); LCD_writeNumber(1,5,time[6]);//秒 } 按键函数 #include"key.h" voidKEY_Delay(void) { inti,j; for(i=0;i<10;i++) for(j=0;j<110;j++); } /*********************************************** @函数名: KEY_Init() @描述: 初始化按键四个IO为高 @输入: void @返回: void ************************************************/ voidKEY_Init(void) { key1=1; key2=1; key3=1; key4=1; } /*********************************************** @函数名: KEY_scan() @描述: 按键检测程序 @输入: void @返回: 按键的标号 ************************************************/ ucharKEY_scan(void) { if(key1==0||key2==0||key3==0||key4==0) { KEY_Delay(); if(key1==0) { while(key1==0); return1; } elseif(key2==0) { while(key2==0); return2; } elseif(key3==0) { while(key3==0); return3; } elseif(key4==0) { while(key4==0); return4; } } return0; } LCD函数 ------------------------------------------------------------------------------------------------------------- #include"lcd.h" /*********************************************** @函数名: LCD_Delay() @描述: 进行1ms延时 @输入: t-延时的时间 @返回: void ************************************************/ staticvoidLCD_Delay(uintt) { unsignedinti,j; for(i=0;i for(j=0;j<115;j++); } /*********************************************** @函数名: LCD_sendByte() @描述: 发送1字节数据 @输入: zdata-发送的数据 @返回: void ************************************************/ voidLCD_sendByte(ucharzdata) { uchari=0; for(i=0;i<8;i++)//i从0计数到7,循环8次 { if((zdata< SID=1;//数据返回为1 else SID=0;//数据返回为1 SCLK=0; SCLK=1; } } /*********************************************** @函数名: LCD_writeCommand() @描述: 发送一字节指令 @输入: com-即command缩写,意为指令 @返回: void ************************************************/ voidLCD_writeCommand(ucharcom)//写指令 { CS=1;//片选拉高,使能12864 LCD_sendByte(0xf8);//控制字,写命令时必须为0XF8! LCD_sendByte(com&0xf0);//先发高4bit,低4bit置0 LCD_sendByte((com<<4)&0xf0);//将低4bit移到高位发出 CS=0; } /*********************************************** @函数名: LCD_writeData() @描述: 发送1字节数据 @输入: Data-发送的数据 @返回: void ************************************************/ voidLCD_writeData(ucharData)//写数据 { CS=1;//片选拉高,使能12864 LCD_sendByte(0xfa);//控制字,写数据时必须为0XFA! LCD_sendByte(Data&0xf0);//先发高4bit,低4bit置0 LCD_sendByte((Data<<4)&0xf0);//将低4bit移到高位发出 CS=0; } /*********************************************** @函数名: LCD_init() @描述: 初始化12864 @输入: void @返回: void ************************************************/ voidLCD_init(void) { LCD_writeCommand(0x30);//8位数据格式,基本指令显示 LCD_Delay(50); LCD_writeCommand(0x30);//8位数据格式,基本指令显示 LCD_Delay(50); LCD_writeCommand(0x0C);//开显示、关闭光标 LCD_Delay(50); LCD_writeCommand(0x01);//清屏指令 LCD_Delay(50);//延时 LCD_writeCommand(0x06);//设置显示点: 指针自加1 LCD_Delay(500);//延时 } /*********************************************** @函数名: LCD_writeString() @描述: 在row(从0开始)行,rank列显示字符串 @输入: row-行rank-列s-字符串指针 @返回: void ************************************************/ voidLCD_writeString(ucharrow,ucharrank,uchar*s) { ucharaddr; //将显示坐标转换成地址 switch(row) { case0: addr=0x80;break; case1: addr=0x90;break; case2: addr=0x88;break; case3: addr=0x98;break; } LCD_writeCommand(addr+rank);//写入显示地址 while(*s>0) { LCD_writeData(*s);//写入显示数据 s++; LCD_Delay(5); } } /*********************************************** @函数名: LCD_writeNumber() @描述: 在row(从0开始)行,rank列显示整形数 由于这里是用来显示时钟数据,所以最大数不超过100 @输入: row-行rank-列s-字符串指针 @返回: void ************************************************/ voidLCD_writeNumber(ucharrow,ucharrank,uints) { ucharaddr; if(s>99) { return; } //将显示坐标转换成地址 switch(row) { case0: addr=0x80;break; case1: addr=0x90;break; case2: addr=0x88;break; case3: addr=0x98;break; } LCD_writeCommand(addr+rank);//写入显示地址 LCD_writeData(s/10+0x30); LCD_writeData(s%10+0x30); } /*********************************************** @函数名: LCD_writeChar() @描述: 显示一个字符 @输入: s--字符ascii码 @返回: void ************************************************/ voidLCD_writeChar(uchars) { LCD_writeData(s); } voidLCD_Wendu(intt) { uintt1,t2; if(t>0) { t1=t/10;//温度的整数部分 t2=t%10;//温度的小数部分 LCD_writeNumber(3,0,t1);//显示整数部分 LCD_writeChar('.');//显示小数点 LCD_writeChar(t2+0x30);//显示小数部分 LCD_writeString(3,2,"℃"); } } 时钟函数 --------------------------------------------------------------------------------------------- #include"ds1302.h" //1年2月3日4时5分6秒7周 uchartime[8]={20,14,6,7,10,10,0,6}; uchartime_buf[8];//时间数据DCB码 /*********************************************** @函数名: DS1302_Write_Byte() @描述: 向addr地址写入1字节数据(d) @输入: addr-地址d-数据内容 @返回: void ************************************************/ voidDS1302_Write_Byte(ucharaddr,uchard) { uchari; RST_SET;//RST置高,开始读写 //写入目标地址: addr addr=addr&0xFE;//最低位置00XFE-11111110 for(i=0;i<8;i++) { if(addr&0x01)//如果地址最低位为1 IO_SET;//数据口返回高 else IO_CLR;//数据口返回低 SCK_SET;//时钟返回高 SCK_CLR;//时钟返回低 addr=addr>>1;//地址右移1位 } //写入数据: d(由于data被编译器使用,这里使用d代表数据) for(i=0;i<8;i++) { if(d&0x01)//如果数据最低位为1 IO_SET;//数据口返回高 else IO_CLR;//数据口返回低 SCK_SET;//时钟返回高 SCK_CLR;//时钟返回低 d=d>>1;//数据右移1位 } RST_CLR;//停止DS1302总线 } /*********************************************** @函数名: Ds1302_Read_Byte() @描述: 从addr处读取1字节数据 @输入: addr-读的地址 @返回: temp(addr
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单片机 综合 实验 报告