51单片机_频率计_1602

合集下载

51单片机 1602液晶显示 TLC5615独立按键调频调幅

51单片机 1602液晶显示 TLC5615独立按键调频调幅

#include <reg52.h>#include <math.h>#define uint unsigned int#define uchar unsigned char#define PI 3.14sbit CS=P2^5; //定义片选信号IO口sbit SCLK=P2^4; //定义时钟信号IO口sbit DIN=P2^3; //定义数据输入IO口uint kk=1;sbit Aup=P1^4; //频率+sbit Adowm=P1^5;//频率-sbit Fup=P1^6; //幅度+sbit Fdowm=P1^7;//幅度-uint DataNum=128;//定义一个周期的点数uint AmNum=256; //定义一个周期的点数/*--------延时子程序----------*/void delay(unsigned char pp) //延迟时间等于k*8ms{while(pp--){unsigned char j;// P2=P2&0XF8;for(j = 0;j<123;j++); //j进行的内部循环,1次延迟8us,延迟1ms}}/*----------DA转换----------*/void DAConvert(uint Data){uchar i;Data<<=6;CS=0;SCLK=0;for (i=0;i<12;i++){DIN=(bit)(Data&0x8000);SCLK=1;Data<<=1;SCLK=0;}CS=1;SCLK=0;for (i=0;i<12;i++);}/*正弦波参数换算程序*/uint GetSinData(uchar x){uint SinData;SinData=((sin(2*PI*x/DataNum)+1)/2.0)*AmNum;return SinData;}/*----------主程序----------*/main(){uint i;while(1){for(i=0;i<DataNum;i++)DAConvert(GetSinData(i));//输出正弦波P1 = 0xFF; // 发全0行扫描码,列线输入if((P1&0xFF) != 0xFF) // 若有键按下{delay(1);// 延时去抖动if((P1&0xFF) != 0xFF)switch(AmNum){case 512: AmNum=256;break;case 32: AmNum=256; break;}switch(DataNum){case 256: DataNum=128;break;case 16: DataNum=128; break;}switch(P1){case 0x7f: AmNum=AmNum+32;break;//幅度+case 0xbf: AmNum=AmNum-32; break;//幅度-case 0xdf: DataNum=DataNum+16; break;//频率-case 0xef: DataNum=DataNum-16; break;//频率+}}}}。

基于51单片机的1602液晶频率计设计(Proteus仿真图和程序)

基于51单片机的1602液晶频率计设计(Proteus仿真图和程序)

基于51单片机的1602液晶频率计设计一、Proteus仿真图:二、程序代码//最大测量65536Hz的频率计//原理:T0定时1S,T1计数#include <REG51.H>#include<INTRINS.H>#define uchar unsigned char#define uint unsigned intuint count=0;uint nm=0;uchar Fw,Fq,Fb,Fs,Fg;#define DataPort P0sbit LCM_RS=P2^0;sbit LCM_RW=P2^1;sbit LCM_EN=P2^2;uchar code str0[]={"-Test frequency-"};uchar code str1[]={"F=00000Hz "};//uchar code str2[]={" "};/*******************************/void delay(unsigned int k){unsigned int i,j;for(i=0;i<k;i++){for(j=0;j<121;j++){;}}}//=================================================///* 函数名:void WaitForEnable(void)作用:检测忙碌信号*///================================================//void WaitForEnable(void){DataPort=0xff;LCM_RS=0;LCM_RW=1;_nop_();LCM_EN=1;_nop_();_nop_();//while(DataPort&0x80);delay(5);LCM_EN=0;}//==========================================================// /* 函数名:void WriteCommandLCM(uchar CMD,uchar Attribc)作用:写命令到LCM *///==========================================================// void WriteCommandLCM(uchar CMD,uchar Attribc){if(Attribc)WaitForEnable();LCM_RS=0;LCM_RW=0;_nop_();DataPort=CMD;_nop_();LCM_EN=1;_nop_();_nop_();LCM_EN=0;}//=========================================================///* 函数名:void WriteDataLCM(uchar dataW)作用:写数据*///=========================================================// void WriteDataLCM(uchar dataW){WaitForEnable();LCM_RS=1;LCM_RW=0;_nop_();DataPort=dataW;_nop_();LCM_EN=1;_nop_();_nop_();LCM_EN=0;}//=========================================================///* 函数名:void InitLcd()作用:LCM初始化*///=========================================================// void InitLcd(){WriteCommandLCM(0x38,1);WriteCommandLCM(0x08,1);WriteCommandLCM(0x01,1);WriteCommandLCM(0x06,1);WriteCommandLCM(0x0c,1);}//=========================================================///*函数名:void DisplayOneChar(uchar X,uchar Y,uchar DData)作用:显示指定坐标的一个字符*///=========================================================// void DisplayOneChar(uchar X,uchar Y,uchar DData){Y&=1;X&=15;if(Y)X|=0x40;X|=0x80;WriteCommandLCM(X,0);WriteDataLCM(DData);}//============================================================// /*函数名:void DisplayListChar(uchar X,uchar Y,uchar code *DData作用:显示指定坐标的一串字符*///============================================================// void DisplayListChar(uchar X,uchar Y,uchar code *DData){uchar ListLength=0;Y&=0x1;X&=0xF;while(X<=15){DisplayOneChar(X,Y,DData[ListLength]);ListLength++;X++;}}//============================================================// /* 函数名:void main(void)作用:主函数*///============================================================////============================================================// /* 函数名:void display()作用:显示函数*///============================================================// void display(){Fw=count/10000+0x30;Fq=count/1000%10+0x30;Fb=count/100%10+0x30;Fs=count/10%10+0x30;Fg=count%10+0x30;DisplayOneChar(2,1,Fw);DisplayOneChar(3,1,Fq);DisplayOneChar(4,1,Fb);DisplayOneChar(5,1,Fs);DisplayOneChar(6,1,Fg);}void InitTime(void){TMOD=0x51;//T0为定时器工作于方式1,T1为计数器工作于方式1TH0=0x4C;//定时器50ms赋高8初值, 12M晶振TL0=0x00;//定时器50ms赋低8初值, 12M晶振TR0=1;//开定时器1TH1=0;//计数器赋高8初值初值TL1=0;//计数器赋低8初值TR1=1;//开计数器0ET0=1;EA=1;}void timeo(void) interrupt 1{TH0=0x4C;//定时器50ms赋高8初值TL0=0x00;//定时器50ms赋低8初值nm=nm+1;if(nm==10){TR1=0; //关闭T1定时器,定时1S完成TR0=0;//关闭T0}}//============================================================// /* 函数名:void main(void)作用:主函数*///============================================================// void main(void){char i;uint temp,temp1;delay(500);InitLcd(); //LCM初始化设置InitTime();for(i=15;i>=0;i--){DisplayListChar(i,0,str0);//显示第一行字符DisplayListChar(i,1,str1);//显示第二行字符delay(100);}while(1){if(nm==10)//定时10*50MS=500ms{temp=TL1;temp1=TH1;count=2*(temp1*256+temp);//定时2乘以500ms=1000ms display();TH1=0;//计数器赋高8初值初值TL1=0;//计数器赋低8初值nm=0;TR1=1;TR0=1;}}}。

