单片机实习报告(包括LED,中断,计算器等)

发布时间:2024-10-12

院系: 姓名: 学号: 班号: 指导教师:

日期:2011年月

一.实习要求

1.1实习设计要求与目的

了解并初步掌握单片机及其开发流程,综合模拟电子技术和数字电子技术,掌握以单片机为核心的电子系统体系。

通过实习掌握必要的单片机开发能力,熟悉开发环境,熟练焊接技巧,培养动手能力,锻炼自主意识。

1.2实习环境

开发环境:Keil /wave6000(伟福6000) 单片机类型:STC89C52

开发工具:万用表、5V稳压电源、电子元件、电烙铁等。

1.3实习内容

独立焊接并利用89C52的小系统板,使用C语言设计一个可以在单片机中显示特定字符,如姓名学号的程序。将其在LCM1602中显示。

可以利用该板另行扩展功能,如PS/2键盘接口,A/D,D/A转换等。

DA 转换 实时时钟 电容 电容 电容 电容 电容 电容 极性电容 电容 电容 电容 电容 电容 电容 极性电容 极性电容 电容 高亮发光二极管 DB9 公头插座 单排 16 针插座 PS2 母头插座 2 脚蓝色插座 2*17,双排 17 针插座 排阻 8 针单排排针 4 位高亮 8 段数码管(小封

U5 U6 C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C15 C16 E1 JP1 JP2 JP3 JP4 JP5 JP6 JP7 JP8 JP9 JP10 JP11 K1 Q1 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 U1

DIP20 DIP24 CAP CAP CAP CAP CAP CAP CAP CAP CAP CAP CAP CAP CAP ELECTOR ELECTOR CAP ELECTOR DB9M HDR1X16 PS2 POWER2 HDR2X17_CEN MHDR1X9 HDR1X8 4LED 4LED JTAG HDR1X3 SW1 NPN AXIAL-0.4 AXIAL-0.4 AXIAL-0.4 AXIAL-0.4 AXIAL-0.4 AXIAL-0.4 AXIAL-0.4 AXIAL-0.4 AXIAL-0.4 AXIAL-0.4 AXIAL-0.4 AXIAL-0.4 AXIAL-0.4 AXIAL-0.4 AXIAL-0.4 DIP16

DAC0832 DS12887 1uF 1uF 0.1uF 1uF 1uF 0.1uF 10uF 0.1uF 0.1uF 30pF 30pF 0.1uF 0.1uF 10uF 10uF 0.1uF 电源指示 串口 1602 插座 PS2 键盘插座 电源插座 扩展插座 10k 键盘插座

装) 4 位高亮 8 段数码管(小封 装) 2*5 插座 3 脚单排排针4 脚方形小按钮 三极管 电阻 电阻 电阻 电阻 电阻 电阻 电阻 电

阻 电阻 电阻 电阻 电阻 电阻 电阻 电位器 电平转换

JTAG 接口 跳线 复位开关 2N5551 1K 200 200 200 200 200 200 200 200 200 200 10K 10K 10K 10K MAX232N

二.芯片资料

2.1 89S52主要特性介绍:

STC89C52是一种低功耗、高性能CMOS8位微控制器,具有8K在系统可编程Flash存储器。使用Atmel公司高密度非易失性存储器技术制造,与工业80C51产品指令和引脚完全兼容。在芯片上,拥有灵巧的8位CPU和在系统可编程Flash,使得STC89C52为众多嵌入式控制应用系统提供高灵活‘超有效的解决方案。

STC89C52具有以下标准功能:8K字节Flash,256字节RAM,32位IO口线,看门狗定时器,2个数据指针,三个16位定时器计数器,一个6向量2级中断结构,全双工串行口,片内晶振及时钟电路。另外,STC89C52可降至0Hz静态逻辑操作,支持2种软件可选择节电模式。空闲模式下,CPU停止工作,允许RAM定时器\计数器,串口,中断继续工作。掉电保护方式下,RAM内容被保存,震荡器被冻结,单片机一切工作停止,直到下一个中断或硬件复位为止。

2.2 LCD1602应用简介

模块内部自带字符发生存储器(CGROM),字符有:阿拉伯数字、英文字母的大小写、常用的符号、和日文假名等,每一个字符都有一个固定的代码,比如大写的英文字母“A”的代码是(41H),显示时模块把代码41H发给液晶模块,我们就能在液晶上看到字母“A”。

