济南大学通信工程大四生产实习综合实训报告2015.9.10 - 图文

更新时间:2024-07-04 12:42:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

生产实习综合实训

学 院 信息科学与工程学院 专 业 通信工程 班 级 学 生

指导老师 赵国毅、李念强、崔世耀、温宇

二〇一五年九月十日

济南大学电子设计综合实训

一、 实习目的

1. 通过课程设计的教学实践,将课本所学应用于实际中,缩小理论与实际的差距,进一

步学习掌握单片机应用系统的有关知识,加深了解单片机的工作原理。

2. 初步掌握简单单片机应用系统的设计,制作,调试的方法。使自己的设计水平和对所

学的知识的应用能力以及分析问题解决问题的能力得到全面提高。

二、 内容要求

1、实习要求

① 认识Altium_Designer软件并且熟练使用。 ② 根据实验原理画出最小系统和电源控制板模型。 ③ 使用相关工具对电路板进行焊接。 ④ 对焊接完成的电路板进行调试。 ⑤ 根据实验原理画出万年历的电路板模型。

2、实习内容

Ⅰ最小系统 ① 实验原理图

2 / 22

济南大学电子设计综合实训

②重点元器件介绍:

1.单片机:选取AT89S51/52兼容单片机。

2.晶振电路:晶振选取11.0592MHz,用于有串口通讯的场合。

3.复位电路:由电容串联电阻构成,结合电容电压不能突变的性质,当系统一上电RST脚将会出现高电平,该最小系统的51单片机当RST脚的高电平持续2个周期以上,就将复位。

③用 Altium_Designer软件仿真并封装:

⑴打开Altium Designer软件,首先建立一个工程,然后在建立一个Schematic,在建立的页面中花电路图。

⑵打开Libraries,导入存储元器件的“库”,根据电路图,通过Search工具,寻找需要的元器件,

⑶把元器件拖入窗口,根据原理图将其连线并修改其参数。

⑷连好电路图之后,运行Project检查电路图的连线以及元器件属性的正确性,保存在桌面位置。

⑸运行PCB Board Wizard,进行封装,并保存在与电路图相同的位置。

⑹将封装后的元器件拖入电路板内,并进行布线,然后自动走线,设计图完成。

3 / 22

济南大学电子设计综合实训

④最小系统仿真图:

⑤焊接电路板实物图:

Ⅱ电源控制板

4 / 22

济南大学电子设计综合实训

①实验原理图

②用 Altium_Designer软件仿真并封装:

5 / 22

济南大学电子设计综合实训

③使用原件:

原件 电容104 电阻10uF 大电容 电阻1K 电阻10K 数量(个) 9 7 5 1 2 6 / 22

济南大学电子设计综合实训

电阻472 芯片1117 散热板 开关 插针 LED灯 插头 3 1 5 1 若干 6 3 ④焊接:根据仿真原理图做好的板子进行焊接,焊接图片如下:

7 / 22

济南大学电子设计综合实训

III万年历

本设计是基于51系列的单片机进行的电子万年历设计,采用八位数码管显示年月日时分秒及温度信息,具有可调整日期和时间功能。时间、日期调整由三个按键来实现,并可对闹铃开关进行设置。日历能显示阳历和阴历年、月、日以及星期、时、分、秒。设计以AT89S52单片机为核心,构成单片机控制电路;以DS1302时钟芯片作为万年历信号发生器;以DS18B20作为检测温度的传感器。

(原理图如下;)

①单片机芯片

采用AT89S52,片内ROM全都采用Flash ROM;能以3V的超低压工作;同时也与MCS-51系列单片机完全相同,该芯片内部存储器为8KB ROM 存储空间,同样具有89C51的功能,且具有在线编程可擦除技术,当在对电路进行调试时,由于程序的错误修改或对程序的新增功能需要烧入程序时,不需要对芯片多次拔插,不会对芯片造成损坏。所以选择采用AT89S52作为主控制系统.

(单片机芯片图如下)

8 / 22

济南大学电子设计综合实训

②时钟芯片

采用DS1302时钟芯片实现时钟,DS1302芯片是一种高性能的时钟芯片,可自动对秒、分、时、日、周、月计数,而且精度高,8位的RAM做为数据暂存区,工作电压2.5V~5.5V范围内,2.5V时耗电小于300nA。

