资讯详情

PCF8591(AD-DA)芯片-51单片机程序

注: PCF8591 是8位AD-DA芯片 转换数据0---5 对应 0--255 通信协议IIC 模拟量输出值和电压的关系: 输出电压=( -基点电位)/255 //以下是源码如果在网页上显示格式错乱可以从这里下载: http://www.ruidan.com/f/8591c.rar //12MHZ晶振 #include <reg51.h> #include <intrins.h> #define uchar unsigned char #define uint unsigned int #include "IIC.h"//i2c库函数 code uchar seg[]={0x28,0x7e,0xa2,0x62,0x74,0x61,0x21,0x7a,0x20,0x60}; // 码表 code uchar tab[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe}; //数码管位选 sbit bz=P3^3; //喇叭位 uchar outdata;//模拟量输出值 sbit k1=P1^2 ; //模拟量输出者增加 sbit k2=P1^1; //模拟量输出者减少 void delay(uint k) //延时子函数 { while(k--); } void key1() //模拟输出值增加 { if(k1==0) { delay(1000); if(k1==0) outdata++; } } void key2() //模拟输出值减少 { if(k2==0) { delay(1000); if(k2==0) outdata--; } } void A inshow(uchar dd)//模拟量输入值显示 { P0=seg[dd/100]; P2=tab[7]; delay(8); P0=0xff; //显示消影 P2=0xff; P0=seg[dd%100/10]; P2=tab[6]; delay(8); P0=0xff; P2=0xff; P0=seg[dd%10]; P2=tab[5]; delay(8); P0=0xff; P2=0xff; } void ADCoutshow(uchar k) //模拟量输出值显示 { P0=seg[k/100]; P2=tab[2]; delay(8); P0=0xff; P2=0xff; P0=seg[k%100/10]; P2=tab[1]; delay(8); P0=0xff; P2=0xff; P0=seg[k%10]; P2=tab[0]; delay(8); P0=0xff; P2=0xff; } //------------------主函数---------------- void main() { uchar val; //模拟量读取值变量 uint cnt=0; //设置喇叭报警延时变量 while(1) { key1(); key2(); val=readADC(3);//读取通道3的转换值 ADCinshow(val); if(writeDAC(outdata)!=0); //模拟量输出值 ADCoutshow(outdata); if(val>200) //模拟量输入值超过200 喇叭报警 { cnt++; if(cnt>2) { bz=~bz; cnt=0; } } else bz=1; } } //IIC库函数--------------------------------------------------------------- sbit scl=P3^0; //IIC 时钟线 sbit sda=P3^1; //IIC 数据线 uchar ack; //应答位 void delay_nop() //延时约5us { _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); } void iic_start() //启动IIC总线 { sda=1; _nop_(); scl=1;//时钟线高电平期间,数据线下降沿产生启动信号 delay_nop(); //5us延时 sda=0; delay_nop(); scl=0; //释放总线开始准备接受/发送数据 _nop_(); _nop_(); } void iic_stop() //停止IIC总线 { sda=0; _nop_(); //时钟线高电平期间,数据线上升沿产生停止信号 scl=1; delay_nop(); sda=1; delay_nop(); } void iic_sendbyte(uchar byte) //IIC发送一个字节命令 { uchar i; for(i=0;i<8;i++) { if((byte<<i)&0x80)sda=1;//把发送字节最高位放入数据线 else sda=0; //发送字节中数据左移一位 _nop_(); scl=1; //时钟线至高位 ,数据保持稳定 delay_nop(); scl=0; //释放开始下一个数据发送 } sda=1; //发送完,释放数据线开始接受应答 _nop_(); _nop_(); scl=1;//时钟线至高位 _nop_(); _nop_(); _nop_(); if(sda==1)ack=0; //应答判断 else ack=1; scl=0; _nop_(); _nop_(); } uchar iic_receive() //IIC接受一个字节 { uchar i; uchar byte=0; sda=1; //数据线释放开始接受 for(i=0;i<8;i++) { scl=0; //时钟线置低开始接受数据 delay_nop(); scl=1; //时钟线置高,接受数据 _nop_(); _nop_(); byte=byte<<1; if(sda==1)byte=byte+1; //数据左移1位 _nop_(); _nop_(); } scl=0; //接受完释放总线 _nop_(); _nop_(); return byte; //返回接受值 } void iic_noack()//非应答 { sda=1; _nop_(); _nop_(); _nop_(); scl=1; delay_nop(); scl=0; _nop_(); _nop_(); } uchar readADC(uchar chl) //ADC转换子函数 选择通道chl { uchar value; iic_start(); iic_sendbyte(0x90);//发送写方向 if(ack==0)return 0; iic_sendbyte(0x40|chl); //控制命令 if(ack==0)return 0; iic_start(); iic_sendbyte(0x91); //发送读方向 if(ack==0)return 0; value=iic_receive(); //接受转换数据 iic_noack(); iic_stop(); return value; //返回转换值 } uchar writeDAC(uchar da) //模拟量输出值函数 { iic_start(); iic_sendbyte(0x90); if(ack==0)return 0; iic_sendbyte(0x40); if(ack==0)return 0; iic_sendbyte(da); if(ack==0)return 0; iic_stop(); return 1; //正常输出返回值1 异常返回值0 } //-------------------------------------------------------------------- -电子元器件采购网(www.ruidan.com)是本土元器件目录分销商,采用“小批量、现货、样品”销售模式,致力于满足客户多型号、高质量、快速交付的采购需求。 自建高效智能仓储,拥有自营库存超过50,000种,提供一站式正品现货采购、个性化解决方案、选型替代等多元化服务。
锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台