項目名稱:模擬電壓表系統設計函數
項目功能:實現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時候的仿真:
好啦,以上就是全部內容啦,祝你們學習愉快!!!