找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 2813|回復(fù): 6
打印 上一主題 下一主題
收起左側(cè)

這個(gè)單片機(jī)+PCF8591串口輸出程序就只輸出 00;有人知道原因嗎?

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:280486 發(fā)表于 2019-1-6 19:54 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
  1. #include<reg52.h>
  2. #include "I2C.H"
  3. #include <intrins.h>
  4. #define  PCF8591 0x90    //PCF8591 地址
  5. unsigned char i=0,j=0,D[4];
  6. void uart_init()
  7.    {
  8.       SCON=0X50;
  9.       PCON=0X00;
  10.       TMOD=0X20;
  11.       TH1=0XFD;   //11.0592MHZ 9600
  12.       TL1=0XFD;
  13.       TR1=1;
  14.       ES=1;
  15.       EA=1;
  16.    }
  17. /*void send(unsigned char D[],unsigned char a)  
  18.    {
  19.       ES=0;
  20.       SBUF=D[a];
  21.       while(TI==0);
  22.       TI=0;
  23.       ES=1;
  24.    }*/
  25. void delay_ms(unsigned int ms)            //延時(shí)
  26.    {  
  27.       unsigned char a,b,c;
  28.       while(ms--)
  29.          {
  30.              for(c=1;c>0;c--)
  31.                for(b=142;b>0;b--)
  32.                      for(a=2;a>0;a--);
  33.          }
  34.    }
  35. /*******************************************************************
  36. DAC 變換, 轉(zhuǎn)化函數(shù)               
  37. *******************************************************************/
  38. bit DACconversion(unsigned char sla,unsigned char c,  unsigned char Val)
  39.    {
  40.       Start_I2c();              //啟動(dòng)總線
  41.       SendByte(sla);            //發(fā)送器件地址
  42.       if(ack==0)return(0);
  43.       SendByte(c);              //發(fā)送控制字節(jié)
  44.       if(ack==0)return(0);
  45.       SendByte(Val);            //發(fā)送DAC的數(shù)值  
  46.       if(ack==0)return(0);
  47.       Stop_I2c();               //結(jié)束總線
  48.       return(1);
  49.    }
  50. /*******************************************************************
  51. ADC發(fā)送字節(jié)[命令]數(shù)據(jù)函數(shù)               
  52. *******************************************************************/
  53. bit ISendByte(unsigned char sla,unsigned char c)
  54.    {
  55.       Start_I2c();              //啟動(dòng)總線
  56.       SendByte(sla);            //發(fā)送器件地址
  57.       if(ack==0)return(0);
  58.       SendByte(c);              //發(fā)送數(shù)據(jù)
  59.       if(ack==0)return(0);
  60.       Stop_I2c();               //結(jié)束總線
  61.       return(1);
  62.    }
  63. /*******************************************************************
  64. ADC讀字節(jié)數(shù)據(jù)函數(shù)               
  65. *******************************************************************/
  66. unsigned char IRcvByte(unsigned char sla)
  67.    {
  68.       unsigned char c;
  69.       Start_I2c();          //啟動(dòng)總線
  70.       SendByte(sla+1);      //發(fā)送器件地址
  71.       if(ack==0)return(0);
  72.       c=RcvByte();          //讀取數(shù)據(jù)0
  73.       Ack_I2c(1);           //發(fā)送非就答位
  74.       Stop_I2c();           //結(jié)束總線
  75.       return(c);
  76.    }
  77. //******************************************************************/
  78. void main()
  79.    {
  80.       uart_init();
  81.       delay_ms(1000);
  82.       while(1)
  83.          {
  84.             /********以下AD-DA處理*************/  
  85.             switch(i)
  86.                {
  87.                   case 0: ISendByte(PCF8591,0x41);
  88.                      D[0]=IRcvByte(PCF8591);  //ADC0 模數(shù)轉(zhuǎn)換1  放大2倍顯示
  89.                   break;  
  90.                   case 1: ISendByte(PCF8591,0x42);
  91.                      D[1]=IRcvByte(PCF8591);  //ADC1  模數(shù)轉(zhuǎn)換2
  92.                   break;  
  93.                   case 2: ISendByte(PCF8591,0x43);
  94.                      D[2]=IRcvByte(PCF8591);  //ADC2  模數(shù)轉(zhuǎn)換3
  95.                   break;
  96.                   case 3: ISendByte(PCF8591,0x40);
  97.                      D[3]=IRcvByte(PCF8591);  //ADC3   模數(shù)轉(zhuǎn)換4
  98.                   break;
  99.                   case 4: DACconversion(PCF8591,0x40, j); //DAC     數(shù)模轉(zhuǎn)換
  100.                   break;
  101.                }
  102.             SBUF=D[1];     //區(qū)別在這里
  103.             while(TI==0);
  104.             TI=0;
  105.             if(++i>4) i=0;
  106.             if(j<256) j++;
  107.             else j=0;
  108.             delay_ms(10000);
  109.          }  
  110.    }
  111. void uart() interrupt 4
  112.    {
  113.       RI=0;
  114.       i=SBUF;
  115.    }
  116. 這樣能正確讀取PCF8591內(nèi)容。



  117. #include<reg52.h>
  118. #include "I2C.H"
  119. #include <intrins.h>
  120. #define  PCF8591 0x90    //PCF8591 地址
  121. unsigned char i=0,j=0,n=0,D[4];
  122. void uart_init()
  123.    {
  124.       SCON=0X50;
  125.       PCON=0X00;
  126.       TMOD=0X20;
  127.       TH1=0XFD;   //11.0592MHZ 9600
  128.       TL1=0XFD;
  129.       TR1=1;
  130.       ES=1;
  131.       EA=1;
  132.    }
  133. /*void send(unsigned char D[],unsigned char a)  
  134.    {
  135.       ES=0;
  136.       SBUF=D[a];
  137.       while(TI==0);
  138.       TI=0;
  139.       ES=1;
  140.    }*/
  141. void delay_ms(unsigned int ms)            //延時(shí)
  142.    {  
  143.       unsigned char a,b,c;
  144.       while(ms--)
  145.          {
  146.              for(c=1;c>0;c--)
  147.                for(b=142;b>0;b--)
  148.                      for(a=2;a>0;a--);
  149.          }
  150.    }
  151. /*******************************************************************
  152. DAC 變換, 轉(zhuǎn)化函數(shù)               
  153. *******************************************************************/
  154. bit DACconversion(unsigned char sla,unsigned char c,  unsigned char Val)
  155.    {
  156.       Start_I2c();              //啟動(dòng)總線
  157.       SendByte(sla);            //發(fā)送器件地址
  158.       if(ack==0)return(0);
  159.       SendByte(c);              //發(fā)送控制字節(jié)
  160.       if(ack==0)return(0);
  161.       SendByte(Val);            //發(fā)送DAC的數(shù)值  
  162.       if(ack==0)return(0);
  163.       Stop_I2c();               //結(jié)束總線
  164.       return(1);
  165.    }
  166. /*******************************************************************
  167. ADC發(fā)送字節(jié)[命令]數(shù)據(jù)函數(shù)               
  168. *******************************************************************/
  169. bit ISendByte(unsigned char sla,unsigned char c)
  170.    {
  171.       Start_I2c();              //啟動(dòng)總線
  172.       SendByte(sla);            //發(fā)送器件地址
  173.       if(ack==0)return(0);
  174.       SendByte(c);              //發(fā)送數(shù)據(jù)
  175.       if(ack==0)return(0);
  176.       Stop_I2c();               //結(jié)束總線
  177.       return(1);
  178.    }
  179. /*******************************************************************
  180. ADC讀字節(jié)數(shù)據(jù)函數(shù)               
  181. *******************************************************************/
  182. unsigned char IRcvByte(unsigned char sla)
  183.    {
  184.       unsigned char c;
  185.       Start_I2c();          //啟動(dòng)總線
  186.       SendByte(sla+1);      //發(fā)送器件地址
  187.       if(ack==0)return(0);
  188.       c=RcvByte();          //讀取數(shù)據(jù)0
  189.       Ack_I2c(1);           //發(fā)送非就答位
  190.       Stop_I2c();           //結(jié)束總線
  191.       return(c);
  192.    }
  193. //******************************************************************/
  194. void main()
  195.    {
  196.       uart_init();
  197.       delay_ms(1000);
  198.       while(1)
  199.          {
  200.             /********以下AD-DA處理*************/  
  201.             switch(i)
  202.                {
  203.                   case 0: ISendByte(PCF8591,0x41);
  204.                      D[0]=IRcvByte(PCF8591);  //ADC0 模數(shù)轉(zhuǎn)換1  放大2倍顯示
  205.                   break;  
  206.                   case 1: ISendByte(PCF8591,0x42);
  207.                      D[1]=IRcvByte(PCF8591);  //ADC1  模數(shù)轉(zhuǎn)換2
  208.                   break;  
  209.                   case 2: ISendByte(PCF8591,0x43);
  210.                      D[2]=IRcvByte(PCF8591);  //ADC2  模數(shù)轉(zhuǎn)換3
  211.                   break;
  212.                   case 3: ISendByte(PCF8591,0x40);
  213.                      D[3]=IRcvByte(PCF8591);  //ADC3   模數(shù)轉(zhuǎn)換4
  214.                   break;
  215.                   case 4: DACconversion(PCF8591,0x40, j); //DAC     數(shù)模轉(zhuǎn)換
  216.                   break;
  217.                }
  218.             SBUF=D[n];    //區(qū)別在這
  219.             while(TI==0);
  220.             TI=0;
  221.             if(++i>4) i=0;
  222.             if(j<256) j++;
  223.             else j=0;
  224.             delay_ms(10000);
  225.          }  
  226.    }
  227. void uart() interrupt 4
  228.    {
  229.       RI=0;
  230.       n=SBUF;
  231.    }
