单片机学习系统课程设计_secret.doc

上传人:scccc 文档编号:14392500 上传时间:2022-02-05 格式:DOC 页数:32 大小:482.50KB
返回 下载 相关 举报
单片机学习系统课程设计_secret.doc_第1页
第1页 / 共32页
单片机学习系统课程设计_secret.doc_第2页
第2页 / 共32页
单片机学习系统课程设计_secret.doc_第3页
第3页 / 共32页
单片机学习系统课程设计_secret.doc_第4页
第4页 / 共32页
单片机学习系统课程设计_secret.doc_第5页
第5页 / 共32页
点击查看更多>>
资源描述

《单片机学习系统课程设计_secret.doc》由会员分享,可在线阅读,更多相关《单片机学习系统课程设计_secret.doc(32页珍藏版)》请在三一文库上搜索。

1、电子系统设计一设计要求设计一个单片机学习系统,能够进行简单的单片机实验,要求具有以下功能:(A)键盘输入功能;(B)数码管显示;(C)LED显示(8位);(D)声音报警功能;设计出完整的电路原理图;编写上述部分实验程序。二方案设计1根据题目要求只需设计出单片机的最小系统就可满足。本次设计在最小系统的基础上增加一些外设,以满足单片机学习的基本要求。本单片机最小系统采用At89S52单片机作为MCU本次设计的外设增加了DS1302时钟芯片共阳极数码管1602液晶显示LED流水灯(8位)LCD12864AD0832数模转换44键盘24C08的存储器串口通信扬声器等。2单片机系统设计分析(1)复位电路

2、:复位电路的基本功能是:系统上电时提供复位信号,直至电源稳定后,撤销复位信号。为可靠起见,电源稳定后还要经一定的延时(共大于两个机器周期)才撤销复位信号,以电源开关或电源插头分合过程中引起抖动而影响复位。复位后P0-P3口均表现为高电平,程序计数器和特殊功能寄存器SFR全部清零。本系统采用按键手动复位方式(2) 晶振电路:晶振是为电路提供频率基准的元器件,通常分为有源晶振和无源晶振两个大类,在引脚XTAL1和XTAL2跨接晶振X1和微调电容C1、C2就构成了内部震荡方式默认值是12MHz。(3) 发光二极管电路:八个LED导通端由VCC通过上拉电阻RP1加电,并由P1口高低电平控制LED发光。

3、这里对单片机内部四个并行I/O口进行说明:1)P0端口是一个8位漏级开路型双向I/O端口,端口置1(对端口写1)时作高阻抗输入端。作为输出口时能驱动8个TTL。对内部Flash程序存储器编程时,接收指令字节;检验程序时输出指令字节,要求外接上拉电阻。在访问外部程序和外部数据存储器时,P0口是分时转换的地址(低8位)/数据总线,访问期间内部的上拉电阻起作用。2)P1端口是一个带有内部上拉电阻的8位双向I/O端口。输出时可驱动4个TTL。端口置1时,内部上拉电阻将端口拉到高电平,做输入用。对内部FLASH程序存储器编程时,接收8位地址信息。3)P2端口是一个带有内部上拉电阻的8位双向I/O端口。输

4、出时可驱动4个TTL。端口置1时,内部上拉电阻将端口拉到高电平,做输入用。对内部FLASH程序存储器编程时,接收8位地址和控制信息。在访问外部程序和16位外部数据存储器时,P2口送出高8位地址。而在访问8位地址的外部数据存储器时其引脚上的内容在此期间不会改变。4)P3端口是一个带有内部上拉电阻的8位双向I/O端口。输出时可驱动4个TTL。端口置1时,内部上拉电阻将端口拉到高电平,做输入用。对内部FLASH程序存储器编程时,接收控制信息。(4) 蜂鸣器电路:P1.7端无法直接驱动SOUNDER,通过PNP放大电流来驱动蜂鸣器。(5) 键盘电路:采用4*4矩阵式键盘,程序编写的时候采用线反转法。(

5、6) 数码管电路:本电路数码管采用四位一体共阳数码管器件,1234为位选线,adp为段码线。(7) 存储器电路:采用24C08存储器。scl为时钟线 sda为数据线。(8) 液晶LCD显示接口:本系统采用字符点阵液晶显示模块LCD1602,接口设计32-39脚为数据接口脚。(9)DS1302时钟芯片:它可以对年、月、日、周日、时、分、秒进行计时,且具有闰年补偿等多种功能.控制字节的最高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入DS1302中,位6如果为0,则表示存取日历时钟数据,为1表示存取RAM数据;位5至位1指示操作单元的地址;最低有效位(位0)如为0表示要进行写操作,为1表

