#include<reg51.h> #include<intrins.h>
#define AD_CLK_WIDTH 1 /*AD7705串口时钟脉冲宽度*/ unsigned char decimal_number[]={0x30,0xf5,0x58,0xd0,0x95,0x92,0x12,0xf4,0x10,0x90}; //0-9所对应的八段码 #define SomeNOP(); {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();} void Wait7705(unsigned int t) { for( ;t>0 ;t-- ); } //void Init_disp(); // 显示板初始化 void Translate(unsigned int ADdata); //结果处理函数 void delay(); //led显示延时函数
sbit SDA=P0^4; //led数据输入 sbit CP=P0^5; //led移位始终信号 sbit P1_6=P1^6; //发光二极管,检验单片机工作状态,是否工作正常 sbit ADC_CS=P1^0; //定义片选管脚 sbit ADC_RESET=P1^1; //复位 sbit ADC_CLK=P1^2; //时钟对应单片机管脚 sbit ADC_DIN=P1^3; //定义数据输入管脚 sbit ADC_DOUT=P1^4; //定义数据输出管脚 sbit ADC_DRDY=P1^5; //AD转换结束标志位
unsigned char data2disp[5]={0x30,0x30,0x30,0x30,0x20}; //显示数据,4个显示板,各5位,共享
void Write_functionAD(unsigned char wridata) //AD写一个字节函数,初始化AD { unsigned char AD8bit,Token,i; ADC_CLK=1; ADC_CS=0; Token=0X80; AD8bit=wridata; for(i=0;i<8;i++) { ADC_CLK=0; Wait7705(AD_CLK_WIDTH); if(AD8bit&Token) ADC_DIN=1; //MSB高位数据先移入AD7705 else ADC_DIN=0; Wait7705(AD_CLK_WIDTH ); ADC_CLK=1; //在SCLK的上升沿,DIN数据有效 Wait7705(AD_CLK_WIDTH); Token=Token>>1; } ADC_CS=1; //ADC_CLK=1;ADC_DIN=1; }
float Read_functionAD() //AD读函数,读取转换结果 { unsigned int AD16bit; unsigned char i; // while(ADC_DRDY==1){;} ADC_CLK=1; ADC_CS=0; AD16bit=0X00; for(i=0;i<16;i++) { AD16bit=AD16bit<<1; ADC_CLK=0; Wait7705(AD_CLK_WIDTH); //在SCL K 的下降沿之后,DOUT数据有效 if(ADC_DOUT==1)AD16bit=AD16bit|0X01; ADC_CLK=1; Wait7705(AD_CLK_WIDTH); } // ADC_CLK=1;ADC_DIN=1; return(AD16bit); //返回AD转换结果 }
void initial_functionAD() //初始化AD转换芯片 { unsigned char i; ADC_CS=0; ADC_RESET=0; SomeNOP(); ADC_RESET=1; //AD复位完成 //xchannel=channel; ADC_CLK=1;ADC_DIN=1; //防止接口迷失,通信寄存器返回到等待写状态,DIN为1的时间在32个以上的时钟周期 for(i=0;i<40;i++) { ADC_CLK=0; ADC_CLK=1; } Write_functionAD(0x20); //通道1 ,下一个写时钟寄存器 Write_functionAD(0x06); //写时钟寄存器设置更新速率为250Hz Write_functionAD(0x10); // 通道1 ,下一个写设置寄存器 Write_functionAD(0x44); //写设置寄存器,设置成单极性、无缓冲、增益为1、滤波器工作、自校准 delay(); //延时 }
void delay() //发光二极管延时函数 { unsigned char i,k,temp; for(i=0;i<38;i++) for(k=0;k<225;k++) for(temp=0;temp<25;temp++); //延时,这里的延时和机器周期关系很大 }
void display(unsigned char datadisplay) //8位数LED显示函数 { unsigned char k,temp; temp=datadisplay; for(k=8;k>0;k--) { temp=temp<<1; if(CY) ADC_DOUT=1; else ADC_DOUT=0; //显示 ADC_CLK=0; SomeNOP(); //延时 ADC_CLK=1; SomeNOP(); } }
void main() { unsigned int ADdata; //转换后的AD读数结果 unsigned char i; unsigned int a; unsigned char flag_disp; //显示完成标志位 flag_disp=0; //显示完成标志 delay(); initial_functionAD(); //初始化AD转换器 while(1) { for(a=0;a<50000;a++); P1_6=0; for(a=0;a<50000;a++); P1_6=1; if(ADC_DRDY==0) { Write_functionAD(0X38); //准备读转换AD结果 ADdata=Read_functionAD(); flag_disp=1; } //ADC_DEDY if(flag_disp==1) { flag_disp=0; Translate(ADdata); for(i=0;i<5;i++) { display(data2disp); } } } //while 1 }
void Translate(unsigned int ADdata) //浮点就过数据处理函数(包括查找自行码) { float airpressf; //0--350bar,气室AD读数对应的气压值 bar为单位 unsigned int ADdata2=ADdata; unsigned char j,k,b; unsigned char i=0; unsigned char a[6]={1,2,3,4,5,6}; unsigned char airpressc,airpressc2,airpressc3; airpressf=(ADdata2/51.0-1)/4.0; airpressc2=airpressc3=airpressc=(unsigned char)airpressf; for(k=0;k<6;k++) { a[k]=airpressc3%10; if(a[k]!=0){ b=a[k];break;} airpressc3/=10; k++; } do { data2disp=airpressc%10; airpressc/=10; //此处处理整数部分 i++; }while(airpressc); // 至此,整数部分已转换为字符 switch (i) //将相应字符移位, { case 1: data2disp[4]=data2disp[0]; break; case 2: data2disp[4]=data2disp[1]; data2disp[3]=data2disp[0]; break; case 3: data2disp[4]=data2disp[2]; data2disp[3]=data2disp[1]; data2disp[2]=data2disp[0]; break; } airpressf-=airpressc2;//取出小数部分 j=5-i; while(j>0) { j--; airpressf*=10; (data2disp[j])=(unsigned char)airpressf; airpressf-=data2disp[j]; } data2disp[0]=b; //防止尾数不稳 for(j=0;j<5;j++) //查找字形码 { data2disp[j]=decimal_number[data2disp][j]]; }
data2disp[5-i]&=0x10; //加上小数点 } |