復(fù)制代碼


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:280486 發(fā)表于 2019-1-6 20:03 | 只看該作者
區(qū)別在主函數(shù),switch語(yǔ)句的下一句SBUF那里,看不清的請(qǐng)反色,從VS code復(fù)制過(guò)來(lái)的,顏色也過(guò)來(lái)了……
回復(fù)

使用道具 舉報(bào)

板凳
ID:432823 發(fā)表于 2019-1-6 20:48 | 只看該作者
n值應(yīng)從0~3變
回復(fù)

使用道具 舉報(bào)

地板
ID:280486 發(fā)表于 2019-1-7 13:57 | 只看該作者

n是全局變量,默認(rèn)是0;把那個(gè)位置換成常數(shù)0能正常發(fā)送。換成變量n就不行了即使n==0;
回復(fù)

使用道具 舉報(bào)

5#
ID:213173 發(fā)表于 2019-1-7 15:42 | 只看該作者
7305 發(fā)表于 2019-1-7 13:57
n是全局變量,默認(rèn)是0;把那個(gè)位置換成常數(shù)0能正常發(fā)送。換成變量n就不行了即使n==0;

給你改了一下,你試試。只有接收到上位機(jī)0x00~0x03的有效選擇指令,否則不發(fā)送數(shù)據(jù)。
#include<reg52.h>
#include "I2C.H"
#include <intrins.h>
#define  PCF8591 0x90    //PCF8591 地址
unsigned char i=0,j=0,D[4];
void uart_init()
   {
      SCON=0X50;
      PCON=0X00;
      TMOD=0X20;
      TH1=0XFD;   //11.0592MHZ 9600
      TL1=0XFD;
      TR1=1;
      ES=1;
      EA=1;
   }