6、示进行读操作,控制字节总是从最低位开始输出需要注意的是应用DS1302编程时涉及到进制的转换,将16进制转换成10进制。(具体算法见后面程序)(10)LCD12864:12864带字库液晶是一种具有4位/8位并行、2线/3线串行口多种接口方式,内部含有国籍一级,二级简体中文字库的点阵图形液晶显示模块。其分辨率为12864,内置8192个1616点汉字和128个168点ASCII字符集。编程序时具体模块分为初始化子程序、控制命令子程序、写一页子程序、读一页子程序(具体详见后面程序)三、电路原理设计,包括原理框图和电路图本次设计均在PROTEUS仿真中实现。(1)复位电路:(2) 晶振电路:(3)

7、 蜂鸣器电路:(4)发光二极管电路:(5) 键盘电路:(6) 数码管电路:(7) 存储器电路:(8) 液晶LCD显示接口:(9)DS1302时钟芯片:(10)LCD12864:总电路图,由于器件太多,如果直接用导线相连图会很乱,所以每个模块采用标号链接方式四、驱动程序及软件流程以下程序均通过Keil编译通过。(1) 44矩阵键盘程序及数码管的显示: 矩阵键盘接P2口,数码管设置接P0口(如图所示)#include unsigned char code table=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0

8、xa1,0x86,0x8e;unsigned char temp;unsigned char key;unsigned char i,j;void delay() /延时程序 for(i=50;i0;i-) for(j=200;j0;j-);void main(void) while(1) P2=0xff; P2_4=0; temp=P2; temp=temp & 0x0f; if (temp!=0x0f) delay(); /防抖动 temp=P2; temp=temp & 0x0f; if (temp!=0x0f) temp=P2; temp=temp & 0x0f; switch(tem

9、p) case 0x0e: key=7; break; case 0x0d: key=8; break; case 0x0b: key=9; break; case 0x07: key=10; break; temp=P2; P1_0=P1_0; P0=tablekey; temp=temp & 0x0f; while(temp!=0x0f) /松手检测 temp=P2; temp=temp & 0x0f; P2=0xff; P2_5=0; temp=P2; temp=temp & 0x0f; if (temp!=0x0f) delay(); temp=P2; temp=temp & 0x0f

10、; if (temp!=0x0f) temp=P2; temp=temp & 0x0f; switch(temp) case 0x0e: key=4; break; case 0x0d: key=5; break; case 0x0b: key=6; break; case 0x07: key=11; break; temp=P2; P1_0=P1_0; P0=tablekey; temp=temp & 0x0f; while(temp!=0x0f) temp=P2; temp=temp & 0x0f; P2=0xff; P2_6=0; temp=P2; temp=temp & 0x0f; i

11、f (temp!=0x0f) delay(); temp=P2; temp=temp & 0x0f; if (temp!=0x0f) temp=P2; temp=temp & 0x0f; switch(temp) case 0x0e: key=1; break; case 0x0d: key=2; break; case 0x0b: key=3; break; case 0x07: key=12; break; temp=P2; P1_0=P1_0; P0=tablekey; temp=temp & 0x0f; while(temp!=0x0f) temp=P2; temp=temp & 0x

12、0f; P2=0xff; P2_7=0; temp=P2; temp=temp & 0x0f; if (temp!=0x0f) delay(); temp=P2; temp=temp & 0x0f; if (temp!=0x0f) temp=P2; temp=temp & 0x0f; switch(temp) case 0x0e: key=0; break; case 0x0d: key=13; break; case 0x0b: key=14; break; case 0x07: key=15; break; temp=P2; P1_0=P1_0; P0=tablekey; temp=tem

13、p & 0x0f; while(temp!=0x0f) temp=P2; temp=temp & 0x0f; (2)LED的移动显示:#include /LED的左移右移unsigned char i;unsigned char temp;unsigned char a,b;void delay(void) unsigned char m,n,s; for(m=20;m0;m-) for(n=20;n0;n-) for(s=248;s0;s-); void main(void) while(1) temp=0xfe; P1=temp; delay(); for(i=1;i8;i+) a=tem

