找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2248|回复: 6
打印 上一主题 下一主题
收起左侧

这个单片机+PCF8591串口输出程序就只输出 00;有人知道原因吗?

[复制链接]
跳转到指定楼层
楼主
ID:280486 发表于 2019-1-6 19:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  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)            //延时
  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 变换, 转化函数               
  37. *******************************************************************/
  38. bit DACconversion(unsigned char sla,unsigned char c,  unsigned char Val)
  39.    {
  40.       Start_I2c();              //启动总线
  41.       SendByte(sla);            //发送器件地址
  42.       if(ack==0)return(0);
  43.       SendByte(c);              //发送控制字节
  44.       if(ack==0)return(0);
  45.       SendByte(Val);            //发送DAC的数值  
  46.       if(ack==0)return(0);
  47.       Stop_I2c();               //结束总线
  48.       return(1);
  49.    }
  50. /*******************************************************************
  51. ADC发送字节[命令]数据函数               
  52. *******************************************************************/
  53. bit ISendByte(unsigned char sla,unsigned char c)
  54.    {
  55.       Start_I2c();              //启动总线
  56.       SendByte(sla);            //发送器件地址
  57.       if(ack==0)return(0);
  58.       SendByte(c);              //发送数据
  59.       if(ack==0)return(0);
  60.       Stop_I2c();               //结束总线
  61.       return(1);
  62.    }
  63. /*******************************************************************
  64. ADC读字节数据函数               
  65. *******************************************************************/
  66. unsigned char IRcvByte(unsigned char sla)
  67.    {
  68.       unsigned char c;
  69.       Start_I2c();          //启动总线
  70.       SendByte(sla+1);      //发送器件地址
  71.       if(ack==0)return(0);
  72.       c=RcvByte();          //读取数据0
  73.       Ack_I2c(1);           //发送非就答位
  74.       Stop_I2c();           //结束总线
  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 模数转换1  放大2倍显示
  89.                   break;  
  90.                   case 1: ISendByte(PCF8591,0x42);
  91.                      D[1]=IRcvByte(PCF8591);  //ADC1  模数转换2
  92.                   break;  
  93.                   case 2: ISendByte(PCF8591,0x43);
  94.                      D[2]=IRcvByte(PCF8591);  //ADC2  模数转换3
  95.                   break;
  96.                   case 3: ISendByte(PCF8591,0x40);
  97.                      D[3]=IRcvByte(PCF8591);  //ADC3   模数转换4
  98.                   break;
  99.                   case 4: DACconversion(PCF8591,0x40, j); //DAC     数模转换
  100.                   break;
  101.                }
  102.             SBUF=D[1];     //区别在这里
  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内容。



  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)            //延时
  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 变换, 转化函数               
  153. *******************************************************************/
  154. bit DACconversion(unsigned char sla,unsigned char c,  unsigned char Val)
  155.    {
  156.       Start_I2c();              //启动总线
  157.       SendByte(sla);            //发送器件地址
  158.       if(ack==0)return(0);
  159.       SendByte(c);              //发送控制字节
  160.       if(ack==0)return(0);
  161.       SendByte(Val);            //发送DAC的数值  
  162.       if(ack==0)return(0);
  163.       Stop_I2c();               //结束总线
  164.       return(1);
  165.    }
  166. /*******************************************************************
  167. ADC发送字节[命令]数据函数               
  168. *******************************************************************/
  169. bit ISendByte(unsigned char sla,unsigned char c)
  170.    {
  171.       Start_I2c();              //启动总线
  172.       SendByte(sla);            //发送器件地址
  173.       if(ack==0)return(0);
  174.       SendByte(c);              //发送数据
  175.       if(ack==0)return(0);
  176.       Stop_I2c();               //结束总线
  177.       return(1);
  178.    }
  179. /*******************************************************************
  180. ADC读字节数据函数               
  181. *******************************************************************/
  182. unsigned char IRcvByte(unsigned char sla)
  183.    {
  184.       unsigned char c;
  185.       Start_I2c();          //启动总线
  186.       SendByte(sla+1);      //发送器件地址
  187.       if(ack==0)return(0);
  188.       c=RcvByte();          //读取数据0
  189.       Ack_I2c(1);           //发送非就答位
  190.       Stop_I2c();           //结束总线
  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 模数转换1  放大2倍显示
  205.                   break;  
  206.                   case 1: ISendByte(PCF8591,0x42);
  207.                      D[1]=IRcvByte(PCF8591);  //ADC1  模数转换2
  208.                   break;  
  209.                   case 2: ISendByte(PCF8591,0x43);
  210.                      D[2]=IRcvByte(PCF8591);  //ADC2  模数转换3
  211.                   break;
  212.                   case 3: ISendByte(PCF8591,0x40);
  213.                      D[3]=IRcvByte(PCF8591);  //ADC3   模数转换4
  214.                   break;
  215.                   case 4: DACconversion(PCF8591,0x40, j); //DAC     数模转换
  216.                   break;
  217.                }
  218.             SBUF=D[n];    //区别在这
  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.    }
复制代码


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:280486 发表于 2019-1-6 20:03 | 只看该作者
区别在主函数,switch语句的下一句SBUF那里,看不清的请反色,从VS code复制过来的,颜色也过来了……
回复

使用道具 举报

板凳
ID:432823 发表于 2019-1-6 20:48 | 只看该作者
n值应从0~3变
回复

使用道具 举报

地板
ID:280486 发表于 2019-1-7 13:57 | 只看该作者

n是全局变量,默认是0;把那个位置换成常数0能正常发送。换成变量n就不行了即使n==0;
回复

使用道具 举报

