專(zhuān)注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計(jì)實(shí)例 >> 瀏覽文章

PCF8591(AD-DA)芯片-51單片機(jī)程序

作者:佚名   來(lái)源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時(shí)間:2013年10月29日   【字體:
注:
     PCF8591  是8位AD-DA芯片   轉(zhuǎn)換數(shù)據(jù)0---5  對(duì)應(yīng) 0--255
    通信協(xié)議IIC
    模擬量輸出值和電壓的關(guān)系:   輸出電壓=(參考電壓-基點(diǎn)電位)/255
 
//以下是源碼如果在網(wǎng)頁(yè)上顯示格式錯(cuò)亂可以從這里下載: http://www.torrancerestoration.com/f/8591c.rar
//12MHZ晶振
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#include "IIC.h"  //i2c庫(kù)函數(shù)
code uchar seg[]={0x28,0x7e,0xa2,0x62,0x74,0x61,0x21,0x7a,0x20,0x60};    //數(shù)碼管碼表
code uchar tab[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};      //數(shù)碼管位選
sbit bz=P3^3;   //喇叭位
uchar outdata; //模擬量輸出值
sbit k1=P1^2 ;   //模擬量輸出者增加
sbit k2=P1^1;   //模擬量輸出者減少 
void delay(uint k)    //延時(shí)子函數(shù)
{
while(k--);
}
  
void key1()    //模擬輸出值增加
{
if(k1==0)
{
delay(1000);
if(k1==0)
outdata++;
}
 }
void key2()     //模擬輸出值減少
{
if(k2==0)
{
delay(1000);
if(k2==0)
outdata--;
}
 }

void ADCinshow(uchar dd)   //模擬量輸入值顯示
{
   P0=seg[dd/100];
   P2=tab[7];
   delay(8);
   P0=0xff;                             //顯示消影
   P2=0xff;
   P0=seg[dd%100/10];
   P2=tab[6];
   delay(8);
   P0=0xff;
   P2=0xff;
   P0=seg[dd%10];
   P2=tab[5];
   delay(8);
   P0=0xff;
   P2=0xff;
}
 
void ADCoutshow(uchar k)    //模擬量輸出值顯示
{
 P0=seg[k/100];
 P2=tab[2];
 delay(8);
 P0=0xff;
 P2=0xff;
 P0=seg[k%100/10];
 P2=tab[1];
 delay(8);
 P0=0xff;
 P2=0xff;
 P0=seg[k%10];
 P2=tab[0];
 delay(8);
 P0=0xff;
 P2=0xff;
 }
//------------------主函數(shù)----------------
void main()
{
   uchar val;      //模擬量讀取值變量 
   uint cnt=0;             //設(shè)置喇叭報(bào)警延時(shí)變量  
   while(1)
   {   key1();
       key2();
      val=readADC(3);   //讀取通道3的轉(zhuǎn)換值
   ADCinshow(val);
     if(writeDAC(outdata)!=0);    //模擬量輸出值
   ADCoutshow(outdata);
      if(val>200)      //模擬量輸入值超過(guò)200  喇叭報(bào)警
   {
  cnt++;
  if(cnt>2)
  {
  bz=~bz;
   cnt=0;
  }
    }
    else
    bz=1;
   }
}
 
//IIC庫(kù)函數(shù)---------------------------------------------------------------

sbit scl=P3^0;    //IIC 時(shí)鐘線(xiàn)
sbit sda=P3^1;    //IIC 數(shù)據(jù)線(xiàn)
uchar ack;     //應(yīng)答位