14、p(8-i); P1=a|b; /利用或运算来使LED左移或右移 delay(); for(i=1;ii; b=temp(8-i); P1=a|b; delay(); (3)声音报警功能;程序说明:用P1.7输出1KHz和500Hz的音频信号驱动扬声器,作报警信号,1KHz信号响100ms,500Hz信号响200ms,交替进行.#include #include /调用空函数所设的头文件bit flag;unsigned char count;void dely500(void) unsigned char i; for(i=250;i0;i-) _nop_(); /空操作 void main

15、(void) while(1) for(count=200;count0;count-) P1_7=P1_7; /取反,产生声音。 dely500(); for(count=200;count0;count-) P1_7=P1_7; dely500(); dely500(); (4)DS1302程序(应用若干模块来设计,方便浏览)#include /主模块#include LCD1602.h#include DS1302.hvoid Delay1ms(unsigned int count)unsigned int i,j;for(i=0;icount;i+)for(j=0;j120;j+);m

16、ain()SYSTEMTIME CurrentTime;LCD_Initial();Initial_DS1302();GotoXY(0,0);Print(Date: );GotoXY(0,1);Print(Time: );while(1)DS1302_GetTime(&CurrentTime);DateToStr(&CurrentTime);TimeToStr(&CurrentTime);GotoXY(6,0);Print(CurrentTime.DateString);GotoXY(6,1);Print(CurrentTime.TimeString);Delay1ms(300);/模块一#i

17、fndef LCD_CHAR_1602_2005_4_9/这是宏定义的一种,它可以根据是否已经定义了一个变量来进行分支选择,一般用于调试等等 #ifndef x 先测试x是否被定义过 #define x 如果没有定义下面就定义x并执行下面的语句 #endif 如果已经定义了则执行#endif后面的语句#define LCD_CHAR_1602_2005_4_9#include /端口定义sbit LcdRs= P20;sbit LcdRw= P21;sbit LcdEn = P22;sfr DBPort = 0x80;/P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口/

18、 LCD内部定义unsigned char LCD_Wait(void)LcdRs=0;LcdRw=1;_nop_();LcdEn=1;_nop_();LcdEn=0;return DBPort;/ 向LCD内部写入数据或命令#define LCD_COMMAND0 / Command#define LCD_DATA1 / Data#define LCD_CLEAR_SCREEN0x01 / 清屏#define LCD_HOMING 0x02 / 光标返回原点void LCD_Write(bit style, unsigned char input)LcdEn=0;LcdRs=style;Lc

19、dRw=0;_nop_();DBPort=input;_nop_();/注意顺序LcdEn=1;_nop_();/注意顺序LcdEn=0;_nop_();LCD_Wait();/设置显示模式#define LCD_SHOW0x04 /显示开#define LCD_HIDE0x00 /显示关 #define LCD_CURSOR0x02 /显示光标#define LCD_NO_CURSOR0x00 /无光标 #define LCD_FLASH0x01 /光标闪动#define LCD_NO_FLASH0x00 /光标不闪动void LCD_SetDisplay(unsigned char Dis

20、playMode)LCD_Write(LCD_COMMAND, 0x08|DisplayMode);/设置输入模式#define LCD_AC_UP0x02#define LCD_AC_DOWN0x00 / default#define LCD_MOVE0x01 / 画面可平移#define LCD_NO_MOVE0x00 /defaultvoid LCD_SetInput(unsigned char InputMode)LCD_Write(LCD_COMMAND, 0x04|InputMode);/初始化LCDvoid LCD_Initial()LcdEn=0;LCD_Write(LCD_C

