微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > STC12C5A60S2

STC12C5A60S2

时间:10-02 整理:3721RD 点击:

用STC12C5A60S2进行AD采样(10位)5.0V供电,结果跳动很大,有0.05V,
和实际结果相差0.15V,怎么会这样,
以前从51一路学过来,觉得国产单片机不会太差,
所以就打算学一学STC12的AD转换部分,
结果很失望。
附上部分程序:
void ADInit()
{
//        P1=0xff;
        P1M1 = 0xff;
        P1M0 = 0xff;
        
        P1ASF=0xff; //P1.0口作为模拟功能AD使用
        ADC_RES=0;  //清零转换结果寄存器高8位
        ADC_RESL=0; //清零转换结果寄存器低2位
        ADC_CONTR=0xe0;//开启AD电源
        Delay1ms();   //等待1ms,让AD电源稳定
        
        write_com(0xc0);
        display(str2);
}
uint getAD()
{

        ADC_CONTR=0xe8;
        _nop_();
        _nop_();
        _nop_();
        _nop_();//要经过4个CPU时钟的延时,其值才能够保证被设置进ADC_CONTR 寄存器         
        while(!(ADC_CONTR&0x10));     //等待转换完成
        ADC_CONTR=0xe0;       //关闭AD转换,ADC_FLAG位由软件清0

        return(ADC_RES*4+ADC_RESL);    //返回AD转换完成的10位数据(16进制)
}
uint getREF()
{

        ADC_CONTR=0xe9;
        while(!(ADC_CONTR&0x10));     //等待转换完成
        ADC_CONTR=0xe0;       //关闭AD转换,ADC_FLAG位由软件清0
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        return(ADC_RES*4+ADC_RESL);    //返回AD转换完成的10位数据(16进制)
}
void filter()
{
        uchar i,j;
        double k;
        for(i=0;i<N;i++)
        {
                for(j=i;j<N;j++)
                {
                        if(filter_data<filter_data[j])
                        {
                    k=filter_data;
                                filter_data=filter_data[j];
                                filter_data[j]=k;
                        }
                }
        }
}
void voltagedisp()
{
        uchar i;
        double vol=0;
        for(i=0;i<N;i++)
        {
                CURRENT_AD=getAD();
                CURRENT_REF=getREF();
        }
        for(i=0;i<N;i++)
        {
                filter_data=1.0*CURRENT_AD/CURRENT_REF;
        }
        
        filter();
        
        for(i=N/2-5;i<N/2+5;i++)
        {
                vol+=3.3*filter_data;         //参考电压3.3V
        }
        disdatavol[0]=(uint)vol/10+0x30;//个位
        disdatavol[1]=(uint)vol%10+0x30;//十分位
        disdatavol[2]=(uint)(vol*10)%10+0x30;//百分位
        disdatavol[3]=(uint)(vol*100)%10+0x30;//千分位
        write_com(0xc9);
        write_dat(disdatavol[0]);        
        write_com(0xca);
        write_dat(0x2e);        //显示小数点
        write_com(0xcb);
        write_dat(disdatavol[1]);         
        write_com(0xcc);
        write_dat(disdatavol[2]);
        write_com(0xcd);
        write_dat(disdatavol[3]);
        write_com(0xce);
        write_dat('V');
}
///*
void Delay1000ms()                //@11.0592MHz
{
        unsigned char i, j, k;
        i = 43;
        j = 6;
        k = 203;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}