DS1302在每次进行读、写程序前都必须初始化,先把SCLK端置 “0”,接着把RST端置“1”,最后才给予SCLK脉冲。DS1302的控制字,此控制字的位7必须置1,若为0则不能把对DS1302进行读写数据。对于位6,若对程序进行读/写时RAM=1,对时间进行读/写时,CK=0。位1至位5指操作单元的地址。位0是读/写操作位,进行读操作时,该位为1;该位为0则表示进行的是写操作。控制字节总是从最低位开始输入/输出的。DS1302的日历、时间寄存器内容:“CH”是时钟暂停标志位,当该位为1时,时钟振荡器停止,DS1302处于低功耗状态;当该位为0时,时钟开始运行。“WP”是写保护位,在任何的对时钟和RAM的写操作之前,WP必须为0。当“WP”为1时,写保护位防止对任一寄存器的写操作。

(时钟芯片图如下)

9 / 22

济南大学电子设计综合实训

③测温传感器

测温可以采用热敏电阻加上模数转换得到电压,然后将测到的电压送到单片机,由单片机处理得到温度值。但是这种方法实现起来复杂,且精度难以达到很高,所以本设计没有采用这种方式。DHT11是一种数字温度传感器,一根线就可以与单片机IO联接,将测到的温度以数字形式传送到单片机,所以使用简单;它的测温误差为+-0.5度,可以达到较好的精度,在日常的应用中足够。这种芯片应用广泛,所以本设计也采用了这种测温方式。

(测温传感器图如下;)

④蜂鸣器

我们采用的有源蜂鸣器,由于单片机的输出电流较小所以我们采用PNP形的三极管作为驱动电路,来驱动蜂鸣器发声,当单片机给低电平时蜂鸣器响。 (蜂鸣器图如下;)

⑤键盘控制电路

该设计采用的是独立按键,S1为时间设置,S2为时间或者日期调整,S3为确定键,S4为闹钟设置。

(键盘控制电路图如下;)

10 / 22

济南大学电子设计综合实训

⑥74HC595芯片介绍

74HC164、74HCT164 是高速硅门 CMOS 器件,与低功耗肖特基型 TTL (LSTTL) 器件的引脚兼容。74HC164、74HCT164 是 8 位边沿触发式移位寄存器,串行输入数据,然后并行输出。数据通过两个输入端(DSA 或 DSB)之一串行输入;任一输入端可以用作高电平使能端,控制另一输入端的数据输入。两个输入端或者连接在一起,或者把不用的输入端接高电平,一定不要悬空。

时钟 (CP) 每次由低变高时,数据右移一位,输入到 Q0, Q0 是两个数据输入端(DSA 和 DSB)的逻辑与,它将上升时钟沿之前保持一个建立时间的长度。

主复位 (MR) 输入端上的一个低电平将使其它所有输入端都无效,同时非同步地清除寄存器,强制所有的输出为低电平。

8位串行输入/输出或者并行输出移位寄存器,具有高阻关断状态。将串行输入的8位数字,转变为并行输出的8位数字,例如控制一个8位数码管,将不会有闪烁。

11 / 22

济南大学电子设计综合实训

⑦仿真软件介绍

Proteus 与其它单片机仿真软件不同的是,它不仅能仿真单片机CPU 的工作情况,也能仿真单片机外围电路或没有单片机参与的其它电路的工作情况。因此在仿真和程序调试时,关心的不再是某些语句执行时单片机寄存器和存储器内容的改变,而是从工程的角度直接看程序运行和电路工作的过程和结果。对于这样的仿真实验,从某种意义上讲,是弥补了实验和工程应用间脱节的矛盾和现象。 (1)proteus 的工作过程

运行proteus 的ISIS 程序后,进入该仿真软件的主界面。在工作前,要设置view 菜单下的捕捉对齐和system下的颜色、图形界面大小等项目。通过工具栏中的p(从库中选择元件命令)命令,在pick devices 窗口中选择电路所需的元件,放置元件并调整其相对位置,元件参数设置,元器件间连线,编写程序;在source 菜单的Definecode generation tools 菜单命令下,选择程序编译的工具、路径、扩展名等项目;在source 菜单的Add/removesource files 命令下,加入单片机硬件电路的对应程序;通过debug 菜单的相应命令仿真程序和电路的运行情况。