5#
ID:213173 发表于 2019-1-7 15:42 | 只看该作者
7305 发表于 2019-1-7 13:57
n是全局变量,默认是0;把那个位置换成常数0能正常发送。换成变量n就不行了即使n==0;

给你改了一下,你试试。只有接收到上位机0x00~0x03的有效选择指令,否则不发送数据。
#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)            //延时
   {  
      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 变换, 转化函数               
*******************************************************************/
bit DACconversion(unsigned char sla,unsigned char c,  unsigned char Val)
   {
      Start_I2c();              //启动总线
      SendByte(sla);            //发送器件地址
      if(ack==0)return(0);
      SendByte(c);              //发送控制字节
      if(ack==0)return(0);
      SendByte(Val);            //发送DAC的数值  
      if(ack==0)return(0);
      Stop_I2c();               //结束总线
      return(1);
   }
/*******************************************************************
ADC发送字节[命令]数据函数               
*******************************************************************/
bit ISendByte(unsigned char sla,unsigned char c)
   {
      Start_I2c();              //启动总线
      SendByte(sla);            //发送器件地址
      if(ack==0)return(0);
      SendByte(c);              //发送数据
      if(ack==0)return(0);
      Stop_I2c();               //结束总线
      return(1);
   }
/*******************************************************************
ADC读字节数据函数               
*******************************************************************/
unsigned char IRcvByte(unsigned char sla)
   {
      unsigned char c;
      Start_I2c();          //启动总线
      SendByte(sla+1);      //发送器件地址
      if(ack==0)return(0);
      c=RcvByte();          //读取数据0
      Ack_I2c(1);           //发送非就答位
      Stop_I2c();           //结束总线
      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 模数转换1  放大2倍显示
                  break;  
                  case 1: ISendByte(PCF8591,0x42);
                     D[1]=IRcvByte(PCF8591);  //ADC1  模数转换2
                  break;  
                  case 2: ISendByte(PCF8591,0x43);
                     D[2]=IRcvByte(PCF8591);  //ADC2  模数转换3
                  break;
                  case 3: ISendByte(PCF8591,0x40);
                     D[3]=IRcvByte(PCF8591);  //ADC3   模数转换4
                  break;
                  case 4: DACconversion(PCF8591,0x40, j); //DAC     数模转换
                  break;
               }
            SBUF=D[1];     //区别在这里
            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内容。



#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;                //接收完成标志
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)            //延时
   {  
      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 变换, 转化函数               
*******************************************************************/
bit DACconversion(unsigned char sla,unsigned char c,  unsigned char Val)
   {
      Start_I2c();              //启动总线
      SendByte(sla);            //发送器件地址
      if(ack==0)return(0);
      SendByte(c);              //发送控制字节
      if(ack==0)return(0);
      SendByte(Val);            //发送DAC的数值  
      if(ack==0)return(0);
      Stop_I2c();               //结束总线
      return(1);
   }
/*******************************************************************
ADC发送字节[命令]数据函数               
*******************************************************************/
bit ISendByte(unsigned char sla,unsigned char c)
   {
      Start_I2c();              //启动总线
      SendByte(sla);            //发送器件地址
      if(ack==0)return(0);
      SendByte(c);              //发送数据
      if(ack==0)return(0);
      Stop_I2c();               //结束总线
      return(1);
   }
/*******************************************************************
ADC读字节数据函数               
*******************************************************************/
unsigned char IRcvByte(unsigned char sla)
   {
      unsigned char c;
      Start_I2c();          //启动总线
      SendByte(sla+1);      //发送器件地址
      if(ack==0)return(0);
      c=RcvByte();          //读取数据0
      Ack_I2c(1);           //发送非就答位
      Stop_I2c();           //结束总线
      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 模数转换1  放大2倍显示
                        break;  
                        case 1: ISendByte(PCF8591,0x42);
                        D[1]=IRcvByte(PCF8591);  //ADC1  模数转换2
                        break;  
                        case 2: ISendByte(PCF8591,0x43);
                        D[2]=IRcvByte(PCF8591);  //ADC2  模数转换3
                        break;
                        case 3: ISendByte(PCF8591,0x40);
                        D[3]=IRcvByte(PCF8591);  //ADC3   模数转换4
                        break;
                        case 4: DACconversion(PCF8591,0x40, j); //DAC     数模转换
                        break;
                }
                if((flag==1)&&(n<4))//接收完成标志为1与只有接收到0~3有效的指令,否则不发送数据
                {
                        ES=0;                //关串口中断
                        flag=0;                //接收完成标志清0
                        SBUF=D[n];  //区别在这
                        while(!TI);        //等待发送中断请求标志位为1
                        TI=0;                //发送中断请求标志位清0
                        ES=1;                //开串口中断
                }
                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;        //接收完成标志置1
}
回复

使用道具 举报

6#
ID:280486 发表于 2019-1-7 21:51 | 只看该作者
wulin 发表于 2019-1-7 15:42
给你改了一下,你试试。只有接收到上位机0x00~0x03的有效选择指令,否则不发送数据。
#include
#includ ...

代码没问题,全局变量n必须在死循环里加一个判断计入次数的语句重赋值n,在主函数里重赋值都不行。全局变量不应该是程序运行就在内存里的吗?
回复

使用道具 举报

7#
ID:213173 发表于 2019-1-8 08:57 | 只看该作者
7305 发表于 2019-1-7 21:51
代码没问题,全局变量n必须在死循环里加一个判断计入次数的语句重赋值n,在主函数里重赋值都不行。全局变 ...

其实你的程序缺少一个解析子函数。通常实用的自定义通讯协议是数据串:由数据头、有效数据、验证码、数据尾等组成。下位机对收到的数据串进行解析验证,提取正确的有效数据来控制相应功能。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表