140711 发表于 2023-5-4 11:00:23

请教,GP2Y1014的ADC寄存器使用是否正确

#include <STC32G.h>
#include <intrins.h>
#include <stdio.h>

typedef unsigned char        u8;
typedef unsigned int        u16;
typedef unsigned long        u32;

#define MAIN_Fosc   12000000UL
#define Baudrate      115200L
#define TM            (65536 -(MAIN_Fosc/Baudrate/4))
#define PrintUart   1

sbit LED = P1^1;

u16 AM_PM;

//unsigned char PM25_value;
       
void delay_ms(unsigned int ms);

u16Get_ADC12bitResult(u8 channel); //channel = 0~15
//u16       PM25_Get_Value(u8 ch);         //获取PM2.5数值

/*串口初始化*/
void UartInit(void)
{
#if(PrintUart == 1)
        SCON = (SCON & 0x3f) | 0x40;
        T1x12 = 1;          //定时器时钟1T模式
        S1BRT = 0;          //串口1选择定时器1为波特率发生器
        TL1= TM;
        TH1= TM>>8;
        TR1 = 1;                                //定时器1开始计时
#else
        S2_S = 1;       //UART2 switch to: 0: P1.0 P1.1,1: P4.6 P4.7
S2CFG |= 0x01;//使用串口2时,W1位必需设置为1,否则可能会产生不可预期的错误
        S2CON = (S2CON & 0x3f) | 0x40;
        T2L= TM;
        T2H= TM>>8;
        AUXR |= 0x14;              //定时器2时钟1T模式,开始计时
#endif
}

void UartPutc(unsigned char dat)
{
#if(PrintUart == 1)
        SBUF = dat;
        while(TI==0);
        TI = 0;
#else
        S2BUF= dat;
        while(S2TI == 0);
        S2TI = 0;    //Clear Tx flag
#endif
}

char putchar(char c)
{
        UartPutc(c);
        return c;
}

void main()
{
        WTST = 0;//设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
        EAXFR = 1; //扩展寄存器(XFR)访问使能
        CKCON = 0; //提高访问XRAM速度

        P1M0 = 0x32; P1M1 = 0x30;

                //ADC初始化
        ADCTIM = 0x3f;      //设置 ADC 内部时序,ADC采样时间建议设最大值
        ADCCFG = 0x2f;      //设置 ADC 转换结果右对齐,时钟为系统时钟/2/16
        ADC_CONTR = 0x81;   //使能 ADC 模块,并选择1通道
        UartInit();

        while(1)
        {
                GetGP2Y();
//                printf("PM2.5:\r\n",PM25_value);
                delay_ms(1000);
        }
}

void delay_ms(unsigned int ms)
{
    unsigned int i;
    do{
      i = MAIN_Fosc / 6000;
      while(--i);   //6T per loop
    }while(--ms);
}

void Delay4us()                //@12.000MHz
{
        unsigned long i;

        _nop_();
        _nop_();
        _nop_();
        i = 10UL;
        while (i) i--;
}

//========================================================================
// 函数: u16 Get_ADC12bitResult(u8 channel)
// 描述: 查询法读一次ADC结果.
// 参数: channel: 选择要转换的ADC.
// 返回: 12位ADC结果.
// 版本: V1.0, 2012-10-22
//========================================================================
u16 Get_ADC12bitResult(u8 channel)//channel = 0~15
{
    ADC_RES = 0;
    ADC_RESL = 0;

    ADC_CONTR = (ADC_CONTR & 0xf0) | channel; //设置ADC转换通道
    ADC_START = 1;//启动ADC转换
    _nop_();
    _nop_();
    _nop_();
    _nop_();

    while(ADC_FLAG == 0);                  //wait for ADC finish
    ADC_FLAG = 0;                                    //清除ADC结束标志
    return(((u16)ADC_RES << 8) | ADC_RESL);
}