(2)Proteus 软件所提供的元件资源Proteus 软件所提供了30 多个元件库,数千种元件。元件涉及到数字和模拟、交流和直流等。 (4)Proteus 软件所提供的调试手段

Proteus 提供了比较丰富的测试信号用于电路的测试。这些测试信号包括模拟信号和数字信号。对于单片机硬件电路和软件的调试,只需要执行debug 菜单下的execute 菜单项或F12 快捷键启动执行,用debug菜单下的pause animation 菜单项或pause 键暂停系统的运行;或用debug 菜单下的stop animation 菜单项或shift-break 组合键停止系统的运行。其运行方式也可以选择工具栏中的相应工具进行。 ⑧软件调试过程

1、仿真:打开KEIL 4,输入所编写的源程序并对程序进行编译,在软件的帮助下检查其中的错误并进行反复修改,知道编译正确后运行,确保没有错误以后对正确的源程序进行保存,保存时给其命名,以便将来载入程序时容易找到。

2、打开PROTEUS软件,并出画单片机电子万年历具体运行电路图。

3、检查所画电路运行图,确保没有错误以后,在PROTEUS下对原理图进行加载KEIL 4下的源程序。

4、加载完成后,单击电路图框下的开始按钮,进行仿真。

软件调试一般包括分块调试和联机调试两个阶段。程序的分块调试一般在单片机开发装置

12 / 22

济南大学电子设计综合实训

上进行,可根据所调程序功能块的入口参量初值编制一个特殊的程序段,并连同被调程序功能块一起在开发装置上运行;也可配合对应硬件电路单独运行某程序功能块,然后检查是否正确,如果执行结果与预想的不一致,可以通过单步运行或设置断点的方法,查出原因并加以改正,直到运行结果正确为止。这时该 程序功能块已调试完毕,可去掉附加程序段。其它程序功能块可按此法进行调试。程序联机调试就是将已调试好的各程序功能块按总体结构联成一个完整程序,在所研制的硬件电路上运行。从而试验程序整体运行的完整性、正确性和与硬件电路的配合情况。在联调中可能会有某些支路上的程序、功能块因受条件制约而得不到相应的输入参数,这时,调试人员应创造条件进行模拟调试。在联调中如发现硬件问题也应及时修正,直到单片机系统的软件、硬件全部调试成功为止。系统调试完成后,还要进行一段时间的试运行,从而检验系统的稳定性和抗干扰能力,验证系统功能是否达到设计要求,是否达到预期的效果。

⑨软件调试过程

1、仿真:打开KEIL 4,输入所编写的源程序并对程序进行编译,在软件的帮助下检查其中的错误并进行反复修改,知道编译正确后运行,确保没有错误以后对正确的源程序进行保存,保存时给其命名,以便将来载入程序时容易找到。

2、打开PROTEUS软件,并出画单片机电子万年历具体运行电路图。

3、检查所画电路运行图,确保没有错误以后,在PROTEUS下对原理图进行加载KEIL 4下的源程序。

4、加载完成后,单击电路图框下的开始按钮,进行仿真。

软件调试一般包括分块调试和联机调试两个阶段。程序的分块调试一般在单片机开发装置上进行,可根据所调程序功能块的入口参量初值编制一个特殊的程序段,并连同被调程序功能块一起在开发装置上运行;也可配合对应硬件电路单独运行某程序功能块,然后检查是否正确,如果执行结果与预想的不一致,可以通过单步运行或设置断点的方法,查出原因并加以改正,直到运行结果正确为止。这时该 程序功能块已调试完毕,可去掉附加程序段。其它程序功能块可按此法进行调试。程序联机调试就是将已调试好的各程序功能块按总体结构联成一个完整程序,在所研制的硬件电路上运行。从而试验程序整体运行的完整性、正确性和与硬件电路的配合情况。在联调中可能会有某些支路上的程序、功能块因受条件制约而得不到相应的输入参数,这时,调试人员应创造条件进行模拟调试。在联调中如发现硬件问题也应及时修正,直到单片机系统的软件、硬件全部调试成功为止。系统调试完成后,还要进行一段时间的试运行,从而检验系统的稳定性和抗干扰能力,验证系统功能是否达到设计要求,是否达到预期的效果。