1602液晶模块内部的控制器共有11条控制指令,丰富的指令可以完成液晶的时序控制、工作方式式设置和数据显示等。

该液晶显示器以其微功耗、体积小、显示内容丰富、超薄轻巧的诸多优点,在袖珍式

仪表和低功耗应用系统中得到越来越广泛的应 用。

三.电路、PCB板设计

本次实习采用PCB板已根据实际情况由宋老师帮助设计,从而除去了学生们独立设计PCB板的障碍。使得大家能够更加集中的将精力放在单片机的总体设计部分。 其中DBNZ1104和DBNZ104的布局如下:

四.主要系统单元设计

4.1 STC89C52外围电路设计

P3.1口接LED状态显示电路;晶振采用12MHz,接两个30pF的电容,起到稳定振荡频率快速起振的作用。同时晶振和电容安装在离单片机的时钟引脚比较近的文职,以减少寄生电容,更好的保证了振荡器稳定可靠的工作。

4.2电源插座、复位电路

复位电路采用手动复位,节约成本。其中RST引脚是复位信号输入端,在所示电路中,通电瞬间,C15的充电过程中,RST段出现一定宽度的正脉冲,只要该脉冲保持10ms以上,就能使单片机可靠的上电复位。

4.3 LCD接口电路

采用的LCM1602液晶模块是标准16针插座,关于LCM1602的详细资料: LCD1602各引脚说明 第1脚:VSS为地电源

第2脚:VDD接5V正电源

第3脚:V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源 时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一 个10K的电位器调整对比度 。

第4脚:RS为寄存器选择,高电平选择数据寄存器、低电平选择指令寄存器。 第5脚:RW为读写信号线,高电平时进行读操作,低电平时进行写操作。 当RS和RW共同为低电平时 (00)可以写入指令或者显示地址; 当RS为低电平RW为高电平时(01)可以读入忙信号; 当RS为高电平RW为低电平时(10)可以写入数据。

第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。 第7~14脚:D0~D7为8位双向数据线。

第15~16脚:背光阳极和背光阴极。

指令1:清显示 指令码01H, 光标复位到地址00H位置; 指令2:光标复位 指令码02H, 光标返回到地址00H位置 ; 指令3:光标和显示模式设置

I/D位 → 光标移动方向,高电平右移,低电平左移;

S 位 → 屏幕上所有文字是否左移或者右移,高电平有效,低电平无效; 指令4:显示开关控制

D 位 → 控制整体显示的开与关,高电平表示开显示,低电平表示关显示; C 位 → 控制光标的开与关,高电平表示有光标,低电平表示无光标; B 位 → 控制光标是否闪烁,高电平闪烁,低电平不闪烁 ; 指令5:光标或显示移位

S/C位 → 高电平时移动显示的文字,低电平时移动光标 指令6:功能命令设置

DL位---高电平时为4位数据总线,低电平时为8位总线; N—位低电平时为单行显示,高电平时为双行显示;

F—位低电平时显示5x7的点阵字符,高电平时为5x10的点阵字符; 指令7:字符发生器RAM地址设置 指令8:DDRAM地址设置 指令9:读忙信号和光标地址

BF位 → 为忙标志位,高电平表示忙,此时模块不能接收命令或者数据 指令10:写数据 指令11:读数据

4.4 并口通讯电路

PC并口是25针,在下载程序到单片机时必须采用合理的ISP下载线,JTAG接口解决了这个问题。

五. 购买元器件、焊接过程体会及实习总结

5.1一开始宋老师要求我们自己买元器件,我们很反感,感觉多此一举,因为以前的实习都是老师统一发放零件,让我们做实习更简单。可是真的到了华中科技市场,才知道自

己还欠缺很多,好多的元器件都不认识,甚至连自己要买什么都不清楚。来来回回跑了三趟,才真的把元器件买齐。看着终于可以写进程序的板子,我们真的感到很开心,也非常感谢老师给我们这次锻炼的机会,如果没有这次经历,直到现在我们还不知道自己差的很远。

在焊接过程中,由于没有吃透电路图的设计,对某些原件的焊接顺序等技巧没有合理掌握,造成焊错焊反的结果,这是十分值得警惕注意的,在后来的过程中,由于需要添加别的原件以及通过并口下载线烧录程序,某些之前没有仔细布局好的地方成了很大的障碍。

5.2实习了十天的我们学会了很多东西,培养了动手能力也为我们以后的工作打下了良好的基础。通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。在设计的过程中遇到问题,可以说得是困难重重,这毕竟第一次做的,难免会遇到过各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固。

