LED流水灯设计微型计算机及控制技术实训.docx
《LED流水灯设计微型计算机及控制技术实训.docx》由会员分享,可在线阅读,更多相关《LED流水灯设计微型计算机及控制技术实训.docx(32页珍藏版)》请在冰豆网上搜索。
LED流水灯设计微型计算机及控制技术实训
LED流水灯设计-微型计算机及控制技术实训
微型计算机及控制技术
实训
班级:
姓名:
学号:
实验一:
LED流水灯设计
一、设计目的
1.通过此次涉及、熟悉并掌握实验系统原理和方法
2.掌握流水灯原理和使用方法
二、设计过程
(1)设计内容
1.了解LED发光二极管的顺序灭
2.了解LED的使用原理和引脚接法
3.掌握实用Keil环境编程
4.掌握下载Keil编译好的称序列AT89C51单片机中
(2)实验步骤
1.掌握AT89C51单片机与外设LED的引脚接法和使用原理
2.使用Keil编译环境,编写LED发光二极管顺序灭的程序
3.在Keil编译好的程序下载到AT89c51单片机中,实现LED发光二极管顺序灭
(3)电路及程序设计
1.电路设计
2.编程如下
org0
sjmpstart
org30h
start:
movP1,#1;P1.0为1,不亮
movP1,#2;P1.1为1,不亮
movP1,#4;以下原理同上
movP1,#8
movP1,#10h
movP1,#20h
movP1,#40h
movP1,#80h
sjmpstart
delay:
nop
nop
nop
nop
ret
end
(4)设计结果
如上图:
D7亮了。
如上图:
D3亮了。
实验二8*8点阵的设计
一、实验目的:
1.了解点阵式LED显示原理。
2.掌握单片机与8×8点阵块之间接口电路设计及编程。
3.掌握8155工作原理及与单片机的接口电路设计。
二、实验要求:
利用8×8点阵显示屏,自己设计并调试电路板,实现在单片机的控制下,点阵显示屏显示数字。
三、实验步骤:
1、实验电路图
2、编码程序:
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
uchari=0,n,k;
ucharcodeTable[][8]={
{~0x00,~0x00,~0x3C,~0x42,~0x42,~0x3C,~0x00,~0x00},
{~0x00,~0x00,~0x00,~0x22,~0x7E,~0x02,~0x00,~0x00},
{~0x00,~0x00,~0x22,~0x46,~0x4A,~0x32,~0x00,~0x00},
{~0x00,~0x00,~0x22,~0x49,~0x49,~0x36,~0x00,~0x00},
{~0x00,~0x00,~0x18,~0x28,~0x7E,~0x08,~0x00,~0x00},
{~0x00,~0x00,~0x7A,~0x29,~0x29,~0x2E,~0x00,~0x00},
{~0x00,~0x00,~0x3E,~0x49,~0x49,~0x26,~0x00,~0x00},
{~0x00,~0x00,~0x40,~0x4F,~0x50,~0x60,~0x00,~0x00},
{~0x00,~0x00,~0x36,~0x49,~0x49,~0x36,~0x00,~0x00},
{~0x00,~0x00,~0x32,~0x49,~0x49,~0x3E,~0x00,~0x00},
{~0x91,~0x52,~0x00,~0xA4,~0xF5,~0xBF,~0xF4,~0xA4},
{~0x11,~0x13,~0x55,~0x51,~0x55,~0x12,~0x11,~0x00},
};
ucharcodeTab[]={~0xfe,~0xfd,~0xfb,~0xf7,~0xef,~0xdf,~0xbf,~0x7f};
voiddelay(uinti);
voidmain()
{
TMOD=0x00;
TH0=(8192-3000)/32;
TL0=(8192-3000)%32;
TR0=1;
EA=1;
ET0=1;
while
(1)
{
n=4;
}
}
voidT0_ISP(void)interrupt1
{
TH0=(8192-3000)/32;
TL0=(8192-3000)%32;
P3=Tab[k++];
if(k==8)k=0;
P0=Table[n][i];
if(++i==8)i=0;
}
voiddelay(uinti)
{
while(i--);
}
3、实验结果:
实验三:
矩阵键盘的设计
一、实验目的:
1、掌握键盘接口的基本特点,了解独立键盘和矩阵键盘的应用方法。
2、掌握键盘接口的硬件设计方法,软件程序设计和贴士排错能力。
3、复习利用Keil51软件对程序进行编译。
4、用Proteus软件绘制“矩阵键盘扫描”电路,并用测试程序进行仿真。
二、实验要求
通过实训,学生应达到以下几方面的要求:
(1)素质要求
1.以积极认真的态度对待本次实训,遵章守纪、团结协作。
2.善于发现数字电路中存在的问题、分析问题、解决问题,努力培养独立工作能力。
(2)能力要求
1.模拟电路的理论知识
2.脉冲与数字电路的理念知识
3.通过模拟、数字电路实验有一定的动手能力
4.能熟练的编写8951单片机汇编程序
5.能够熟练的运用仿真软件进行仿真
三、实训基本步骤
1、用Proteus绘制“矩阵键盘扫描”电路原理图。
2、编写程序使数码管显示当前闭合按键的键值。
(代码)
#include
#defineucharunsignedchar
#defineuintunsignedint
ucharcodedis[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0X88,0X83,
0XC6,0XA1,0X86,0X8E};
ucharcodetab[]={
0x77,0xb7,0xd7,0xe7,0x7b,0xbb,0xdb,0xeb,0x7d,0xbd,0xdd,0xed,0x7e,0xbe,0xde,0xee
};
voiddelay(uintx)
{
uchari;
while(x--)
for(i=0;i<120;i++);
}
ucharscan()
{
uchara,b,c,i;
P2=0XF0;
delay(10);
P2=0X0F;
for(i=0;i<16;i++)
if(c==tab[i])
returni;
}
voidmain()
{
ucharkey;
while
(1)
{
key=scan();
if(key!
=-1)
{
P0=dis[key];
delay(100);
}
}
}
3、利用Proteus软件的仿真功能对其进行仿真测试,观察数码管的显示状态和按键开关的对应关系。
(实验结束)
如上图:
当K7被按下时,数码管上显示出数字7了。
实验四:
电子时钟设计
一、设计目的
通过此次设计,熟悉并掌握实验系统的原理和方法。
掌握电子时钟的原理和使用方法。
二、设计要求
1、设计一个电子时钟,并且能够实现分秒实现的和调节。
2、设计出硬件电路、
3、设计出软件编程方法,并写出程序。
4、用汇编语言实现程序设计
5、利用查表,中断等方式实现目的
三、电路程序设计
1、电路设计
2、编码程序
#include
#include
//#include"LCD1602.h"
//#include"DS1302.h"
#defineuintunsignedint
#defineucharunsignedchar
sbitDS1302_CLK=P1^7;//实时时钟时钟线引脚
sbitDS1302_IO=P1^6;//实时时钟数据线引脚
sbitDS1302_RST=P1^5;//实时时钟复位线引脚
sbitACC0=ACC^0;
sbitACC7=ACC^7;
charhide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year;//秒,分,时到日,月,年位闪的计数
sbitSet=P2^0;//模式切换键
sbitUp=P2^1;//加法按钮
sbitDown=P2^2;//减法按钮
sbitout=P2^3;//立刻跳出调整模式按钮
chardone,count,temp,flag,up_flag,down_flag;
ucharTempBuffer[5],week_value[2];
voidshow_time();//液晶显示程序
/***********1602液晶显示部分子程序****************/
//PortDefinitions**********************************************************
sbitLcdRs=P2^5;
sbitLcdRw=P2^6;
sbitLcdEn=P2^7;
sfrDBPort=0x80;//P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口
//内部等待函数**************************************************************************
unsignedcharLCD_Wait(void)
{LcdRs=0;LcdRw=1;_nop_();LcdEn=1;_nop_();LcdEn=0;returnDBPort;}
//向LCD写入命令或数据************************************************************
#defineLCD_COMMAND0//Command
#defineLCD_DATA1//Data
#defineLCD_CLEAR_SCREEN0x01//清屏
#defineLCD_HOMING0x02//光标返回原点
voidLCD_Write(bitstyle,unsignedcharinput)
{LcdEn=0;LcdRs=style;LcdRw=0;_nop_();DBPort=input;_nop_();//注意顺序
LcdEn=1;_nop_();//注意顺序
LcdEn=0;_nop_();LCD_Wait();
}
//设置显示模式************************************************************
#defineLCD_SHOW0x04//显示开
#defineLCD_HIDE0x00//显示关
#defineLCD_CURSOR0x02//显示光标
#defineLCD_NO_CURSOR0x00//无光标
#defineLCD_FLASH0x01//光标闪动
#defineLCD_NO_FLASH0x00//光标不闪动
voidLCD_SetDisplay(unsignedcharDisplayMode)
{LCD_Write(LCD_COMMAND,0x08|DisplayMode);}
//设置输入模式************************************************************
#defineLCD_AC_UP0x02
#defineLCD_AC_DOWN0x00//default
#defineLCD_MOVE0x01//画面可平移
#defineLCD_NO_MOVE0x00//default
voidLCD_SetInput(unsignedcharInputMode)
{LCD_Write(LCD_COMMAND,0x04|InputMode);}
//初始化LCD************************************************************
voidLCD_Initial()
{LcdEn=0;
LCD_Write(LCD_COMMAND,0x38);//8位数据端口,2行显示,5*7点阵
LCD_Write(LCD_COMMAND,0x38);
LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR);//开启显示,无光标
LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);//清屏
LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE);//AC递增,画面不动}
//液晶字符输入的位置************************
voidGotoXY(unsignedcharx,unsignedchary)
{if(y==0)LCD_Write(LCD_COMMAND,0x80|x);
if(y==1)LCD_Write(LCD_COMMAND,0x80|(x-0x40));}
//将字符输出到液晶显示
voidPrint(unsignedchar*str)
{while(*str!
='\0')
{LCD_Write(LCD_DATA,*str);str++;}}
/***********DS1302时钟部分子程序******************/
typedefstruct__SYSTEMTIME__
{
unsignedcharSecond;
unsignedcharMinute;
unsignedcharHour;
unsignedcharWeek;
unsignedcharDay;
unsignedcharMonth;
unsignedcharYear;
unsignedcharDateString[11];
unsignedcharTimeString[9];
}SYSTEMTIME;//定义的时间类型
SYSTEMTIMECurrentTime;
#defineAM(X)X
#definePM(X)(X+12)//转成24小时制
#defineDS1302_SECOND0x80//时钟芯片的寄存器位置,存放时间
#defineDS1302_MINUTE0x82
#defineDS1302_HOUR0x84
#defineDS1302_WEEK0x8A
#defineDS1302_DAY0x86
#defineDS1302_MONTH0x88
#defineDS1302_YEAR0x8C
voidDS1302InputByte(unsignedchard)//实时时钟写入一字节(内部函数)
{unsignedchari;ACC=d;for(i=8;i>0;i--)
{DS1302_IO=ACC0;//相当于汇编中的RRC
DS1302_CLK=1;DS1302_CLK=0;ACC=ACC>>1;}}
unsignedcharDS1302OutputByte(void)//实时时钟读取一字节(内部函数)
{unsignedchari;for(i=8;i>0;i--)
{ACC=ACC>>1;//相当于汇编中的RRC
ACC7=DS1302_IO;DS1302_CLK=1;DS1302_CLK=0;}
return(ACC);}
voidWrite1302(unsignedcharucAddr,unsignedcharucDa)//ucAddr:
DS1302地址,ucData:
要写的数据
{DS1302_RST=0;
DS1302_CLK=0;
DS1302_RST=1;
DS1302InputByte(ucAddr);//地址,命令
DS1302InputByte(ucDa);//写1Byte数据
DS1302_CLK=1;
DS1302_RST=0;
}unsignedcharRead1302(unsignedcharucAddr)//读取DS1302某地址的数据
{unsignedcharucData;
DS1302_RST=0;
DS1302_CLK=0;
DS1302_RST=1;
DS1302InputByte(ucAddr|0x01);//地址,命令
ucData=DS1302OutputByte();//读1Byte数据
DS1302_CLK=1;
DS1302_RST=0;
return(ucData);}
voidDS1302_GetTime(SYSTEMTIME*Time)//获取时钟芯片的时钟数据到自定义的结构型数组
{unsignedcharReadValue;
ReadValue=Read1302(DS1302_SECOND);
Time->Second=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_MINUTE);
Time->Minute=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_HOUR);
Time->Hour=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_DAY);
Time->Day=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_WEEK);
Time->Week=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_MONTH);
Time->Month=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_YEAR);
Time->Year=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);}
voidDateToStr(SYSTEMTIME*Time)//将时间年,月,日,星期数据转换成液晶显示字符串,放到数组里DateString[]
{if(hide_year<2)//这里的if,else语句都是判断位闪烁,<2显示数据,>2就不显示,输出字符串为2007/07/22
{Time->DateString[0]='2';
Time->DateString[1]='0';
Time->DateString[2]=Time->Year/10+'0';
Time->DateString[3]=Time->Year%10+'0';}
else{Time->DateString[0]='';Time->DateString[1]='';
Time->DateString[2]='';Time->DateString[3]='';}
Time->DateString[4]='/';
if(hide_month<2)
{Time->DateString[5]=Time->Month/10+'0';
Time->DateString[6]=Time->Month%10+'0';}
else{Time->DateString[5]='';Time->DateString[6]='';}
Time->DateString[7]='/';
if(hide_day<2)
{Time->DateString[8]=Time->Day/10+'0';
Time->DateString[9]=Time->Day%10+'0';}
else{Time->DateString[8]='';Time->DateString[9]='';}
if(hide_week<2){
week_value[0]=Time->Week%10+'0';//星期的数据另外放到week_value[]数组里,跟年,月,日的分开存放,因为等一下要在最后显示}
else{week_value[0]='';}
week_value[1]='\0';
Time->DateString[10]='\0';//字符串末尾加'\0',判断结束字符}
voidTimeToStr(SYSTEMTIME*Time)//将时,分,秒数据转换成液晶显示字符放到数组TimeString[];
{if(hide_hour<2)
{Time->TimeString[0]=Time->Hour/10+'0';
Time->TimeString[1]=Time->Hour%10+'0';}
else{Time->TimeString[0]='';Time->TimeString[1]='';}
Time->TimeString[2]=':
';
if(hide_min<2){Time->TimeString[3]=Time->Minute/10+'0';
Time->TimeString[4]=Time->Minute%10+'0';}
else