13 / 22

济南大学电子设计综合实训

⑩程序见附录

14 / 22

济南大学电子设计综合实训

三、 实习总结

1通过本次历时两周的生产实习课程设计以及自己亲自动手焊接电路,我发现原来焊接电路板是一件这么有趣的事情。它不仅要求我们在焊接电路板时有足够的耐心和细心,更要求我们要有发现问题解决问题的能力,同时要与老师和同学多交流合作,这样才能更快更好地完成任务。

2这次学习了Altium_Designer的使用,我发现这是一个非常有用的软件,我们可以根据实验原理先做出实验原理图,然后进行仿真。

3后期调试过程中,因为操作的一些原因,因此有时候结果有些地方不尽如人意,需要我们多次调试和修改,所以我们在面对问题是不应该逃避,应该满怀信心冷静分析判断,并且与同学交流学习,最终完成开始设定的目标。

4单片机理论的学习是为课程的设计作准备的,但有时学习的理论也解决不了实践中的问题。实践中获得的知识能让我对单片机的知识有更好的认识和理解。虽然这次的课程设计我参考了一些文献资料,没有做到创新,但在对程序的读写过程中我明白了许多。这次生产实习的最大收获是只有把理论用到实践中我们才能真正掌握好所学知识。

5这次设计让我学到了许多知识,同时看到自己的设计顺利完成时有满满的成就感,我们要不断学习,不断进步,让自己的人生变得更加充实有意义。

附实验源程序: #include #include #include #define uint unsigned int #define uchar unsigned char sbit IO= P1^0; //DS1302数据线 sbit SCLK = P1^1; //DS130时钟线 sbit RST = P1^2; //DS1302复位线 sbit RS = P2^0; sbit RW = P2^1; sbit EN = P2^2; sbit K1=P3^4; sbit K2=P3^5;

//LCD数据/命令选择端 //LCD读/写控制 //LCD使能端

//选择 //加

15 / 22

济南大学电子设计综合实训

sbit K3=P3^6; uchar tCount=0;

uchar MonthsDays[]={0,31,0,31,30,31,30,31,31,30,31,30,31}; uchar *WEEK[]={%uchar LCD_DSY_BUFFER1[]={\显示格式 uchar LCD_DSY_BUFFER2[]={%uchar DateTime[7]; //所读取的日期时间

char Adjust_Index=-1; //当前调节的时间对象:,,分,是,日,月,年(1,2,3,4,6) uchar Change_Flag[]= \ //(分,时,日,月,年)(不调节秒与周) /*---------延时程序------------------*/ void DelayMS(uint ms) {

uchar i;

while(ms--){for(i=0;i<120;i++);} }

//-----------向DS1302写入一字节------------------// void Write_A_Byte_TO_DS1302(uchar x) { uchar i;

for(i=0;i<8;i++){ } }

//-----------从DS1302读取一字节------------------// uchar Get_A_Byte_FROM_DS1302() { uchar i,b=0x00; for(i=0;i<8;i++){ }

return b/16*10+b; //返回BCD码 }

//-----------从DS1302指定位置读数据------------------// uchar Read_Data(uchar addr) {

uchar dat;

RST = 0;SCLK=0;RST=1;

//减

sbit K4=P3^7; //确定

IO=x&0x01; //每一位与1与存入IO中

SCLK=1;SCLK=0; //一个高脉冲将数据送入液晶控制器 x>>=1; // 右移

b |= _crol_((uchar)IO,i); SCLK=1;SCLK=0;

//每一个高脉冲读取一位数据

//RST高电平时读/写

16 / 22

济南大学电子设计综合实训

}

//---------向DS1302某地址写入数据--------------------// void Write_DS1302(uchar addr,uchar dat) { SCLK=0;RST=1;

Write_A_Byte_TO_DS1302(addr); Write_A_Byte_TO_DS1302(dat); SCLK=0;RST=0; }

//--------------设置时间----------------// void SET_DS1302() { uchar i;

