这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » STC8G1K08A单片机中模数转换器ADC的应用问题

共7条 1/1 1 跳转至

STC8G1K08A单片机中模数转换器ADC的应用问题

工程师
2021-07-04 22:26:14     打赏

四个电阻串联,用STC8G1K08A单片机的P3^0口做模数转换ADC,用万用表测 2  3  4 点的电压,分别为 1.25V,2.50V,3.75V 按照理论,这三个点的模数变换数值应该为 256, 512, 768 ,实际显示的是250,377,440,除去变换的误差,这和理论值差的也太多了,程序是按照厂家提供的例程编写的,电路上的5V电压直接取自单片机的VCC和GND.测量时就是直接用杜邦线连P3^0口和 2 3 4 点,没有串限流电阻,也没有并分流电阻,这是程序出了问题还是电路出了问题?

求论坛里的大神给指点一二!


image.png




关键词: STC8G1K08A     模数转换器     ADC     A/D    

工程师
2021-07-04 23:13:24     打赏
2楼

给你一个应用实例参考,因电池供电,P3.2既作ADC输入,也作中断唤醒。ADC检测压力传感器信号,当无压力达到一定时间,进入休眠。一旦有压力MCU唤醒正常工作。你的问题可能是ADC转换结果寄存器设置不当。

//STC8G1K08A工作电压范围1.9~5.5V

//#include "reg51.h"

#include <STC8.H>

#include "intrins.h"

typedef unsigned char uchar;

typedef unsigned int uint;

typedef unsigned long ulong;

#define  ADCTIM  (*(unsigned char volatile xdata *)0xfea8)

//#define ceiling 636 //上限

//#define floor   923 //下限

sbit LED_R=P5^4;

sbit LED_G=P5^5;

//sbit AVDD =P3^3;


uint code table[36]={

923         ,//        0 

915         ,//        1 

907         ,//        2 

898         ,//        3 

890         ,//        4 

882         ,//        5 

874         ,//        6 

866         ,//        7 

858         ,//        8 

850         ,//        9 

841         ,//        10 

833         ,//        11 

825         ,//        12 

817         ,//        13 

809         ,//        14 

800         ,//        15 

792         ,//        16 

784         ,//        17 

776         ,//        18 

768         ,//        19 

760         ,//        20 

751         ,//        21 

743         ,//        22 

735         ,//        23 

727         ,//        24 

719         ,//        25 

710         ,//        26 

702         ,//        27 

694         ,//        28 

686         ,//        29 

677         ,//        30 

669         ,//        31 

661         ,//        32 

653         ,//        33 

645         ,//        34 

636    };//35 


bit flag=0;//完成标志

//uchar i;

uint CY_ADC;//采样值

uint time;


void Timer0Init()                //2毫秒@11.0592MHz

{

        AUXR |= 0x80;                //定时器时钟1T模式

        TMOD &= 0xF0;                //设置定时器自动重装模式

        TL0 = 0x9A;                        //设置定时初值

        TH0 = 0xA9;                        //设置定时初值

        TF0 = 0;                        //清除TF0标志

        TR0 = 1;                        //定时器0开始计时

}

/*----------------------------

        读取ADC结果

----------------------------*/

void GetADCResult()

{        //ADC 控制器  电源  启动  完成  --   15通道模拟选择位

        //ADC_CONTR    B7    B6    B5   B4   B3   B2   B1   B0

        static uint count=0;

        static uint PJZ_ADC=0;                //累加10次采样的变量1


        count++;

        if(count==1)ADC_CONTR = 0x80;           //使能ADC模块

        if(count>=2&&count<=11)

        {

                ADC_CONTR|= 0x42;       //启动AD转换,P3.2 ADC输入    

                _nop_();_nop_();

                while (!(ADC_CONTR & 0x20));            //查询ADC完成标志

                ADC_CONTR &= ~0x20;                     //清完成标志

                PJZ_ADC+=(ADC_RES<<8|ADC_RESL);         //累计10次读取10位ADC结果

        }

        if(count==11)

        {

                CY_ADC=PJZ_ADC/10;

                PJZ_ADC=0;

                ADC_CONTR = 0x00;                //关闭ADC

                flag=1;

        }

        if(count>=10)//200ms

                count=0;

}


void main()

{

        P3M0 = 0x00;        //设置P3.2为ADC口

        P3M1 = 0x04;        //设置P3.2为ADC口

        P5M0 = 0x00;

        P5M1 = 0x00;

        P_SW2 |= 0x80;                //打开

        ADCTIM = 0x3f;          //设置 ADC 内部时序

        P_SW2 &= 0x7f;                //关闭

        ADCCFG = 0x27;           //设置ADC结果右对齐,速度为512系统时钟        ADCCFG = 0x0f;  // 设置 ADC 时钟为系统时钟 /2/16/16

//        ADC_CONTR = 0x80;  // 使能 ADC 模块

        Timer0Init();

  //ADC配置寄存器 --  --  格式控制  --   速度控制位

  //   ADCCFG     B7  B6     B5     B4   B3 B2 B1 B0     

        while (1)

        {

                if(TF0)

                {

                        TF0=0;

                        GetADCResult();

                        if(flag==1)

                        {

                                flag=0;

                                if(CY_ADC>table[0])

                                {

                                        time++;

                                        LED_R=1;

                                        LED_G=1;

                                }

                                else if(CY_ADC>table[0] && CY_ADC<table[36])

                                {

                                        time=0;

                                        LED_R=1;

                                        LED_G=0;

                                }

                                else if(CY_ADC<table[36])

                                {

                                        time=0;

                                        LED_R=0;

                                        LED_G=0;

                                }

                                if(time>=15000)

                                {

                                        time=0;

                                        P3M1 = 0x00;//设置P3.2为准双向

//                                        AVDD = 0;

                                        TR0 = 0;//关闭定时器

                                        EX0 = 1; // 使能 INT0 中断 , 用于唤醒 MCU

                                        EA = 1;

                                        _nop_();_nop_();_nop_();_nop_();

                                        PCON = IDL;  //MCU 进入空闲(省电)模式   

                                        _nop_();_nop_();_nop_();_nop_();

                                }

                        }

                }

        }

}


void INT0_Isr() interrupt 0

{

        EX0 = 0; // 关闭 INT0 中断

        EA = 0;        // 关闭总中断

//        AVDD = 1;

        P3M1=0x04; //设置P3.2为ADC口

        TR0 = 1;                //启动定时器

}




工程师
2021-07-04 23:17:13     打赏
3楼

楼主,你代码呢?
STC8G1K08A这个IC容易受干扰,特别是电路中有高频信号的情况下
在ADC的采样输入一定要有一个104以上的电容,而且得是靠近端口的
单片机的VCC一定在做好滤波,104电容一定要靠近VCC
GND不能到处乱跑


工程师
2021-07-04 23:21:39     打赏
4楼

用一个高精度的电压表对比一下


工程师
2021-07-05 22:22:59     打赏
5楼

官方好像有ADC例子吧? 套用看看


工程师
2021-07-05 22:26:45     打赏
6楼

确定硬件没连错?


工程师
2021-07-05 22:31:59     打赏
7楼

经验告诉我,多数情况下是用户自己的问题,如写错代码或操作错误等等


共7条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]