项目名称:模拟电压表系统设计函数
项目功能:实现0 ~ 5V、5 ~ 10V双量程电压测量并显示学习
本项目是在此次疫情下,大三学期的课程设计,本身辛苦了一晚上,最后成绩得了优(哈哈哈哈)。下面简单说明一下本项目,为像我同样笨手笨脚的同窗提供些经验(嘻嘻嘻嘻)。ui
该部分无非是驱动及数据处理。设计
首先是驱动:指针
#ifndef __LCD1602_H__ #define __LCD1602_H__ #define uchar unsigned char #define uint unsigned int /******LCD端口设置******/ sbit LcdEn = P3^7; sbit LcdRw = P3^6; sbit LcdRs = P3^5; /******定义测量按键******/ sbit Start = P3^2; sbit Stop = P3^3; void LcdDisplay(); void LcdPrintL1(char* str); /*第一行整屏左移显示*/ void LcdPrint1(char* str); /*第一行显示*/ void LcdPrint11(char* str); /*第一行显示,不清屏·*/ void LcdPrint2(char* str); /*第二行显示,不清屏*/ void WriteCom(uchar comData); void WriteData(uchar Data); void Delay_ms(unsigned int n); void Delay_10ms(); #endif
/******LCD驱动及显示******/ #include<reg51.h> #include"LCD1602.h" #define uchar unsigned char #define uint unsigned int extern code uchar table1[]; extern code uchar table2[]; extern code uchar table3[]; extern code uchar table4[]; extern code uchar table5[]; uchar num = 0; /*-----------------LCD驱动程序----------------*/ /*******LCD写命令*******/ void WriteCom(uchar comData){ LcdRs = 0; //写命令 LcdRw = 0; //写选择端 //Delay_ms(5); // P0 = comData; //将数据送达数据线 LcdEn = 1; //开始能 Delay_ms(5); LcdEn = 0; //关始能 } /******LCD写数据*******/ void WriteData(uchar Data){ LcdRs = 1; //写数据 LcdRw = 0; //写选择 P0 = Data; Delay_ms(5); LcdEn = 1; Delay_ms(5); LcdEn = 0; } /*---------------LCD初始化---------------*/ void LcdDisplay(){ LcdRw = 0; LcdEn = 0; WriteCom(0x38); //设置16x2显示,5x7点阵,8位数据接口 WriteCom(0x0c); //设置开显示,不显示光标 Delay_ms(1); WriteCom(0x06); //写一个字符后地址指针加1 WriteCom(0x01); //显示清零,数据指针清零 Delay_ms(1); WriteCom(0x80); //光标位置初始化 while(table1[num]!='\0'){ //没有换行符,一直执行 WriteData(table1[num]); num++; Delay_ms(2); } Delay_ms(1000); } /*---------------LCD显示指令--------------*/ /*******第一行显示指令*******/ void LcdPrint1(char* str){ uchar i = 0; WriteCom(0x01); WriteCom(0x80); for(i=0;str[i]!=0;i++) WriteData(str[i]); } /*******第一行显示指令,不清屏*******/ void LcdPrint11(char* str){ uchar i = 0; // WriteCom(0x01); WriteCom(0x80); for(i=0;str[i]!=0;i++) WriteData(str[i]); } /******第二行显示指令******/ void LcdPrint2(char* str){ uchar i = 0; WriteCom(0x80 + 0x40); for(i=0;str[i]!=0;i++) WriteData(str[i]); } /******第一行整屏左移显示指令******/ void LcdPrintL1(char* str){ uchar i = 0; WriteCom(0x01); //显示清零,指针清零 WriteCom(0x80); for(i=0;str[i]!=0;i++) WriteData(str[i]); Delay_ms(150); num = 0; while(table4[num]!='\0'){ WriteCom(0x18); //整屏左移指令 num++; Delay_ms(150); //控制移动速度 } }
#ifndef __ADC0808_H__ #define __ADC0808_H__ #define uchar unsigned char #define uint unsigned int /******ADC0808端口设置******/ sbit START = P3^1; /*A/D转换启动信号,正脉冲有效*/ sbit EOC = P3^0; /*转换结束信号,高电平有效;该信号在A/D转换过程当中为低电平,其他时间为高电平*/ sbit OE = P3^4; /*转换容许信号*/ /******定义ADC数据选择端口******/ sbit a = P1^0; sbit b = P1^1; sbit c = P1^2; /******定义量程选择端口******/ sbit K1 = P1^3; sbit K2 = P1^4; uint ReadData(); void AdStar(); void SetData0(uchar addr,uint Data); void SetData1(uchar addr,uint Data); void DataSelector(); #endif
/******BuzzerWarning******/ #include<reg51.h> #include"LCD1602.h" #include"ADC0808.h" #define uchar unsigned char #define uint unsigned int extern code uchar table5[]; extern code uchar table6[]; sbit SPEAKER = P1^7; void BuzzerWarning0_5V(){ uint t,i; //SPEAKER = 1; //LcdPrint11(table5); for(t=0;t<3;t++){ for(i=0;i<35;i++) Delay_10ms(); SPEAKER =~ SPEAKER; } SPEAKER = 1; Delay_ms(800); }
主函数部分:code
#include<reg51.h> #include<intrins.h> #include"LCD1602.h" #include"ADC0808.h" #include<stdio.h> #define uchar unsigned char #define uint unsigned int code uchar tablea[]="0123456789"; code uchar tableb[]="Voltage:00.00 V"; code uchar table1[]={"System ready."}; code uchar table2[]={"Press STAR to start measuring."}; code uchar table3[]={"Measuring... "}; code uchar table4[]={"Measurement end."}; code uchar table5[]={"Maximum range."}; code uchar table6[]={"Minimum range"}; uchar res = 0; bit flag1 = 0; bit flag2 = 1; bit flag3 = 1; uchar k = 1; void Interrupt_eint(); void StartInt0(); void StopInt1(); void main(void){ /*------系统初始化------*/ LcdDisplay(); Interrupt_eint(); while(!IE0 && !IE1) LcdPrintL1(table2); /*------系统运行------*/ while(1){ StartInt0(); StopInt1(); } }
下面是数据处理部分及按键部分,因为老师要求有两个按键即:开始按键、结束按键;又因为在系统启动后会有字幕的提示信息,且提示信息是以滚动的方式显示的,因此这个项目的按键部分采用了中断的方式进行实现(效果:在提示信息显示及系统运行的任什么时候候均可以随时按下按键)。blog
注意:在系统刚启动后,只能按下 START按键,按下STOP按键无效,这是在程序中设计好的。接口
下面是程序:rem
/******利用外部中断函数实现按键功能******/ #include<reg51.h> #include"LCD1602.h" #include"ADC0808.h" #define uchar unsigned char #define uint unsigned int extern code uchar tablea[]; extern code uchar tableb[]; extern code uchar table1[]; /*系统准备就绪*/ extern code uchar table2[]; /*请按“Start”开始测量*/ extern code uchar table3[]; /*正在测量*/ extern code uchar table4[]; /*测量结束*/ extern code uchar table5[]; extern code uchar table6[]; extern uchar res; /*接收数据*/ extern bit flag2; extern bit flag3; void BuzzerWarning0_5V(); /******中断初始化******/ void Interrupt_eint(){ EX0 = 1; //开启外部中断0 IT0 = 0; //设置外部中断0触发模式:低电平触发 EX1 = 1; //开启外部中断1 IT1 = 0; //设置外部中断1触发模式 EA = 1; //开启总中断 PX0 = 1; //将外部中断的优先级提升 } /******外部0中断服务函数******/ void StartInt0() interrupt 0{ if(IE0 && flag2 == 1){ //按下START Delay_10ms(); flag2 = 0; LcdPrint1(table3); LcdPrint2(tableb); while(!IE1){ WriteCom(0x80+0x40+8); AdStar(); res = ReadData(); if(flag3){ SetData0(8,res); if((res*1.0/255*500)/100 == 5){//判断电压是否超过或等于 5 V LcdPrint11(table5); BuzzerWarning0_5V(); } else LcdPrint11(table3); } else{ SetData1(8,res); if(res*1.0/255*500*3 >= 1000){//判断电压是否超过或等于 10 V LcdPrint11(table5); BuzzerWarning0_5V(); } else if(res*1.0/255*500*3/100 < 5){ LcdPrint11(table6); BuzzerWarning0_5V(); } else LcdPrint11(table3); } } } } /******外部1中断服务函数******/ void StopInt1() interrupt 2{ if(IE1 && flag2 == 0){ //按下STOP Delay_10ms(); flag2 = 1; LcdPrint1(table4); LcdPrint2(tableb); res = ReadData(); if(flag3) SetData0(8,res); else SetData1(8,res); while(!IE0); } }
以上就是全部的源程序啦。程序中也有些小细节,大多都有注释。it
下面是Protues的仿真原理图:
5V时候的仿真:
好啦,以上就是全部内容啦,祝你们学习愉快!!!