找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4201|回復(fù): 2
收起左側(cè)

pcf8591驅(qū)動(dòng)程序

[復(fù)制鏈接]
ID:76190 發(fā)表于 2015-4-5 18:19 | 顯示全部樓層 |閱讀模式
//-----------------------函數(shù)聲明,變量定義--------------------------------------------------------
#include <reg51.h>
#include <intrins.h>
sbit SDA=P1^0;                          // 將p1.0口模擬數(shù)據(jù)口
sbit SCL=P1^1;                          // 將p1.1口模擬時(shí)鐘口
#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};                  
bit   bdata SystemError;                // 從機(jī)錯(cuò)誤標(biāo)志位
//-----------------------PCF8591專用變量定義--------------------------------------------------------
#define PCF8591_WRITE 0x92
#define PCF8591_READ  0x93
#define  NUM  4                      // 接收和發(fā)送緩存區(qū)的深度
unsigned char idata receivebuf[NUM];    // 數(shù)據(jù)接收緩沖區(qū)
//--------------------------------------------------------------------------------------------------
// 函數(shù)名稱: iic_start()
// 函數(shù)功能: 啟動(dòng)I2C總線子程序
//--------------------------------------------------------------------------------------------------
void iic_start(void)
{  EA=0;            //時(shí)鐘保持高,數(shù)據(jù)線從高到低一次跳變,I2C通信開始
SDA = 1;         
SCL = 1;
delayNOP();      // 延時(shí)5us
SDA = 0;
delayNOP();
SCL = 0;
}
//--------------------------------------------------------------------------------------------------
// 函數(shù)名稱: iic_stop()
// 函數(shù)功能: 停止I2C總線數(shù)據(jù)傳送子程序
//--------------------------------------------------------------------------------------------------
void iic_stop(void)
{
SDA = 0;       //時(shí)鐘保持高,數(shù)據(jù)線從低到高一次跳變,I2C通信停止
SCL = 1;
delayNOP();
SDA = 1;
delayNOP();
SCL = 0;
}
//--------------------------------------------------------------------------------------------------
// 函數(shù)名稱: slave_ACK
// 函數(shù)功能: 從機(jī)發(fā)送應(yīng)答位子程序
//--------------------------------------------------------------------------------------------------
void slave_ACK(void)
{
SDA = 0;   
SCL = 1;
delayNOP();   
SDA = 1;
SCL = 0;
}
//--------------------------------------------------------------------------------------------------
// 函數(shù)名稱: slave_NOACK
// 函數(shù)功能: 從機(jī)發(fā)送非應(yīng)答位子程序,迫使數(shù)據(jù)傳輸過程結(jié)束
//--------------------------------------------------------------------------------------------------
void slave_NOACK(void)
{
SDA = 1;   
SCL = 1;
delayNOP();
SDA = 0;
SCL = 0;
}
//--------------------------------------------------------------------------------------------------
// 函數(shù)名稱: check_ACK
// 函數(shù)功能: 主機(jī)應(yīng)答位檢查子程序,迫使數(shù)據(jù)傳輸過程結(jié)束
//--------------------------------------------------------------------------------------------------
void check_ACK(void)
{
SDA = 1;      // 將p1.0設(shè)置成輸入,必須先向端口寫1
SCL = 1;
F0 = 0;
if(SDA == 1)    // 若SDA=1表明非應(yīng)答,置位非應(yīng)答標(biāo)志F0
  F0 = 1;
SCL = 0;
}
//--------------------------------------------------------------------------------------------------
// 函數(shù)名稱: IICSendByte
// 入口參數(shù): ch
// 函數(shù)功能: 發(fā)送一個(gè)字節(jié)
//--------------------------------------------------------------------------------------------------
void IICSendByte(unsigned char ch)
{
unsigned char idata n=8;     // 向SDA上發(fā)送一位數(shù)據(jù)字節(jié),共八位
while(n--)
{
  if((ch&0x80) == 0x80)    // 若要發(fā)送的數(shù)據(jù)最高位為1則發(fā)送位1
  {
   SDA = 1;    // 傳送位1
   SCL = 1;
   delayNOP();
   SDA = 0;
   SCL = 0;   
  }
  else
  {  
   SDA = 0;    // 否則傳送位0
   SCL = 1;
   delayNOP();
   SCL = 0;  
  }
  ch = ch<<1;    // 數(shù)據(jù)左移一位
}
}
//--------------------------------------------------------------------------------------------------
// 函數(shù)名稱: IICreceiveByte
// 返回接收的數(shù)據(jù)
// 函數(shù)功能: 接收一字節(jié)子程序
//--------------------------------------------------------------------------------------------------
unsigned char IICreceiveByte(void)
{
unsigned char idata n=8;    // 從SDA線上讀取一上數(shù)據(jù)字節(jié),共八位
unsigned char tdata;
while(n--)
{
  SDA = 1;
  SCL = 1;
  tdata = tdata<<1;    // 左移一位,或_crol_(temp,1)
  if(SDA == 1)
   tdata = tdata|0x01;    // 若接收到的位為1,則數(shù)據(jù)的最后一位置1
  else
   tdata = tdata&0xfe;    // 否則數(shù)據(jù)的最后一位置0
  SCL=0;
}
return(tdata);
}
//--------------------------------------------------------------------------------------------------
// 函數(shù)名稱: DAC_PCF8591
// 入口參數(shù): slave_add從機(jī)地址,n要發(fā)送的數(shù)據(jù)個(gè)數(shù)
// 函數(shù)功能: 發(fā)送n位數(shù)據(jù)子程序
//--------------------------------------------------------------------------------------------------
void DAC_PCF8591(unsigned char controlbyte,unsigned char wdata)
{   
iic_start();                // 啟動(dòng)I2C
IICSendByte(PCF8591_WRITE);     // 發(fā)送地址位
check_ACK();                // 檢查應(yīng)答位
    if(F0 == 1)
{
  SystemError = 1;
  return;    // 若非應(yīng)答表明器件錯(cuò)誤或已壞,置錯(cuò)誤標(biāo)志位SystemError
}
    IICSendByte(controlbyte&0x77); //Control byte
check_ACK();                // 檢查應(yīng)答位
    if(F0 == 1)
{
  SystemError = 1;
  return;    // 若非應(yīng)答表明器件錯(cuò)誤或已壞,置錯(cuò)誤標(biāo)志位SystemError
}
     IICSendByte(wdata); //data byte
check_ACK();                // 檢查應(yīng)答位
    if(F0 == 1)
{
  SystemError = 1;
  return;    // 若非應(yīng)答表明器件錯(cuò)誤或已壞,置錯(cuò)誤標(biāo)志位SystemError
}
iic_stop();         // 全部發(fā)完則停止
delayNOP();
delayNOP();
delayNOP();
delayNOP();
}
//--------------------------------------------------------------------------------------------------
// 函數(shù)名稱: ADC_PCF8591
// 入口參數(shù): controlbyte控制字
// 函數(shù)功能: 連續(xù)讀入4路通道的A/D轉(zhuǎn)換結(jié)果到receivebuf
//--------------------------------------------------------------------------------------------------
void ADC_PCF8591(unsigned char controlbyte)
{
    unsigned char idata receive_da,i=0;
iic_start();
IICSendByte(PCF8591_WRITE); //控制字
check_ACK();
if(F0 == 1)
{
  SystemError = 1;
  return;
}
IICSendByte(controlbyte); //控制字
check_ACK();
if(F0 == 1)
{
  SystemError = 1;
  return;
}
    iic_start();     //重新發(fā)送開始命令
    IICSendByte(PCF8591_READ); //控制字
check_ACK();
if(F0 == 1)
{
  SystemError = 1;
  return;
}
while(i<4)
{
  receive_da=IICreceiveByte();
  receivebuf[i++]=receive_da;
  slave_ACK();    // 收到一個(gè)字節(jié)后發(fā)送一個(gè)應(yīng)答位
}
slave_NOACK();    // 收到最后一個(gè)字節(jié)后發(fā)送一個(gè)非應(yīng)答位
iic_stop();
}
//--------------------------------------------------------------------------------------------------
// 函數(shù)名稱: main
// 函數(shù)功能: 主程序
//--------------------------------------------------------------------------------------------------
main()
{
DAC_PCF8591(0x40,0); //控制字為0100 0000,允許模擬量輸出
                     //零值點(diǎn)輸出測試
DAC_PCF8591(0x40,0xff); //控制字為0100 0000,允許模擬量輸出
                     //滿值點(diǎn)輸入測試
ADC_PCF8591(0x40);
}

