单片机89S52小游戏1602显示
单片机应用技术课程报告~1602LCD液晶显示屏的显示
单片机应用技术课程报告
实验名称1602LCD液晶显示屏的显示实验时间2020年 7月 9日学生姓名实验地点钉钉群线上
同组人员专业班级
1、实验目的
1、会使用单片机4个并行I/O端口连接外部设备并构建单片机最小应用系统。
2、能使用工具软件绘制单片机硬件原理图、能编写简LCD控制程序。
3、会使用LCD1602显示指定的内容。
2、任务设计要求
采用STC89C52单片机构建最小系统,在I/O口外接1602,编程实现在1602字符型LCD显示:实现字符的静态和动态显示。
显示字符为第一行:“I am xx”,第二行:“Hou are you”。
3、总体设计方案
根据实验任务要求,通过功能分析,设计的系统总体方案如图所示。
并
行接口AT89C51
单片机
电源
时钟电路
复位电路
实现led显示屏显示
4、硬件电路设计
5、软件程序设计
(2)程序清单
#include<reg51.h>
#include<intrins.h>//包含_nop_()空函数指令的头文件#define uchar unsigned char
#define uint unsigned int
#define out P0
sbit RS=P2^0;//位变量
sbit RW=P2^1;//位变量
sbit E=P2^2;//位变量
void lcd_ini();//LCD初始化函数
void check_busy();//检查忙标志函数
2)性能指标测试及结果分析。
基于单片机的1602液晶显示电路设计
本科毕业论文(设计)题目:基于单片机的1602液晶显示电路设计学生姓名:学号:系别:理工部专业:电气工程及其自动化入学时间:2012年09月导师姓名:职称/学位:基于单片机的1602液晶显示电路设计摘要本文是一篇介绍利用AT89S52单片机和LCD1602液晶显示屏设计一种液晶显示电路并编程实现信息的显示功能。
AT89S52是一种低功耗、高性能CMOS8位微控制器,具有8K系统可编程Flash存储器。
使用Atmel公司高密度非易失性存储器技术制造,与工业80C51产品指令和引脚完全兼容。
片上Flash允许程序存储器在系统可编程,亦适于常规编程器。
在单芯片上,拥有灵巧的8 位CPU 和在系统可编程Flash,使得AT89S52在众多嵌入式控制应用系统中得到广泛应用。
1602LCD是指显示的内容为16*2,即可以显示两行,每行16个字符液晶模块(显示字符和数字)。
从AT89S52单片机与LCD1602液晶显示器性能特点出发,实现两者接口的衔接设计。
经过多次的调试, 使得该设计取得了比较满意的结果, 且系统软硬件设计简单方便、稳定可靠, 可广泛应用于智能化仪器仪表及各种宣传场所, 为嵌入式控制系统提供高灵活、高性价比的解决方案。
关键词:AT89S52单片机;LCD1602液晶显示器;复位电路;时钟电路目录第一章前言 (2)1.1 研究现状 (2)1.2 研究意义 (2)第二章系统硬件电路设计 (3)2.1 AT89S52单片机最小系统 (3)2.1.1 主要性能 (3)2.1.2 功能 (3)2.1.3 引脚说明及实物图 (4)2.2 LCD1602液晶显示器 (7)2.2.1功能 (7)2.2.2 特点 (7)2.2.3 引脚 (7)2.3 复位电路 (9)2.4 时钟电路 (9)第三章软件设计 (10)3.1 软件设计思路 (10)3.1.1 Altium Designer (11)3.1.2 keil (11)3.1.3 AVR_fighter (11)3.2 程序设计 (12)第四章仿真及硬件电路 (15)第五章总结与展望 (17)主要参考文献 (18)致谢 (19)第一章前言本文是一篇研究基于AT89S52单片机的1602液晶显示电路设计,本次设计要求通过对单片机和1602液晶显示模块的学习,设计出完整的电路并焊出电路板,再对单片机写入程序,从而实现在液晶屏上显示出字符。
单片机1602显示程序
ORG 0000HAJMP STARTORG 0030H;液晶初始化START: MOV OUT,#01H;清屏LCALL WRMLMOV OUT,#38H;8为数据口,两行显示5*7点阵 LCALL WRMLMOV OUT,#06H;设置输入方式为光标向右移,屏幕上文字不移动LCALL WRMLMOV OUT,#0CH;设置显示方式,开显示屏LCALL WRML;第一行显示Hello!MOV OUT,#80H;设定第一行起始地址LCALL WRMLMOV R3,#80HMOV R4,#16MOV R5,#00HMOV DPTR,#TAB1WRIN1: LCALL DISPDJNZ R4,WRIN1;第二行逐字显示Nice to meet youMOV OUT,#0FH;设置显示方式,开显示屏,有光标,光标闪烁LCALL WRMLMOV OUT,#0C0H;设定第二行起始地址LCALL WRMLMOV R3,#0C0HMOV R4,#16MOV R5,#00HMOV DPTR,#TAB2WRIN2: LCALL DISPLCALL DELAYDJNZ R4,WRIN2MOV OUT,#08H;设置显示方式,关显示屏LCALL WRMLLCALL DELAYAJMP START;******************查表显示子程序******************DISP: PUSH AMOV A ,R5MOVC A,@A+DPTRMOV OUT,ALCALL WRDTINC R3INC R5POP ARET;*************判忙子程序************RDBF: MOV OUT,#0FFH;置位,准备读CLR RS;RS=0SETB RW ;R/W=1CLR ENOPSETB EJB OUT.7, RDBFRET;**************写命令子程序***************WRML: CLR RSCLR RWCLR ELCALL RDBFSETB ERET;*************写显示数据子程序*************WRDT: SETB RSCLR RW ;准备写入数据CLR E ;执行显示命令LCALL RDBF ;判断液晶模块是否忙?SETB ERET;*******************延时子程序*********** DELAY: MOV R6,#00HMOV R7,#00HDELAY1: NOPDJNZ R7,DELAY1DJNZ R6,DELAY1RETTAB1: DB 20H,20H,20H,20H,20H,48H,65H,6CH,6CH,6FH,21H ;Hello!DB 20H,20H,20H,20H,20HTAB2: DB 4EH,69H,63H,65H,20H,74H,6FH,20H,6DH,65H,65H ;Nice to meet youDB 74H,20H,79H,6FH,75HEND。
1602字符液晶显示原理+实例详解
1602详细资料和实例1602字符液晶在实际的产品中运用的也比较多了,前几天留意了一下,发现宿舍门前的自动售水机就是采用的1602液晶进行显示的。
而且对于单片机的学习而言,掌握1602的用法是每一个学习者必然要经历的过程。
在此,我将使用1602过程中遇到的问题以及感受记录下来,希望能够给初学者带来一点指导,少走一点弯路。
所谓1602是指显示的内容为16*2,即可以显示两行,每行16个字符。
目前市面上字符液晶绝大多数是基于HD44780液晶芯片的,控制原理是完全相同的,因此基于HD44780写的控制程序可以很方便地应用于市面上大部分的字符型液晶。
1602液晶的正面(绿色背光,黑色字体)1602液晶背面(绿色背光,黑色字体)另一种1602液晶模块,显示屏是蓝色背光白色字体字符型LCD1602通常有14条引脚线或16条引脚线的LCD,多出来的2条线是背光电源线VCC(15脚)和地线GND(16脚),其控制原理与14脚的LCD完全一样,引脚定义如下表所示:HD44780内置了DDRAM、CGROM和CGRAM。
DDRAM就是显示数据RAM,用来寄存待显示的字符代码。
共80个字节,其地址和屏幕的对应关系如下表:也就是说想要在LCD1602屏幕的第一行第一列显示一个"A"字,就要向DDRAM的00H地址写入“A”字的代码(指A的字模代码,0x20~0x7F为标准的ASCII码,通过这个代码,在CGROM中查找到相应的字符显示)就行了。
但具体的写入是要按LCD模块的指令格式来进行的,后面我会说到的。
那么一行可有40个地址呀?是的,在1602中我们就用前16个就行了。
第二行也一样用前16个地址。
对应如下:DDRAM地址与显示位置的对应关系。
(事实上我们往DDRAM里的00H地址处送一个数据,譬如0x31(数字1的代码,见字模关系对照表)并不能显示1出来。
这是一个令初学者很容易出错的地方,原因就是如果你要想在DDRAM的00H地址处显示数据,则必须将00H加上80H,即80H,若要在DDRAM的01H处显示数据,则必须将01H加上80H即81H。
基于AT89s52单片机1602四位数据口液晶显示
//*****************************************************************/*程序功能:显示两行字符并且整屏左移(程序使用在接口为4位的1602液晶)涉及芯片:1602液晶显示器*///*****************************************************************#include<reg52.h>#define uint unsigned int#define uchar unsigned charsbit rs=P2^0;//数据/命令选择端(H/L)sbit rw=P2^1;//读/写选择端(H/L)sbit en=P2^2; //使能选择端uchar code mingzi[]="Gci fa zhi !_! "; //定义数据mingzi【】uchar code num[]="tel:10778434282 "; //定义数组num【】void delay(uint time)//延时函数(运行的时间与晶振有关系){uint i,j;for(i=time;i>0;i--)for(j=110;j>0;j--);}void write_com(uchar mingling)//命令输入函数{uchar gao,di; //定义高、低四位gao=mingling&0xf0;//分出高四位di=(mingling<<4)&0xf0;//分出低四位//==========================================读走高四位P2=gao;//让数据(mingling)高四位有效rs=0;//rs端为低电平时,为接收命令delay(5);en=1; //en一个高脉冲读走高四位数据(mingling)delay(5);en=0;//把使能端拉回低电平//============================================读走低四位delay(5);P2=di;//让数据(mingling)低四位有效rs=0;//rs端为低电平时,为接收命令delay(5);en=1 ;//en一个高电平读走低四位命令(mingling)delay(5);en=0;//把使能端拉回低电平}void write_date(uchar shuju)//数据输入函数{uchar gao,di;gao=shuju&0xf0;//分出高四位di=(shuju<<4)&0xf0;//分出低四位//=======================================读走高四位P2=gao;//让数据(shuju)高四位有效rs=1;//rs端为高电平时,为接收数据delay(5);en=1;//en一个高电平读走低四位数据(shuju)delay(5);en=0;//把使能端拉回低电平//============================================读走低四位delay(5);P2=di;//让数据(shuju)低四位有效rs=1;//rs端为高电平时,为接收数据delay(5);en=1;//en一个高电平读走低四位数据(shuju)delay(5);en=0;//把使能端拉回低电平}void chushihua(){rw=0;//把数据/命令选择端先置为零en=0;//把使能端先置为零write_com(0x28);//设置16*12显示,5*7点阵,4位数据接口write_com(0x01);//清屏write_com(0x0c);//显示开启,不显示光标write_com(0x06);//整屏不移动}void main()//主函数{uint i,j;chushihua();//对液晶初始化while(1)//死循环{write_com(0x80);for(i=0;i<16;i++){write_date(mingzi[i]);}write_com(0x80+0x40);for(j=0;j<16;j++){write_date(num[j]);}write_com(0x18);//写控制字,在英文文档里介绍。
1602动态显示字符串的完整程序
#include<reg52.H>#include <stdio.h>#include<string.h>#define uchar unsigned charsfr lcd_data=0x80;sbit lcd_E=P0^0;sbit lcd_RW=P0^1;sbit lcd_RS=P0^2;sbit P3_4=P3^4;sbit P3_5=P3^5;sbit P3_6=P3^6;unsigned char code show1[]="Welcome"; unsigned char code show2[]="Friend"; unsigned char code show3[]="Welcome gj"; unsigned char code show4[]="Friendship"; unsigned char code show5[]="Welcome ftl"; unsigned char code show6[]="Friendship"; unsigned char code show7[]="Welcome wf"; unsigned char code show8[]="Friendship"; unsigned char temp;unsigned char key;uchar i,j,k;/****************************延时函数**************************//*函数原型:void f_v_delay5ms(void)/*函数功能:延时/*输入参数:无/*输出参数:无///**********************************************************************/void f_v_delay5ms(void){unsigned char i;unsigned char j;for(i=0;i<100;i++){for(j=0;j<250;j++);}}void f_v_delay50us(void){unsigned char i;for(i=0;i<50;i++){;}}void f_v_delay2ms(void){unsigned char i;unsigned char j;for(i=0;i<200;i++){for(j=0;j<50;j++);}}void f_v_delay10ms(void){f_v_delay5ms();f_v_delay5ms();}//*lcd显示*//****************************1602A读状态函数**************************//*函数原型:unsigned char f_uc_lcdReadStatus(void) /*函数功能:1602A读状态/*输入参数:无/*输出参数:1602A返回的状态/*调用模块:///**********************************************************************/void f_uc_lcdReadStatus(void){lcd_data=0xff;lcd_RS = 0;lcd_RW = 1;lcd_E = 1;f_v_delay50us();while(P2&0x80);//检测忙信号lcd_E = 0;}/****************************1602A写数据函数**************************//*函数原型:void f_v_lcdWriteData(unsigned charWDLCM)/*函数功能:1602A写数据/*输入参数:要写入的数?/*输出参数:无/*调用模块:/**********************************************************************/void f_v_lcdWriteData(unsigned char WDLCM){f_uc_lcdReadStatus(); //检测忙P2 = WDLCM;lcd_RS = 1;lcd_RW = 0;lcd_E = 1;//若晶振速度太高可以在这后加小的延时f_v_delay50us();//延时lcd_E = 0;}/****************************1602A写指令函数**************************//*函数原型:void f_v_lcdWriteCommand(unsigned charWCLCM,BuysC)/*函数功能:1602A写指令/*输入参数:要写入的指令/*输出参数:无/*调用模块:/**********************************************************************/void f_v_lcdWriteCommand(unsigned char WCLCM,unsigned char BuysC)/ /BuysC为0时忽略忙检测{if (BuysC)f_uc_lcdReadStatus();//根据需要检测忙P2 = WCLCM;lcd_RS = 0;lcd_RW = 0;lcd_E = 1;f_v_delay50us();//延时lcd_E = 0;}/****************************1602A读数据函数**************************//*函数原型:unsigned char f_v_lcdReadData(void)/*函数功能:1602A读数据/*输入参数:无/*输出参数:1602A返回的数据/*调用模块:/***********************************************************************//*unsigned char f_uc_lcdReadData(void){lcd_RS = 1;lcd_RW = 1;lcd_E = 0;lcd_E = 0;lcd_E = 1;return(lcd_data);}*//******************1602A按指定位置显示一个字符函数**********************//*函数原型:void f_v_displayOneChar(unsigne char X, unsigned char Y, unsigned char DData)/*函数功能:1602A按指定位置显示一个字符/*输入参数:X坐标Y坐标要显示的字符/*输出参数:无/*调用模块:/**********************************************************************/void f_v_displayOneChar(unsigned char X, unsigned char Y, unsigned ch ar DData){Y &= 0x1;X &= 0xF;//限制X不能大于15,Y不能大于1if (Y)X |= 0x40;//当要显示第二行时地址码+0x40;X |= 0x80;// 算出指令码f_v_lcdWriteCommand(X, 0);//这里不检测忙信号,发送地址码f_v_lcdWriteData(DData);}/*******************1602A按指定位置显示一串字符函数*********************//*函数原型:void f_v_displayListChar(unsigned charX, unsigned char Y, unsigned char code *DData)/*函数功能:1602A按指定位置显示一个字符/*输入参数:X坐标Y坐标要显示字符串的首地址/*输出参数:/**********************************************************************/void f_v_displayListChar(unsigned char X, unsigned char Y, unsigned cha r *DData){unsigned char ListLength;ListLength = 0;Y &= 0x1;X &= 0xF;//限制X不能大于15,Y不能大于1while (DData[ListLength]>=0x20)//若到达字串尾则退出{if (X <= 0xF)//X坐标应小于0xF{f_v_displayOneChar(X, Y, DData[ListLength]);//显示单个字符ListLength++;X++;}}}/****************************1602A初始化函数**************************//*函数原型:void f_v_lcdInit(void)/*函数功能:1602A初始化/*输入参数:无/*输出参数:无/*调用模块://**********************************************************************/void f_v_lcdInit(void){lcd_data = 0;f_v_lcdWriteCommand(0x38,0);//三次显示模式设置,不检测忙信号f_v_delay5ms();f_v_lcdWriteCommand(0x38,0);f_v_delay5ms();f_v_lcdWriteCommand(0x38,0);f_v_delay5ms();f_v_lcdWriteCommand(0x38,1);//显示模式设置,开始要求每次检测忙信号f_v_lcdWriteCommand(0x08,1);//关闭显示f_v_lcdWriteCommand(0x01,1);//显示清屏f_v_delay2ms();f_v_lcdWriteCommand(0x06,1);// 显示光标移动设置f_v_lcdWriteCommand(0x0C,1);// 显示开及光标设置}/////////////////////////////////////////////////////////////////////////////*喂狗程序*//*void f_v_watchDog(){dog=1;;;;;;;;dog=0;}*/////////////////////////////////////////////////// ///////////////////////////*void f1(){f_v_delay10ms();f_v_delay10ms();f_v_lcdInit();f_v_delay10ms();f_v_delay10ms();f_v_displayListChar(0,0,show1); f_v_displayListChar(0,1,show2); }void f2(){f_v_delay10ms();f_v_delay10ms();f_v_lcdInit();f_v_delay10ms();f_v_delay10ms();f_v_displayListChar(0,0,show3); f_v_displayListChar(0,1,show4); }void f3(){f_v_delay10ms();f_v_delay10ms();f_v_lcdInit();f_v_delay10ms();f_v_delay10ms();f_v_displayListChar(0,0,show5);f_v_displayListChar(0,1,show6);}*/void main(void){i="0";j="0";while(1){/* for(i=0;i<10;i++){;f_v_lcdInit();;f_v_displayListChar(i,0,show1);f_v_displayListChar(i,1,show2);;}for(i=10;i<16;i++){;f_v_lcdInit();;for(j=0;j<7;j++){f_v_displayOneChar((i+j)%16,0,show1[j]);f_v_displayOneChar((i+j)%16,1,show2[j]); ;}}*/for(i=0;i<16;i++){;f_v_lcdInit();;for(j=0;j<strlen(show1);j++){f_v_displayOneChar((i+j)%16,0,show1[j]);;}for(j=0;j<strlen(show2);j++){f_v_displayOneChar((i+j)%16,1,show2[j]); ;}}}}。
单片机89S52小游戏1602显示
百度贴吧,中国南车1985编写C程序源码:/*********************************************猜图案小游戏,通过4*4矩阵键盘下注,键值按从上到下,从左到右依次为0~16。
**********************************************/#include<reg52.h>#include "stdlib.h" //后面ran()随机函数调用,必须先声明#include<intrins.h>#include <string.h> //后面要调用strlen()函数,必须声明#define uchar unsigned char#define uint unsigned intsbit key_a=P1^0;sbit key_b=P1^1;sbit key_c=P1^2;sbit key_d=P1^3;sbit key_1=P1^4;sbit key_2=P1^5;sbit key_3=P1^6;sbit key_4=P1^7;sbit rs=P2^5;sbit rw=P2^6;sbit ep=P2^7;unsigned char code dis_num[]={"0123456789abcdef"};unsigned char code dis2[]={'7','4','1','.','8','5','2','0','9','6','3','=','/','*','-','+','\0'};//键盘按键值unsigned char a[8];uchar code zf1[8][8]={//自定义字符字模表10x04,0x0e,0x0f,0x1f,0x1e,0x0e,0x04,0x00, //方块0x04,0x0e,0x1f,0x1f,0x1f,0x04,0x0e,0x00,0x0e,0x0e,0x1f,0x1f,0x1f,0x04,0x0e,0x00,0x00,0x0a,0x1f,0x1f,0x1f,0x0e,0x04,0x00,0x04,0x04,0x0e,0x1f,0x0e,0x04,0x04,0x00,0x1b,0x1b,0x00,0x1b,0x00,0x1b,0x1b,0x00,0x04,0x04,0x1b,0x04,0x1b,0x04,0x04,0x00,0x04,0x0c,0x1c,0x1e,0x0f,0x06,0x04,0x00};uchar code zf2[8][8]={//自定义字符字模表20x04,0x0e,0x1e,0x1b,0x0f,0x0e,0x04,0x00,0x09,0x1b,0x1f,0x0e,0x1f,0x1b,0x12,0x00,0x0e,0x1f,0x1f,0x1f,0x1f,0x1f,0x0e,0x00,0x1f,0x1f,0x15,0x1f,0x15,0x1f,0x1f,0x00,0x0e,0x0a,0x04,0x15,0x15,0x0e,0x04,0x00,0x04,0x1f,0x15,0x04,0x0e,0x1b,0x0e,0x00,0x00,0x00,0x0a,0x00,0x11,0x0e,0x00,0x00,0x0e,0x11,0x1b,0x11,0x15,0x1b,0x0e,0x00};void delay(unsigned char ms) //延时函数{unsigned char i;while(ms--){for(i=0;i<250;i++){_nop_();_nop_();_nop_();_nop_();}}}bit lcd_bz() //测忙函数{bit result;rs=0; //1602的HD44780芯片时序表:R=L,W=H,E=H为读状态,且由D7位输出状态:H为忙,L为不忙rw=1;ep=1;_nop_();_nop_();_nop_();_nop_();result=(bit)(P0&0x80); //判断D7位状态并赋给result返回ep=0;return result;}void lcd_wcmd(unsigned char cmd) //写指令函数{while(lcd_bz());//判断LCD是否忙碌每次读写指令必须先测忙rs=0; //S=L,W=L,e为高脉冲(即L-H——L)。
基于89c52单片机LCD1602滚动显示的程序
#include "reg52.h"//此文件中定义了单片机的一些特殊功能寄存器
#include "lcd.h"
typedef unsigned int u16;//对数据类型进行声明定义
typedef unsigned char u8;
u8 a[16]="perchin designed";
{
LcdWriteData(a[i]);
}
LcdWriteCom(0x40+0x80);
for(i=0;i<27;i++)
{
LcdWriteData(b[i]);
}
LcdWriteCom(0x07);//每写一个数据屏幕就要右移一位,就相对于数据来说就是左移了;
while(1)
{
LcdWriteCom(0x00+0x80);
{
uchar a,b;
for (; c>0; c--)
{
for (b=199;b>0;b--)
{
for(a=1;a>0;a--);
}
}
}
/**************************************************************************
* 函 数 名 : LcdWriteCom
Lcd1602_Delay1ms(5); //保持时间
LCD1602_E = 0;
}
#else
void LcdWriteData(uchar dat)//写入数据
{
LCD1602_E = 0;//使能清零
LCD1602_RS = 1;//选择写入数据
89C52RC温湿度传感器DHT11液晶1602显示程序
89C52RC温湿度传感器DHT11液晶1602显示程序#include#define uint unsigned int#define uchar unsigned charuchar DHT11[5],RTflag=0;uchar FLAG; //超时标志位uchar a;sbit dat=P2^3;sbit RS=P3^4;sbit RW=P3^6;sbit EN=P3^7;uchar table[5];uint wd,sd;void Delay_t(uint j){ uchar i;for(;j>0;j--){for(i=0;i<27;i++);}}void Delay_10us(void) //10us延时函数{uchar i;i--;i--;i--;i--;i--;i--;}void delay(uint z)//1毫秒延时函数{uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void lcd_write_com(uchar com) //1602写指令{RS=0;RW=0;EN=1;P0=com;delay(1);EN=0;}void lcd_init() //1602初始化{lcd_write_com(0x38);delay(1);lcd_write_com(0x08);delay(1);lcd_write_com(0x01);//1602清屏指令delay(1);lcd_write_com(0x06);delay(1);lcd_write_com(0x0C);delay(1);}void lcd_write_data(uchar date)//1602写数据{RS=1;RW=0;EN=1;P0=date;delay(1);EN=0;}void write_str(uchar x,uchar y,uchar *s)//在任意地址写符号字母或数字{if(y==0)lcd_write_com(0x80+x);elselcd_write_com(0xc0+x);while(*s){lcd_write_data(*s);s++;}}void write_shu(uchar x,uchar y,uchar num)//数据显示函数{uchar s,g;if(y==0)lcd_write_com(0x80+x);elselcd_write_com(0xc0+x);s=num/10;// 数据分离显示lcd_write_data(0x30+s);g=num%10;//数据分离显示lcd_write_data(0x30+g);}uchar write_byte1() //读一个字节{uchar i,comdata,temp1;for(i=0;i<8;i++){FLAG=2;while((!dat)&&FLAG++);//判断数据位是0还是1Delay_10us();Delay_10us();Delay_10us();temp1=0;if(dat)temp1=1; // 如果高电平高过预定0高电平值则数据位为 1 FLAG=2;while((dat)&&FLAG++);//flag先与后加1 如果dat一直为1uchar型变量 flag 溢出变为0 再自加1if(FLAG==1)break; //超时则跳出for循环comdata<<=1;//左移一位高位在前低位在后comdata|=temp1;}return (comdata);}void DHT11_5() //读5个字节数据两个字节为温度数据两个字节为湿度数据最后一个字节为校验{uchar i,temp;//主机拉低18msdat=0;Delay_t(180);dat=1;//总线由上拉电阻拉高主机延时20usDelay_10us();Delay_10us();Delay_10us();Delay_10us();//主机设为输入判断从机响应信号dat=1;//判断从机是否有低电平响应信号如不响应则跳出,响应则向下运行if(!dat) //T !{FLAG=2; //超时标志位while((!dat)&&FLAG++);//判断从机是否发出80us 的低电平响应信号是否结束FLAG=2;while((dat)&&FLAG++); //判断从机拉高80us是否结束for(i=0;i<5;i++)//数据接收状态{DHT11[i]=write_byte1();}dat=1; //释放数据总线为下一次读取做好准备temp=(DHT11[0]+DHT11[1]+DHT11[2]+DHT11[3]);if(temp==DHT11[4]) //数据校验{RTflag=1;}if(RTflag==1) //如果RTflag=1 说明读取到得数据正确{RTflag=0;// tm[0]=DATARHT[0]/10;// tm[1]=DATARHT[0]%10;// tm[2]=DATARHT[1]/10; //湿度// tm[3]=DATARHT[2]/10;// tm[4]=DATARHT[2]%10;// tm[5]=DATARHT[3]/10; //温度write_str(0,0,"measurement ");//第一行显示湿度write_shu(12,0,DHT11[0]);write_str(14,0,"RH");write_str(0,1,"Temperature ");//第二行为显示温度write_shu(12,1,DHT11[2]);write_str(14,1,"^C");}}}void main(){lcd_init(); //1602初始化delay(1000); //等待DHT11温湿度传感器数据稳定开始激活DHT11while(1)//循环读取并更新数据显示{delay(1000);//等待DHT11温湿度传感器数据稳定开始激活DHT11write_byte1();//读一个字节DHT11_5(); //读数据delay(1000); //延时等待}}。
基于51单片机的打地鼠游戏机1602和led显示模拟(源码齐全)
目录一、摘要 (3)二、流程图 (4)三、电路原理 (5)四、操作说明 (7)五、演示图片 (8)六、程序代码 (11)一、摘要本作品采用STC89C52单片机作为主控芯片,选取LCD1602液晶作为显示屏,选用24C02芯片作为外部EEPROM存储得分等数据。
游戏程序应用C语言编译,主要使用函数为显示主界面函数,选择模式函数,随机函数,键盘扫描函数和众多界面函数。
系统配有开机音乐和led短暂特效;以及关闭游戏音乐效果。
目前配有三个难度等级,可以随时添加。
游戏中可以实时显示得分、时间等数据。
能够通过led显示和LCD1602同时显示地鼠的出现。
题目要求中所有内容均已完成,且加入了很多额外显示环节。
二、流程图三、电路原理1、主控芯片2、地鼠led和3*3键盘3、蜂鸣器和buzzer4、1602环节5、24C02芯片四、操作说明1.插上电源后,打开作品左下角的自锁开关启动。
2.系统启动后,会次显示“welcome”字样,以及本队伍的名称,并伴随着短暂的旋律,led闪烁效果。
紧接着便进入游戏选择界面,分别是:1.start 2.s core 3.exit分别对应着开始游戏,进入历史分数菜单,以及结束的功能。
通过button1 和button2键可以进行功能选择的切换和选取,button1用于切换,button2用于确认。
3.选择start选项之后会有5秒钟的准备时间,之后即可进入游戏,游戏分为3个关卡,难度依次上升,具体表现为地鼠产生的时间间隔依次减少,第一次为3秒间隔,往后依次递减。
以9个灯泡作为地鼠,每次随机亮一个灯泡,游戏者需要在另一个3*3的矩阵上在灯泡亮的时间内按下相应的按钮即代表击打相应位置,从而实现打地鼠的模拟功能。
4.游戏界面的上方有左右两行,分别对应显示剩余时间(每次游戏的时间为30秒),以及所获得的分数。
下方也有左右两行,分别对应当前所示洞的序数,5.若击中地鼠:正常情况下分数加1,播放提示音1;6.每关有(30/地鼠实现时间) 个地鼠(或地雷),击打完成后若分数大于等于level*10则进入下一关。
基于89c52单片机LCD1602显示温度与串口接收温度程序
for(i=0; i<6; i++)
{
SBUF = CNCHAR[i];//将接收到的数据放入到发送寄存器
while (!TI);//等待发送数据完成
TI = 0;
}
}
/*******************************************************************************
TI = 0;
LcdWriteCom(0x83);//写地址 80表示初始地址
LcdWriteData('0'+datas[1]); //十位
SBUF = '0'+datas[1];//将接收到的数据放入到发送寄存器
while (!TI);//等待发送数据完成
TI = 0;
LcdWriteCom(0x84);//写地址 80表示初始地址
Main.c
#include<reg52.h>
#include"lcd.h"
#include"temp.h"
uchar CNCHAR[6] = "摄氏度";
void LcdDisplay(int);
void UsartConfiguration();
/*******************************************************************************
datas[3] = temp % 100 / 10;
datas[4] = temp % 10;
LcdWriteCom(0x82);//写地址 80表示初始地址
STC89C52单片机实验---DS18B20的1602显示
这是一个利用1602液晶显示温度和蜂鸣器报警的函数;使用的测温器件是单总线DS18B20;#include<reg52.h>#include<intrins.h>#include<math.h>#define uchar unsigned char#define uint unsigned intsbit dula=P2^6; //数码管的段选sbit wela=P2^7; //数码管的位选sbit RW=P1^1; //1602sbit RS=P1^0; //1602sbit LCDEN=P2^5;sbit DS=P2^2; //DS18B20的总线sbit FM=P2^3; //蜂鸣器void delayUs(){_nop_();//微秒级的延时}void delayMs(uint a) //毫秒级的延时。
{uint i,j;for(i=a;i>0;i--)for(j=100;j>0;j--);}void writecom(uchar com) //向1602写命令;{RS=0;P0=com;LCDEN=1;delayUs();LCDEN=0;delayMs(1);}void writedat(uchar dat) //写数据。
P0=dat;LCDEN=1;delayUs();LCDEN=0;delayMs(1);}void init() // 1602初始化{RW=0;dula=0;wela=0;writecom(0x38);writecom(0x0c);writecom(0x06);writecom(0x01);}void writeString(uchar *str) //向1602写字符串。
{uchar length;uchar i=0;do{length=1+i;i++;} while(str[i]);for(i=length;i>0;i--){writedat(str[length-i]);}}int DSinit() //DS18B20的初始化{uint i;DS=0;i=100;while(i>0) i--;while(i>0) i--;while(DS) //检验是否初始化成功{i++;if(i>40000)return 0;}return 1;}void DSwait(){uint i;while(DS);while(~DS);i=4;while(i>0) i--;}bit readbit() //读一个比特{uint i;bit b;DS=0;i++;DS=1;i++;i++;b=DS;i=8;while(i>0) i--;return b;}uchar readbyte()// 利用前面的函数读一个字节{uint i;uchar j,dat;dat=0;for(i=0;i<8;i++){j=readbit();//赋值给最低位dat=(j<<7)|(dat>>1);//每位放到高位;return dat;}void writebyte(uchar dat)//写一个字节;{uint i;uchar j;bit b;for(j=0;j<8;j++){b=dat&0x01;dat>>=1;if(b){DS=0;i++;i++;i++;DS=1;i=8;while(i>0)i--;}else{DS=0;i=8;while(i>0)i--;DS=1;i++;i++;}}}void sendChangecom(){DSinit();DSwait();delayMs(1);writebyte(0xcc);writebyte(0x44);void sendReadcom(){DSinit();DSwait();delayMs(1);writebyte(0xcc);writebyte(0xbe);}int getTmpvalue(){uint tmpvalue;int value;float t;uchar low,high;sendReadcom();low=readbyte();high=readbyte();tmpvalue=high,tmpvalue<<=8;tmpvalue|=low;value = tmpvalue;t=value*0.0625;value=t*100+(value>0?0.5:-0.5); return value;}void display(int v){int count;char datas[]={0,0,0,0,0,0};uint tmp=abs(v);datas[0]=tmp/10000;datas[1]=tmp%10000/1000;datas[2]=tmp%1000/100;datas[3]=tmp%100/10;datas[4]=tmp%10;{writedat('-');}else{writedat('+');}if(datas[0]!=0)writedat('0'+datas[0]);for(count = 1;count!=5;count++){writedat('0'+datas[count]);if(count==2)writedat('.');}}void warning(int x){if((x/100)>26){ delayMs(100);FM=~FM;delayMs(100);}}void main(){char table[]="WENDU:";while(!DSinit());init();P1=0x00;writecom(0x80);sendChangecom();writeString(table );while(1){delayMs(1000);writecom(0xc0);delayMs(850);warning(getTmpvalue());sendChangecom();}}。
利用STC89C52单片机控制LCD1602
//液晶显示中文-版本0.0//作者:pcdian//定义液晶的一些功能位//RS 为数据、指令寄存器选择位//RW 为读写选择位//E 为使能位RS BIT p2.5RW BIT P2.6E BIT P2.7ORG 0000HSJMP STARTORG 000BHLJMP Timer_ITORG 0030HSTART:MOV SP,#60HMOV TMOD,#01HMOV TH0,#0A6HMOV TL0,#00HSETB EASETB ET0CLR TR0MAIN:MOV P0,#01H //清屏ACALL ENABLEMOV P0,#38H //显示模式设置为16字*2行ACALL ENABLEMOV P0,#0CH //不显示光标ACALL ENABLEMOV P0,#06H //显示方向正向且屏不移动ACALL ENABLEDISPLAY:ACALL DISPLAY_C0//我MOV P0,#80HACALL ENABLEMOV P0,#00HACALL WRITEMOV P0,#81HACALL ENABLEMOV P0,#01HACALL WRITEMOV P0,#82HACALL ENABLEMOV P0,#02HACALL WRITEMOV P0,#0C0HACALL ENABLEMOV P0,#03HACALL WRITEMOV P0,#0C1HACALL ENABLEMOV P0,#04HACALL WRITEMOV P0,#0C2HACALL ENABLEMOV P0,#05HACALL WRITELCALL DELAY1SMOV P0,#01HACALL ENABLEACALL DISPLAY_C1//们MOV P0,#83HACALL ENABLEMOV P0,#00HACALL WRITEMOV P0,#84HACALL ENABLEMOV P0,#01HACALL WRITEMOV P0,#85HACALL ENABLEMOV P0,#02HACALL WRITEMOV P0,#0C3HACALL ENABLEMOV P0,#03HACALL WRITEMOV P0,#0C4HACALL ENABLEACALL WRITEMOV P0,#0C5HACALL ENABLEMOV P0,#05HACALL WRITELCALL DELAY1SMOV P0,#01HACALL ENABLEACALL DISPLAY_C2//的MOV P0,#86HACALL ENABLEMOV P0,#00HACALL WRITEMOV P0,#87HACALL ENABLEMOV P0,#01HACALL WRITEMOV P0,#88HACALL ENABLEMOV P0,#02HACALL WRITEMOV P0,#0C6HACALL ENABLEMOV P0,#03HACALL WRITEACALL ENABLEMOV P0,#04HACALL WRITEMOV P0,#0C8HACALL ENABLEMOV P0,#05HACALL WRITELCALL DELAY1SMOV P0,#01HACALL ENABLEACALL DISPLAY_C3//0MOV P0,#89HACALL ENABLEMOV P0,#00HACALL WRITEMOV P0,#8AHACALL ENABLEMOV P0,#01HACALL WRITEMOV P0,#0C9HACALL ENABLEMOV P0,#02HACALL WRITEMOV P0,#0CAHACALL ENABLEMOV P0,#03HLCALL DELAY1SMOV P0,#01HACALL ENABLEACALL DISPLAY_C4//7MOV P0,#8BHACALL ENABLEMOV P0,#00HACALL WRITEMOV P0,#8CHACALL ENABLEMOV P0,#01HACALL WRITEMOV P0,#0CBHACALL ENABLEMOV P0,#02HACALL WRITEMOV P0,#0CCHACALL ENABLEMOV P0,#03HACALL WRITE//3MOV P0,#8DHACALL ENABLEMOV P0,#04HACALL WRITEMOV P0,#8EHACALL ENABLEMOV P0,#05HACALL WRITEMOV P0,#0CDHACALL ENABLEMOV P0,#06HACALL WRITEMOV P0,#0CEHACALL ENABLEMOV P0,#07HACALL WRITELCALL DELAY1SMOV P0,#01HACALL ENABLELJMP DISPLAY DISPLAY_C0:MOV DPTR,#TAB0MOV R2,#48ACALL DISPLAY_CRET DISPLAY_C1:MOV DPTR,#TAB1MOV R2,#48ACALL DISPLAY_CRET DISPLAY_C2:MOV DPTR,#TAB2MOV R2,#48ACALL DISPLAY_CRET DISPLAY_C3:MOV DPTR,#TAB3MOV R2,#32ACALL DISPLAY_CRET DISPLAY_C4:MOV DPTR,#TAB4MOV R2,#64ACALL DISPLAY_CRETDISPLAY_C:MOV P0,#40HACALL ENABLEMOV R3,#0DISPLAY_CC:MOV A,R3MOVC A,@A+DPTRMOV P0,ALCALL WRITEINC R3DJNZ R2,DISPLAY_CCRETENABLE:CLR RSCLR RWCLR EACALL DELAYSETB ERETWRITE:SETB RSCLR RWCLR EACALL DELAYSETB ERETDELAY1S:SETB TR0CJNE R0,#20,DELAY1SCLR TR0MOV R0,#0RETDELAY:MOV R5,#08HL1:MOV R4,#0FAHL0:DJNZ R4,L0DJNZ R5,L1RETTimer_IT:MOV TH0,#0A6HMOV TL0,#00HINC R0RETITAB0: //我DB 0x00,0x07,0x01,0x01,0x01,0x1F,0x01,0x01 DB 0x19,0x01,0x01,0x01,0x01,0x1F,0x01,0x01 DB 0x00,0x08,0x04,0x04,0x00,0x1F,0x00,0x04 DB 0x01,0x07,0x19,0x01,0x01,0x01,0x05,0x02 DB 0x18,0x00,0x00,0x01,0x06,0x00,0x00,0x00 DB 0x14,0x18,0x10,0x08,0x09,0x05,0x03,0x01TAB1: //们DB 0x01,0x01,0x02,0x02,0x06,0x04,0x0c,0x14 DB 0x08,0x04,0x06,0x04,0x10,0x10,0x10,0x10 DB 0x00,0x00,0x1e,0x02,0x02,0x02,0x02,0x02 DB 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00 DB 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00 DB 0x02,0x02,0x02,0x02,0x02,0x0a,0x04,0x00TAB2: //的DB 0x02,0x02,0x04,0x0f,0x08,0x08,0x08,0x0f DB 0x02,0x02,0x02,0x13,0x14,0x14,0x18,0x12DB 0x00,0x00,0x00,0x1e,0x02,0x02,0x02,0x02DB 0x08,0x08,0x08,0x08,0x0f,0x08,0x08,0x00DB 0x11,0x11,0x10,0x10,0x10,0x10,0x00,0x00DB 0x02,0x12,0x12,0x02,0x02,0x14,0x08,0x00TAB3: //0DB 0x00,0x00,0x03,0x04,0x08,0x08,0x08,0x08DB 0x00,0x00,0x18,0x04,0x02,0x02,0x02,0X02DB 0x08,0x08,0x08,0x08,0x04,0x03,0x00,0x00DB 0x02,0x02,0x02,0x02,0x04,0x18,0x00,0x00TAB4: //7DB 0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00DB 0x00,0x00,0x1E,0x1E,0x06,0x06,0x06,0X06DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00DB 0x06,0x06,0x06,0x06,0x06,0x06,0x00,0x00//3DB 0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x0FDB 0x00,0x00,0x1E,0x1E,0x06,0x06,0x06,0X1EDB 0x0F,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00DB 0x1E,0x06,0x06,0x06,0x1E,0x1E,0x00,0x00END四、总结:虽然LCD1602可以利用自建字符显示中文,但最多不能超过8个字符位。
基于AT89S52单片机8位数据口1602液晶显示
5、延时子程序: void delay(uint time)//延时函数,每移一位毫秒 { uint k,l; for(k=time;k>0;k--) for(l=110;l>0;l--); }
主函数:
void main()//主函数 { rw=0; en=0; write_com(0x01); write_com(0x06); write_com(0x0d); write_com(0x38); write_com(0x80+0x10); }
2、LCD1602基本初始化子程序: void chushihua() //液晶初始化 { rw=0;//开始时,把读/写选择端置为低电平 en=0;//开始时,把使能端置为低电平 write_com(0x38);//设置16*12显示,5*7点阵,8位数 据接口 write_com(0x01); //清屏 write_com(0x0f); //光标开启 write_com(0x06); //整屏不移动 }
指令集: 显示模式设置: (初始化) 0011 1000 [0x38] 设置16×2显示,5×7点阵, 8位数据接口; 数据指针设置: 数据首地址为80H,所以数据地址为80H+地址 码(0-27H,40-67H)
0x38 设置16*2显示,5*7点阵,8位数据接口 0x01 清屏 0x0F 开显示,显示光标,光标闪烁 0x08 只开显示 0x0e 开显示,显示光标,光标不闪烁 0x0c 开显示,不显示光标 0x06 地址加1,当写入数据的时候光标右移 0x02 地址计数器AC=0;(此时地址为0x80) 光标 归原点,但是DDRAM中断内容不变 0x18 光标和显示一起向左移动
因为1602识别的是ASCII码,试验可以用ASCII码直接赋值,在单片机编 程中还可以用字符型常量或变量赋值
经验证的1602显示C程序
经验证的1602显示C程序刚拿到1602时一头雾水,在网上找了资料,写好程序,接好线,将程序下载到单片机,发现1602没有任何反应。
因此我深刻怀疑我找到的参考程序有些问题。
于是又上网看看别的参考资料。
找到另一份资料时发现我的对比度调节引接的是VCC,而他的对比度调节脚接的是GND。
这时我才明白,原来这脚位的电平至关重要。
接VCC时屏幕无任何显示,而接GND时屏幕显示的高亮的小方块,只有通过电位器调到一个合适的电压时,1602才可以用合适的对比度显示出字符。
参考图片经过我的综合和修改得到以下程序,并且已经过验证。
1602显示正常。
此程序基于STC89C52RC单片机。
程序显示字符串:Holle Everone!主程序:#include <reg52.h>/************************************************************* 函数名称:main功能说明:主函数*************************************************************/ void main(void){SP=0x60;delay_ms(30); // 上电延时15msinit_LCD(); // LCD初始化LCD_disp_char(1,display_char); // 在第1行显示while(1); // 死循环}//位定义sbit LCD_RS=P2^0;sbit LCD_RW=P2^1;sbit LCD_E=P2^2;uchar display_char[17]="Holle Everone!";/*********************************************************程序名称:init_LCD()功能说明:1602初始化*********************************************************/ void init_LCD(void){LCD_write_cmd(0x38); // 8位总线,2行显示,5*7点降delay_ms(10); // 延时大于4.1msLCD_write_cmd(0x38); // 8位总线,2行显示,5*7点降delay_ms(1); // 延时大于100usLCD_write_cmd(0x38); // 8位总线,2行显示,5*7点降delay_ms(1);//总线长度while(LCD_check_BF());LCD_write_cmd(0x38); // 8位总线,2行显示,5*7点降//开显示功能while(LCD_check_BF());LCD_write_cmd(0x0f); // 开显示,有光标,闪烁// LCD_write_cmd(0x0e); // 开显示,有光标,不闪烁//清屏while(LCD_check_BF());LCD_write_cmd(0x01); // 清屏//模式设置while(LCD_check_BF());LCD_write_cmd(0x06); // 写入一个字符时:光标右移,屏幕不移}/*********************************************************程序名称:LCD_write_cmd()功能说明:写命令*********************************************************/void LCD_write_cmd(uchar comand){LCD_DATA=comand;LCD_RS_LOW();LCD_RW_LOW();LCD_E_HIGH();_nop_();_nop_();_nop_();_nop_();LCD_E_LOW();}/*********************************************************程序名称:LCD_write_data(uchar dat)功能说明:写数据*********************************************************/void LCD_write_data(uchar dat){LCD_DATA=dat;LCD_RS_HIGH();LCD_RW_LOW();LCD_E_HIGH();_nop_();_nop_();_nop_();_nop_();LCD_E_LOW();}/*********************************************************程序名称:LCD_disp_char(uchar line,uchar *p)功能说明:在什么地址显示什么字符*********************************************************/void LCD_disp_char(uchar line,uchar *p){uchar i;while(LCD_check_BF());if(line==2){LCD_write_cmd(0xc0);}else{LCD_write_cmd(0x80);}for(i=0;i<16;i++){while(LCD_check_BF());LCD_write_data(*p++);}}/********************************************************* 程序名称:LCD_check_BF()功能说明:检查忙标志*********************************************************/ uchar LCD_check_BF(void){uchar i;LCD_RS_LOW();LCD_RW_HIGH();LCD_E_HIGH();LCD_DATA=0xff;_nop_();_nop_();_nop_();_nop_();i=LCD_DATA&0x80;return(i);}/********************************************************* 程序名称:delay_40us()功能说明:*********************************************************/void delay_ms(uchar d_time){uchar i,j;for(i=0;i<d_time;i++){for(j=0;j<60;j++){_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}}}此程序只是演示了1602的基本功能,实际应用中还需要重新组织程序的编写。
89s52单片机显示四位数码管汇编语言测温程序,,,,温度可显示范围在-20—+120度
TEMPER_L EQU 36HTEMPER_H EQU 35HTEMPER_d EQU 61H ;小数位TEMPER_NUM EQU 60HFLAG1 BIT 00HDQ BIT P2.2dula bit P2.6;wela bit P2.7;bai_c equ 37hsh_c equ 38hg_c equ 39hMOV SP,#70HAAA:LCALL GET_TEMPERLCALL TEMPER_COVmov a,TEMPER_NUM ;分开TEMPER_NUM anl a,#0f0hswap amov bai_c,amov a,TEMPER_NUManl a,#0fhmov sh_c,amov g_c,TEMPER_dmov r2,#256lplp:lcall displaydjnz r2,lplpLJMP AAANOP;------------------读出转换后的温度值GET_TEMPER: LCALL INIT_1820 ;初始化程序SETB DQ ; 定时入口BCD:JB FLAG1,S22LJMP BCD ; 若DS18B20不存在则返回S22:LCALL DELAY1MOV A,#0CCH ; 跳过ROM匹配------0CCLCALL WRITE_1820MOV A,#44H ; 发出温度转换命令LCALL WRITE_1820NOPLCALL DELAYLCALL DELAYCBA:LCALL INIT_1820JB FLAG1,ABCLJMP CBAABC:LCALL DELAY1MOV A,#0CCH ; 跳过ROM匹配LCALL WRITE_1820MOV A,#0BEH ; 发出读温度命令LCALL WRITE_1820LCALL READ_18200 ;或者READ_1820RET;------------------读DS18B20的程序,从DS18B20中读出一个字节的数据READ_1820:MOV R2,#8RE1:CLR CSETB DQNOPNOPCLR DQNOPNOPNOPSETB DQMOV R3,#7DJNZ R3,$MOV C,DQMOV R3,#23DJNZ R3,$RRC ADJNZ R2,RE1RET;-------------------写DS18B20的程序WRITE_1820:MOV R2,#8CLR CWR1:CLR DQMOV R3,#6DJNZ R3,$RRC AMOV DQ,CMOV R3,#23DJNZ R3,$SETB DQNOPDJNZ R2,WR1SETB DQRET;-------------------读DS18B20的程序,从DS18B20中读出两个字节的温度数据READ_18200:MOV R4,#2 ; 将温度高位和低位从DS18B20中读出MOV R1,#36H ; 低位存入36H(TEMPER_L),高位存入35H(TEMPER_H) RE00:MOV R2,#8RE01:CLR CSETB DQNOPNOPCLR DQNOPNOPNOPSETB DQMOV R3,#7DJNZ R3,$MOV C,DQMOV R3,#23DJNZ R3,$RRC ADJNZ R2,RE01MOV @R1,ADEC R1DJNZ R4,RE00RET;-------------------将从DS18B20中读出的温度数据进行转换TEMPER_COV:MOV A,#0F0HANL A,TEMPER_L ; 舍去温度低位中小数点后的四位温度数值SWAP AMOV TEMPER_NUM,AMOV A,TEMPER_LJNB ACC.3,TEMPER_COV1 ; 四舍五入去温度值INC TEMPER_NUMTEMPER_COV1:MOV A,TEMPER_HANL A,#07HSWAP AORL A,TEMPER_NUMMOV TEMPER_NUM,A ; 保存变换后的温度数据mov a,#0fhANL A,TEMPER_Lmov TEMPER_d,aclr csubb a,#10jc jianlomov TEMPER_d,ainc TEMPER_NUMjianlo:LCALL BIN_BCDRET;-------------------将16进制的温度数据转换成压缩BCD码BIN_BCD:MOV DPTR,#TEMP_TABMOV A,TEMPER_NUMMOVC A,@A+DPTRMOV TEMPER_NUM,ARETTEMP_TAB:DB 00H,01H,02H,03H,04H,05H,06H,07HDB 08H,09H,10H,11H,12H,13H,14H,15HDB 16H,17H,18H,19H,20H,21H,22H,23HDB 24H,25H,26H,27H,28H,29H,30H,31HDB 32H,33H,34H,35H,36H,37H,38H,39HDB 40H,41H,42H,43H,44H,45H,46H,47HDB 48H,49H,50H,51H,52H,53H,54H,55HDB 56H,57H,58H,59H,60H,61H,62H,63HDB 64H,65H,66H,67H,68H,69H,70H,71HDB 72H,73H,74H,75H,76H,77H,78H,79HDB 80H,81H,82H,83H,84H,85H,86H,87HDB 88H,89H,90H,91H,92H,93H,94H,95HDB 96H,97H,98H,99H;-------------------DS18B20初始化程序INIT_1820:SETB DQNOPCLR DQMOV R0,#80HTSR1:DJNZ R0,TSR1 ; 延时SETB DQMOV R0,#25H ;96US-25HTSR2:DJNZ R0,TSR2JNB DQ,TSR3LJMP TSR4 ; 延时TSR3:SETB FLAG1 ; 置标志位,表示DS1820存在LJMP TSR5TSR4:CLR FLAG1 ; 清标志位,表示DS1820不存在LJMP TSR7TSR5:MOV R0,#06BH ;200USTSR6:DJNZ R0,TSR6 ; 延时TSR7:SETB DQRET;------------------重新写DS18B20暂存存储器设定值RE_CONFIG:JB FLAG1,RE_CONFIG1 ; 若DS18B20存在,转RE_CONFIG1 RETRE_CONFIG1:MOV A,#0CCH ; 发SKIP ROM命令LCALL WRITE_1820MOV A,#4EH ; 发写暂存存储器命令LCALL WRITE_1820MOV A,#00H ; TH(报警上限)中写入00H LCALL WRITE_1820MOV A,#00H ; TL(报警下限)中写入00H LCALL WRITE_1820MOV A,#7FH ; 选择12位温度分辨率LCALL WRITE_1820RET;------------------延时子程序DELAY:MOV R7,#2HMIN:DJNZ R7,YS500RETYS500:LCALL YS500USLJMP MINYS500US:MOV R6,#200DJNZ R6,$RETDELAY1:MOV R7,#20HDJNZ R7,$RETdisplay: ;显示程序MOV DPTR,#TABLEclr dula;mov a,bai_cMOVC a,@A+DPTRmov p0,a ;显示百位setb dula;clr dula;clr wela;mov P0,#7eh;setb wela;clr wela;mov 50h,#5hcall delayxmsclr dula;mov a,sh_cMOVC a,@A+DPTRorl a,#80h ;显示小数点mov p0,a ; ;显示十位setb dula;clr dula;clr wela;mov P0,#7dh;setb wela;clr wela;mov 50h,#5hcall delayxmsmov a,g_cMOVC a,@A+DPTRmov p0,a ; ;显示个位setb dula;clr dula;mov P0,#7bh;setb wela;clr wela;mov 50h,#5hcall delayxmsretdelayxms:mov 52h,#1 ;50h,51h,52h用于延时50h为参数x 延时1*x msdelaya: mov 51h,#125djnz 51h,$djnz 52h,delayadjnz 50h,delayxmsret ;延时返回table:db 3fh,06h,5bh,4fh,66h,6dh,7dh,07h,db 7fh,6fh,77h,7ch,39h,5eh,79h,71h。
单片机课程毕业设计 数字钟万年历1602显示原理图源程序纯手工电路板
晒晒我自己做的单片机设计手工电路板
数字钟万年历
1.AT89S51芯片作为核心。
2.实现小时、分、秒、年、月、日、星期的显示和实时温度检测。
3.该设计的电子时钟系统由时钟电路、LCD显示电路、按键调整电路和温度检测电路四部分组成。
4.使用时钟芯片DS1302完成时钟日期的功能,以LCD1602为显示器,同时利用温度传感器DS18B20测量周围环境温度.
5.共设计四个按键:
第一个是功能键,切换三个功能,分别是日期、时间和秒表;
第二个是调整键,按一下屏幕不会变化,只有当按调整加减键时,屏幕就会变化。
例如:一上电显示的是年月日,然后想调整,按一下调整键,对应的位置会闪烁,即可按调整加减键,进行修改,年调整好后,再按一下第二个调整键,光标会移动,等到合适的位置即可修改。
第三四个键是加减键;。
1602液晶屏资料和STC89C52-资料
ADC0809(1)IN0~IN7——8路模拟输入,通过3根地址译码线ADD A、ADD B、ADD C来选通一路。
(2)D7~D0——A/D转换后的数据输出端,为三态可控输出,故可直接和微处理器数据线连接。
8位排列顺序是D7为最高位,D0为最低位。
(3)ADD A、ADD B、ADD C——模拟通道选择地址信号,ADD A为低位,ADD C为高位。
地址信号与选中通道对应关系如表11.3所示。
(4)V R(+)、V R(-)——正、负参考电压输入端,用于提供片内DAC电阻网络的基准电压。
在单极性输入时,V R(+)=5V,V R(-)=0V;双极性输入时,V R(+)、V R(-)分别接正、负极性的参考电压。
图11.20 ADC0808/0809外部引脚图地址选中通道ADD C ADD B ADD A0 0 0 0 1 1 1 1 011111111IN0IN1IN2IN3IN4IN5IN6IN7(5)ALE——地址锁存允许信号,高电平有效。
当此信号有效时,A、B、C三位地址信号被锁存,译码选通对应模拟通道。
在使用时,该信号常和START信号连在一起,以便同时锁存通道地址和启动A/D转换。
(6)START——A/D转换启动信号,正脉冲有效。
加于该端的脉冲的上升沿使逐次逼近寄存器清零,下降沿开始A/D转换。
如正在进行转换时又接到新的启动脉冲,则原来的转换进程被中止,重新从头开始转换。
(7)EOC——转换结束信号,高电平有效。
该信号在A/D转换过程中为低电平,其余时间为高电平。
该信号可作为被CPU查询的状态信号,也可作为对CPU的中断请求信号。
在需要对某个模拟量不断采样、转换的情况下,EOC也可作为启动信号反馈接到START端,但在刚加电时需由外电路第一次启动。
(8)OE——输出允许信号,高电平有效。
当微处理器送出该信号时,ADC0808/0809的输出三态门被打开,使转换结果通过数据总线被读走。
在中断工作方式下,该信号往往是CPU发出的中断请求响应信号。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
百度贴吧,中国南车1985编写C程序源码:/*********************************************猜图案小游戏,通过4*4矩阵键盘下注,键值按从上到下,从左到右依次为0~16。
**********************************************/#include<reg52.h>#include "stdlib.h" //后面ran()随机函数调用,必须先声明#include<intrins.h>#include <string.h> //后面要调用strlen()函数,必须声明#define uchar unsigned char#define uint unsigned intsbit key_a=P1^0;sbit key_b=P1^1;sbit key_c=P1^2;sbit key_d=P1^3;sbit key_1=P1^4;sbit key_2=P1^5;sbit key_3=P1^6;sbit key_4=P1^7;sbit rs=P2^5;sbit rw=P2^6;sbit ep=P2^7;unsigned char code dis_num[]={"0123456789abcdef"};unsigned char code dis2[]={'7','4','1','.','8','5','2','0','9','6','3','=','/','*','-','+','\0'};//键盘按键值unsigned char a[8];uchar code zf1[8][8]={//自定义字符字模表10x04,0x0e,0x0f,0x1f,0x1e,0x0e,0x04,0x00, //方块0x04,0x0e,0x1f,0x1f,0x1f,0x04,0x0e,0x00,0x0e,0x0e,0x1f,0x1f,0x1f,0x04,0x0e,0x00,0x00,0x0a,0x1f,0x1f,0x1f,0x0e,0x04,0x00,0x04,0x04,0x0e,0x1f,0x0e,0x04,0x04,0x00,0x1b,0x1b,0x00,0x1b,0x00,0x1b,0x1b,0x00,0x04,0x04,0x1b,0x04,0x1b,0x04,0x04,0x00,0x04,0x0c,0x1c,0x1e,0x0f,0x06,0x04,0x00};uchar code zf2[8][8]={//自定义字符字模表20x04,0x0e,0x1e,0x1b,0x0f,0x0e,0x04,0x00,0x09,0x1b,0x1f,0x0e,0x1f,0x1b,0x12,0x00,0x0e,0x1f,0x1f,0x1f,0x1f,0x1f,0x0e,0x00,0x1f,0x1f,0x15,0x1f,0x15,0x1f,0x1f,0x00,0x0e,0x0a,0x04,0x15,0x15,0x0e,0x04,0x00,0x04,0x1f,0x15,0x04,0x0e,0x1b,0x0e,0x00,0x00,0x00,0x0a,0x00,0x11,0x0e,0x00,0x00,0x0e,0x11,0x1b,0x11,0x15,0x1b,0x0e,0x00};void delay(unsigned char ms) //延时函数{unsigned char i;while(ms--){for(i=0;i<250;i++){_nop_();_nop_();_nop_();_nop_();}}}bit lcd_bz() //测忙函数{bit result;rs=0; //1602的HD44780芯片时序表:R=L,W=H,E=H为读状态,且由D7位输出状态:H为忙,L为不忙rw=1;ep=1;_nop_();_nop_();_nop_();_nop_();result=(bit)(P0&0x80); //判断D7位状态并赋给result返回ep=0;return result;}void lcd_wcmd(unsigned char cmd) //写指令函数{while(lcd_bz());//判断LCD是否忙碌每次读写指令必须先测忙rs=0; //S=L,W=L,e为高脉冲(即L-H——L)。
为写指令 rw=0;ep=0;_nop_();_nop_();P0=cmd;_nop_();_nop_();_nop_();_nop_();ep=1;_nop_();_nop_();_nop_();_nop_();ep=0;}void lcd_pos(unsigned char row,pos) //光标位置设定函数,因高定光标必须要求D7=1;{if(row==1)lcd_wcmd(pos-1|0x80); //光标第一行位置设定函数0x00位开始,elselcd_wcmd(pos-1|0xc0); //光标第二行位置设定函数起始位0x40,}void lcd_wdat(unsigned char dat) //写数据函数{while(lcd_bz());//判断LCD是否忙碌rs=1;rw=0;ep=0;P0=dat;_nop_();_nop_();_nop_();_nop_();ep=1;_nop_();_nop_();_nop_();_nop_();ep=0;}void dis_lcd_byte(uchar y,uchar x,uchar z) //Y=0,1(起始行)X=0~15(起始列)Z=想写字符的ASCII码{if(y>=2) //是否显示在第二行(若在第一行Y=0,不进入IF语句,若在第二行,进入IF语句{x+=0x40; //第二行起始地址加上列数为字符显示地址}x+=0x80; //设置数据指针位置lcd_wcmd(x);lcd_wdat(z); //写入数据}void dis_lcd_text(unsigned char y,unsigned char x,unsigned char table[]) //Y,X同上字符显示,table[]字符串数组{unsigned char z=0;unsigned char t;t=strlen(table)+x; // 求得字符串长度加上起始列位置while(x<t) //功能为LCD显示到字符串最后一个字符,防止字符串{ //没有16个字符,从而不够位产生乱码;dis_lcd_byte(y,x,table[z]); //逐位显示数组内字符x++;z++;}}void lcd_init() //初始化LCD函数{delay(15);lcd_wcmd(0x38);delay(5);lcd_wcmd(0x38);delay(5);lcd_wcmd(0x38);delay(5);lcd_wcmd(0x38);delay(1);lcd_wcmd(0x08);delay(1);lcd_wcmd(0x0c);delay(1);lcd_wcmd(0x06);delay(1);lcd_wcmd(0x01);delay(1);}void lcd_cls() //清屏函数{lcd_wcmd(0x01);}unsigned char key_scan() //键盘扫描函数,4*4键盘扫描返回结果为0~15 {unsigned char i,key;unsigned char k=88;P1=0xf0;if(P1!=0xf0){P1=0xfe;for(i=0;i<4;i++){key=P1&0xf0;switch(key){case 0xe0:k=i;break;case 0xd0:k=i+4;break;case 0xb0:k=i+8;break;case 0x70:k=i+12;break;default: ;}P1=(P1<<1)+1;if(k!=88)break;}P1=0xf0;while(P1!=0xf0);return(k);}elsereturn 16;}void my_word(uchar wei,uchar *zf) //自定义字符函数{uchar j;wei=wei<<3;for(j=0;j<8;j++){lcd_wcmd(0x40|wei+j); //自定义字符地址delay(1); //延迟,否则容易出错lcd_wdat(*zf++); //自定义字符字模}}void main(void){unsigned int j,i,HP,ran,sum8;lcd_init();//初始化LCDP1=0xf0;dis_lcd_text(0,0," Made by:");dis_lcd_text(2,0," CSR1985");while(P1==0xf0);while(P1!=0xf0);start:lcd_wcmd(0x01);HP=100;while(1){for(i=0;i<8;i++)my_word(i,zf1[i]); //将自定义字符字模表1写入CGRAM dis_lcd_text(0,0,"Ready go !");lcd_wcmd(0x0f); //光标闪烁while(P1==0xf0);delay(10);while(P1!=0xf0);lcd_wcmd(0x0c); //关光标lcd_cls();delay(5);lcd_wdat('H');delay(5); //延迟一下,否则容易出错显示不出来lcd_wdat('P');delay(5);lcd_wdat('=');delay(5);lcd_wdat(dis_num[HP/100]);delay(5);lcd_wdat(dis_num[HP%100/10]);delay(5);lcd_wdat(dis_num[HP%10]);for(j=0;j<8;j++)dis_lcd_byte(1,8+j,j); //从CGRAM输出8个自定义字符dis_lcd_text(2,0,"Choose 00000000");xz:lcd_pos(2,9); //下注开始处光标设定为第二行第9个,并在此行程序做好标记XZlcd_wcmd(0x0f);for(i=0;i<8;i++){while(P1==0xf0);delay(10);a[i]=key_scan(); //用键盘下注for(j=0;j<8;j++)sum8=sum8+a[j]; //8个下注分求总和后是否为零,为零那么回到XZ处重新下注,避免全押零分开结果if(i==7&&sum8==0)goto xz;sum8=0; //下注总和清零if(HP>=a[i]) //判断总分是否够下注HP=HP-a[i];else{a[i]=HP;HP=0;}lcd_pos(1,4);lcd_wdat(dis_num[HP/100]);delay(5);lcd_wdat(dis_num[HP%100/10]);delay(5);lcd_wdat(dis_num[HP%10]);delay(5);lcd_pos(2,9+i);lcd_wdat(dis_num[a[i]]); //输出下注分数delay(5);while(P1!=0xf0);}lcd_wcmd(0x0c);while(P1==0xf0);while(P1!=0xf0);ran=TL1;j=rand(); //随机一个数作为结果j=j%8;a[j]=a[j]*(2*j+1); //所得分等于所押下注分数乘以对应倍数lcd_pos(2,1);delay(5);for(i=0;i<6;i++)lcd_wdat(j); //输出5个结果图形HP=HP+a[j]; //总分加上得分lcd_pos(1,4);lcd_wdat(dis_num[HP/100]);delay(5);lcd_wdat(dis_num[HP%100/10]);delay(5);lcd_wdat(dis_num[HP%10]);delay(5);if(HP==0) //判断HP是否为零,为零则输掉了游戏 {delay(5);dis_lcd_text(2,0,"YOU LOST GAME !!");while(1){if(key_scan()==15) //按f键重来一局{lcd_wcmd(0x01);dis_lcd_text(0,0," Try again? ");while(P1==0xf0); //任意键重来while(P1!=0xf0);goto start;}}}if(HP>800) //判断HP如果到了800,则赢得了比赛 {delay(5);dis_lcd_text(2,0," YOU WIN !! ");while(1){if(key_scan()==15){lcd_wcmd(0x01);dis_lcd_text(0,0,"Try again?");while(P1==0xf0);while(P1!=0xf0);goto start;}}}while(P1==0xf0); while(P1!=0xf0); lcd_cls();}}。