此项目是作为单片机应用系统设计,通过STC单片机实验开发装置的结构、原理电路、以及其所能实现的功能和应用,建立单片机实现多功能综合应用系统的整体概念,打下实际工程项目设计、开发、应用的较好基础。
- 分析和熟悉实验装置的硬件结构
- 分析和掌握实验装置的电路原理:器件工作原理、电路接口原理、端口和编址分配原理、电路的主要技术参数等
- 分析和了解设计方法,理解器件的合理布局,装置的工艺设计及安装工艺
一、说明
系统是一个综合性单片机开发应用的系统,是以“单片机实验开发装置”为基础进行设计,包括:存储器扩展、I/O部件控制(LED、数码管、继电器、扬声器、矩阵键盘等电路。在Proteus虚拟仿真集成环境下设计了“单片机实验开发装置”的仿真电路,在Keil µVision4集成开发环境下,采用C51编程编程实现以下功能:
- 用LED显示外部中断。LED花样自动循环显示,并自动控制显示的次数和时间间隔:①流水灯30遍;②高低4位交替闪亮10遍;③双流水灯30遍;④循环二进制加1结果1遍;⑤奇偶灯交替闪亮30遍。⑥二进制减1
- 用矩阵式键盘的0-9数字键控制8段数码管显示0-9。将矩阵键盘的键值采用LED数码管显示出来,当按下数字键0-9时,在数码管上显示,要求每按一个新数字时,数码管显示新数字
- 连接一个Proteus器件库有的LCD模块进行显示。在Keil µVision4集成开发环境下,采用C51编程,完成了LCD汉字动态显示控制,用按键控制显示“产教融合”的拼音
二、重点
- 分析和熟悉实验装置的硬件结构
- 分析和掌握实验装置的电路原理:器件工作原理、电路接口原理、端口和编址分配原理、电路的主要技术参数等
- 在仿真调试中验证仿真电路设计的正确性和软件设计的正确性,实现设计的目标
三、实现
用LED显示外部中断
#include <reg52.h> //#include <absacc.h> //#define LED XBYTE[0x4000] sbit P26 = P2^6; sbit INT_0 = P3^2; unsigned int i=0; //unsigned char key1=0,key=0; unsigned int count=0; unsigned char kd1=0x01,kd2=0x0f,kd3=0x03,kd4=0;kd5=0x55;kd6=0xff; //功能:51单片机,12M,10ms延时程序 void delay10ms(void) { unsigned char i,j,k; //idata for(i=5;i>0;i--) for(j=4;j>0;j--) for(k=248;k>0;k--); } //500ms延时子程序(12MHZ) void delay500ms(void) { unsigned char i,j,k; //idata for(i=10;i>0;i--) for(j=132;j>0;j--) for(k=150;k>0;k--); } void main() { EA=1; //开总中断 EX0=1; //开外部中断0 IT0=1; //=1为边沿触发,至关重要 while(1) { P1=0x0f; switch (count) { case 0:P0=kd1; P26=1;P26=0;kd1<<=1;delay500ms();if (kd1==0) kd1=0x01; break; case 1: P0=kd2;P26=1;P26=0;kd2=~kd2;delay500ms(); break; case 2: P0=kd3;P26=1;P26=0;kd3<<=1; kd3<<=1;delay500ms();if (kd3==0x00) kd3=0x03; break; case 3: P0=kd4;P26=1;P26=0;delay500ms();kd4++; break; case 4: P0=kd5;P26=1;P26=0;delay500ms();kd5=~kd5; break; case 5: P0=kd6;P26=1;P26=0;delay500ms();kd6--; break; } } } void int0(void) interrupt 0 { EX0=0; delay10ms(); if (INT_0==0) { count++; if (count==6) count=0; } EX0=1; }
用矩阵式键盘的0-9数字键控制8段数码管显示0-9
#include <reg51.h> #include <string.h> unsigned char data kd1=0x01,kd2=0x0f,kd3=0x03,kd4=0,key; sbit P26=P2^6; void delay() { unsigned char data i,j; for(i=0;i<255;i++) for(j=0;j<255;j++); } void main(void) { // P1=0x0f; 此句放此不行,分析原因:其它语句对P1口信号有影响; while(1) { delay(); P1=0x0f; key=~P1; key=key&0x06; switch (key) { case 0: P0=kd1; P26=1; P26=0; kd1=kd1<<1; if (kd1==0) kd1=0x01; break; case 2: P0=kd2; P26=1; P26=0; kd2=~kd2; //不能用:kd2=!kd2,!不是按位取反,而是表达式的逻辑值取反。 break; case 4: P0=kd3; P26=1; P26=0; // kd3=kd3<<1; kd3=kd3<<1; kd3<<=1; kd3<<=1; //注意:kd3<<1的写法不对 if (kd3==0x00) kd3=0x03; break; case 6: P0=kd4; P26=1; P26=0; kd4++; break; // default: break; //此句可不要 } } }
连接一个Proteus器件库有的LCD模块进行显示
#include <REGX52.H> #include "LCD1602.h" unsigned char TempBuffer[10]; void IntToStr(unsigned int t, unsigned char *str, unsigned char n) { unsigned char a[5]; char i, j; a[0]=(t/10000)%10; //取得整数值到数组 a[1]=(t/1000)%10; a[2]=(t/100)%10; a[3]=(t/10)%10; a[4]=(t/1)%10; for(i=0; i<5; i++) //转成ASCII码 a[i]=a[i]+'0'; for(i=0; a[i]=='0' && i<=3; i++); for(j=5-n; j<i; j++) //填充空格 { *str=' '; str++; } for(; i<5; i++) { *str=a[i]; str++; } //加入有效的数字 *str='\0'; } void Delay1ms(unsigned int count) { unsigned int i,j; for(i=0;i<count;i++) for(j=0;j<120;j++); } main() { unsigned int Count = 0; LCD_Initial(); GotoXY(0,0); Print("ChanJiaoRongHe"); GotoXY(0,1); Print(" Count"); while(1) { IntToStr(Count++,&TempBuffer[0],5); GotoXY(3,1); Print(&TempBuffer[0]); Delay1ms(100); } }
四、下载