|
使用proteus,8051單片機(jī),與pcf8591進(jìn)行ad轉(zhuǎn)換
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
09-34-16-forum.jpg (440.93 KB, 下載次數(shù): 78)
下載附件
2019-10-29 09:41 上傳
單片機(jī)源程序如下:
- #include<reg52.h>
- #define uint unsigned int
- #define uchar unsigned char
- sbit sda=P2^0; //自定義由普通IO口模擬I2C
- sbit scl=P2^1;
- sbit dm=P2^6; //段鎖存
- sbit wm=P2^7;
- uchar code table[]={0x3f,0x06,0x5b,0x4f,
- 0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
- void Delay(uint n)
- {
- uint i,j;
- for(i=n;i>0;i--)
- for(j=110;j>0;j--);
- }
- void delay() //延時(shí)幾微秒。延時(shí)函數(shù)在很多函數(shù)里都要用它。至少要大于4.7us
- {;;} //當(dāng)你把這個(gè)函數(shù)寫在用它這個(gè)函數(shù)的前面就不用聲明了
- void init() //初始化總線。將總線都拉高以釋放
- {
- scl=1;
- delay(); //I2C總線使用時(shí)一般都要延時(shí)5us左右
- sda=1;
- delay();
- }
- void start() //啟始信號(hào)。 時(shí)鐘信號(hào)為高電平期間,數(shù)據(jù)總線產(chǎn)生下降沿。
- { //為什么要下降沿,且sda先要為1。因?yàn)橄纫WC數(shù)據(jù)線為空才能工作
- sda=1; //先釋放數(shù)據(jù)總線。高電平釋放
- delay();
- scl=1;
- delay();
- sda=0;
- delay();
- }
- void stop()
- {
- sda=0; //先要有工作狀態(tài)才能釋放,sda=0時(shí)在工作狀態(tài)
- delay();
- scl=1;
- delay();
- sda=1; //釋放數(shù)據(jù)總線
- delay();
- }
- void respons() //應(yīng)答函數(shù)
- {
- uchar i=0;
- scl=1; //每個(gè)字節(jié)發(fā)送完后的第九個(gè)時(shí)鐘信號(hào)的開始
- delay();
- while((sda==1)&&(i<255)) //此處i的定義使用了uchar.只要填一個(gè)小于255的就行
- i++; //此處的sda是從機(jī)的
- scl=0; //表示主器件默認(rèn)從器件已經(jīng)收到而不再等待。不再等待之后,時(shí)鐘的高電平過了就是低電平,所以scl=0
- //此時(shí)第酒個(gè)時(shí)鐘信號(hào)結(jié)束
- }
- void writebyte(uchar d) //寫一字節(jié),每次左移一位
- {
- uchar i,temp;
- temp=d;
- for(i=0;i<8;i++)
- {
- temp=temp<<1;
- scl=0; //數(shù)據(jù)傳輸期間要想sda可變,先把時(shí)鐘拉低。此處要給sda賦值
- delay();
- sda=CY; //CY為左移移入PSW寄存器中的的CY位。
- delay();
- scl=1; //sda有數(shù)據(jù)了。保持?jǐn)?shù)據(jù)穩(wěn)定
- delay();
- }
- scl=0; //此處是寫數(shù)據(jù),是屬于數(shù)據(jù)傳輸過程中。只有在時(shí)鐘信號(hào)為低電平期間
- delay(); //數(shù)據(jù)總線才可以變化。
- sda=1; //所以要想釋放數(shù)據(jù)總線,就必須先把時(shí)鐘拉低
- delay();
- /*此處釋放總線寫在末尾是因?yàn)檎{(diào)用它時(shí),前面有起始函數(shù)釋放了總線*/
- }
- uchar readbyte()
- {
- uchar i,k;
- scl=0;
- delay();
- sda=1;
- delay();
- /*此處釋放總線放在前面是因?yàn)橐话愣际窍葘懞笞x,保險(xiǎn)起見,釋放一下總線*/
- for(i=0;i<8;i++)
- {
- scl=1; //一個(gè)時(shí)鐘信號(hào)的開始
- delay();
- k=(k<<1)|sda; //實(shí)質(zhì)是把sda的數(shù)據(jù),最先傳來的放在最高位,依次往下排
- scl=0; //一個(gè)時(shí)鐘信號(hào)結(jié)束
- delay();
- }
- return k;
- }
- void display(uchar bai,uchar shi,uchar ge)
- {
- dm=1;
- P0=table[bai]; //顯示第一位
- dm=0;
- P0=0xff; //消隱
- wm=1;
- P0=0xfe;
- wm=0;
- P0=0x00; //消除仿真亂碼
- Delay(5);
-
- dm=1;
- P0=table[shi]; //顯示第二位
- dm=0;
- P0=0xff; //消隱
- wm=1;
- P0=0xfd;
- wm=0;
- P0=0x00; //消除仿真亂碼
- Delay(5);
-
- dm=1;
- P0=table[ge]; //顯示第三位
- dm=0;
- P0=0xff; //消隱
- wm=1;
- P0=0xfb;
- wm=0;
- P0=0x00; //消除仿真亂碼
- Delay(5);
- }
- /*void write(uchar addr,uchar dat)
- {
- start(); //初始化
- writebyte(0x90); //調(diào)用寫一字節(jié)函數(shù).PCF8591為1001。此處是給從機(jī)發(fā)送寫信號(hào)(最低位是0)
- respons(); //調(diào)用應(yīng)答函數(shù)讓從機(jī)應(yīng)答
- writebyte(addr); //寫入地址
- respons(); //每寫一字節(jié)都要應(yīng)答
- writebyte(dat);
- respons();
- stop();
- }*/
- uchar read(uchar addr)
- {
- uchar dat;
- start();
- writebyte(0x90); //從此處的發(fā)送地址和方向位0到從機(jī)
- respons(); //此處的從機(jī)產(chǎn)生應(yīng)答。屬于“偽寫”。用于確定和哪臺(tái)機(jī)子通信
- writebyte(addr);
- respons();
- start();
- writebyte(0x91); //從此處開始,從機(jī)向主機(jī)寫數(shù)據(jù)。讀的方向位為1
- respons();
- dat=readbyte();
- stop();
- return dat; //讀得的數(shù)據(jù)要返回
- }
- void main()
- {
- uchar ge,shi,bai,n;
- init();
- while(1)
- {
- n=read(0x00); //此處是讀取內(nèi)存的不同位置。至于從哪兒開始應(yīng)該沒要求
- ge=n%10;
- shi=n%100/10;
- bai=n/100;
- display(bai,shi,ge);
- }
- }
復(fù)制代碼
所有資料51hei提供下載:
AD轉(zhuǎn)換.zip
(27.18 KB, 下載次數(shù): 219)
2019-10-29 09:42 上傳
點(diǎn)擊文件名下載附件
源文件 下載積分: 黑幣 -5
|
評(píng)分
-
查看全部評(píng)分
|