/*void send(unsigned char D[],unsigned char a)  
   {
      ES=0;
      SBUF=D[a];
      while(TI==0);
      TI=0;
      ES=1;
   }*/
void delay_ms(unsigned int ms)            //延時(shí)
   {  
      unsigned char a,b,c;
      while(ms--)
         {
             for(c=1;c>0;c--)
               for(b=142;b>0;b--)
                     for(a=2;a>0;a--);
         }
   }
/*******************************************************************
DAC 變換, 轉(zhuǎn)化函數(shù)               
*******************************************************************/
bit DACconversion(unsigned char sla,unsigned char c,  unsigned char Val)
   {
      Start_I2c();              //啟動(dòng)總線
      SendByte(sla);            //發(fā)送器件地址
      if(ack==0)return(0);
      SendByte(c);              //發(fā)送控制字節(jié)
      if(ack==0)return(0);
      SendByte(Val);            //發(fā)送DAC的數(shù)值  
      if(ack==0)return(0);
      Stop_I2c();               //結(jié)束總線
      return(1);
   }
/*******************************************************************
ADC發(fā)送字節(jié)[命令]數(shù)據(jù)函數(shù)               
*******************************************************************/
bit ISendByte(unsigned char sla,unsigned char c)
   {
      Start_I2c();              //啟動(dòng)總線
      SendByte(sla);            //發(fā)送器件地址
      if(ack==0)return(0);
      SendByte(c);              //發(fā)送數(shù)據(jù)
      if(ack==0)return(0);
      Stop_I2c();               //結(jié)束總線
      return(1);
   }
