单片机课程设计指导书文档格式.docx
《单片机课程设计指导书文档格式.docx》由会员分享,可在线阅读,更多相关《单片机课程设计指导书文档格式.docx(31页珍藏版)》请在冰豆网上搜索。
本设计中用到以下资源:
P0口外扩LCD1602显示器,P13口外扩蜂鸣器、P21、P22、P23、P24口外扩四个按键开关。
1)、数字开关:
给P2.0、P2.1、P2.2、P2.3口提供控制输入信号
K1:
控制PP2.0,K2:
控制P2.1,K3:
控制P2.3,K4:
控制P2.2
2)、P1口:
作为输入口,通过编写程序来起到控制计数器的工作状态的作用,从而达到设计的要求。
3)、定时/计数器T1:
对外部输入的脉冲进行计数。
4)、P3口的P3.5接74LS393的任一根信号线,提供待计数的脉冲。
5)、74LS393:
分频器,提供不同频率的脉冲信号。
6)、74LS240与LED显示器组合,用来显示计数值。
4.2硬件原理图
4.3软件流程图
Y
N
……
、调试运行
根据课程设计一周的工作经历,记录并描述系统搭建、调试、运行结果,
星期一:
确定课题目的,设计初步方案。
星期二:
编写并调试DS18B20和DS1302子程序,基本实现时间和温度的显示。
星期三:
建立LCD1602自定义字符库,编写并调试温度曲线子程序。
星期四:
编写并调试4个功能按键程序。
星期五:
整理整合,完善主程序,答辩。
、设计结果
经过多次调试与完善,能够顺利运行,符合设计要求。
板子开启工作状态,进入欢迎界面“welcome”。
选择key1,进入时间和温度显示界面。
(默认最低温限为20摄氏度,最高温限为25摄氏度,若温度不在这个范围,则蜂鸣器开始警报)。
选择key2,进入温度曲线显示界面。
选择key3,进入最低温限设置。
(若继续按KEY3键,最低温限减1,若按KEY4键,最低温限加1)
选择key4,进入最高温限设置。
KEY2显示实时温度曲线;
KEY3设置温度警报下限;
KEY4设置温度警报上限。
但温度曲线只能显示在LCD第一排,第二排还未作调试,无法显示。
温度上下限设置以0和50为界,此界内上限不的低于下限,下限不得高于上限,否则按键无回应。
、设计心得体会及建议
通过一周的单片机课程实践,深入了解了上学期单片机课程上所学的知识。
将课本知识运用到实际操作中,使我们更加深入地认识51单片机、LCD1602、DS1302以及DS18B20等元器件。
从定下实验目的和要求,我们便一步步地实现我们预期定下的任务,并不断改进,让我们的作品尽量完美。
设计期间,我们迷茫过,但是我们一直坚持着,和队员甚至凌晨一两点钟还在思考着,尝试着。
最终交上一份还算满意的答卷。
很喜欢这种感觉,通过自己的努力达到预期的目的。
单片机课程实践周,我学得了更多的单片机知识。
也懂得了团结的意义。
很充实。
谢谢组员带给我的快乐,谢谢老师给与的指导。
附录1程序清单
clude<
reg52.h>
#include<
intrins.h>
stdio.h>
#defineucharunsignedchar
#defineuintunsignedint
sbitRS=P1^0;
//定义端口
sbitRW=P1^1;
sbitEN=P1^2;
sbitBell=P1^3;
sbitkey1=P2^0;
sbitkey2=P2^1;
sbitkey3=P2^2;
sbitkey4=P2^3;
sbitDQ=P2^4;
sbitSCK=P2^5;
sbitSDA=P2^6;
sbitRST=P2^7;
#defineRS_CLRRS=0
#defineRS_SETRS=1
#defineRW_CLRRW=0
#defineRW_SETRW=1
#defineEN_CLREN=0
#defineEN_SETEN=1
#defineDataPortP0
#definekey1_CLRkey1=0
#definekey1_SETkey1=1
#definekey2_CLRkey2=0
#definekey2_SETkey2=1
#definekey3_CLRkey3=0
#definekey3_SETkey3=1
#definekey4_CLRkey4=0
#definekey4_SETkey4=1
#defineRST_CLRRST=0//电平置低
#defineRST_SETRST=1//电平置高
//双向数据
#defineIO_CLRSDA=0//电平置低
#defineIO_SETSDA=1//电平置高
#defineIO_RSDA//电平读取
//时钟信号
#defineSCK_CLRSCK=0//时钟信号
#defineSCK_SETSCK=1//电平置高
#defineds1302_sec_add0x80//秒数据地址
#defineds1302_min_add0x82//分数据地址
#defineds1302_hr_add0x84//时数据地址
#defineds1302_date_add0x86//日数据地址
#defineds1302_month_add0x88//月数据地址
#defineds1302_day_add0x8a//星期数据地址
#defineds1302_year_add0x8c//年数据地址
#defineds1302_control_add0x8e//控制数据地址
#defineds1302_charger_add0x90
#defineds1302_clkburst_add0xbe
unsignedchartime_buf1[8]={20,13,11,29,13,58,00,5};
//空年月日时分秒周
unsignedchartime_buf[8];
bitReadTimeFlag,ReadTempFlag;
//定义读时间、读温度标志
unsignedinttemperture;
voidDelayUs2x(unsignedchart)
{
while(--t);
}
voidDelayMs(unsignedchart)
{
while(t--)
{
//大致延时1mS
DelayUs2x(245);
}
/*------------------------------------------------
向DS1302写入一字节数据
------------------------------------------------*/
voidDs1302_Write_Byte(unsignedcharaddr,unsignedchard)
unsignedchari;
RST_SET;
//写入目标地址:
addr
addr=addr&
0xFE;
//最低位置零
for(i=0;
i<
8;
i++)
{
if(addr&
0x01)
{
IO_SET;
}
else
IO_CLR;
SCK_SET;
SCK_CLR;
addr=addr>
>
1;
}
//写入数据:
d
if(d&
d=d>
RST_CLR;
//停止DS1302总线
从DS1302读出一字节数据
unsignedcharDs1302_Read_Byte(unsignedcharaddr)
unsignedchartemp;
addr=addr|0x01;
//最低位置高
//输出数据:
temp
temp=temp>
if(IO_R)
temp|=0x80;
temp&
=0x7F;
//停止DS1302总线
returntemp;
向DS1302写入时钟数据
voidDs1302_Write_Time(void)
unsignedchari,tmp;
for(i=0;
i<
8;
i++)
{//BCD处理
tmp=time_buf1[i]/10;
time_buf[i]=time_buf1[i]%10;
time_buf[i]=time_buf[i]+tmp*16;
Ds1302_Write_Byte(ds1302_control_add,0x00);
//关闭写保护
Ds1302_Write_Byte(ds1302_sec_add,0x80);
//暂停
Ds1302_Write_Byte(ds1302_year_add,time_buf[1]);
//年
Ds1302_Write_Byte(ds1302_month_add,time_buf[2]);
//月
Ds1302_Write_Byte(ds1302_date_add,time_buf[3]);
//日
Ds1302_Write_Byte(ds1302_day_add,time_buf[7]);
//周
Ds1302_Write_Byte(ds1302_hr_add,time_buf[4]);
//时
Ds1302_Write_Byte(ds1302_min_add,time_buf[5]);
//分
Ds1302_Write_Byte(ds1302_sec_add,time_buf[6]);
//秒
Ds1302_Write_Byte(ds1302_control_add,0x80);
//打开写保护
从DS1302读出时钟数据
voidDs1302_Read_Time(void)
unsignedchari,tmp;
time_buf[1]=Ds1302_Read_Byte(ds1302_year_add);
//年
time_buf[2]=Ds1302_Read_Byte(ds1302_month_add);
//月
time_buf[3]=Ds1302_Read_Byte(ds1302_date_add);
//日
time_buf[4]=Ds1302_Read_Byte(ds1302_hr_add);
//时
time_buf[5]=Ds1302_Read_Byte(ds1302_min_add);
//分
time_buf[6]=(Ds1302_Read_Byte(ds1302_sec_add))&
0x7F;
//秒
time_buf[7]=Ds1302_Read_Byte(ds1302_day_add);
//周
tmp=time_buf[i]/16;
time_buf1[i]=time_buf[i]%16;
time_buf1[i]=time_buf1[i]+tmp*10;
DS1302初始化
voidDs1302_Init(void)
//RST脚置低
SCK_CLR;
//SCK脚置低
Ds1302_Write_Byte(ds1302_sec_add,0x00);
DS18B20初始化
bitInit_DS18B20(void)
bitdat=0;
DQ=1;
//DQ复位
DelayUs2x(5);
//稍做延时
DQ=0;
//单片机将DQ拉低
DelayUs2x(200);
//精确延时大于480us小于960us
//拉高总线
DelayUs2x(50);
//15~60us后接收60-240us的存在脉冲
dat=DQ;
//如果x=0则初始化成功,x=1则初始化失败
DelayUs2x(25);
//稍作延时返回
returndat;
DS18B20读取一个字节
unsignedcharReadOneChar(void)
unsignedchari=0;
unsignedchardat=0;
for(i=8;
i>
0;
i--)
//给脉冲信号
dat>
=1;
if(DQ)
dat|=0x80;
return(dat);
DS18B20写入一个字节
voidWriteOneChar(unsignedchardat)
unsignedchari=0;
for(i=8;
i>
i--)
DQ=dat&
0x01;
DelayUs2x(25);
DS18B20读取温度
unsignedintReadTemp(void)
unsignedchara=0;
unsignedintb=0;
unsignedintt=0;
Init_DS18B20();
WriteOneChar(0xCC);
//跳过读序号列号的操作
WriteOneChar(0x44);
//启动温度转换
DelayMs(10);
//跳过读序号列号的操作
WriteOneChar(0xBE);
//读取温度寄存器等(共可读9个寄存器)前两个就是温度
a=ReadOneChar();
//低位
b=ReadOneChar();
//高位
t=b;
t<
<
=8;
t=t|a;
t=t*0.625;
return(t);
LCD1602判忙函数
bitLCD_Check_Busy(void)
DataPort=0xFF;
RS_CLR;
RW_SET;
EN_CLR;
_nop_();
EN_SET;
return(bit)(DataPort&
0x80);
LCD1602写入命令函数
voidLCD_Write_Com(unsignedcharcom)
while(LCD_Check_Busy());
//忙则等待
RW_CLR;
DataPort=com;
LCD1602写入数据函数
voidLCD_Write_Data(unsignedcharData)
RS_SET;
DataPort=Data;
LCD1602清屏函数
voidLCD_Clear(void)
LCD_Write_Com(0x01);
DelayMs(5);
LCD1602写入字符串函数
voidLCD_Write_String(unsignedcharx,unsignedchary,unsignedchar*s)
if(y==0)
{
LCD_Write_Com(0x80+x);
//表示第一行
else
LCD_Write_Com(0xC0+x);