程序设计及调试: 开始 初始化 调用A/D转换子程序 调用显示子程序 结束 初始化程序 所谓初始化,是对将要用到的MCS_51系列单片机内部部件或扩展芯片进行初始工作状态设定,初始化子程序的主要工作是设置定时器的工作模式,初值预置,开中断和打开定时器等[9]。 A/D转换子程序
A/D转换子程序用来控制对输入的模块电压信号的采集测量,并将对应的数值存入相应的内存单元,其转换流程图如图13所示。 开始 启动转换 A/D转换结束? 输出转换结果 数值转换 显示 结束
11
图13 A/D转换流程图
3 显示子程序
跟据LCD1602液晶的显示方式,先对其进行初始化,输入设置方式,在显示数值的时候要先写地址符号。
Write_LCD_Command(0x80);//设置显示的初始位置
LCD_Display(display_buffer[0]); //显示测得的数据
本人在小组中的工作及设计体会:
由于我承担小组长的职位,在设计的时候兼顾整体的方案。根据本小组成员的需要及个人所长,工作分配如下:
XXX(我):仿真电路图的设计及程序的设计
XX:仿真电路图的设计及电路图的布线 XXX:元器件的采购及电路图的焊接
设计体会:
本次设计很大程度考验了一个团队的合作能力,一个人并不能擅长做所有的东西,而对于设计,其关键就在于设计的思路,有步骤的设计可以省去很多不必要的麻烦,我觉得做这样的课程设计,不仅仅是考验我们的设计能力,或者说是写程序能力,而是我们将成品做出来后,它并没有按照我们的设定工作,更大程度的考验我们解决问题的能力。比如这次我们的设计,在仿真成功后,电路板焊接完毕,连线完毕,将程序输入到单片机里工作时就出了差错,检查了很久的连线都没有检查出来,然后就想到了测电位的方法来判断,当时就得出了结论:单片机没有工作。省去了大量的不必要的检查导线的问题,最后查出复位开关焊接出错了,也就很容易的改正过来了!
参考文献:
1.MCS-51单片机原理、系统设计与应用(万福君等著 清华大学出版社) 2.51单片机C语言教程(郭天祥著 电子工业出版社)
元器件清单:
STC89C52单片机*1 LCD1602液晶 *1 杜邦线导线若干 电阻1K *9 ADC0809 *1 按键 *1 晶振12M *1 74LS148 *1 排针若干 点解电容10uf *1 104电容 *2
12
程序清单:
#include
#define uchar unsigned char #define uint unsigned int
#define delay4us() {_nop_();_nop_();_nop_();_nop_();} sbit AB3=P3^0;//对74HC148进行判断 sbit AB2=P3^1;//报警设置
sbit RS=P2^0;//RS=1 数据 RS=0 命令 sbit RW=P2^1;//RW=1 读取 RW=0 写入 sbit E=P2^2;//E 使能信号 sbit EOC=P2^4; sbit OE=P2^5; sbit START=P2^3; sbit CLOCK=P2^6;
void Refresh_show(); void delay50us(uint m) {
uint n,k;
for(n=m;n>0;n--) for(k=25;k>0;k--); }
void Write_LCD_Command(uchar cmd);//向LCD写入命令
void Write_LCD_Data(uchar dat); //向LCD写入一个字节的数据函数 void Initialize_LCD1602(); //液晶初始化函数
void LCD_Display(uchar *str);//在LCD上显示字符串
//---------------忙检查-------------------// uchar LCD_Busy_Check() {
uchar LCD_Status; RS = 0; RW = 1; E = 1;
delay50us(4);
13
LCD_Status = P0;
E = 0;
return LCD_Status; }
//--------------向LCD写入命令--------------------// void Write_LCD_Command(uchar cmd) {
while((LCD_Busy_Check()& 0x80)==0x80); //忙等待 RS = 0; RW = 0; E = 0;
P0 = cmd; delay4us(); E = 1;
delay4us(); E = 0; }
//-----------向LCD写入一个字节的数据函数-----------------*/ void Write_LCD_Data(uchar dat) {
while((LCD_Busy_Check()&0x80)==0x80); RS = 1; RW = 0; E = 0; P0 = dat; delay4us(); E = 1;
delay4us(); E = 0; }
//-----------LCD初始化-----------------*/ void Initialize_LCD1602() //液晶初始化函数 {
Write_LCD_Command(0x38);delay50us(10); //功能设置,数据长度为8位,双行显示,5×7点阵字体
Write_LCD_Command(0x0C);delay50us(10); // 显示开,关光标
Write_LCD_Command(0x06);delay50us(10); //字符进入模式:屏幕不动,字符后移
14
Write_LCD_Command(0x01); delay50us(10);//清屏 }
//-----------在LCD上显示字符串-----------------*/ void LCD_Display(uchar *str) {
uchar i;
for(i=0;i Write_LCD_Data(str[i]); delay50us(100); } } unsigned long dat_adc0808; uchar display_buffer[][16]={ {\ {\ }; uint adc0808_init() // AD初始化 { START=0; START=1; START=0; while(EOC==0); OE=1; delay50us(20); dat_adc0808=P1; OE=0; return dat_adc0808; } void Refresh_show() //刷新显示 { uint t=dat_adc0808*500.0/255; // if(t>400||t<100)//报警的上下限设置 AB2=1; else 15 AB2=0; display_buffer[1][3] = t/100+'0'; //整数位 display_buffer[1][5] = t/10+'0'; //两个小数位 display_buffer[1][6] = t+'0'; } void main() { TMOD=0x02; TH0=0x14; TL0=0x00; EA=1; ET0=1; TR0=1; Initialize_LCD1602(); delay50us(10); Write_LCD_Command(0x80);//设置显示的初始位置 LCD_Display(display_buffer[0]); //显示测得的数据 while(1) { if(AB3==1) { Write_LCD_Command(0xc0);//设置显示的初始位置 LCD_Display(display_buffer[1]); //显示测得的数据 } else{ adc0808_init(); Refresh_show(); //更新测的电压数据 Write_LCD_Command(0xc0);//设置显示的初始位置 LCD_Display(display_buffer[1]); //显示测得的数据 } } } void Timer0_INT() interrupt 1 using 1 { CLOCK=!CLOCK; } 16