/*******************************************************************
ADC讀字節(jié)數(shù)據(jù)函數(shù)               
*******************************************************************/
unsigned char IRcvByte(unsigned char sla)
   {
      unsigned char c;
      Start_I2c();          //啟動(dòng)總線
      SendByte(sla+1);      //發(fā)送器件地址
      if(ack==0)return(0);
      c=RcvByte();          //讀取數(shù)據(jù)0
      Ack_I2c(1);           //發(fā)送非就答位
      Stop_I2c();           //結(jié)束總線
      return(c);
   }
//******************************************************************/
void main()
   {
      uart_init();
      delay_ms(1000);
      while(1)
         {
            /********以下AD-DA處理*************/  
            switch(i)
               {
                  case 0: ISendByte(PCF8591,0x41);
                     D[0]=IRcvByte(PCF8591);  //ADC0 模數(shù)轉(zhuǎn)換1  放大2倍顯示
                  break;  
                  case 1: ISendByte(PCF8591,0x42);
                     D[1]=IRcvByte(PCF8591);  //ADC1  模數(shù)轉(zhuǎn)換2
                  break;  
                  case 2: ISendByte(PCF8591,0x43);
                     D[2]=IRcvByte(PCF8591);  //ADC2  模數(shù)轉(zhuǎn)換3
                  break;
                  case 3: ISendByte(PCF8591,0x40);
                     D[3]=IRcvByte(PCF8591);  //ADC3   模數(shù)轉(zhuǎn)換4
                  break;
                  case 4: DACconversion(PCF8591,0x40, j); //DAC     數(shù)模轉(zhuǎn)換
                  break;
               }
            SBUF=D[1];     //區(qū)別在這里
            while(TI==0);
            TI=0;
            if(++i>4) i=0;
            if(j<256) j++;
            else j=0;
            delay_ms(10000);
         }  
   }
void uart() interrupt 4
   {
      RI=0;
      i=SBUF;
   }
這樣能正確讀取PCF8591內(nèi)容。



#include<reg52.h>
#include "I2C.H"
#include <intrins.h>
#define  PCF8591 0x90    //PCF8591 地址
unsigned char i=0,j=0,n=0,D[4];
uchar flag;                //接收完成標(biāo)志
void uart_init()
   {
      SCON=0X50;
      PCON=0X00;
      TMOD=0X20;
      TH1=0XFD;   //11.0592MHZ 9600
      TL1=0XFD;
      TR1=1;
      ES=1;
      EA=1;
   }
/*void send(unsigned char D[],unsigned char a)  
   {
      ES=0;
      SBUF=D[a];
      while(TI==0);
      TI=0;
      ES=1;
   }*/
void delay_ms(unsigned int ms)            //延時(shí)
   {  
      unsigned char a,b,c;
      while(ms--)
         {
             for(c=1;c>0;c--)
               for(b=142;b>0;b--)
                     for(a=2;a>0;a--);
         }
   }
/*******************************************************************
DAC 變換, 轉(zhuǎn)化函數(shù)               
*******************************************************************/
bit DACconversion(unsigned char sla,unsigned char c,  unsigned char Val)
   {
      Start_I2c();              //啟動(dòng)總線
      SendByte(sla);            //發(fā)送器件地址
      if(ack==0)return(0);
      SendByte(c);              //發(fā)送控制字節(jié)
      if(ack==0)return(0);
      SendByte(Val);            //發(fā)送DAC的數(shù)值  
      if(ack==0)return(0);
      Stop_I2c();               //結(jié)束總線
      return(1);
   }
/*******************************************************************
ADC發(fā)送字節(jié)[命令]數(shù)據(jù)函數(shù)               
*******************************************************************/
bit ISendByte(unsigned char sla,unsigned char c)
   {
      Start_I2c();              //啟動(dòng)總線
      SendByte(sla);            //發(fā)送器件地址
      if(ack==0)return(0);
      SendByte(c);              //發(fā)送數(shù)據(jù)
      if(ack==0)return(0);
      Stop_I2c();               //結(jié)束總線
      return(1);
   }