//写控制字,取消写保护 Write_DS1302(0x8E,0x00); //分时日月年依次写入 for(i=1;i<7;i++)

{ //分的起始地址10000010(0x82),后面依次是时,日,月,周,年,写入地址每次递增2

}

Write_DS1302(0x8E,0x80); //加保护 }

//----------读取当前日期时间------------// void GetTime() {uchar i;

for(i=0;i<7;i++){ }

//-----------读LCD状态------------------// uchar Read_LCD_State() { uchar state;

RS=0;RW=1;EN=1; //输出:D0~D7=状态字 DelayMS(1); state=P0;

//从P0口读LCD状态

EN = 0;DelayMS(1); return state; }

//-----------忙等待------------------//

17 / 22

Write_A_Byte_TO_DS1302(addr); SCLK=1;RST=0;

//先写入地址

dat = Get_A_Byte_FROM_DS1302(); return dat;

//高脉冲写入数据

Write_DS1302(0x80+2*i,(DateTime[i]/10<<4)|(DateTime[i]));

DateTime[i]=Read_Data(0X81+2*i);}

济南大学电子设计综合实训

void LCD_Busy_Wait() {

while((Read_LCD_State()&0x80)==0x80); DelayMS(5); }

//-----------向LCD写数据------------------// void Write_LCD_Data(uchar dat) {

LCD_Busy_Wait(); RS=1;EN=0;RW=0; }

//-------------写LCD指令-------------------// void Write_LCD_Command(uchar cmd) {

LCD_Busy_Wait();

RS=0;EN=0; RW=0; //写指令,EN高脉冲,输出:D0~D7=数据 P0=cmd;EN=1;DelayMS(1);EN=0; }

//-------------LCD初始化-------------------// void Init_LCD() {

Write_LCD_Command(0x38); //设置16*2显示,5*7点阵,8位数据接口 DelayMS(1);

Write_LCD_Command(0x01); //显示清零,数据指针清零 DelayMS(1);

Write_LCD_Command(0x06); //写一个字符后地址指针自动加1 DelayMS(1);

Write_LCD_Command(0x0c); //设置开显示,不显示光标 DelayMS(1); }

//------------------------------------------ //设置液晶显示位置

//------------------------------------------ void Set_LCD_POS(uchar p){

Write_LCD_Command(p|0x80);//相当于在0x80基础上加入位置量 }

//----在LCD上显示字符串---------//

18 / 22

//写数据,EN为高脉冲,

P0=dat;EN=1;DelayMS(1);EN=0;

济南大学电子设计综合实训

void Display_LCD_String(uchar p,uchar *s) {

uchar i;

Set_LCD_POS(p); for(i=0;i<16;i++) { } }

//---------日期与时间值转换为数字字符----------------// void Format_DateTime(uchar d,uchar *a) {

a[0]=d/10+'0'; a[1]=d+'0'; }

//判断是否为闰年 uchar isLeapYear(uint y)

{ return (y%4==0&&y0!=0)||(y@0==0);} //求自2000.1.1开始的任何一天是星期几 //函数没有通过,求出总天数后再求星期几 //因为求总天数可能会超出uint的范围 void RefreshWeekDay() { uint i,d,w=5; { } d=0;

for(i=1;i

d+=MonthsDays[i];

}

d+=DateTime[3];

//保存星期,0~6表示星期日,星期一,二,...,六,为了与DS1302的星期格式匹配,

返回值需要加1

DateTime[5]=(w+d)%7+1; }

//*****年月日时分++/--********// void DateTime_Adjust(char x) {

Write_LCD_Data(s[i]); //在固定位置显示时间日期 DelayMS(1);

//已知1999.12.31是周五

for(i=2000;i<2000+DateTime[6];i++)

d=isLeapYear(i)?366:365; w=(w+d)%7;

switch(Adjust_Index)

19 / 22

济南大学电子设计综合实训

{ } }

//---定时器0每秒刷新LCD显示----// void T0_INT() interrupt 1 {

20 / 22

case 6: //年00-99

if(x==1&&DateTime[6]<99) DateTime[6]++; if(x==-1&&DateTime[6]>0) DateTime[6]--; //获取2月天数