21、OMMAND,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递增, 画面不动/*void GotoXY(unsigned char x, unsigned char y)if(y=0)LCD_Write(LCD_COMMAND,0x80|x);if(y=1)LCD_Wri

22、te(LCD_COMMAND,0x80|(x-0x40);void Print(unsigned char *str)while(*str!=0)LCD_Write(LCD_DATA,*str);str+;/*void LCD_LoadChar(unsigned char user8, unsigned char place)unsigned char i;LCD_Write(LCD_COMMAND,0x40|(place*8);for(i=0; i0; i-) DS1302_IO = ACC0; /相当于汇编中的 RRC DS1302_CLK = 1; DS1302_CLK = 0; ACC

23、 = ACC 1; unsigned char DS1302OutputByte(void) /实时时钟读取一字节(内部函数) unsigned char i; for(i=8; i0; i-) ACC = ACC 1; /相当于汇编中的 RRC ACC7 = DS1302_IO; DS1302_CLK = 1; DS1302_CLK = 0; return(ACC); void Write1302(unsigned char ucAddr, unsigned char ucDa)/ucAddr: DS1302地址, ucData: 要写的数据 DS1302_RST = 0; DS1302_C

24、LK = 0; DS1302_RST = 1; DS1302InputByte(ucAddr); / 地址,命令 DS1302InputByte(ucDa); / 写1Byte数据 DS1302_CLK = 1; DS1302_RST = 0; unsigned char Read1302(unsigned char ucAddr)/读取DS1302某地址的数据 unsigned char ucData; DS1302_RST = 0; DS1302_CLK = 0; DS1302_RST = 1; DS1302InputByte(ucAddr|0x01); / 地址,命令 ucData =

25、DS1302OutputByte(); / 读1Byte数据 DS1302_CLK = 1; DS1302_RST = 0; return(ucData);void DS1302_SetProtect(bit flag) /是否写保护if(flag)Write1302(0x8E,0x10);/?0x80elseWrite1302(0x8E,0x00);void DS1302_SetTime(unsigned char Address, unsigned char Value) / 设置时间函数DS1302_SetProtect(0);Write1302(Address, (Value/10)S

26、econd = (ReadValue&0x70)4)*10 + (ReadValue&0x0F);/16进制转10进制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)*

27、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);void DateToStr(

28、SYSTEMTIME *Time) /将时间年,月,日,星期数据转换成液晶显示字符串,放到数组里DateStringTime-DateString0 = Time-Year/10 + 0;/ 0 ascii码Time-DateString1 = Time-Year%10 + 0;Time-DateString2 = -;Time-DateString3 = Time-Month/10 + 0;Time-DateString4 = Time-Month%10 + 0;Time-DateString5 = -;Time-DateString6 = Time-Day/10 + 0;Time-Date

29、String7 = Time-Day%10 + 0;Time-DateString8 = 0;void TimeToStr(SYSTEMTIME *Time)Time-TimeString0 = Time-Hour/10 + 0;Time-TimeString1 = Time-Hour%10 + 0;Time-TimeString2 = :;Time-TimeString3 = Time-Minute/10 + 0;Time-TimeString4 = Time-Minute%10 + 0;Time-TimeString5 = :;Time-TimeString6 = Time-Second/

30、10 + 0;Time-TimeString7 = Time-Second%10 + 0;Time-DateString8 = 0;void Initial_DS1302(void)unsigned char Second=Read1302(DS1302_SECOND);if(Second&0x80) /判断时钟芯片是否关闭DS1302_SetTime(DS1302_SECOND,0);由于本次单片机设计的系统无法满足本次试验要求,顾重新布线仿真: (5)12864显示程序:#include#includezifuku.h#define uchar unsigned char#define u

31、int unsigned intsbit CS1=P20;/LCD右屏幕sbit CS2=P21;/LCD左屏幕sbit RS=P22;/LCD数据、指令寄存器sbit RW=P23;/LCD读、写操作sbit E=P24;/LCD使能信号,下降沿有效/*自定义延时子函数*/void delayms(uchar z) int x,y; for(x=z;x0;x-) for(y=110;y0;y-);/*判断LCD忙信号状*/void buys() int dat; RW=1; RS=0; do P0=0x00; E=1;dat=P0;E=0;dat=0x80 & dat; while(!(dat=0x00);/*LCD写指令函数*/void w_com(uchar com) /buys(); RW=0; RS=0; E=1; P0=com; E=0; /*LCD写数据函数*/void w_date(uchar date) /buys(); RW=0; RS=1; E=1; P0=date; E=0;/*LCD选屏函数*/void select_screen(uchar screen) switch(screen) case 0: /选择全屏

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 社会民生


经营许可证编号:宁ICP备18001539号-1