这个是我做的课设,虽然不是很高级的程序,但是想分享给那些需要的小伙伴。
单片机源程序如下:
- #include<reg52.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit sda=P2^0; //I2C串行数据
- sbit scl=P2^1; ////I2C串行时钟
- sbit dula=P2^6;
- sbit wela=P2^7;
- uchar code table[]={
-
- 0x3F, //"0"
- 0x06, //"1"
- 0x5B, //"2"
- 0x4F, //"3"
- 0x66, //"4"
- 0x6D, //"5"
- 0x7D, //"6"
- 0x07, //"7"
- 0x7F, //"8"
- 0x6F, //"9"
- 0x77, //"A"
- 0x7C, //"B"
- 0x39, //"C"
- 0x5E, //"D"
- 0x79, //"E"
- 0x71, //"F"
- };
- uchar code table1[]={ 0xbf,0x86,0xdb,0xcf,0xe6,0xed }; //带小数点的0-5
- void delay() //5us
- {_nop_();}
- void delay1(uint z)//1ms
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=114;y>0;y--);
- }
- void display(uchar value)
- { uchar a,b,c,d;
-
-
- a=value*196/10000; // 个位
- b=value*196/1000%10; //小数点后一位
- c=value*196/100%10; //小数点后两位
- d=value*196/10%10; //小数点后三位
- dula=1;
- P0=table1[a]; //显示带小数点的个位
- dula=0;
- P0=0xff;
- wela=1;
- P0=0xfe;
- wela=0;
- delay1(1);
- dula=1;
- P0=table[b];
- dula=0;
- P0=0xff;
- wela=1;
- P0=0xfd;
- wela=0;
- delay1(1);
- dula=1;
- P0=table[c];
- dula=0;
- P0=0xff;
- wela=1;
- P0=0xfb;
- wela=0;
- delay1(1);
- dula=1;
- P0=table[d];
- dula=0;
- P0=0xff;
- wela=1;
- P0=0xf7;
- wela=0;
- delay1(1);
- }
- void start() //I2C起始信号,线为高电平期间,SDA线由高电平向低电平的变化表示起始信号;
- {
- scl=1;
- _nop_();
- sda=1;
- delay();
- sda=0;
- delay();
- scl=0;
- _nop_();
- }
- void stop() //SCL线为高电平期间,SDA线由低电平向高电平的变化表示终止信号。
- {
- scl=1;
- _nop_();
- sda=0;
- delay();
- sda=1;
- delay();
- }
- void respons() //I2C主机发送应答
- {
- scl=1;//拉高时钟总线 让从机从SDA线上读走 主机的应答信号
- _nop_();
- sda=0;//应答为0
- delay();
- scl=0; //释放SDA数据总线。
- _nop_();
- }
- void norespons() //I2C检测从机应非答
- {
- scl=1;//时钟总线为高电平期间可以读取从机应答信号
- _nop_();
- sda=1; //非应答为1
- delay();
- }
- void init() //初始化
- {
- scl=1;
- _nop_();
- sda=1;
- _nop_();
- }
- void write_byte(uchar dat) //I2C发送一个字节
- {
- uchar i,temp;
- temp=dat;
- for(i=0;i<8;i++)
- {
- scl=0; //释放sda数据总线
- _nop_();
- if((temp&0x80)==0x80) //1000 0000 高位发送
- sda=1;
- else
- sda=0;
- scl=1; //从机从SDA线上读走信号,就是已发送
- _nop_();
- temp<<=1; //高位移除
- }
- scl=0;
- _nop_();
- }
- uchar read_byte() //I2C读一个字节
- {
- uchar dat,i;
- sda=1;
- _nop_();
- scl=0;
- _nop_();
- for(i=0;i<8;i++)
- {
- scl=1; //时钟总线为高电平期间可以读取从机应答信号
- _nop_();
- if(sda)
- dat|=0x01; //0000 0001 主机读取 高位信号存入dat的低位
- if(i<7)
- dat<<=1; //左移一位,方便下一次读取数据
- scl=0;
- _nop_();
- }
- return dat;
- }
- void DAC_write(uchar dat) // DAT,发送给PCF8591转换的数字量
- {
- start(); //I2C总线起始
- write_byte(0x90); //发送PCF8591地址加读写方向位0(写)
- respons(); //发送成功(应答)
- write_byte(0x40); //发送控制字节DAC输出使能
- respons(); //发送成功(应答)
- write_byte(dat); //发送数字量交由PCF8591转为模拟量AOUT脚输出
- respons(); //发送成功(应答)
- stop(); // //I2C总线停止
- }
- uchar ADC_read(uchar com)
- {
- uchar dat;
- dat=com;
- start();
- write_byte(0x90); //地址选择字 10010000 写 ,发送第一字节
- respons();
- write_byte(com); //发送控制字节
- respons(); //发送应答
- start();
- write_byte(0x91); //改变读写方向(读)
- respons();
- dat=read_byte(); //把读取的值赋给形参
- norespons();
- stop();
- return dat;
- }
- void main()
- {
- uchar i=0,ad_value;
- init();
- while(1)
- {
-
- ad_value=ADC_read(0x40);
-
-
- display(ad_value);
-
- delay1(1);
- }
- }
复制代码
所有资料51hei提供下载:
AD电压采集.zip
(16.28 KB, 下载次数: 76)
|