/****
*******获取PM2.5值函数
*******传入值:adc通道
*******返回值:PM2.5值
*******注意:本函数需要调用adc获取函数
*****/
//u16 PM25_Get_Value(u8 ch)
//{
//   u16 adc_value = 0;                                                      //adc值变量
//   u16 PM_count = 0;                                                     //计数次数值变量
//   u16 PM25_value = 0;                                                    //PM2.5值变量
//   LED = 0;                                                             //PM2.5 LED灯拉低开启
//   delay_ms(0.28);                     
//   adc_value += Get_ADC12bitResult(u8 channel); //获取一次adc值,并累加
//   Delay4us();                                                 //延时40us
//   LED = 1;                                                                
//   if(++PM_count >= 5)                           //获取5次adc值
//   {
//      PM_count = 0;                      //计数次数清零
//      adc_value = adc_value / 5;         //取5次平均值
//      PM25_value = ((adc_value/255.0)*5*0.17-0.1)*1000;   //计算PM2.5值
//      adc_value = 0;                     //adc值清零
//   }
//   return PM25_value;                  //返回PM2.5值
//}

void GetGP2Y(void)
{
        float pm;
        LED = 0;                                                        //PM2.5 LED灯拉低开启
        delay_ms(0.28);                                                //延时280us
        AD_PM = Get_ADC12bitResult(u8 channel);        //获取一次adc值
        Delay4us();                                                //延时40us
        LED = 1;                                                        //PM2.5 LED灯拉高关闭
        delay_ms();
        pm = 0.17*AD_PM-0.1;                                 //电压-灰尘转换
        printf("%f\n",pm);       
}

电子DIY小家 发表于 2023-5-5 09:58:17

ADC寄存器使用是否正确?这个问题好像问的让人摸不着头脑,你是想说寄存器这样配置之后采集到的adc数值是否正确吗?

140711 发表于 2023-5-5 10:59:53

电子DIY小家 发表于 2023-5-5 09:58
ADC寄存器使用是否正确?这个问题好像问的让人摸不着头脑,你是想说寄存器这样配置之后采集到的adc数值是否 ...

是的,我想问ADC寄存器这样配置是否正确

电子DIY小家 发表于 2023-5-5 11:38:31

140711 发表于 2023-5-5 10:59
是的,我想问ADC寄存器这样配置是否正确

最简单的办法就是接个电位器,然后直接串口监测adc数值直接看一下就知道了,从0v拧到5v,看看adc数值是不是从0到最大值

140711 发表于 2023-5-14 17:49:51

哎,我真后悔选这个单片机做毕设

梁工 发表于 2023-5-14 20:04:09

140711 发表于 2023-5-14 17:49
哎,我真后悔选这个单片机做毕设

赶快换我们的STC32G做毕设。

神农鼎 发表于 2023-5-14 20:50:16

他没上原理图,都不知道他错在硬件还是软件,楼主先上你原理图的PDF,大家才好帮你

140711 发表于 2023-5-22 21:18:24

神农鼎 发表于 2023-5-14 20:50
他没上原理图,都不知道他错在硬件还是软件,楼主先上你原理图的PDF,大家才好帮你 ...

这是传感器的原理图

梁工 发表于 2023-5-22 23:13:31

140711 发表于 2023-5-22 21:18
这是传感器的原理图

楼主不管用什么MCU,最关键是要先了解你用的传感器。
GP2Y1014AU是一个粉尘传感器,模拟电压输出,按其手册要求是工作于脉冲方式。
你贴一个STM32的电路,再问STC32的ADC寄存器配置,很多人都不明白你要问是什么,有心做工程,总得理一下电路,改成你现在使用的MCU和IO,而不是网上下载一个STM32的电路。
ADC寄存器配置,可以参考STC的官方例程,或者先测试STC的例程,再添加一点程序达到你的要求。


特意下了个手册看,按你图中连接,PA1接ADC输入,PA0提供周期10ms、高电平0.32ms的驱动脉冲,则在输出0.28ms就可以开启ADC采样了。


140711 发表于 2023-5-23 10:40:29

梁工 发表于 2023-5-22 23:13
楼主不管用什么MCU,最关键是要先了解你用的传感器。
GP2Y1014AU是一个粉尘传感器,模拟电压输出,按其手 ...

我写的代码是这样的,选择P1.0作为ADC读取通道,即传感器OUT口接P1.0,LED接P1.1,然后需要调用ADC寄存器来读取P1.0通道的数据,但是我找的51程序都是外接ADC0832,而STC32G又集成了ADC模块,我就不知道怎么改了
页: [1] 2
查看完整版本: 请教,GP2Y1014的ADC寄存器使用是否正确