基于51单片机数字温度计课设1602的设计和实现

基于51单片机数字温度计课设1602的设计和实现

基于51单片机数字温度计课设1602的设计和实现引言随着科技的发展和时代的进步,人们的生活水平日渐提高,对于环境的要求也越来越高。

其中,温度是一个非常重要的参数。

无论是日常生活还是科学实验,温度的测量都是至关重要的。

本文主要介绍了一个基于51单片机数字温度计课设1602的设计和实现,旨在方便人们测量温度、监测环境的变化。

系统设计设计要求本次的温度计设计需要满足以下要求:1、能够准确测量环境温度,并且实时监测环境的变化。

2、能够以数字的形式将温度值显示在1602液晶显示屏上。

3、具备温度过高或过低时进行声音提示和灯光警告的功能。

硬件选型本次设计采用了如下硬件:1、51单片机:主要负责数据的处理和控制。

2、DS18B20温度传感器:专门用来测量温度。

3、1602液晶显示器:用于显示温度值。

4、蜂鸣器:用来进行声音提示。

5、LED灯:用来进行灯光警告。

6、面包板、电源、杜邦线等。

系统原理DS18B20是一种数字温度传感器,它可以在一个单芯线上实现数字温度测量。

我们可以通过51单片机来对DS18B20进行一系列的控制和读取。

经过一定的计算,我们可以将测得的温度值以数字的形式显示在1602液晶显示器上。

在此基础上,通过对蜂鸣器和LED等的控制,可以进行声音和灯光的警告功能。

系统实现硬件连接根据硬件选型及系统原理,将各个器件以如下图的方式进行连接。

软件设计软件主要分为硬件初始化、温度计算、数码管显示、报警功能等几大部分。

1、硬件初始化:需要初始化IO口、定时器、串口等,将各个硬件初始化,以便后续的使用。

2、温度计算:读取DS18B20传感器寄存器中的数值,并进行一定的计算,将其转化为温度值。

3、数码管显示:将温度值按照规定的格式以数字的形式在1602液晶屏上进行显示。

4、报警功能:当温度过高或过低时,通过蜂鸣器和LED等进行声音和灯光警告。

系统测试经过一系列的硬件和软件设计,我们可以对整个系统进行测试。

首先,在正常温度下,我们可以看到液晶显示屏上显示的温度值以及蜂鸣器和LED等均未进行报警提示。

基于51单片机的频率计