/*******************************************************************
ADC讀字節(jié)數(shù)據(jù)函數(shù)               
*******************************************************************/
unsigned char IRcvByte(unsigned char sla)
   {
      unsigned char c;
      Start_I2c();          //啟動(dòng)總線
      SendByte(sla+1);      //發(fā)送器件地址
      if(ack==0)return(0);
      c=RcvByte();          //讀取數(shù)據(jù)0
      Ack_I2c(1);           //發(fā)送非就答位
      Stop_I2c();           //結(jié)束總線
      return(c);
   }
//******************************************************************/
        void main()
        {
        uart_init();
        delay_ms(1000);
        while(1)
        {
                /********以下AD-DA處理*************/  
                switch(i)
                {
                        case 0: ISendByte(PCF8591,0x41);
                        D[0]=IRcvByte(PCF8591);  //ADC0 模數(shù)轉(zhuǎn)換1  放大2倍顯示
                        break;  
                        case 1: ISendByte(PCF8591,0x42);
                        D[1]=IRcvByte(PCF8591);  //ADC1  模數(shù)轉(zhuǎn)換2
                        break;  
                        case 2: ISendByte(PCF8591,0x43);
                        D[2]=IRcvByte(PCF8591);  //ADC2  模數(shù)轉(zhuǎn)換3
                        break;
                        case 3: ISendByte(PCF8591,0x40);
                        D[3]=IRcvByte(PCF8591);  //ADC3   模數(shù)轉(zhuǎn)換4
                        break;
                        case 4: DACconversion(PCF8591,0x40, j); //DAC     數(shù)模轉(zhuǎn)換
                        break;
                }
                if((flag==1)&&(n<4))//接收完成標(biāo)志為1與只有接收到0~3有效的指令,否則不發(fā)送數(shù)據(jù)
                {
                        ES=0;                //關(guān)串口中斷
                        flag=0;                //接收完成標(biāo)志清0
                        SBUF=D[n];  //區(qū)別在這
                        while(!TI);        //等待發(fā)送中斷請(qǐng)求標(biāo)志位為1
                        TI=0;                //發(fā)送中斷請(qǐng)求標(biāo)志位清0
                        ES=1;                //開(kāi)串口中斷
                }
                if(++i>4) i=0;
                if(j<256) j++;
                else j=0;
                delay_ms(10000);
        }  
}
void uart() interrupt 4
{
        RI=0;
        n=SBUF;
        flag=1;        //接收完成標(biāo)志置1
}
回復(fù)

使用道具 舉報(bào)

6#
ID:280486 發(fā)表于 2019-1-7 21:51 | 只看該作者
wulin 發(fā)表于 2019-1-7 15:42
給你改了一下,你試試。只有接收到上位機(jī)0x00~0x03的有效選擇指令,否則不發(fā)送數(shù)據(jù)。
#include
#includ ...

代碼沒(méi)問(wèn)題,全局變量n必須在死循環(huán)里加一個(gè)判斷計(jì)入次數(shù)的語(yǔ)句重賦值n,在主函數(shù)里重賦值都不行。全局變量不應(yīng)該是程序運(yùn)行就在內(nèi)存里的嗎?
回復(fù)

使用道具 舉報(bào)

7#
ID:213173 發(fā)表于 2019-1-8 08:57 | 只看該作者
7305 發(fā)表于 2019-1-7 21:51
代碼沒(méi)問(wèn)題,全局變量n必須在死循環(huán)里加一個(gè)判斷計(jì)入次數(shù)的語(yǔ)句重賦值n,在主函數(shù)里重賦值都不行。全局變 ...

其實(shí)你的程序缺少一個(gè)解析子函數(shù)。通常實(shí)用的自定義通訊協(xié)議是數(shù)據(jù)串:由數(shù)據(jù)頭、有效數(shù)據(jù)、驗(yàn)證碼、數(shù)據(jù)尾等組成。下位機(jī)對(duì)收到的數(shù)據(jù)串進(jìn)行解析驗(yàn)證,提取正確的有效數(shù)據(jù)來(lái)控制相應(yīng)功能。
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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