当前位置:文档之家› 单片机ADDA模块应用

单片机ADDA模块应用

单片微型计算机与接口技术姓名:***班级:15电气2班学号:************第一题:ADDA1.系统方案论证及方案选择1.1 总体设计方案题目要求使用AD转换模块,将模拟信号的值转换为数值并通过液晶屏显示;使用矩阵键盘为输入,使其能够设置报警电压,并能够与AD转换值进行比较;使用DA模块通过矩阵键盘能够产生方波,并且能够调节占空比;1.2方案论证与选择1.2.1 设计要求及思路题目要求使用ADDA模块,将数字模拟量互相转换。

我们的设计主要控制是用单片机,它将测得模拟量通过AD模块的转换,在用ASCIl换算成数据显示在液晶屏上。

加入矩阵键盘可以设置报警电压,一旦检测AD模块转换的电压高于报警电压,蜂鸣器发出警报,液晶屏显示“warning”。

使用DA模块与矩阵键盘连接可以调试产生方波,且可以用按键设计占空比。

1.2.2方案论证与选择芯片选择论证方案一:PCF8591TPCF8591是一种具有I2C总线接口的8位A/D ,D/A转换芯片,在与CPU 的信息传输过程中仅靠时钟线SCL与数据线SDA就可以实现。

I2C总线是飞利浦公司推出的串行总线,它与传统的通信方式相比具有读写方便,结构简单,可维护性好,易实现系统扩展,易实现模块化标准化设计,可靠性高等优点;在PCF8591器件上输入输出的地址、控制和数据信号都是通过双线双向I2C 总线以串行的方式进行传输。

PCF8591的功能包括多路模拟输入、内置跟踪保持、8-bit模数转换和8-bit数模转换。

PCF8591的最大转化速率由I2C总线的最大速率决定。

方案二:ADC0809ADC0809 是8 位逐次逼近型A/D转换器。

它由一个8路模拟开关、一个地址锁存译码器、一个A/D 转换器和一个三态输出锁存器组成。

多路开关可选通8个模拟通道,允许8 路模拟量分时输入,共用A/D 转换器进行转换。

三态输出锁存器用于锁存A/D 转换完的数字量,当OE 端为高电平时,才可以从三态输出锁存器取走转换完的数据。

由于ADC0809芯片需要用到的引脚过多,单片机的接口不允许它占用这么多端口,而PCF8591芯片需要的端口较少并可长时间待机,所以我们选择方案一。

2.系统的软硬件2.1主控制芯片STC89c51STC89C51RC是采用8051核的ISP(In System Programming)在系统可编程芯片,最高工作时钟频率为80MHz,片内含4K Bytes的可反复擦写1000次的Flash只读程序存储器,器件兼容标准MCS-51指令系统及80C51引脚结构,芯片内集成了通用8位中央处理器和ISP Flash存储单元,具有在系统可编程(ISP)特性,配合PC端的控制程序即可将用户的程序代码下载进单片机内部,省去了购买通用编程器,而且速度更快。

STC89C51RC系列单片机是单时钟/机器周期(1T)的兼容8051 内核单片机,是高速/ 低功耗的新一代8051 单片机,全新的流水线/精简指令集结构,内部集成MAX810 专用复位电路。

2.2矩阵键盘矩阵键盘是单片机外部设备中所使用的排布类似于矩阵的键盘组。

在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式。

在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。

这样,一个端口(如P1口)就可以构成4*4=16个按键,比之直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显,比如再多加一条线就可以构成20键的键盘,而直接用端口线则只能多出一键(9键)。

由此可见,在需要的键数比较多时,采用矩阵法来做键盘是合理的。

2.3液晶显示1602液晶也叫1602字符型液晶,它是一种专门用来显示字母、数字、符号等的点阵型液晶模块。

它由若干个5X7或者5X11等点阵字符位组成,每个点阵字符位都可以显示一个字符,每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用。

在本次设计中使用液晶屏双行显示报警电压与实测电压,也显示方波的占空比。

2.4蜂鸣器本次实验设计使用蜂鸣器作为报警器,蜂鸣器端口默认为高电平(即为1),不发出警报;当蜂鸣器端口为低电平(即为0)时,蜂鸣器即发出警报;2.5数模转换模块数模转换就是将离散的数字量转换为连接变化的模拟量。

与数模转换相对应的就是模数转换,模数转换是数模转换的逆过程。

D/A转换:发送给PCF8591的第三个字节被存储到DAC数据寄存器,并使用片上D/A转换器转换成对应的模拟电压。

这个D/A转换器由连接至外部参考电压的具有256个接头的电阻分压电路和选择开关组成。

模拟输出电压由自动清零单位增益放大器缓冲。

这个缓冲放大器可通过设置控制寄存器的模拟输出允许标志来开户或关闭。

在激活状态,输出电压保持到新的数据字节被发送。

A/D转换:A/D转换器采用逐次逼近转换技术。

在A/D转换周期将来临时片上D/A抓换器和高增益比较器。

一个A/D转换周期总是开始于发送一个有效读模式地址给PCF8591之后。

A/D转换周期在应答时钟脉冲的后沿被触发,并在传输前一次转换结果时执行。

一旦一个转换周期被触发,所选通道的输入电压采样将保存到芯片被转换为对应的8为二进制码。