基于51单片机的频率计
while(1)
TL0=0xfd;
EA=1; //开总中断
ET0=1; //开定时器0中断
TR0=1; //启动定时器0
TH1=0x00;//定时器1装初值
TL1=0x00;
ET1=1;//开定时器1中断
TR1=1;//启动定时器1
}
/*显示函数*/
void show1()
{
rate7=f/1000000;
write_sfm(0,rate7);
f1=f;
}
}
void show2()
{
if(f1!=0)
{
T=100000000/f1;
t7=T/1000000;
write_sfm(0,t7);
t6=(T%1000000)/10000;
write_sfm(2,t6);
t5=(T%10000)/100;
write_sfm(4,t5);
write_string(6,1,".");
}
void init_1602()//初始化
{
dx=0;wx=0;led_cs=0,c=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
TMOD=0x51;//设置定时器1计数工作模式1 定时器0计时工作模式1
TH0=0x4b;//定时器0装初值
2.2程序的设计
2.2.1程序设计思路
以T0计数器计数,程序主要完成对输入信号和标准号个数的测量、测量输入信号高电平和低电平。单片机主要完成对程序的控制、计算和显示相关信息及进行人机交互,并通过1602显示屏显示。

51单片机驱动LCM1602

51单片机驱动LCM1602

功能;驱动LCM1602,LCM1602为深圳誉信公司的16*2液晶字符型显示模块,程序使用读写方式控制LCM1602,地址分别为:写指令口:80H; 读忙检查口:81H;写数据口:82H; 读数据口:83H;;子程序1:写控制指令子程序;子程序2:写CGRAM数据子程序;子程序3:写DDRAM子程序;子程序4:写数据子程序;子程序5:读忙子程序RG_DLY EQU 2HORG 0000HAJMP MAIORG 0030HMAI: MOV SP,#60HLP_MAI: NOPLCALL SB_WRIN;调用写控制指令子程序LCALL SB_WRCG;调用写CGRAMLP2_MAI:NOPLCALL SB_WRDR;调用写DDRAMRT_MAI: AJMP LP2_MAI;---------------------------------------------------------;---------子程序---开始------------------------------------;-1------写控制指令子程序----------SB_WRIN:PUSH ACCMOV R0,#80H ;写指令口MOV A,#01H ;(INSTR.1)LCALL SB_WAT ;清屏MOVX @R0,AMOV A,#02H ;(INSTR.2)LCALL SB_WAT ;A光标归位MOVX @R0,AMOV A,#06H ;(INSTR.3)LCALL SB_WAT ;AC自动加一,画面不动;MOVX @R0,AMOV A,#0CH ;(INSTR.4)0FH:显示开,关标开,闪烁开LCALL SB_WAT ;0CH 显示开,关标、闪烁关 MOVX @R0,A;MOV A,#18H ;(INSTR.5);LCALL SB_WAT ;光标或画面平移指令;MOVX @R0,AMOV A,#38H ;(INSTR.6)LCALL SB_WAT ;8位数据,2行显示,5-7点阵MOVX @R0,APOP ACCRET;-2----写CGRAM数据子程序------SB_WRCG:PUSH ACCMOV DPTR,#CGRMOV R1,#40H;=CGRAM的首地址MOV R2,#4;=4个字符LP_WG0: MOV R3,#8;=每个字符有8位数据即8行LP_WG1: MOV R0,#80HMOV A,R1LCALL SB_WATMOVX @R0,ACLR AMOVC A,@A+DPTRLCALL SB_WRTDINC R1INC DPTRDJNZ R3,LP_WG1DJNZ R2,LP_WG0NOPPOP ACCRET;-3-----写DDRAM子程序--------SB_WRDR:PUSH ACCMOV R0,#80HMOV A,#80H ; 写第一行DDRAM数据LCALL SB_WATMOVX @R0,AMOV A,#49H ; ILCALL SB_WRTDMOV A,#20H ; SPACELCALL SB_WRTDMOV A,#4CH ; LLCALL SB_WRTDMOV A,#4FH ; OLCALL SB_WRTDMOV A,#56H ; VLCALL SB_WRTDMOV A,#45H ; ELCALL SB_WRTDMOV A,#20H ; SPACELCALL SB_WRTDMOV A,#4DH ; MLCALL SB_WRTDMOV A,#59H ; YLCALL SB_WRTDMOV A,#20H ; SPACELCALL SB_WRTDMOV A,#42H ; BLCALL SB_WRTDMOV A,#41H ; ALCALL SB_WRTDMOV A,#42H ; BLCALL SB_WRTDMOV A,#59H ; YLCALL SB_WRTDMOV A,#20H ; EMPTYLCALL SB_WRTDMOV A,#20H ; EMPTYLCALL SB_WRTDMOV R0,#80HMOV A,#0C0H ;写第二行DDRAM LCALL SB_WATMOVX @R0,AMOV A,#49H ; ILCALL SB_WRTDMOV A,#20H ; SPACE LCALL SB_WRTDMOV A,#41H ; ALCALL SB_WRTDMOV A,#4CH ; LLCALL SB_WRTDMOV A,#53H ; SLCALL SB_WRTDMOV A,#4FH ; OLCALL SB_WRTDMOV A,#20H ; SPACELCALL SB_WRTDMOV A,#4DH ; MLCALL SB_WRTDMOV A,#49H ; ILCALL SB_WRTDMOV A,#53H ; SLCALL SB_WRTDMOV A,#53H ; SLCALL SB_WRTDMOV A,#20H ; SPACE LCALL SB_WRTDMOV A,#59H ; YLCALL SB_WRTDMOV A,#4FH ; OLCALL SB_WRTDMOV A,#55H ; ULCALL SB_WRTDMOV R2,#50 ;延时229ms ACALL SB_DLYPOP ACCRET;-4---写数据子程序---------SB_WRTD:MOV R0,#82H ; LCALL SB_WATMOVX @R0,A ;RET;-5---读忙子程序-----------SB_WAT: PUSH ACCPUSH 00HMOV R0,#81HLP_WAT: MOVX A,@R0RLC AJC LP_WATPOP 00HPOP ACCRET;---------子程序----结束----------------------------------- ;---------------------------------------------------------;------延时子程序-----------SB_DLY: PUSH RG_DLY ;LP1_DLY:PUSH RG_DLYLP2_DLY:PUSH RG_DLYDJNZ R2,$POP RG_DLYDJNZ R2,LP2_DLYPOP RG_DLYDJNZ R2,LP1_DLYPOP RG_DLYDJNZ R2,SB_DLYRET;----------CGRAM区---------- CGR:...................;(用户自编码字符区)END。

51单片机的1602计算器

51单片机的1602计算器

51单片机的1602计算器一、51 单片机和 1602 液晶显示屏简介51 单片机是指英特尔公司生产的 8051 系列单片机,它具有丰富的资源,包括 I/O 端口、定时器、中断等。

通过编程,可以让 51 单片机完成各种复杂的任务。

1602 液晶显示屏是一种字符型液晶显示模块,它能够显示两行,每行 16 个字符。

1602 液晶显示屏的控制方式相对简单,通过发送特定的指令和数据,就可以实现字符的显示。

二、硬件设计要实现 51 单片机的 1602 计算器,首先需要进行硬件设计。

硬件部分主要包括 51 单片机最小系统、1602 液晶显示屏、按键等。

51 单片机最小系统通常包括单片机芯片、晶振电路和复位电路。

晶振电路为单片机提供时钟信号,复位电路则保证单片机能够正常启动。

1602 液晶显示屏与51 单片机的连接需要用到一些数据线和控制线。

数据线用于传输要显示的数据,控制线用于控制显示屏的工作状态。

按键用于输入数字和运算符,常见的按键有数字键 0 9 、运算符+、、、/以及等于号=等。

三、软件编程软件编程是实现 51 单片机 1602 计算器的关键。

在编程过程中,需要实现以下几个主要功能:1、初始化 1602 液晶显示屏在程序开始时,需要对 1602 液晶显示屏进行初始化,设置显示模式、光标显示等。

2、按键扫描通过不断扫描按键状态,获取用户输入的数字和运算符。

3、数据处理根据用户输入的数字和运算符,进行相应的计算,并将结果存储起来。

4、显示结果将计算结果显示在 1602 液晶显示屏上。

```cinclude <reg52h> //包含 51 单片机的头文件//定义 1602 液晶显示屏的控制引脚sbit RS = P2^0;sbit RW = P2^1;sbit EN = P2^2;//定义 1602 液晶显示屏的数据引脚sbit D0 = P0^0;sbit D1 = P0^1;sbit D2 = P0^2;sbit D3 = P0^3;sbit D4 = P0^4;sbit D5 = P0^5;sbit D6 = P0^6;sbit D7 = P0^7;//定义按键引脚sbit key0 = P1^0;sbit key1 = P1^1;sbit key2 = P1^2;sbit key3 = P1^3;sbit key4 = P1^4;sbit key5 = P1^5;sbit key6 = P1^6;sbit key7 = P1^7;sbit key8 = P3^0;sbit key9 = P3^1;sbit key_add = P3^2;sbit key_sub = P3^3;sbit key_mul = P3^4;sbit key_div = P3^5;sbit key_eq = P3^6;//定义变量unsigned char num1, num2, op, result;unsigned char flag = 0; //标志位,用于判断输入状态//写指令函数void write_command(unsigned char command){RS = 0;RW = 0;EN = 0;P0 = command;EN = 1;EN = 0;}//写数据函数void write_data(unsigned char data){RS = 1;RW = 0;EN = 0;P0 = data;EN = 1;EN = 0;}//初始化 1602 液晶显示屏函数void init_1602(){write_command(0x38);// 8 位数据,2 行显示,5x7 点阵write_command(0x0c);//显示开,光标关,闪烁关write_command(0x06);//字符右移,地址指针加 1 write_command(0x01);//清屏}//按键扫描函数void key_scan(){if (key0 == 0){delay_ms(10);//消抖if (key0 == 0){if (flag == 0){num1 = num1 10 + 0;write_data('0');}else{num2 = num2 10 + 0;write_data('0');}}while (!key0);//等待按键松开}//其他按键扫描类似}//计算函数void calculate(){switch (op){case '+':result = num1 + num2;break;case '':result = num1 num2;break;case '':result = num1 num2;break;case '/':if (num2!= 0)result = num1 / num2;elsewrite_data('E');//除数为 0 ,显示错误break;}}//主函数void main(){init_1602();while (1){key_scan();if (key_add == 0 || key_sub == 0 || key_mul == 0 ||key_div == 0){delay_ms(10);//消抖if (key_add == 0){op ='+';flag = 1;write_data('+');}//其他运算符处理类似}if (key_eq == 0){delay_ms(10);//消抖if (key_eq == 0){calculate();write_data(result);num1 = 0;num2 = 0;flag = 0;}}}}```上述代码只是一个简单的示例,实际应用中还需要进行更多的优化和完善,比如处理输入错误、添加更多的功能等。

51单片机 1602液晶显示 NE555频率计

51单片机 1602液晶显示 NE555频率计

#include<reg52.h>#define uint unsigned int#define uchar unsigned charsbit LCD_RS= P2^0;//定义LCD引脚sbit LCD_RW= P2^1;sbit LCD_E= P2^2;uchar code DIS[]={"NE555-------TEST"};//NE555 测试;uchar code dsptab[]={'0','1','2','3','4','5','6','7','8','9'};//字符代表码;uchar i,c[4],a[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; uint s;/*====================延时子程序====================*/ void delay(uint z){uchar m;for(;z>0;z--)for(m=124;m>0;m--);}void delay400ms(void)////400ms延时{ uchar z = 5;uint m;while(z--){ m=7269;while(m--);}}/*====================LCD1602子程序====================*/ /*-- 读状态--*///读状态子程序;有返回值;返回值类型为CHAR型;//读回的状态通过RETURN返回;uchar read_estate(void) //定义有返回值的函数;{ P0=0Xff; //把LCD端口全置1方便读取信号; LCD_RS=0; //RS置0;LCD_RW=1; //RW置1;LCD_E=0; //E端置0;delay(10); //短延时;LCD_E=1; //E端置1;以锁存数据; while(P0&0x80); //检测忙,则一直循环;return(P0); //返回读取的信号;}/*-- 写数据--*///写数据子程序;无返回值;输入变量I;//I为要写入LCD中的数据;//数据类型CHAR形;void write_data(uchar i) //定义输入变量值I;{read_estate(); //检测忙信号;P0=i; //把I中数据送到LCD数据端;LCD_RS=1; //RS置1;LCD_RW=0; //RW置0;LCD_E=0; //E置0;delay(10); //短延时;LCD_E=1; //E置1;以锁存数据;}/*-- 写指令--*///写指令子程序;无返回值;输入二个变量I和J.//I为要写入LCD的指令;J为判断要不要检测忙.//如果J为0则不判断检测忙;//如果J为1则判断检测忙;void write_dictate(uchar i,j) //定义二个变量;{if(j)read_estate(); //根据需要检测忙;P0=i; //把要写入的数据送到LCD数据端; LCD_RS=0; //RS置0;LCD_RW=0; //RW置0;LCD_E =1; //E端置0;delay(10); //延时;LCD_E =0; //E端置1;以锁存数据;}/*-- LCD初始化--*///LCD初始化程序;主要作用初始化LCD,对LCD进行复位以及设置;void initialization(void) //定义函数;{delay(50); //延时5MS;write_dictate(0x38,0); //写指令38H;不检测忙;delay(50); //延时5MS;write_dictate(0x38,0); //写指令38H;不检测忙;delay(50); //延时5MS;write_dictate(0x38,0); //写指令38H;不检测忙;delay(50);write_dictate(0x38,1); //显示模式设置;检测忙;write_dictate(0x08,1); //关闭显示;检测忙;write_dictate(0x01,1); //显示清屏;检测忙;write_dictate(0x06,1); //显示光标移动设置;检测忙;write_dictate(0x0C,1); //显示开及光标设置;检测忙;}/*-- 在指定位置显示一个字符--*/void displayonechar(uchar x, y,ddata){y &= 0x01;x &= 0x0f; //限制X不能大于15,Y不能大于1if (y) x+= 0x40; //当要显示第二行时地址码+0x40;x+= 0x80; //算出指令码write_dictate(x,0); //这里不检测忙信号,发送地址码write_data(ddata);}/*-- 在指定位置显示一串字符--*/void displaylistchar(uchar x,y,uchar code *ddata){uchar a=0;y&=0x01;x&=0xf;while(ddata[a]>0x20){ if(x<=0xff){displayonechar(x, y,ddata[a]);a++;x++;}}}/*====================MAIN主程序====================*/void main(){delay400ms();//延时400MSinitialization();//LCD复位;displaylistchar(0,0,DIS);//显示NE555 测试;displayonechar(0,1,'F'); //在LCD是显示F=____Hzdisplayonechar(1,1,'=');displayonechar(9,1,'H');displayonechar(10,1,'z');TMOD=0X51; //定义T0为方式一(十六位进制),T1为计数器(16位)TH0=0X3C; //50 msTL0=0XB0;TH1=0X00; //初始值TL1=0X00;TR0=1;TR1=1;ET0=1;ET1=0;EA=1;i=0;/* 显示*/ // 调用显示子程序(显示位,显示行,显示数据)注:显示行“0”为第一行,“1为第二行”while(1){if(s/10000>=1){displayonechar(2,1,dsptab[s/10000]); //万displayonechar(3,1,dsptab[s/1000%10]);//千displayonechar(4,1,'.'); //点displayonechar(5,1,dsptab[s/100%10]);//百displayonechar(6,1,dsptab[s/10%10]); //十displayonechar(7,1,dsptab[s%10]); //个displayonechar(8,1,'K');}else if(s/1000>=1){displayonechar(2,1,' ');displayonechar(3,1,dsptab[s/1000%10]);//千displayonechar(4,1,'.'); //点displayonechar(5,1,dsptab[s/100%10]);//百displayonechar(6,1,dsptab[s/10%10]); //十displayonechar(7,1,dsptab[s%10]); //个displayonechar(8,1,'K');}else if(s/100>=1){displayonechar(2,1,' ');displayonechar(3,1,' ');displayonechar(4,1,' '); //万displayonechar(5,1,' '); //千displayonechar(6,1,dsptab[s/100%10]);//百displayonechar(7,1,dsptab[s/10%10]); //十displayonechar(8,1,dsptab[s%10]); //个}else if(s/10>=1){displayonechar(2,1,' ');displayonechar(3,1,' ');displayonechar(4,1,' '); //万displayonechar(5,1,' '); //千displayonechar(6,1,' ');//百displayonechar(7,1,dsptab[s/10%10]); //十displayonechar(8,1,dsptab[s%10]); //个}else{displayonechar(2,1,' ');displayonechar(3,1,' ');displayonechar(4,1,' '); //万displayonechar(5,1,' '); //千displayonechar(6,1,' ');//百displayonechar(7,1,dsptab[s/10%10]); //十displayonechar(8,1,dsptab[s%10]); //个}}}/* 中断*/void t0()interrupt 1{TH0=0X3C;TL0=0XB0;i++;if(i==20) //1 s时间到时{s=TH1; //555信号发生器的输出口接P3.5(T1) 15脚s=s<<8;s=s+TL1;i=0; //清零TH1=0X00;TL1=0X00;}}/*----------------------------------------------------------------*//*----------------- 1602液晶数据读取子程序-----------------------*///读数据子程序;有返回值,返回值类型为CHAR型;/*uchar read_data(void) //定义有返回值的子函数; {LCD_DATA=0Xff; //LCD数据端口置1; LCD_RS=1; //RS置1;LCD_RW=1; //RW置1; LCD_E=0; //E置0;delay(10); //短延时;LCD_E=1; //E置1;以锁存数据; return(LCD_DATA); //返回读取的值;}/*----------------------------------------------------------------*/。

基于51单片机24小时可调时钟1602液晶显示程序

基于51单片机24小时可调时钟1602液晶显示程序

基于51单片机24小时可调时钟1602液晶显示程序#include<reg52.h>#define uchar unsigned char#define uint unsigned intsbit key1=P1^0;sbit key2=P1^1;sbit key3=P1^2;sbit key4=P1^3;sbit key5=P1^4;sbit key6=P1^5;sbit rs=P0^0; //液晶的第4端RS由开关独立s2 p3^5控制高电平写数据,低电平写命令。

sbit lecdn=P0^1; //使能端需控制LECDN,p3^6控制。

根据硬件电路而定uchar miao ,fen ,shi,num;uchar miao1,miao2,shi1,shi2,fen1,fen2;uchar table[]="0123456789";void delay(uint x){uint i,j;for(i=x;i>0;i--)for(j=10;j>0;j--);}void write_com(uchar com )//写指令{P2=com;//RW=0;写指令位定义一个io口控制lecdn=0; //起初为低电平时序图rs=0; //写指令rs为低delay(10); //简短延时lecdn=1; //给以高脉冲delay(5);lecdn=0;}void write_data(uchar shu ) //写数据{P2=shu; //将数据送给控制数据位的io口//RW=0;写指令位定义一个io口控制lecdn=0;rs=1; //写数据rs为低区别delay(10);lecdn=1;delay(5);lecdn=0;}void init() //初始化{write_com(0x38); //显示模式设置delay(20);write_com(0x0f); // 显示开关,和光标设置,开关必开,光标不开ox0c,开并闪烁0x0fdelay(20);write_com(0x06); //写完一个数据,数据地址指针自动往后移动一位delay(20);write_com(0x01); //清屏指令,按下复位键上次的结果变清掉。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

电子产品设计与开发结课论文题目:其于51单片机的频率计设计与仿真班级:电子1104班姓名:陈** (组员)学号:03 电话:1376******成员:曾* (组长)学号:29 电话:13726****** 成员:孙* (组员)学号:21 电话:137*******目录一、需求分析二、方案设计1设计基本原理 (4)1.1测量频率的原理 (4)1.2系统设计框图 (4)三、软件设计 (5)1资源分配表 (5)2程序流程框图 (6)四、系统硬件线路设计图 (7)1 单片机最小系统设计 (7)2 液晶LCD1602显示电路 (8)3 频率测量电路 (11)五.系统仿真、测试结果及性能分析 (12)1系统仿真、测试结果 (12)2性能分析 (13)六、心得与体会 (14)七、参考文献 (14)摘要本设计提出了一种基于AT89C51单片机开发的数字频率测量仪的设计。

系统以单片机AT89C51为核心,构成完备的测量系统。

可以对信号进行频率的精确测量,测频在1Hz至10kHZ。

采用液晶LCD1602显示被测信号的频率。

与传统的电路系统相比,其有处理速度快、稳定性高、性价比高、硬件结构简单的优点。

关键词:单片机;低频;绝对误差一、需求分析频率测量在科技研究和实际应用中的作用日益重要。

传统的频率计通采用组合电路和时序电路等大量的硬件电路构成,产品不但体积较大,运行速度慢,而且测量低频信号时不宜直接使用。

频率信号抗干扰性强、易于传输,可以获得较高的测量精度。

同时,频率测量方法的优化也越来越受到重视.并采用AT89C51 单片机和相关硬软件实现。

MCS—51系列单片机具有体积小,功能强,性能价格比较高等特点,因此被广泛应用于工业控制和智能化仪器,仪表等领域。

我们研制的频率计以89c51单片机为核心,具有性能优良,精度高,可靠性好等特点。

二、设计方案此次课程设计采用间接测量法来测量。

要用到GATE信号,GATE=1时,TR0=1,INTO=1才能启动计数器,而计数器0是通过外部中断INTO的下降沿开始触发的,计时器从0开始计时,计数器只能测高电平,因此测得的时间为半个周期。

当计数器0计时溢出,执行m加1的操作。

则测量时间为:t1=TH0*256+TL0+m*65536 ,所求频率F=1000000/(2*t1) 1设计基本原理1.1测量频率的原理定时/计数器工作在方式1,每产生一次定时器0中断,计数65536个脉冲,此时的脉冲来自振荡器的12分频后的脉冲,其周期为1uS。

根据产生外部中断0时,定时器0中断的次数u,以及此时定时/计数器0计数寄存器的数值X,即可求得待测方波的周期为:T=(65536*u+X)us ,取其倒数即可求得待测方波的频率,小数点后保留两位,即可使得频率精度为0.1HZ。

1.2系统设计框图经过方案论证和比较后,最终确定的系统框图如图1所示,主要由AT89C51单片机、异或器件、LCD1602、电源等组成。

图2 系统设计框图三、软件设计1资源分配表表5 资源分配表I/O口作用P0 LCD1602数据接口P1.6 LCD1602 RW接口P1.7 LCD1602 RS接口P2.4 LCD1602 E接口P3.2 频率测量接口2程序流程框图频率程序流程图如图9所示:图10 程序流程图四、系统硬件线路设计图1 单片机最小系统设计单片机最小系统是能补足单片机工作的最简单电路,它由单片机、电源、晶体振荡器、复位电路等构成。

它是本系统的处理单元也是控制单元,负责处理信号、外设的接口与控制,同时它也是所有软件的载体。

本系统采用AT89C51是美国Atmel公司生产的低电压、高性能CMOS 8位单片机,片内含4KB的可反复檫写的程序存储器和12B的随机存取数据存储器(RAM),器件采用Atmel 公司的高密度、非易失性存储技术生产,片内配置通用8位中央处理器(CPU)和Flash存储单元,功能强大的AT89C51单片机可灵活应用于各种控制领域。

与Intel公司的80C51在引脚排列、硬件组成、工作特点和指令系统等方面兼容。

主要管脚有:XTAL1(19 脚)和XTAL2(18 脚)为振荡器输入输出端口,外接12MHz 晶振。

RST/Vpd(9 脚)为复位输入端口,外接电阻电容组成的复位电路。

VCC(40 脚)和VSS(20 脚)为供电端口,分别接+5V电源的正负端。

P0~P3 为可编程通用I/O 脚,其功能用途由软件定义。

其管脚如下图所示:图3 AT89C51单片机管脚图本设计中,P0 端口(32~39 脚)被定义为N1 功能控制端口,分别与N1的相应功能管脚相连接。

单片机正常工作时,都需要有一个时钟电路和一个复位电路。

本设计中选择了内部时钟方式和按键电平复位电路,来构成单片机的最小电路。

如图3所示。

图4 单片机最小系统2液晶LCD1602显示电路字符型液晶显示模块是一种专门用于显示字母、数字、符号等点阵式LCD,目前常用16*1,16*2,20*2和40*2行等的模块。

LCD1602分为带背光和不带背光两种,基控制器大部分为HD44780,带背光的比不带背光的厚,是否带背光在应用中并无差别。

LCD1602采用标准的14脚(无背光)或16脚(带背光)接口,各引脚接口说明如下表1所示:表 1 LCD1602引脚接口说明编号符号引脚说明编号符号引脚说明1 VSS 电源地9 D2 数据2 VDD 电源正极10 D3 数据3 VL 液晶显示偏压11 D4 数据4 RS 数据/命令选择12 D5 数据5 R/W 读/写选择13 D6 数据6 E 使能信号14 D7 数据7 D0 数据15 BLA 背光源正极8 D1 数据16 BLK 背光源负极1602液晶模块的读写操作、屏幕和光标的操作都是通过指令编程来实现的。

1602液晶模块内部的控制器共有11条控制指令,如下表2所示,其中1为高电平、0为低电平。

表 2 LCD1602控制指令指令1:清显示,指令码01H,光标复位到地址00H位置。

指令2:光标复位,光标返回到地址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:写数据。

与HD44780相兼容的芯片时序如下表3所示:表 3 基本操作时序表读状态输入RS=L,R/W=H,E=H 输出D0—D7=状态字写指令输入RS=L,R/W=L,输出无D0—D7=指令码,E=高脉冲读数据输入RS=H,R/W=H,E=H 输出D0—D7=数据写数据输入RS=H,R/W=L,输出无D0—D7=数据,E=高脉冲其操作时序图如下所示:图5 读操作时序图图6 写操作时序图本设计中采用液晶LCD1602显示输入方波A的频率,其D0~D7与单片机的P0端口连接,使能端E、RS、RW分别与单片机P2.4、P1.7、P1.6连接,此电路原理简单,电路连接方便,如图7所示。

图7 液晶LCD1602显示电路3频率测量电路本设计中将方波A输入,采用定时中断测量其频率。

如图7所示。

图8 频率测量电路综上所述,频率的总体电路图如图9所示:图9 频率计的总体电路图五.系统仿真、测试结果及性能分析1系统仿真、测试结果在仿真软件PROTUES中按照电路图连接好电路。

输入待测方波信号波形,当测试频率时,先依次设置好方波A的频率,进行仿真测得数据;测试波形和结果如图11所示:图11 仿真波形输入频率/HZ 1 2 10 50 100 200 500测得频率/HZ 0.99 1.99 10.00 50.00 100.00 200.01 500.00输入频率/HZ 900 1000 1024 1234 2000 5000 10000测得频率/HZ 899.92 1000.64 1024.23 1234.20 2000.92 5000.48 10000.602性能分析根据表6测试所得结果可以看出:,频率范围为1Hz~3000HZ;频率误差少于1Hz.当输入频率大于4000HZ时,频率误差小于6HZ,并且随着输入频率增大,频率误差逐渐增大。

由此可得如下结论:本次所设计的频率适合测试低频信号,最佳频率范围为1-3000HZ,输入方波任意均可。

六、心得与体会刚刚拿到做频率计这个题目时,我们的感觉可以说是比较轻松的,在一开始的时候也不算太着急。

过了几天后,我和几个组员开始打算动手去做了,这时才感觉到频率计不是那么容易做的。

虽然心中有个大概的想法,但要实施起来时才觉得不知从哪里入手。

可是我们还是硬着头皮做了,我和组长曾潜,组员孙凯开始上网了解频率计的具体做法。

通过几个小时的讨论,终于大概定出了本次设计的思路、流程与分工。

在本次的设计中,我主要负责做PCB版和协助组长曾潜设计详细的程序。

通过好几天的努力,我们终于做出了最初的设计,但是程序在仿真图片中的显示不正常,误差也很大。

我们三人通过不断的修改,调试,终于,做出了基本符合要求的51单片机频率计。

这次的频率计设计,虽然在过程中也走了不少的弯路,但终究是学到许多知识,学到课堂上没有的知识,除了实践上的,理论上的知识也有。

除此之外,我还认识到了与人合作的重要性,这次设计如果只是我一个人做是很有可能做不出来的,在设计中往往会遇到一些个人弄很长时间都弄不明白的地方,但几个人一起讨论后就往往会害然开朗。

由于本次设计时间的安排还是不够合理,设计中还有很多不够完美的地方,系统中还有许多有待改进的地方。

最后,要感谢老师,给我们一个把理论应用到实践的机会,也感谢同学们在我困难的时候能伸出援手,谢谢。

七、参考文献【1】周美娟、肖来胜编著。

《单片机技术及系统设计》,清华大学出版社【2】谭浩强编著。

《C程序设计》,清华大学出版社附录一:仿真图附录二:原理图附录三:PCB图附录四:源程序#include<reg51.h>#include<math.h>#define uint unsigned int#define uchar unsigned charuchar m=0;uchar u;uint i;uint x;uint c; //相位数据结果保存float t0,f;uint a[]={70,61,48,48,48,48,48,46,48,48,72,90}; //频率数据结果保存//F,=,0,0,0,0,0,.,0,0,H,Zsbit lcdrw=P1^6;sbit lcdrs=P1^7;sbit lcden=P2^4;/////////////////LCD1602的设置////////////////////////////////// void delay(uint s)//延时1MS{uint r,g;for(r=s;r>0;r--)for(g=110;g>0;g--);}void write_com(uchar com) // 写指令{lcdrs=0;P0=com;delay(5);lcden=1;delay(5);lcden=0;}void write_data(uchar date) // 写数据{lcdrs=1;P0=date;delay(5);lcden=1;delay(5);lcden=0;}void initlcd()//初始化{lcdrw=0;lcden=0;//write_com(0x01);//显示清屏write_com(0x38);//显示模式设置write_com(0x0c); //显示开,开游标,不闪烁write_com(0x06); // 字符时整体不移动}////////////LCD1602设置//////////////////////////定时器的设置//////////////void CT_init() //定时计数器初始化{ TMOD=0x99; //GATE=1,T1、T0工作在方式1,定时方式TH0=0; //定时计数器初值清零TL0=0;// TH1=0;// TL1=0;TR0=1; //TR0,TR1置位,此时定时计数器的启动有INT0,INT1引脚电平决定// TR1=1;ET0=1; //开中断// ET1=1;}void ITC0() interrupt 0 //外部中断0服务程序{u=m; //读定时计数器0溢出次数m=0; //溢出次数清零x=TH0*256+TL0; //读定时计数器0当前值TH0=0; //定时计数器0清零TL0=0;}void TIME0() interrupt 1 //定时计数器0溢出中断{m++; //溢出次数加1}////////////定时器的设置//////////////void main(){initlcd(); //液晶显示初始化CT_init(); //定时计数器初始化EA=1; //开总中断EX0=1; //允许外部中断// EX1=1;IT0=1; //设置外部中断方式为下降沿触发// IT1=1;P3=0xff;while(1){t0=u*65536+x; //计算脉冲时间宽度f=1000000/(2*t0); //计算频率c=f*100; //计算结果逐位保存a[9]=c%10+48;a[8]=(c/10)%10+48;c=f;a[6]=c%10+48;a[5]=(c/10)%10+48;a[4]=(c/100)%10+48;a[3]=(c/1000)%10+48;a[2]=(c/10000)%10+48;write_com(0x80);for(i=0;i<=11;i++){write_data(a[i]);delay(10);}}}。

相关文档
最新文档