這個是我做的課設,雖然不是很高級的程序,但是想分享給那些需要的小伙伴。
單片機源程序如下:
- #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)
2018-7-12 14:50 上傳
點擊文件名下載附件
|