void delay_nop()  //延時(shí)約5us
{
 _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
}
void iic_start()   //啟動(dòng)IIC總線(xiàn)
{
   sda=1;
   _nop_();
   scl=1;    //時(shí)鐘線(xiàn)高電平期間,數(shù)據(jù)線(xiàn)下降沿產(chǎn)生啟動(dòng)信號(hào)
   delay_nop();    //5us延時(shí)
   sda=0;
  delay_nop(); 
   scl=0;      //釋放總線(xiàn)開(kāi)始準(zhǔn)備接受/發(fā)送數(shù)據(jù)
    _nop_();
  _nop_();
}
void iic_stop()     //停止IIC總線(xiàn)
{
   sda=0;
   _nop_();     //時(shí)鐘線(xiàn)高電平期間,數(shù)據(jù)線(xiàn)上升沿產(chǎn)生停止信號(hào)
   scl=1;
    delay_nop(); 
   sda=1;
   delay_nop(); 
}
void iic_sendbyte(uchar byte)    //IIC發(fā)送一個(gè)字節(jié)命令
{
  uchar i;
  for(i=0;i<8;i++)
  {
 if((byte<<i)&0x80)sda=1;    //把發(fā)送字節(jié)最高位放入數(shù)據(jù)線(xiàn)
 else sda=0;      //發(fā)送字節(jié)中數(shù)據(jù)左移一位
 _nop_();      
 scl=1;          //時(shí)鐘線(xiàn)至高位 ,數(shù)據(jù)保持穩(wěn)定
  delay_nop(); 
 scl=0;          //釋放開(kāi)始下一個(gè)數(shù)據(jù)發(fā)送
  }
  sda=1;           //發(fā)送完,釋放數(shù)據(jù)線(xiàn)開(kāi)始接受應(yīng)答
  _nop_();
  _nop_();
  scl=1;         //時(shí)鐘線(xiàn)至高位
  _nop_();
  _nop_();
  _nop_();
  if(sda==1)ack=0;         //應(yīng)答判斷
  else ack=1;
  scl=0;
  _nop_();
  _nop_();
 }
 
uchar iic_receive()  //IIC接受一個(gè)字節(jié)
{
   uchar i;
   uchar byte=0;
   sda=1;                        //數(shù)據(jù)線(xiàn)釋放開(kāi)始接受
   for(i=0;i<8;i++)
   {
   scl=0;        //時(shí)鐘線(xiàn)置低開(kāi)始接受數(shù)據(jù)
   delay_nop(); 
   scl=1;          //時(shí)鐘線(xiàn)置高,接受數(shù)據(jù)
    _nop_(); _nop_();
    byte=byte<<1;       
   if(sda==1)byte=byte+1;     //數(shù)據(jù)左移1位      
   _nop_();
   _nop_();
 }
 scl=0;        //接受完釋放總線(xiàn)
 _nop_();
 _nop_();
 return byte;       //返回接受值
}
void iic_noack()  //非應(yīng)答
{
 sda=1;
 _nop_();
 _nop_();
  _nop_();
 scl=1;
  delay_nop(); 
 scl=0;
 _nop_();
 _nop_();
}
uchar readADC(uchar chl)    //ADC轉(zhuǎn)換子函數(shù) 選擇通道chl
{
 uchar value;
 iic_start();
 iic_sendbyte(0x90);    //發(fā)送寫(xiě)方向
 if(ack==0)return 0;
 iic_sendbyte(0x40|chl);    //控制命令
 if(ack==0)return 0;
 iic_start();
 iic_sendbyte(0x91);     //發(fā)送讀方向
 if(ack==0)return 0;
 value=iic_receive();     //接受轉(zhuǎn)換數(shù)據(jù)
 iic_noack();
 iic_stop();
 return value;         //返回轉(zhuǎn)換值
 }

uchar writeDAC(uchar da)    //模擬量輸出值函數(shù)
{
  iic_start();
  iic_sendbyte(0x90);
  if(ack==0)return 0;
  iic_sendbyte(0x40);
  if(ack==0)return 0;
  iic_sendbyte(da);
  if(ack==0)return 0;
  iic_stop();
  return 1;         //正常輸出返回值1  異常返回值0
}
 
//--------------------------------------------------------------------

 
關(guān)閉窗口

相關(guān)文章