关于将模拟信号转变成数字信号然后送入单片机内进行处理

2019-07-16 05:16发布

一直都很疑惑如何将由传感器得到的模拟信号经过转变,然后送入单片机内进行处理。请高手指教,最好有个实例讲解,小生不胜感激,这个问题困扰好久了,找了好久都没有答案
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
11条回答
獊韹→狼
2019-07-16 12:12
关键是想用什么样的AD芯片!我用的是PCF8591!
#include <reg52.h>
#define unint unsigned int
#define unchar unsigned char
#define        PCF8591_WRITE        0x90 //本机的PCF8591芯片地址为 1001 0000 即为低四位的前三位为000.不同开发板可能不同
#define        PCF8591_READ         0x91
unchar ge,shi,bai,idata receive_da;
sbit SDA=P2^1;          
sbit SCL=P2^0;
sbit dula=P1^0;
sbit    LS138A=P2^2;  
sbit    LS138B=P2^3;
sbit    LS138C=P2^4;  

unchar code Disp_Tab[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

unchar AD_CHANNEL;

void delay()         //响应函数
{  ;  ; }                                               

void init()                //总线初始化函数
{
        SDA=1;
        delay();
        SCL=1;
        delay();
}
void iic_start()                //启动函数
{
   SDA=1;
   delay();
   SCL=1;
   delay();
   SDA=0;
   delay();
   
   /*SCL=0;
   delay();        */

}
void STOP_I2C()          //停止信号
{
   SDA=0;
   delay();
   SCL=1;
   delay();
   SDA=1;
   delay();
}
void  ACK_I2c()        //          应答
{
   unint i;
   SCL=1;
   delay();
   while((SDA=1)&&(i<255)) i++;
   SCL=0;
   delay();
}
void NOACK_I2c()  //非应答
{
   SCL=1;
   delay();
   SDA=0;
   SCL=0;
   delay();



}
void write_byte(unchar date )          
{
    unchar i,temp;
        temp=date;
        for(i=0;i<8;i++)
         {
                 temp=temp<<1;
                SCL=0;
                delay();
                SDA=CY;
                delay();
                SCL=1;
                delay();
         }
        // SCL=1;  调试时的错误
         SCL=0;
         delay();
         SDA=1;
         delay();
           SCL=1;
           delay();
}
unchar read_byte()         
{
        unchar k,j;                          

        SCL=0; // 为下一步SDA=1作准备
        delay();
        SDA=1;//置“读取数据”模式
        delay();
        //以便数据变化
        for(j=0;j<8;j++)
         {
                 SCL=1;///让数据稳定才能读操作
                delay();
                k=(k<<1)|SDA;
                SCL=0;//完成一个时钟
                delay();
               
         }
        return k;                  
}

unchar ADC_PCF8591(unchar controlbyte)           //完整的AD转换函数,注意要先写后读
   {
             unchar c,i=0;
         
          iic_start();
          write_byte(PCF8591_WRITE);
          ACK_I2c();
          write_byte(controlbyte); //控制字
          ACK_I2c();

          iic_start();
          write_byte(PCF8591_READ);
             ACK_I2c();
      c=read_byte();     
          NOACK_I2c();
          STOP_I2C();
          return(c); //返回读的数据

   }

                                                                                  
void main()
{  unchar i,j;
   unchar LedOut[8];
   unint  D[10];
        init();
   while(1)
  {/********以下AD-DA处理*************/  
   switch(AD_CHANNEL)
   {
     case 0:
             D[0]=ADC_PCF8591(0x41)*2;  //ADC0 模数转换1  放大2倍显示
                         break;  

         case 1:
             D[1]=ADC_PCF8591(0x42)*2;  //ADC1  模数转换2
                         break;  

         case 2:
             D[2]=ADC_PCF8591(0x43)*2;  //ADC2        模数转换3
                         break;  

         case 3:
             D[3]=ADC_PCF8591(0x40)*2;  //ADC3   模数转换4
                         break;  

        // case 4: DACconversion(0x90,0x40, D[4]/4); //DAC          数模转换
                 break;
   }

              // D[4]=400;  //数字--->>模拟输出
                   //D[4]=D[0];  //   把模拟输入 采样的信号 通过数模转换输出
   if(++AD_CHANNEL>4) AD_CHANNEL=0;

/********以下将AD的值送到LED数码管显示,本程序只使用了两个通道即D1和D2*************/  
                      
         LedOut[0]=Disp_Tab[D[1]%10000/1000];
     LedOut[1]=Disp_Tab[D[1]%1000/100];
     LedOut[2]=Disp_Tab[D[1]%100/10]|0x80;
     LedOut[3]=Disp_Tab[D[1]%10];
         
         LedOut[4]=Disp_Tab[D[0]%10000/1000];
     LedOut[5]=Disp_Tab[D[0]%1000/100];
     LedOut[6]=Disp_Tab[D[0]%100/10]|0x80;//含小数点
     LedOut[7]=Disp_Tab[D[0]%10];  
          
       
         for( i=0; i<8; i++)
         {         P0 = LedOut[i];
                       
          switch(i)          //使用switch 语句控制138译码器  也可以是用查表的方式 学员可以试着自己修改                                  
             {            
                        case 0:LS138A=0; LS138B=0; LS138C=0; break;         
                case 1:LS138A=1; LS138B=0; LS138C=0; break;                    
                case 2:LS138A=0; LS138B=1; LS138C=0; break;
                case 3:LS138A=1; LS138B=1; LS138C=0; break;
                        case 4:LS138A=0; LS138B=0; LS138C=1; break;
                        case 5:LS138A=1; LS138B=0; LS138C=1; break;
                        case 6:LS138A=0; LS138B=1; LS138C=1; break;
                        case 7:LS138A=1; LS138B=1; LS138C=1; break;
                       
             }
         
             for (j = 0 ; j<90 ;j++) { ;}           //扫描间隔时间
          }

            P0 = 0;

}  
}

//本例中暂时只有模数转换,数模转换需要修改程序

一周热门 更多>