• STC51单片机学习笔记8——stc12c56 串口显示AD(多路ad)


    stc12c56 串口显示AD(多路ad).

     AD中断设置

    AUXR:

     ADC_CONTR:

    //#define ADC_POWER 0x80后面不能加分号,不然就会错。其他定义必须加分号!!!
    //烧写程序时,一定要选用外部晶振(烧写软件默认为内部晶振(5M~6M))
    //烧写时,有时候写不进去,尝试断开地线,然后接上上电
    /*****************************************************
                  关于以下两个问题的说明
        a=ADC_LOW2&0x03;//如果是dat=ADC_DATA<<2+ADC_LOW2&0x03;就会出错!莫名其妙!
        dat=ADC_DATA*4+a;    //如果是dat=ADC_DATA<<2+a 。就乱窜,一直飚过1024!而且串口老死!
        从这两个问题可以看出,如果直接对某个8位寄存器进行操作,它会将中间产生的值,直接
        放到该寄存器里,对于寄存器里的的数据不要直接操作,应该先读出来,在内存中处理数据 。
        对寄存器的操作不要用<<、>>等等,也不要使用很长的公式(dat=ADC_DATA<<2+ADC_LOW2&0x03)
    *****************************************************/

    #include
    #include

    sfr ADC_CONTR = 0xc5;
    sfr ADC_DATA =0xc6;
    sfr ADC_LOW2 =0xbe;
    sfr P1M0 =0x91;
    sfr P1M1= 0x92;

    sfr AUXR=0x8e;
    //sfr AUXR1=0xA2;
    //sfr BRT=0x9c;
    sbit Led=P1^4;

    #define ADC_POWER 0x80
    #define ADC_FLAG  0x10
    #define ADC_START 0x08
    #define ADC_SPEEDLL 0x00
    #define    ADC_SPEEDL  0x20
    #define ADC_SPEEDH  0x40     //这个速度,读出的数据噪声很大
    #define ADC_SPEEDHH 0x60

    #define RELOAD_COUNT      0xf3 //4M晶振,smod=0,9600bps 实际波特率=4000000/(256-243)/32=9615.误差=15/9600=0.16%
                                  //具体计算看《STC12C5A60S2》第79页及其之后
    unsigned char ch=0;            //用于ad通道选择
    unsigned char ch_times=0;    //选中某一个ad通道时,前几次采样值不稳定,噪声太大,需要去除

    void serial_port_initial(void);
    void send_UART(unsigned char i);
    void UART_Interrupt_Receive(void);
    void delay(unsigned char n);
    void initADC(void);
    void print_uint(unsigned int num);
    void Long_delay();

    void main()
    {
      Long_delay();//防止pc运行串口驱动时,与本程序自行向pc发送数据产生冲突,从而产生的混乱
      Led=0;
      serial_port_initial();
      initADC();
       AUXR=0x50; //T1定时器不分频,1T的速度,设置EADCI中断允许
       IE=0xa0;                 //设置EADC_SPI中断和EA总中断允许
       while(1)    
       ;
        
    }

    void serial_port_initial(void)      // 使用独立波特率发生器作为波特率发生器
    {
      SCON=0x50;//8位可变波特率,无奇偶校验位
      TMOD=0X21;
      AUXR=0x40; //T1定时器不分频,1T的速度
      TH1=RELOAD_COUNT;
      TL1=RELOAD_COUNT;
      //TR1=1;
      EA=1;          // 开总中断
    }

    void send_UART(unsigned char i)
    {
      ES=0;       // 关串口中断
      TI=0;    // 清零串口发送完成中断请求标志
      SBUF=i;    
      while(TI==0);     //   等待发送完成
      TI=0;            //  清零串口发送完成中断请求标志
      //ES=1;        //     允许串口中断
    }

    void print_uint(unsigned int num)
    {
      unsigned char w5,w4,w3,w2,w1;
        
         w5=num/10000;
         w4=num%10000/1000;
         w3=num%1000/100;
         w2=num%100/10;
         w1=num%10;
         send_UART('0'+w5);
         send_UART('0'+w4);
         send_UART('0'+w3);
         send_UART('0'+w2);
         send_UART('0'+w1);
         send_UART(' ');
    }


    void delay(unsigned char n)
    {
       unsigned char x;
       while(n--)
       {
         x=100;
         while(x--);
       }
    }

    void initADC()
    {
      ch=0;
      //P1=P1M0=P1M1=0xff;    //P1口设置为开漏型,做AD
       P1=P1M0=0xef;
       P1M1=0x00;      //P1.0/2/3口设置为高阻输入,做AD. P1.4作准双向口,做led指示灯
       ADC_DATA=0;
      //此句不对,不能用或。ADC_CONTR=ADC_POWER|ADC_SPEEDL|ADC_START|ch|0xef;
      ADC_CONTR=0x88;//ADC_CONTR=ADC_POWER|ADC_SPEEDL|ADC_START|ch|0xef
      delay(2);
    }

    void adc_isr() interrupt 5
    {
      unsigned int dat;
      unsigned char a;
      AUXR=0x40; //T1定时器不分频,1T的速度,设置EADCI中断禁止
      if(ch_times==10)
      {
        a=ADC_LOW2;//如果是dat=ADC_DATA<<8+ADC_LOW2&0x03;就会出错!莫名其妙!(在看到这的时候,忽然觉得好像是先算的8+ADC_LOW2&0x03···)
        a=a&0x03;
        dat=ADC_DATA*4+a;    //如果是dat=ADC_DATA<<2+a 。就他妈的乱窜,一直飚过1024!
        TR1=1;//开启定时器1 ,开启串口
        send_UART(ch+0x30);
        send_UART(':');
        print_uint(dat);
        delay(2);    //如果没有延时,串口就会混乱!
        TR1=0;//关闭定时器1
        ch_times=0;
        ch++;
        if(ch==4)
          ch=0;
      }
      ADC_CONTR=0x88+ch; //开启下一次转换
      ch_times++;          
      AUXR=0x10; //设置EADCI中断允许
    }
    void Long_delay()
    {
      unsigned char i,j,k;
      for(k=0;k<50;k++)
        for(i=0;i<255;i++)
          for(j=0;j<255;j++)
            ;
    }

    完整资料打包:

    STC51单片机学习笔记8-stc12c56串口显示AD(多路ad)资源-单片机文档类资源-CSDN下载

  • 相关阅读:
    Mybatis拦截器
    CobaltStrike 流量隐藏
    golang之context实用记录
    一种基于Prompt的通用信息抽取(UIE)框架
    AWS CLI 命令行详解
    springboot整合https使用自签名证书实现浏览器和服务器之间的双向认证
    MySqL速成教程笔记系列八
    JAVA 浏览器下载excel,自定义样式:合并单元格,设置多种背景填充颜色,冻结窗格
    一文梳理NLP主要模型发展脉络
    【openstack】卷迁移导致的虚机热迁移失败问题排查及解决
  • 原文地址:https://blog.csdn.net/fengyuzhe13/article/details/127609938