请教,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);
}
ADC寄存器使用是否正确?这个问题好像问的让人摸不着头脑,你是想说寄存器这样配置之后采集到的adc数值是否正确吗? 电子DIY小家 发表于 2023-5-5 09:58
ADC寄存器使用是否正确?这个问题好像问的让人摸不着头脑,你是想说寄存器这样配置之后采集到的adc数值是否 ...
是的,我想问ADC寄存器这样配置是否正确 140711 发表于 2023-5-5 10:59
是的,我想问ADC寄存器这样配置是否正确
最简单的办法就是接个电位器,然后直接串口监测adc数值直接看一下就知道了,从0v拧到5v,看看adc数值是不是从0到最大值 哎,我真后悔选这个单片机做毕设 140711 发表于 2023-5-14 17:49
哎,我真后悔选这个单片机做毕设
赶快换我们的STC32G做毕设。 他没上原理图,都不知道他错在硬件还是软件,楼主先上你原理图的PDF,大家才好帮你 神农鼎 发表于 2023-5-14 20:50
他没上原理图,都不知道他错在硬件还是软件,楼主先上你原理图的PDF,大家才好帮你 ...
这是传感器的原理图
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采样了。
梁工 发表于 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