MonthsDays[2]=isLeapYear(2000+DateTime[6])?29:28; //如果年份变化后当前月份的天数大于上限则设为上限 if(DateTime[3]>MonthsDays[DateTime[4]]) {

DateTime[3]=MonthsDays[DateTime[4]];} RefreshWeekDay(); //刷新星期 break;

if(x==1&&DateTime[4]<12) DateTime[4]++; if(x==-1&&DateTime[4]>1) DateTime[4]--;

MonthsDays[2]=isLeapYear(2000+DateTime[6])?29:28; if(DateTime[3]>MonthsDays[DateTime[4]]) {

DateTime[3]=MonthsDays[DateTime[4]];} RefreshWeekDay(); break;

MonthsDays[2]=isLeapYear(2000+DateTime[6])?29:28; //根据当前月份决定调节日期的上限

if(x==1&&DateTime[3]0) DateTime[3]--; RefreshWeekDay(); break;

if(x==1&&DateTime[2]<23) DateTime[2]++; if(x==-1&&DateTime[2]>0) DateTime[2]--; break;

//分

if(x==1&&DateTime[1]<59) DateTime[1]++; if(x==-1&&DateTime[1]>0) DateTime[1]--; break;

case 4: //月01-12

case 3: //日00-28、29、30、31,调节之前首先根据年份得出该年中断二月 天数

case 2: //时

case 1:

济南大学电子设计综合实训

TH0=-50000/256; TL0=-50000%6;

if(++tCount !=2) return; tCount=0;

//按指定格式生成待显示的日期时间串

Format_DateTime(DateTime[6],LCD_DSY_BUFFER1+5); Format_DateTime(DateTime[4],LCD_DSY_BUFFER1+8); Format_DateTime(DateTime[3],LCD_DSY_BUFFER1+11); //星期

strcpy(LCD_DSY_BUFFER1+13,WEEK[DateTime[5]-1]); //时分秒

Format_DateTime(DateTime[2],LCD_DSY_BUFFER2+5); Format_DateTime(DateTime[1],LCD_DSY_BUFFER2+8); Format_DateTime(DateTime[0],LCD_DSY_BUFFER2+11); //显示年月日,星期,时分秒

Display_LCD_String(0x00,LCD_DSY_BUFFER1); Display_LCD_String(0x40,LCD_DSY_BUFFER2); }

//----------键盘中断(INT0)-------------// void EX_INT0() interrupt 0 {

if(K1==0) { }

else if(K2==0) {

//选择调整对象(Y M D H M)

DelayMS(10); if(K1==0){ //while(K1==0);

if(Adjust_Index==-1||Adjust_Index==1) { }

Adjust_Index--;

if(Adjust_Index==5) Adjust_Index=4; LCD_DSY_BUFFER2[13]='['; LCD_DSY_BUFFER2[15]=']'; }

//加

21 / 22

Adjust_Index=7;

LCD_DSY_BUFFER2[14]=Change_Flag[Adjust_Index]; //显示调节对象

//while(K2==0);

济南大学电子设计综合实训

}

else if(K3==0) { }

else if(K4==0) { } }

void main() { Init_LCD();

//液晶初始化

IE=0x83; //允许INT0,T0中断,EA=1,,ET0=1,EX0=1 IP=0x01; //设置外部中断0为高级中断 IT0=0x01;

//外部中断0为电平触发,低电平有效

//装入初始值,定时1秒

TMOD=0x01; //设置定时器T0工作方式为方式1, TH0=-50000/256; TL0=-50000%6; TR0=1; while(1) {

//如果未执行调整操作则正常读取当前时间 }

22 / 22

DelayMS(10); if(K2==0)

DateTime_Adjust(1);

//减

DelayMS(10);//while(K3==0); DateTime_Adjust(-1);

//确定

if(K3==0)

//while(K4==0); DelayMS(10); if(K4==0){ SET_DS1302();

//将调整后的时间写入DS1302

LCD_DSY_BUFFER2[13]=' '; LCD_DSY_BUFFER2[14]=' '; LCD_DSY_BUFFER2[15]=' '; Adjust_Index=-1; }

//启动定时器

if(Adjust_Index==-1) GetTime();

本文来源:https://www.bwwdw.com/article/mnl.html

Top