课程设计报告
华中师大学传媒学院
传媒技术学院
电子信息工程2011
仅发布百度文库,所有.
AD转换
要求:
A.使用单片机实现AD转换
B.可以实现一位AD转换,并显示(保留4位数字)设计框图:
方案设计:
AD转换时单片机设计比较重要的实验。模数转换芯片种类多,可以满足不同用途和不同精度功耗等。
外部模拟量选择的是简单的电位器,通过控制电位器来改变模拟电压。显示电压值采用一般的四位七段数码管。而AD转换芯片采用使用最广的ADC0809
ADC0809芯片有28条引脚,采用双列直插式封装,如图所示。
下面说明各引脚功能:
?IN0~IN7:8路模拟量输入端。
?2-1~2-8:8位数字量输出端。
?ADDA、ADDB、ADDC:3位地址输入线,用于选通8路模拟输入中的一路。
?ALE:地址锁存允许信号,输入端,高电平有效。
?START:A/D转换启动脉冲输入端,输入一个正脉冲(至少100ns宽)使其启动(脉冲上升沿使0809复位,下降沿启动A/D转换)。
?EOC:A/D转换结束信号,输出端,当A/D转换结束时,此端输出一个高电平(转换期间一直为低电平)。
?OE:数据输出允许信号,输入端,高电平有效。当A/D转换结束时,此端输入一个高电平,才能打开输出三态门,输出数字量。
?CLK:时钟脉冲输入端。要求时钟频率不高于640KHz。
?REF(+)、REF(-):基准电压。
?Vcc:电源,单一+5V。
?GND:地
工作原理:
首先输入3位地址,并使ALE=1,将地址存入地址锁存器中。此地址经译码选通8路模拟输入之一到比较器。START上升沿将逐次逼近寄存器复位。下降沿启动A/D转换,之后EOC输出信号变低,指示转换正在进行。直到A/D转换完成,EOC变为高电平,指示A/D转换结束,结果数据已存入锁存器,这个信号可用作中断申请。当OE输入高电平时,输出三态门打开,转换结果的数字量输出到数据总线上。
本次实验采用中断方式
把表明转换完成的状态信号(EOC)作为中断请求信号,以中断方式进行数据传送。
不管使用上述哪种方式,只要一旦确定转换完成,即可通过指令进行数据传送。首先送出口地址并以信号有效时,OE信号即有效,把转换数据送上数据总线,供单片机接受。
采用中断可以减轻单片机负担。并可以使程序有更多的空间作二次开发。
硬件原理图:
程序流程图:
仿真图:
制作实物图:AD转换模块:
最小系统及显示:
整体效果:
调试:
调试最多的是数码管显示问题扫描太慢显示会太暗和有闪烁问题,通过不断改变延迟来调整达到最佳状态。
心得体会:
通过这次的实验设计特别是前期的电路设计,和芯片选择以及后期的实物焊接。对我们专业的电路认识了很多,学到了很多。
做一个东西要选择你要的芯片的,你必须要先了解一些大体的东西当你选择好后你更要全面了解它的性能。对于单片机硬件来说要了解芯片,你要如何去驱动他来满足你的要求。这对于编程和看懂芯片的时序有着高要求。毕竟现在硬件更新换代太快,必须要学习怎么去设计去编写你要的程序来控制它。这是我这次实验最深刻的理解。
这次实验也培养了我团队合作能力积极主动沟通,遇到问题一起解决。对于现在的我们即将走出校门的人来说意义重大。
同时这次实验也大大拓宽了我的视野我还有很多东西要去理解去学习。
原程序:
#include
#include
#include
#define uchar unsigned char
#define uint unsigned int
uint temp=0;
sbit ST=P3^6; //启动信号
sbit EOC=P3^3; //转换结束信号,连到外部中断1口,转换结束后进入外部中断sbit OE=P3^7; //输出使能
//sbit ls=P2^7;
sbit dig_hc595_sh_dr=P1^7; //数码管的74HC595程序
sbit dig_hc595_st_dr=P1^6;
sbit dig_hc595_ds_dr=P1^5;
void initial_myself();
void initial_peripheral();
void delay_short(unsigned int uiDelayShort);
void delay_long(unsigned int uiDelayLong);
//void display_service();
void display_drive();
void dis_service(int temp);
//unsigned char ucDigShow8; //第8位数码管要显示的容
//unsigned char ucDigShow7; //第7位数码管要显示的容
//unsigned char ucDigShow6; //第6位数码管要显示的容
//unsigned char ucDigShow5; //第5位数码管要显示的容
unsigned char ucDigShow4; //第4位数码管要显示的容
unsigned char ucDigShow3; //第3位数码管要显示的容
unsigned char ucDigShow2; //第2位数码管要显示的容
unsigned char ucDigShow1; //第1位数码管要显示的容
unsigned char code dig_table[17]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码
unsigned char ucDigShowTemp=0; //临时中间变量
unsigned char ucDisplayDriveStep=1; //动态扫描数码管的步骤变量
void dig_hc595_drive(unsigned char ucLedStatusTemp16_09,unsigned char ucLedStatusTemp08_01);
main()
{
initial_myself();//初始化单片机
delay_long(100);
initial_peripheral(); //初始化外围
while(1)
{
P0=0xff;
ST=0;
ST=1;
ST=0;
// 启动A/D转换
while(EOC==0);
OE=1;
//EA=0;
//temp=0xff;
dis_service(temp);
//EA=0;
display_drive();//显示电压值
//delay_long(1);
//EA=1;
OE=0;
}
}
void dis_service(int temp)
{
int Tp=0;
Tp=temp*1.0/255*500;
ucDigShow1 = dig_table[Tp / 1000];
ucDigShow2 = dig_table[Tp % 1000 / 100] | 0x80;
ucDigShow3 = dig_table[Tp % 100 / 10] ;
ucDigShow4 = dig_table[Tp % 10 / 1];
}
void display_drive()//显示电压值
{
uchar i=1;
for(i=1;i<5;i++)
{ switch(i)
{
case 1: //显示第1位
ucDigShowTemp=ucDigShow1;
dig_hc595_drive(ucDigShowTemp,0xfe);
break;
case 2: //显示第2位
ucDigShowTemp=ucDigShow2;
dig_hc595_drive(ucDigShowTemp ,0xfd);
break;
case 3: //显示第3位
ucDigShowTemp=ucDigShow3;
dig_hc595_drive(ucDigShowTemp,0xfb);
break;
case 4: //显示第4位
ucDigShowTemp=ucDigShow4;
dig_hc595_drive(ucDigShowTemp,0xf7);
break;
/*case 5: //显示第5位
ucDigShowTemp=ucDigShow5;
dig_hc595_drive(ucDigShowTemp,0xef);
break;
case 6: //显示第6位
ucDigShowTemp=ucDigShow6;
dig_hc595_drive(ucDigShowTemp,0xdf);
case 7: //显示第7位
ucDigShowTemp=ucDigShow7;
dig_hc595_drive(ucDigShowTemp,0xbf);
break;
case 8: //显示第8位
ucDigShowTemp=ucDigShow8;
dig_hc595_drive(ucDigShowTemp,0x7f);
break; */
}
}
}
//数码管的74HC595驱动函数
void dig_hc595_drive(unsigned char ucDigStatusTemp16_09,unsigned char ucDigStatusTemp08_01)
{
unsigned char i;
unsigned char ucTempData;
dig_hc595_sh_dr=0;
dig_hc595_st_dr=0;
ucTempData=ucDigStatusTemp16_09; //先送高8位
for(i=0;i<8;i++)
{
if(ucTempData>=0x80)dig_hc595_ds_dr=1;
else dig_hc595_ds_dr=0;
dig_hc595_sh_dr=0; //SH引脚的上升沿把数据送入寄存器
delay_short(1);
dig_hc595_sh_dr=1;
delay_short(1);
ucTempData=ucTempData<<1;
}
ucTempData=ucDigStatusTemp08_01; //再先送低8位
for(i=0;i<8;i++)
{
if(ucTempData>=0x80)dig_hc595_ds_dr=1;
else dig_hc595_ds_dr=0;
dig_hc595_sh_dr=0; //SH引脚的上升沿把数据送入寄存器
delay_short(1);
dig_hc595_sh_dr=1;
ucTempData=ucTempData<<1;
}
dig_hc595_st_dr=0; //ST引脚把两个寄存器的数据更新输出到74HC595的输出引脚上并且锁存起来
delay_short(1);
dig_hc595_st_dr=1;
delay_short(1);
dig_hc595_sh_dr=0; //拉低,抗干扰就增强
dig_hc595_st_dr=0;
dig_hc595_ds_dr=0;
}
void delay_short(unsigned int uiDelayShort)
{
unsigned int i;
for(i=0;i { ; } } void delay_long(unsigned int uiDelayLong) { unsigned int i; unsigned int j; for(i=0;i { for(j=0;j<500;j++) { ; } } } void initial_myself() { P0=0xff; P1=0xff; P2=0xff; P3=0xff; TMOD=0x02;//T1工作模式2 TH0=0x14; TL0=0x00; } void initial_peripheral() //初始化外围 { IE=0x82; //IE.7位为1表示CPU开放中断,IE.1位也为1,表示允许定时器T0溢出中断 TR0=1; //使能定时器 P0=0xff; //选择ADC0809的通道7(111)(P1.0~P1.2) //ls=0; ST=0; OE=0; IT1=1; //下降沿触发 EX1=1; //使能外部中断1 EA=1; //允许全局中断 } void counter1(void) interrupt 2 using 2 { EX1=0; temp=P0; //temp=0xfe; EX1=1; }