历史上的今天
今天是:2025年02月20日(星期四)
2020年02月20日 | 浅谈stm32f1两路adc采集(非DMA)
2020-02-20 来源:eefocus
由于项目的需要写2路ADC采集,发现采集的电压出现很大的误差。(后来换成ADC1和ADC2模式后解决了)仔细看了一下,不会是板子对应的引脚共用,那到底是怎么回事呢?想到了电路上的上拉电阻,测量出现的电压数值跳变不就是高阻态吗?在程序当中要是利用到上拉电阻不就搞定了吗!翻开某库函数关于ADC的介绍如下:
STM32 拥有 1~3 个 ADC(STM32F101/102 系列只有 1 个 ADC),这些 ADC 可以独立使用,也可以使用双重模式(提高采样率)。STM32 的 ADC 是 12 位逐次逼近型的模拟数字转换器。
它有 18 个通道,可测量 16 个外部和 2 个内部信号源。各通道的 A/D 转换可以单次、连续、扫描或间断模式执行。ADC 的结果可以左对齐或右对齐方式存储在 16 位数据寄存器中。
模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高/低阀值。
STM32F103 系列最少都拥有 2 个 ADC,我们选择的 STM32F103ZET 包含有 3 个 ADC。
STM32 的 ADC 最大的转换速率为 1Mhz,也就是转换时间为 1us(在 ADCCLK=14M,采样周期为 1.5 个 ADC 时钟下得到),不要让 ADC 的时钟超过 14M,否则将导致结果准确度下降。
STM32 将 ADC 的转换分为 2 个通道组:规则通道组和注入通道组。规则通道相当于你正
常运行的程序,而注入通道呢,就相当于中断。在你程序正常执行的时候,中断是可以打断你的执行的。同这个类似,注入通道的转换可以打断规则通道的转换, 在注入通道被转换完成之后,规则通道才得以继续转换。STM32 其 ADC 的规则通道组最多包含 16 个转换,而注入通道组最多包含 4 个通道。STM32 的 ADC 可以进行很多种不同的转换模式,本章仅介绍如何使用规则通道的单次转换模式。STM32 的 ADC 在单次转换模式下,只执行一次转换,该模式可以通过 ADC_CR2 寄存器的 ADON 位(只适用于规则通道)启动,也可以通过外部触发启动(适用于规则通道和注入通道),这是 CONT 位为 0。
以规则通道为例,一旦所选择的通道转换完成,转换结果将被存在 ADC_DR 寄存器中,
EOC(转换结束)标志将被置位,如果设置了 EOCIE,则会产生中断。然后 ADC 将停止,直到下次启动,还是直接上程序吧。
//初始化ADC这里我们仅以规则通道为例,默认将开启通道0~3
void Adc_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_ADC1|RCC_APB2Periph_ADC2|RCC_APB2Periph_AFIO,ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M
//PA1 作为模拟通道输入引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
GPIO_Init(GPIOA, &GPIO_InitStructure);
//////
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1; //选择你要设置的IO口
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
GPIO_Init(GPIOB,&GPIO_InitStructure); /* 初始化GPIO */
ADC_DeInit(ADC1); //复位ADC1
ADC_DeInit(ADC2); //复位ADC2
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //模数转换工作在单通道模式
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //模数转换工作在单次转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道的数目
ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
ADC_Init(ADC2, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存?
ADC_RegularChannelConfig(ADC1,ADC_Channel_1,1,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC2,ADC_Channel_9,1,ADC_SampleTime_239Cycles5);
ADC_DiscModeCmd(ADC1, ENABLE);
ADC_DiscModeCmd(ADC2, ENABLE);
ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1
ADC_Cmd(ADC2, ENABLE);
ADC_ResetCalibration(ADC1); //使能复位校准
ADC_ResetCalibration(ADC2); //使能复位校准
while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束
while(ADC_GetResetCalibrationStatus(ADC2)); //等待复位校准结束
ADC_StartCalibration(ADC1); //开启AD校准
ADC_StartCalibration(ADC2); //开启AD校准
while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束
while(ADC_GetCalibrationStatus(ADC2)); //等待校准结束
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
ADC_SoftwareStartConvCmd(ADC2, ENABLE);
}
//获得ADC值
//ch:通道值 0~3
u16 Get_Adc(u8 ch)
{
//设置指定ADC的规则组通道,一个序列,采样时间
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道,采样时间为239.5周期
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束
return ADC_GetConversionValue(ADC1); //返回最近一次ADC1规则组的转换结果
}
u16 Get_Adc2(u8 ch2)
{
//设置指定ADC的规则组通道,一个序列,采样时间
ADC_RegularChannelConfig(ADC2, ch2, 2, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道,采样时间为239.5周期
ADC_SoftwareStartConvCmd(ADC2, ENABLE); //使能指定的ADC1的软件转换启动功能
while(!ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC ));//等待转换结束
return ADC_GetConversionValue(ADC2); //返回最近一次ADC1规则组的转换结果////
}
u16 Get_Adc_Average(u8 ch,u8 times)
{
u32 temp_val=0;
u8 t;
for(t=0;t temp_val+=Get_Adc(ch); delay_ms(5); } return temp_val/times; } u16 Get_Adc_Average2(u8 ch,u8 tim) { u32 temp_val=0; u8 t; for(t=0;t temp_val+=Get_Adc2(ch); delay_ms(5); } return temp_val/tim; } 这样一来,只要在main 里面初始化和调用Get_Adc_Average(ADC_Channel_1,10); 和Get_Adc_Average2(ADC_Channel_9,10); 就可以啦,其他多路采集也可以参照上述方式进行
史海拾趣
|
求高手解答 关于围绕7128的硬件电路设计问题 迷茫啊 。。。 我的程序在试验箱上已经调试出来了 。可是 硬件板子却不知道怎么设计 主要是接0832DA转换的 那一段 因为之前都用单片机 要接片选 用7128 不知道怎么设计接口了 直接PIN上IO口就可以了么 7128有没有 ...… 查看全部问答> |
|
目前,随着石化、钢铁、造纸、食品、医药企业自动化水平的不断提高,对现场仪表维护人员的技术水平提出了更高要求。为缩短处理仪表故障时间,保证安全生产提高经济效益,本文发表一点仪表现场维护经验,供仪表维护人员参考。 一、现 ...… 查看全部问答> |
|
一、引言 智能天线通常也称作自适应天线阵列,可以形成特定的天线波束,实现定向发送和接收,主要用于完成空间滤波和定位。从本质上看,它利用了天线阵列中各单元之间的位置关系,即利用了信号的相位关系克服多址干扰及多径干扰,这 ...… 查看全部问答> |
|
最近工作一直比较忙,没有及时发帖,不好意思了,今天把我这段时间的搞的小成果,给大家show一下,请大家多指教了。 首先那,先展示一下自己DIY的底板;见下图: 正面: 背面: 分开: ...… 查看全部问答> |
|
西门子M440 的变频器,开机报A0503(母线欠压),一按运行显示F0003 (母线欠压故障),用万用表测量了母线电压有D C500多伏电压 ,但看r0026参数却显示0V,这是怎么回事呢,应该怎么修呢,谢谢!… 查看全部问答> |
|
前段时间拜QFN封装很低价格的吸引(不到10元一片),头脑发热就买了几片。今天终于搞定了……最后调整铜线时掉了一根,一查是PIO3_5,人品太好了继续焊……用NanoM0的调试器下载代码成功。记得某位大侠说过:珍爱生活,远离QFN……不多说了上图:… 查看全部问答> |
|
//DMA1 通道配置 DMA_DeInit(DMA1_Channel1); //设置成CH1 DMA中包含了7个通道(CH1-CH7) DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; //给DMA起始地址 DMA_InitStructure.DMA_MemoryBa ...… 查看全部问答> |
|
好消息,TI的带PHY网口的TM4C129X出来了,DEMO板已经到手,明天上图 好消息,TI的带PHY网口的TM4C129X出来了,DEMO板已经到手,明天上图 主要区别,封装只有BGA212,TQFP128 FLASH 1M RAM 256K EEPROM 6K CAN 2 I2C 10 SPI 4 UART ...… 查看全部问答> |