回復(fù)

使用道具 舉報(bào)

ID:76190 發(fā)表于 2015-4-5 18:21 | 顯示全部樓層


  1. #include<reg52.h>
  2. #define uint unsigned int
  3. #define uchar unsigned char

  4. sbit SCL=P1^1;//時(shí)鐘脈沖
  5. sbit SDA=P1^2;//雙向輸入輸出數(shù)據(jù)端
  6. #define SCL_SET SCL=1
  7. #define SCL_CLR SCL=0
  8. #define SDA_SET SDA=1
  9. #define SDA_CLR SDA=0
  10. #define AddWr 0x90   //寫數(shù)據(jù)地址
  11. #define AddRd 0x91   //讀數(shù)據(jù)地址
  12. #define adCon 0x40   //AD控制字節(jié)


  13. sbit RS=P2^4;
  14. sbit RW=P2^5;
  15. sbit E=P2^6;
  16. #define setRS RS=1
  17. #define clrRS RS=0
  18. #define setRW RW=1
  19. #define clrRW RW=0
  20. #define setE E=1
  21. #define clrE E=0

  22. uint time=0;
  23. uchar ADFlag=0;
  24. uchar str[8]="Ci n.mv ";

  25. //延時(shí)1US
  26. void delay(uint cnt)
  27. {
  28. while(--cnt);
  29. }
  30. //延時(shí)1MS
  31. void delayms(uint time)
  32. {
  33. uint i;
  34. for(i=0; i<time; i++)
  35.   delay(120);
  36. }
  37. //寫數(shù)據(jù),P0
  38. void writeData(uchar Data)
  39. {
  40.   setRS;
  41.   clrRW;
  42.   delay(1);
  43.   setE;
  44.   delay(1);
  45.   P0=Data;
  46.   delay(5);
  47.   clrE;
  48. }
  49. //寫命令,P0
  50. void writeCom(uchar Com)
  51. {
  52.   clrRS;
  53.   clrRW;
  54.   delay(1);
  55.   setE;
  56.   delay(1);
  57.   P0=Com;
  58.   delay(5);
  59.   clrE;
  60. }
  61. //清屏函數(shù)
  62. void clear_scr(void)
  63. {
  64.    writeCom(0x01);
  65.    delayms(5);
  66.   }

  67. //寫一個(gè)字符串在(X,Y )位置
  68. void disStr(uchar x, uchar y, uchar *str)
  69. {
  70. if(y==0) writeCom(0x80+x);//第一行
  71. else writeCom(0xc0+x);//第二行
  72. while(*str)
  73. {
  74.   writeData(*str);
  75.   str++;
  76. }
  77. }
  78. //LCD1602初始化
  79. void lcdInitial()
  80. {
  81.    writeCom(0x38);//顯示模式設(shè)置
  82.    delayms(5);
  83.    writeCom(0x08);//顯示關(guān)閉
  84.    clear_scr();//清屏
  85.    writeCom(0x06); //顯示光標(biāo)移動(dòng)設(shè)置
  86.    delayms(5);
  87.    writeCom(0x0C); //顯示開及光標(biāo)設(shè)置
  88. }


  89. void start()
  90. {
  91. SDA_SET;
  92. delay(1);
  93. SCL_SET;
  94. delay(5);
  95. SDA_CLR;
  96. }


  97. void stop()
  98. {
  99. SDA_CLR;
  100. delay(1);
  101. SCL_SET;
  102. delay(5);
  103. SDA_SET;  
  104. }


  105. void ack()
  106. {
  107. SDA_CLR;
  108. SCL_SET;
  109. delay(1);
  110. SCL_CLR;
  111. }


  112. void noAck()
  113. {
  114.     SDA_SET;
  115. SCL_SET;
  116. delay(1);
  117. SCL_CLR;
  118. }


  119. void send(uchar Data)
  120. {
  121. uchar i=0;
  122. uchar temp=0;

  123. temp=Data;
  124. for(i=0; i<8; i++)
  125. {
  126.   SCL_CLR;
  127.   delay(1);
  128.   if(temp&0x80) SDA_SET;
  129.   else SDA_CLR;
  130.   delay(1);
  131.   SCL_SET;
  132.   delay(1);
  133.   temp<<=1;
  134. }
  135.    SCL_CLR;
  136. }


  137. uchar recive()
  138. {
  139. uchar i=0;
  140. uchar temp=0;

  141. SDA_SET;//必須設(shè)置
  142. for(i=0; i<8; i++)
  143. {
  144.   SCL_CLR;//拉低允許數(shù)據(jù)改變
  145.   delay(1);
  146.   SCL_SET;//拉高保持?jǐn)?shù)據(jù),等待讀走
  147.   delay(2);
  148.   if(SDA) temp|=0x01;
  149.   else temp&=0xfe;
  150.   if(i<7)   temp<<=1;//最低位發(fā)送完成不能移位,否則出錯(cuò)
  151. }
  152.     SCL_CLR;
  153. return temp;
  154. }


  155. uchar read(uchar ch )
  156. {
  157. uchar temp=0;

  158. start();
  159. send(AddWr);//確認(rèn)芯片
  160. ack();
  161. send(adCon|ch);//確認(rèn)通道
  162. ack();
  163. //讀出數(shù)據(jù),放進(jìn)temp
  164. start();
  165. send(AddRd);
  166. ack();
  167. temp=recive();
  168. noAck();
  169. stop();
  170. return temp;
  171. }

  172. uchar DAC(uchar light)
  173. {
  174. start();
  175. send(AddWr);
  176. ack();
  177. send(0x40);  //寫入控制位,使能DAC輸出
  178. ack();
  179. send(light);
  180. ack();
  181. stop();
  182. }



  183. void dis(uchar *date)
  184. {

  185. uchar i=0;
  186. uchar ch1, ch2, ch3;

  187. for(i=0; i<4; i++)
  188. {
  189.   ch1=i+48;
  190.   str[1]=ch1;
  191.   ch2=date[i]/50+48;
  192.   str[3]=ch2;
  193.   ch3=date[i]%50/10+48;
  194.   str[5]=ch3;
  195.   if(i>1) disStr(i*8-16, 1, str);
  196.   else disStr(i*8, 0, str);
  197. }
  198. }


  199. void interrupt_init()
  200. {
  201. ET0=1;//定時(shí)器0溢出中斷允許
  202. TR0=1;//啟動(dòng)定時(shí)器0
  203. TMOD=0X01;
  204. TH0=0Xd8;
  205. TL0=0Xf0;  
  206. EA=1;//開總中斷
  207. }



  208. void main()
  209. {
  210. uchar i=0;
  211. uchar vot[4];

  212. interrupt_init();
  213. lcdInitial();

  214. //DAC(0);
  215. while(1)
  216. {
  217.     if(ADFlag==1)
  218.     {
  219.        for(i=0; i<4; i++) vot[i]=read(i);
  220.     DAC(200);//DA轉(zhuǎn)換函數(shù),0-255漸暗
  221.   }
  222.     dis(vot);
  223. }
  224. }

  225. void tim0_() interrupt 1 using 1
  226. {
  227.    TH0=0xd8;  //重新賦值
  228.    TL0=0xf0;

  229. time++;
  230.    if(time==100)
  231.       {  time=0;
  232.       ADFlag=1;
  233.     } //定時(shí)置位AD采樣標(biāo)志位
  234. }




復(fù)制代碼
回復(fù)

使用道具 舉報(bào)

ID:192309 發(fā)表于 2017-4-22 13:20 | 顯示全部樓層
很給力!!!
回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表