本课程设计的主要任务是完成将模拟电压转换成数字电压,然后通过数码管显示出来,主要包括转换模块和显示模块两个模块,采用软硬件结合的方式,尽量减少误差。2.系统总体方案设计2.1总体设计方案根据系统设计的要求和功能,将系统分为主控模块、A/D转换模块、LED显示模块、复位电路、时钟电路等几个模块。系统框图如图1所示。主控模块采用AT89S52单片机,A/D转换模块采用ADC0809芯片进行A/D转换,显示模块采用4位七段共阳极LED数码管显示电压值。 1 单片机原理与系统课程设计报告 2.2 系统组成框图 时钟和复位电路 单片机显示电路 输入电路图 2.2 系统组成框图 3.硬件设计 3.1 系统硬件设计原理 通过变量设置选择八个通道中的第三个通道,将此通道的模拟电压送入 ADC0808 对应通道。单片机软件设置 ADC0808 开始 A/D 转换,当转换完成后,ADC0808 的 EOC 端口产生高电平,同时 ADC0808 的 OE 端口设置为高电平。单片机把 ADC0809 转换后的数字量存入片内 RAM 中。系统调用数据处理子程序,把测量结果转换成 0.00~5.00V,最后通过查表将各位数据输出到 LED 显示电路,显示对应电压,程序进入下一个循环。
单片机的P0.0~P0.7作为4位动态数码显示管的段显示控制。P2.1~P2.3作为4位动态显示管的位显示控制。3.2硬件设计原理图在Proteus仿真环境中搭建的系统硬件电路图如图3.2所示。2单片机原理与系统课程设计报告图3.2系统原理图4软件设计4.1软件设计方案主程序包括初始化部分、调用A/D转换子程序和延时部分。 A/D转换程序从开始设置的ST的变化开始(产生一个下降沿使ADC0809的START开始工作)然后当转换完成(EOC=1)时开始向P1发送数据(OE=1输出使能信号设置为1)直到发送结束OE设置为0,将得到的电压转换成相应的十六进制数据并存储起来,然后用取模的方法逐位取出数字,最后通过查询码表得到相应的BCD码,显示结束。ADC0809转换后输出的结果是一个8位二进制数,当ADC0809输出为(111111111)时,输入电压值VI=5.00V;当ADC0809输出为时,输入电压值VI=0.00V;当ADC0809输出为时,输入电压值VI=2.50V。 由于单片机在进行数学运算时只取整数部分,因此计算得出输出时电压值VI=2.00V,非常不准确。
为了提高精度,小数部分必须保留,具体做法是:若小数点后有两位小数,计算时将分子乘以100,若有三位小数,则乘以1000。本设计保留小数点后两位小数。计算方法为:VI=Dout/255×5×100=Dout×100/51。4.2 主程序流程图图4.2为程序软件设计流程图,其中(a)为主程序流程图,(b)为A/D转换子程序流程图。开始启动3 单片机原理与系统课程设计报告初始化启动模数转换调用A/D转换程序N 转换完成吗? 调用显示子程序 Y 得到模数转换结果 调用延时程序 Bing 转换为数字量 End 显示转换结果 End (a)主程序流程图 (b)AD 转换流程图 5.系统调试及仿真结果 6.小结 4 单片机原理与系统课程设计报告 为期两周的课程设计结束了,在这个过程中,我学到了很多东西,首先通过查找资料了解了单片机设计的基本流程,各个流程的基本步骤,以及如何完成每个步骤。其次巩固了上学期学到的一些单片机知识,从而加深了对 ADC0809 芯片功能的理解。在编程的过程中,我遇到了很多困难,最终通过和同学的交流、请教解决了这些困难。俗话说,熟能生巧,只有把所学的知识运用到实践中,才能真正感受到知识的力量。
最后,通过这次课程设计,我明白了想法和实践之间还是有差距的,当你真正去做某件事的时候,你会发现你的想法可能并不适用,需要随时调整。另外,扎实的理论知识也是完成任何设计不可缺少的要素,没有理论知识,一切想法都是幻想。 参考文献 [1] 彭炜,黄柯,雷道忠. 单片机典型系统设计实例详解[M]. 电子工业出版社。2009:22-54。 [2] 谭浩强. C语言程序设计(第三版)[M]. 清华大学出版社。2009:32-46。 [3] 王思明,张金民,张欣等. 单片机原理与应用系统设计(第一版)[M]. 科学出版社。 2012:70-292.5 单片机原理与系统课程设计报告 附录A 源代码 #includereg52.h #includeintrins.h #define uchar unsigned char sbit p21=P2^1; sbit p22=P2^2; sbit p23=P2^3; sbit EOC=P3^1; sbit OE=P3^0; sbit ST=P3^2; sbit p34=P3^4; sbit p35=P3^5; sbit p36=P3^6; uchar code tab[]={0x40,0x79,0x24,0x30,0x19,0x12}; uchar 代码 led[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; uchar 代码 led_[]={0xC0,0xf9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; void delay(uchar n) {uchar i,j;for(i=0;in;i++)for(j=0;j125;j++); } void convert(uchar volt_data) { temp;temp=100*volt_data/51;P0=led[temp/100];//数字显示在个位 p21=1;//选择个位 delay(3);//延迟 p21=0;//不选择个位 P0=led_[temp0/10];//数字显示在十位 p22=1;//选择十位 delay(3);//延迟 p22=0;//不选择十位 P0=led_[temp];//数字显示在百分位 p23=1;//选择百分位 delay(3);//延迟 p23=0;//不选择百分位} void main() {uchar volt_data;p34=1;p35=1;p36=0;//选择 IN3 通道 ADC0808while(1){ST=0;_nop_();ST=1;_nop_();ST=0; //开始转换 if(EOC==0) //如果EOC为0,继续转换 delay(100); while(EOC==0); //当EOC为1时,转换完成 OE=1; //数据输出标志 volt_data=P1; //将P1口的数据送入volt_data OE=0; convert(volt_data); } }