这次课程设计终于顺利完成了,在设计中遇到了很多专业知识问题,最后在老师的辛勤指导下,终于游逆而解。同时,在老师的身上我们学也到很多实用的知识,在次我们表示感谢!同时,对给过我帮助的所有同学和各位指导老师再次表示忠心的感谢!

六.源程序

6.1 LED

#include"reg51.h" unsigned char Key;

unsigned char code value[16]= {

0x0e7,0x0d7,0x0b7,0x077, 0x0eb,0x0db,0x0bb,0x07b, 0x0ed,0x0dd,0x0bd,0x07d, 0x0ee,0x0de,0x0be,0x07e };

void delay() {

unsigned int t; t=2000; while(t--); }

void ScanKey() {

unsigned char P0Buf,scan,j; P0=0x0f; P0Buf=P0;

if(P0Buf!=0x0f) {

P0=0xf0; scan=P0Buf; P0Buf=P0;

scan=scan+P0Buf; for(j=0;j<16;j++) {

if(value[j]==scan) {

Key=j; break;

} } } }

void main() {

Delay(); Key=0x00; while(1)

{

ScanKey(); P1=0x40+Key; } }

6.2 1602液晶 #include"reg51.h"

unsigned char Led[8]={0,1,2,3,4,5,6,7}; void delay() {

unsigned int t; t=20000; while(t--); }

void Display() {

unsigned char i,P1Buf; for(i=0;i<=7;i++) {

P1Buf=i*2;

P1Buf=P1Buf<<4; P1Buf=Led[i]+P1Buf; P1=P1Buf; delay(); } }

void main() {

delay(); while(1) { /*

P1=0x00; P1=0x21; P1=0x42; P1=0x63; P1=0x84; P1=0xa5; P1=0xc6; */ Display(); } }

6.4定时器

#include"reg51.h"