3.系统操作显示流程图ADDA流程图附件1 说明书按键布局使用说明:附件2 程序#include <reg52.h>#include <intrins.h>#include<math.h>#define OP_WRITE 0x90 //PCF8591地址#define OP_READ 0x91#define uchar unsigned char#define uint unsigned intsbit BEEP = P2^3; //蜂鸣器sbit SDA = P2^0; //I2C串行数据sbit SCL = P2^1; //I2C串行时钟sbit RS=P1^0;sbit RW=P1^1;sbit EN=P1^2;uchar K,Key;char b[10]="v safe ";double aa;char pd,n,xsd,d=50,l=50;char a[]="0123456789. ";uchar table1[10]="v warning";void delayNOP(){_nop_();_nop_();_nop_();_nop_();void delay(unsigned char t) {char i;while(t--)for(i=0;i<125;i++);}void start(){SDA = 1;SCL = 1;delayNOP();SDA = 0;delayNOP();SCL = 0;}void stop(){SDA = 0;delayNOP();SCL = 1;delayNOP();}uchar shin()// 从AT24C02移出数据到MCU{uchar i,read_data;for(i = 0; i < 8; i++){SCL = 1;read_data <<= 1;read_data |= SDA;SCL = 0;}return(read_data);}bit shout(uchar write_data)// 从MCU移出数据到AT24C02{uchar i;bit ack_bit;for(i = 0; i < 8; i++) // 循环移入8个位{SDA = (bit)(write_data & 0x80); //写数据,将R/W置1 _nop_();delayNOP();SCL = 0;write_data <<= 1; //左移1位,高位移出}SDA = 1; // 读取应答delayNOP();SCL = 1;delayNOP();ack_bit = SDA;SCL = 0;return ack_bit; // 返回AT24C02应答位}void write_byte(uchar addr, uchar write_data)// 在指定地址addr处写入数据write_data{start();shout(OP_WRITE); //发出写命令shout(addr); //先输出地址shout(write_data); //后写数据stop();delay(10);// 写入周期}uchar read_current()// 在当前地址读取{uchar read_data;start();shout(OP_READ);read_data = shin();stop();return read_data;}uchar read_random(uchar random_addr) // 在指定地址读取{start();shout(OP_WRITE);shout(random_addr);return(read_current());}void wcmd(uchar cmd){RS=0;RW=0;P0=cmd;delay(5);EN=1;delay(5);EN=0;delay(5);}void wdat(uchar dat) {RS=1;RW=0;P0=dat;delay(5);EN=1;delay(5);EN=0;delay(5);}void init(){EN=0;wcmd(0x01); delay(5);wcmd(0x06); delay(5);wcmd(0x0c);delay(5);wcmd(0x38);delay(5);}unsigned char data1_conve(unsigned char dat_temp){unsigned char data1;data1=(unsigned char)(((float)dat_temp/255)*5); //换算为电压值的个位值data1=data1+48; //转换为对应的ASCII码,因为0对应ASCII码的48,以此类推return data1;}unsigned char data0_convert(unsigned char dat_temp){unsigned char data0,data1;data1=(unsigned char)(((float)dat_temp/255)*5); //换算为电压值的个位值data0=(unsigned char)((((float)dat_temp/255)*5-data1)*10); //换算为为电压值的小数点后第一位的那个值data0=data0+48;return data0; //转换为对应的ASCII码}unsigned char Keycan(void) //按键扫描程序P3.0--P3.3为行线P3.4--P3.7为列线{unsigned char rcode, ccode;P3 = 0xF0; // 发全0行扫描码,列线输入if((P3&0xF0) != 0xF0) // 若有键按下{delay(3);// 延时去抖动if((P3&0xF0) != 0xF0){ rcode = 0xFE; // 逐行扫描初值while((rcode&0x10) != 0){P3 = rcode; // 输出行扫描码if((P3&0xF0) != 0xF0) // 本行有键按下{ccode = (P3&0xF0)|0x0F;while((P3&0xF0) != 0xF0); //等待键释放return ((~rcode) + (~ccode)); // 返回键编码}elsercode = (rcode<<1)|0x01; // 行扫描码左移一位}}}return 0; // 无键按下,返回值为0}void KeyDeal(unsigned char Key){if(Key!=0){switch(Key){case 0x11: K=0; break;case 0x21: K=1; break;case 0x41: K=2; break;case 0x81: K=3; break;case 0x12: K=4; break;case 0x22: K=5; break;case 0x42: K=6; break;case 0x82: K=7; break;case 0x14: K=8; break;case 0x24: K=9; break;case 0x44: K=10;xsd=1;break;case 0x84: K=11;break;case 0x18: K=12;if(l>10||l<100){d=d+10;l=l-10;}break;case 0x28: K=13; if(d>10||d<100){l=l+10;d=d-10;}break;case 0x48: K=14;pd=2;break;case 0x88: K=15;pd=1;break;default: break;}if(K<10){if(xsd==0)aa=aa*10+K;else{n++;aa=aa+pow(0.1,n)*K;}}if(K<=10){wdat(a[K]);}}}void main(){uchar ll,dd,i,j;wcmd(0x80);SDA=1;SCL=1;while(1){Key = Keycan();KeyDeal(Key);//单端输入,读出通道0的值if(pd==1){wcmd(0xc0);wdat(data1_conve(read_random(0x02)));wcmd(0xc1);wdat('.');wcmd(0xc2);wdat(data0_convert(read_random(0x02)));if (((float)read_random(0x02)/255)*5 > aa) {BEEP = 0;for(i=0;i<9;i++)wdat(table1[i]);}else{BEEP = 1;for(j=0;j<9;j++)wdat(b[j]);}delay(5);}if(pd==2){ll=l;dd=d;wcmd(0x85);wdat(ll/10);wcmd(0x86);wdat(ll%10)while(l--)write_byte(0x40, 255);while(d--)write_byte(0x40, 0 );}}。

相关主题