//*/
/********************主程序***********************************/
void main()
{
        init_display();//初始化显示
        ADInit();
        while(1)
        {               
                voltagedisp();
                Delay1000ms();
        }
}

  1. #include<stc12c5a60s2.h>
  2. #include "intrins.h"

  3. #define FOSC    11059200L
  4. #define BAUD    4800

  5. typedef unsigned char uchar;//0~255
  6. typedef unsigned int uint;//0~65535
  7. typedef unsigned long ulong;//0~4294967295

  8. #define ADC_START   0x08            //ADC start control bit
  9. #define ADC_SPEEDLL 0x00            //540 clocks
  10. #define ADC_SPEEDL  0x20            //360 clocks
  11. #define ADC_SPEEDH  0x40            //180 clocks
  12. #define ADC_SPEEDHH 0x60            //90 clocks

  13. void InitUart();
  14. void SendData(uchar dat);
  15. void Delay(uint n);
  16. void InitADC();

  17. uchar ch = 0;                        //ADC channel NO.
  18. uint Voltage,Vol;
  19. uchar i;
  20. uchar TxBuf[4]={0};

  21. void main()
  22. {
  23.         InitUart();                     //Init UART, use to show ADC result
  24.         InitADC();                      //Init ADC sfr
  25.         IE = 0xa0;                      //Enable ADC interrupt and Open master interrupt switch
  26.                                                                                                                                         //Start A/D conversion
  27.         while (1);
  28. }

  29. /*----------------------------
  30. ADC interrupt service routine
  31. ----------------------------*/
  32. void adc_isr() interrupt 5 using 1
  33. {
  34.         ADC_CONTR &= !ADC_FLAG;         //Clear ADC interrupt flag

  35.         Vol = ADC_RES*256+ADC_RESL;
  36.         Voltage = Vol*500.00/1024;
  37.         TxBuf[0]=Voltage/100+'0';
  38.         TxBuf[1]='.';
  39.         TxBuf[2]=Voltage%100/10+'0';
  40.         TxBuf[3]=Voltage%10+'0';

  41. for(i=0;i<4;i++)
  42.         {
  43.                 SendData(TxBuf[i]);                       
  44.         }
  45. //if (++ch > 2) ch = 0;           //switch to next channel这里只使用第0通道
  46.         ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | ch;
  47. }

  48. /*----------------------------
  49. Initial ADC sfr
  50. ----------------------------*/
  51. void InitADC()
  52. {
  53.         P1ASF = 0xf8;                   //Set all P1 as analog input port
  54.         ADC_RES = 0;                    //Clear previous result
  55.         ADC_RESL = 0;
  56.         AUXR1 &= 0xfb;                                                                        //10位
  57.         AUXR1 |= 0x04;
  58.         ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | ch;
  59.         Delay(2);                       //ADC power-on delay and Start A/D conversion
  60. }

  61. /*----------------------------
  62. Initial UART
  63. ----------------------------*/
  64. void InitUart()
  65. {
  66.         SCON = 0x5a;                    //8 bit data ,no parity bit
  67.         TMOD = 0x20;                    //T1 as 8-bit auto reload
  68.         TH1 = TL1 = -(FOSC/12/32/BAUD); //Set Uart baudrate
  69.         TR1 = 1;                        //T1 start running
  70. }

  71. /*----------------------------
  72. Send one byte data to PC
  73. Input: dat (UART data)
  74. Output:-
  75. ----------------------------*/
  76. void SendData(uchar dat)
  77. {
  78.         while (!TI);                    //Wait for the previous data is sent£?TIê?′?DD?ú1·¢?í?D??±ê??
  79.         TI = 0;                         //Clear TI flag
  80.         SBUF = dat;                     //Send current data
  81. }

  82. /*----------------------------
  83. Software delay function
  84. ----------------------------*/
  85. void Delay(uint n)
  86. {
  87.         uint x;

  88.         while (n--)
  89.         {
  90.                 x = 5000;
  91.                 while (x--);
  92.         }
  93. }

复制代码

小编使用的的是两个通道对比的结果来产生所谓的滤波效果,由于两个通道都是经过ADC转换来个值,这样会造成误差的累积,最终导致结果偏差严重,因此建议尽量不要这样使用。另外建议小编书写程序尽量简洁,规范,这样方便自己查找错误。我写的程序已经贴出来了,请对照着看吧,#include<stc12c5a60s2.h>这个头文件在新版的STC的官方烧录软件里能找到


正常,很多时候需要处理的。更有人在前面加跟随器!

shiyigehaotie!

好厉害,学习了

学习 学习                  

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top