void T0Server() interrupt 1 {

TL0=0XAF;

TH0=0X3C;//重载初值 TR0=1; P10=~P10; }

void main() {

TMOD=0x01;//定时器0 方式1 TL0=0XAF;

TH0=0X3C;//50mS TR0=1;//启动定时 ET0=1;//启动中断 EA=1; while(1); }

6.3中断

#include"reg51.h" void delay() {

unsigned char t=100; while(t--); }

void ledon() interrupt 0 {

EA=0; EX0=0; P10=~P10; EX0=1; EA=1; }

void main() {

delay();

IT0=1;//边缘

EX0=1;//INT0允许 EA=1;//全局中断允许 while(1); }

6.5 4*4键盘输入 #include"reg51.h"

unsigned char Led[8]={1,2,3,4,5,6,7,8}; unsigned char KeyV=0;

unsigned char code Key[16]= {

0x77,0x7b,0x7d,0x7e, 0xb7,0xbb,0xbd,0xbe, 0xd7,0xdb,0xdd,0xde, 0xe7,0xeb,0xed,0xee };

void delay() {

unsigned char t; t=200; while(t--); }

void dly() {

unsigned int q; q=2000; while(q--); }

void display() {

unsigned char i,P1Buf; for(i=0;i<=7;i++) {

P1Buf=i*2;

P1Buf=P1Buf<<4; P1Buf=P1Buf+Led[i]; P1=P1Buf; delay(); } }

/*0为放开,1为未放开*/ unsigned char up() {

unsigned char P0Buf; P0=0xf0; delay(); P0Buf=P0;

return(P0Buf-0xf0); }

void scan() {

unsigned char P0Buf,P0Buf2,i; P0=0xf0; P0Buf=P0;

if(P0Buf!=0xf0) {

dly(); P0=0xf0; P0Buf=P0;

if(P0Buf!=0xf0) {

P0=0x0f; P0Buf2=P0;

P0Buf=P0Buf+P0Buf2;

KeyV=P0Buf; while(up())

{display();}; /*判断按键放开*/ for(i=0;i<=15;i++) {

if(KeyV==Key[i])

{

KeyV=i; break; } }

for(i=7;i>0;i--) {

Led[i]=Led[i-1]; }

Led[0]=KeyV; } } }

void main() {

dly(); while(1) {

scan(); display(); } }

6.6计算器#include <reg51.h> #include <intrins.h> #include <math.h>

#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};

void delay(unsigned char x); //x*0.14MS void delay1(int ms);

unsigned char kk=0; //输入显示屏位数 sbit IRIN = P3^2; //红外接收器数据线 unsigned char cod[]={" "}; //符号的数组 unsigned char co=0; //第几个符号和数字 unsigned char shu[]={" "}; //数字的数组 unsigned char IRCOM[7]; //?

sbit LCD_RS = P2^6; sbit LCD_RW = P2^5; sbit LCD_EN = P2^7;

/*******************************************************************/ /* */

/*检查LCD忙状态 */

/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 */ /* */

/*******************************************************************/

bit lcd_busy() {

bit result; LCD_RS = 0; LCD_RW = 1; LCD_EN = 1;

delayNOP();

result = (bit)(P0&0x80); LCD_EN = 0; return(result); }

/*******************************************************************/ /* */

/*写指令数据到LCD */

/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 */ /* */

/*******************************************************************/

void lcd_wcmd(unsigned char cmd) {

while(lcd_busy()); LCD_RS = 0; LCD_RW = 0; LCD_EN = 0; _nop_(); _nop_(); P0 = cmd; delayNOP(); LCD_EN = 1; delayNOP(); LCD_EN = 0; }

/*******************************************************************/ /* */

/*写显示数据到LCD */

/*RS=H,RW=L,E=高脉冲,D0-D7=数据。 */ /* */

/*******************************************************************/

void lcd_wdat(unsigned char dat) {

while(lcd_busy()); LCD_RS = 1; LCD_RW = 0; LCD_EN = 0; P0 = dat; delayNOP(); LCD_EN = 1; delayNOP(); LCD_EN = 0; }

/*******************************************************************/ /* */

/* LCD初始化设定 */ /* */

/*******************************************************************/

void lcd_init() {

delay1(15);

lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据 delay1(5);

lcd_wcmd(0x38); delay1(5);

lcd_wcmd(0x38); delay1(5);

lcd_wcmd(0x0c); //显示开,关光标 delay1(5);

lcd_wcmd(0x06); //移动光标 delay1(5);

lcd_wcmd(0x01); //清除LCD的显示内容 delay1(5); }

/*******************************************************************/ /* */

/* 设定显示位置 */ /* */

/*******************************************************************/

void lcd_pos(unsigned char pos) {

lcd_wcmd(pos | 0x80); //数据指针=80+地址变量 }

/*******************************************************************/ main()

{ unsigned char code cdis1[ ] = {" calculator "}; unsigned char code cdis2[ ] = {" loading... "};

unsigned char m; long jj=1000;

IRIN=1; //I/O口初始化 shu[0]=0;

delay1(10); //延时

lcd_init(); //初始化LCD ////////////////初始化///////////////////// while(jj--) {

lcd_pos(0); //设置显示位置为第一行的第1个字符

m = 0;

while(cdis1[m] != '\0') { //显示字符 lcd_wdat(cdis1[m]); m++; }

lcd_pos(0x40); //设置显示位置为第二行第1个字符 m = 0;

while(cdis2[m] != '\0') {

lcd_wdat(cdis2[m]); //显示字符 m++; } }

////////////////////////////////////////////////// lcd_wcmd(0x01); //清屏 IE = 0x81; //允许总中断中断,使能 INT0 外部中断 TCON = 0x01; //触发方式为脉冲负边沿触发

while(1) ;

} //end main

/**********************************************************/ void jisuan(unsigned char dodo)//计算 dodo为键值 { unsigned int v=0; // 运算的数字 unsigned char b;// 得数的位 unsigned char ans;

unsigned char ww=0x40;//输出显示的位

unsigned char ca[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39}; //的字符

unsigned char dd=0; unsigned char cow;

if (dodo==15) {

co=0;v=0;shu[0]=0; }

/****/ if (dodo>=10&&dodo<=13) //符号出现 {

cod[co]=dodo; co+=1; shu[co]=0;

//得到数字 }

/****/if (dodo>=0&&dodo<=9) //数字出现 {

shu[co]=shu[co]*10+dodo; }

/****/ if (dodo==14) //等号出现 { b=0;

////////计算过程/////////

cow=co;ans=shu[0]; //cow为运算符号总数 for(co=0;co<cow;co++) { if (cod[co]==12) {

shu[co+1]=(shu[co]*shu[co+1]);

for(v=co;v<cow;v++) {

shu[v]=shu[v+1]; cod[v]=cod[v+1]; }

co-=1;

输出显示

    精彩图片

    热门精选

    大家正在看