/*-----------------------------------------------
名称:IIC协议 PCF8591ADDA转换
内容:此程序通过IIC协议对DAAD芯片操作,读取电位器的电压,并输出模拟量,用LED亮度渐变指示,晶体选用12MHz
------------------------------------------------*/
#include\"reg52.h\"
#include #define AddWr 0x90 //写数据地址 #define AddRd 0x91 //读数据地址 sbit Sda=P1^2; //定义总线连接端口 sbit Scl=P1^1; sbit control_signal=P1^5; data unsigned int Display[8];//定义临时存放数码管数值 unsigned char code Datatab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//7段数共阴码管段码表 unsigned int ADtemp; //定义全局变量 unsigned int high,low; static unsigned int count1; /*------------------------------------------------ 延时程序 ------------------------------------------------*/ void mDelay(unsigned char j) { unsigned int i; for(;j>0;j--) { for(i=0;i<125;i++) {;} } } /*------------------------------------------------ 初始化定时器0 ------------------------------------------------*/ void Init_Timer0(void) { TMOD |=0x01; //定时器设置 0.1ms in 11.0592M crystal TH0=(65536-78)/256; TL0=(65536-78)%256; //定时0.1mS ET0=1;//定时器中断打开 EA=1;//总中断 TR0=1; //启动定时器0 } /*------------------------------------------------ 启动IIC总线 ------------------------------------------------*/ void Start(void) { Sda=1; _nop_(); Scl=1; _nop_(); Sda=0; _nop_(); Scl=0; } /*------------------------------------------------ 停止IIC总线 ------------------------------------------------*/ void Stop(void) { Sda=0; _nop_(); Scl=1; _nop_(); Sda=1; _nop_(); Scl=0; } /*------------------------------------------------ 应答IIC总线 ------------------------------------------------*/ void Ack(void) { Sda=0; _nop_(); Scl=1; _nop_(); Scl=0; _nop_(); } /*------------------------------------------------ 非应答IIC总线 ------------------------------------------------*/ void NoAck(void) { Sda=1; _nop_(); Scl=1; _nop_(); Scl=0; _nop_(); } /*------------------------------------------------ 发送一个字节 ------------------------------------------------*/ void Send(unsigned char Data) { unsigned char BitCounter=8; unsigned char temp; do { temp=Data; Scl=0; _nop_(); if((temp&0x80)==0x80) Sda=1; else Sda=0; Scl=1; temp=Data<<1; Data=temp; BitCounter--; } while(BitCounter); Scl=0; } /*------------------------------------------------ 读入一个字节并返回 ------------------------------------------------*/ unsigned char Read(void) { unsigned char temp=0; unsigned char temp1=0; unsigned char BitCounter=8; Sda=1; do { Scl=0; _nop_(); Scl=1; _nop_(); if(Sda) temp=temp|0x01; else temp=temp&0xfe; if(BitCounter-1) { temp1=temp<<1; temp=temp1; } BitCounter--; } while(BitCounter); return(temp); } /*------------------------------------------------ 读取AD模数转换的值,有返回值 ------------------------------------------------*/ unsigned int ReadADC(unsigned char Chl) { unsigned int Data; Start(); //启始信号 Send(AddWr);//0x90 Ack(); Send(0x40|Chl);//写入选择的通道,本程序只用单端输入,差分部分需要自行添加 //Chl的值分别为0、1、2、3,分别代表1-4通道 Ack(); Start(); Send(AddRd); //读入地址 Ack(); Data=Read(); //读数据 Scl=0; NoAck(); Stop(); return Data; //返回值 } /******************************************************************/ /* 主程序 /******************************************************************/ */ void main() { Init_Timer0(); while(1) { unsigned int angle; ADtemp=ReadADC(0); //ADtemp的取值范围是0-255,定时的时间范围是0.5-2.5ms high=65075-7.2*ADtemp; // ( high=65035-7.8*ADtemp;12MHz)(65535-(460+7.2*ADtemp 11.0592MHz) low=47563+7.2*ADtemp; // ( low=46035+7.8*ADtemp; ) ( 65535-(17972-7.2*ADtemp 11.0592MHz ) angle=ADtemp*0.7; Display[0]=Datatab[angle/100];//处理0通道电压显示 Display[1]=Datatab[(angle%100)/10]; Display[2]=Datatab[angle%10]; while(1) { P0=Display[count1];//用于动态扫描数码管 P2=count1; mDelay(1); count1++; if(count1==3) //表示扫描8个数码管 { count1=0; break; } } } } /******************************************************************/ /* 定时器中断函数,需要更改 /******************************************************************/ void tim(void) interrupt 1 using 1 { static unsigned char count; if (!count) { control_signal = 1; //给高电平 TH0=high/256; TL0=high%256; } else { control_signal=0 ; TH0=low/256; TL0=low%256; } count=~count; //定时0.05mS,经过示波器的测量 //定时0.05mS,经过示波器的测量 } 因篇幅问题不能全部显示,请点此查看更多更全内容