精华内容
下载资源
问答
  • STC8单片机ADC采样注意事项

    千次阅读 2019-10-03 22:09:18
    STC8单片机ADC采样注意事项 STC8单片机ADC采样注意事项 最近在做一个模块,使用宏晶公司的STC8单片机开发,模块主要使用了单片机的ADC采样功能,因为需要10个以上的通道,而且模块要经常震动,所以希望...

    STC8单片机ADC采样注意事项

    最近在做一个模块,使用宏晶公司的STC8单片机开发,模块主要使用了单片机的ADC采样功能,因为需要10个以上的通道,而且模块要经常震动,所以希望使用一种耐操一点的芯片, 于是我使用了STC8系列的单片机,有16路通道的ADC,采样精度是12位,可以比较好的满足我的要求。 一开始模块做的还不错,半年之后有一次要进行改进,在程序上我加大了单片机通道切换之间的时间,然而最后却出现了采样出错的现象。

    因为我要轮询所有的ADC通道,出于设计方面,我采用了特别的采样顺序,采样出错的结果不知道是怎么回事,在改了程序之后便出现了问题, 我一直认为是程序的问题,搞到最后怀疑人生了,,感觉难道这又是STC的一个bug?

    不过,最后我终于在网上找到了一个线索,并且尝试按照那个方法改了一下程序,ojbk了。 贴一下那个线索的原话:

    如果输入信号内阻很大(超过1K就算大了,如果10K就很大了),ADC输入端对地接一个0.01~0.1uF的电容。
    切换通道后,第一次转换值丢弃。

    为什么会有这些要求?为什么外挂专门的ADC也一样的有这种要求?
    对于没有输入缓冲的ADC(STC的ADC输入就是没有缓冲的),采样时ADC输入端通过一个电阻(r,通常是几K欧姆)给采样电容C充电(采样电容一般是10~30PF,STC的可以按30PF计算),假设信号源内阻为R0,则采样充电就是((R0+r)*C),采样时间t一般是很短的,比如STC最快时采样就是几个时钟,时间很短。

    贴一下我的ADC采集函数(更改之前的):

    /**
     * [ADCRead description]
     * @Author     叶鹏程
     * @DateTime   2019-08-01T20:24:46+0800
     * @discrption : ADC采样函数,
     *  
     * @param      n                        [要采样的通道]
     * @param      value_point              [采样值存放地址]
     */
    void ADCRead(uint8_t n,unsigned int  xdata *value_point){
        unsigned int adc_value = 0;
        
        ADC_SET_CHANEL(n);  //设置当前待转换的ADC通道
        ADC_START_ENABLE();
    
        while(ADC_STATE()); //等待转换
        
        ADC_FLAG_CLEAR();  
    
        adc_value = (int)ADC_RES << 8;                               //读取ADC结果
        adc_value |= (int)ADC_RESL;
        adc_value = adc_value>>4;
    
        *value_point = adc_value;
    }

    这是按照线索,更改之后的:

    /**
     * [ADCRead description]
     * @Author     叶鹏程
     * @DateTime   2019-08-01T20:24:46+0800
     * @discrption : ADC采样函数,
     *  
     * @param      n                        [要采样的通道]
     * @param      value_point              [采样值存放地址]
     */
    void ADCRead(uint8_t n,unsigned int  xdata *value_point){
        unsigned int adc_value = 0;
        
        ADC_SET_CHANEL(n);  //设置当前待转换的ADC通道
        
        ADC_START_ENABLE();
        while(ADC_STATE()); //等待转换
        ADC_FLAG_CLEAR();  
        
        /* 这是清除了第一次转换的值,采用第二次采样,这样在切换通道时更加稳定*/
        ADC_START_ENABLE();
        while(ADC_STATE()); //等待转换
        ADC_FLAG_CLEAR();  
    
        adc_value = (int)ADC_RES << 8;                               //读取ADC结果
        adc_value |= (int)ADC_RESL;
        adc_value = adc_value>>4;
    
        *value_point = adc_value;
    }

    总结,这是ADC电路的问题, 以后一定要注意这些东西, 看来还是自己的知识没有学扎实。 加油!

    posted on 2019-08-01 20:52  Gentleaves 阅读( ...) 评论( ...) 编辑 收藏

    转载于:https://www.cnblogs.com/Gentleaves/p/11285243.html

    展开全文
  • 通过STM8S003单片机ADC采样,将采样的数据经过10种不同的滤波方法滤波,然后将滤波后的数据通过串口发送出来,比较10种滤波方法的差异。
  • ADC采样频率的计算

    千次阅读 2020-05-29 11:18:56
    因为又要做和毕设相关的内容,发现答辩时候老师特别喜欢问采样频率,那么ADC采样频率是多少呢? 因为做的压力传感器阻值变化的ADC采集 再通过标定公式转换成压力值。 首先补充一下: ADC的中转换时间是 Tconv...

    因为又要做和毕设相关的内容,发现答辩时候老师特别喜欢问采样频率,那么ADC的采样频率是多少呢?

    因为做的压力传感器阻值变化的ADC采集 再通过标定公式转换成压力值。

    首先补充一下: ADC的中转换时间是   

    Tconv = 采样时间 + 12 个周期

    当然也有说是+12.5个周期的 ,但是大概是这个数,我的资料上12  所以暂时用12个周期。

    那个采样时间 根据库函数发现一般有:

    /** @defgroup ADC_sampling_times 
      * @{
      */ 
    #define ADC_SampleTime_3Cycles                    ((uint8_t)0x00)
    #define ADC_SampleTime_15Cycles                   ((uint8_t)0x01)
    #define ADC_SampleTime_28Cycles                   ((uint8_t)0x02)
    #define ADC_SampleTime_56Cycles                   ((uint8_t)0x03)
    #define ADC_SampleTime_84Cycles                   ((uint8_t)0x04)
    #define ADC_SampleTime_112Cycles                  ((uint8_t)0x05)
    #define ADC_SampleTime_144Cycles                  ((uint8_t)0x06)
    #define ADC_SampleTime_480Cycles                  ((uint8_t)0x07)
    #define IS_ADC_SAMPLE_TIME(TIME) (((TIME) == ADC_SampleTime_3Cycles) || \
                                      ((TIME) == ADC_SampleTime_15Cycles) || \
                                      ((TIME) == ADC_SampleTime_28Cycles) || \
                                      ((TIME) == ADC_SampleTime_56Cycles) || \
                                      ((TIME) == ADC_SampleTime_84Cycles) || \
                                      ((TIME) == ADC_SampleTime_112Cycles) || \
                                      ((TIME) == ADC_SampleTime_144Cycles) || \
                                      ((TIME) == ADC_SampleTime_480Cycles))
    /**
      * @}
      */ 

    3个、15个、28个、56个、84个、112个、144个、480个。一般情况不单纯追求采样频率,采样周期越长,信息越真实,提高精确度。我发现之前的程序选的是480个采样周期 

    u16 Get_Adc2(u8 ch,u8 nb)   
    {
    	  	//设置指定ADC的规则组通道,一个序列,采样时间
    	ADC_RegularChannelConfig(ADC2, ch, 1, ADC_SampleTime_480Cycles );	//ADC1,ADC通道,480个周期,提高采样时间可以提高精确度			    
    
    	ADC_SoftwareStartConv(ADC2);		//使能指定的ADC1的软件转换启动功能	
    	 
    	while(!ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC ));//等待转换结束
    
    	return ADC_GetConversionValue(ADC2);	//返回最近一次ADC1规则组的转换结果
    }

    ADC的时钟,是通过系统时钟 分频得来的 ,这里一般不超过36MHZ,所以四分频到21MHZ。

    ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;
    //ADCCLK=PCLK2/4=84/4=21Mhz,ADC时钟最好不要超过36Mhz 
    

    在补充一下 外部晶振8MHZ的,在system_stm32f4xx.c文件里,通过PLL_M=8,PLL_N=336,PLL_P=4, 已经将系统时钟PCLK设置为84M。

    言归正传,因此我的最小采样频率  : 21M/(480+12) = 42683HZ;

    这样老师在提问的时候也特么能理直气壮忽悠个数了。

    下一次讲一下用的九轴JY901怎么用32采集和设置采样频率,JY901有自己的数据产生频率,所以不太一样。头疼!

    展开全文
  • adc 采样时间 采样周期 采样频率计算,PDF格式。 ADC 转换就是输入模拟的信号量, 单片机转换成数字量。 读取数字量必须等转换完成后, 完成一个通道的读取叫做采样周期。 采样周期一般来说=转换时间+读取时间 。 ...
  • STM32F4单片机ADC采样及ARM-DSP库的FFT

    千次阅读 多人点赞 2019-07-29 12:31:00
    模拟信号经过ADC采样后变成数字信号,数字信号可以进行FFT运算,在频域中更容易分析信号的特征。本文将介绍如何用STM32F4的进行ADC采样,并利用ARMDSP库里的FFT算法对ADC采样值进行快速傅里叶变换。

    模拟信号经过ADC采样后变成数字信号,数字信号可以进行FFT运算,在频域中更容易分析信号的特征。本文将介绍如何用STM32F4的进行ADC采样,并利用ARMDSP库里的FFT算法对ADC采样值进行快速傅里叶变换。

    我使用的是STM32F407VG单片机,由于需要的ADC采样值较多(采集了4096个点),所以配置了STM32的ADC和DMA,使用DMA将ADC采样值传输到内存效率更高。配置外设时,使用APB2时钟的2分频作为ADCCLK,ADC采样时间为84个ADCCLK,Tconv(总转换时间) = 采样时间+12个ADCCLK,理论上ADC的采样频率约4,375,00Hz。为了保证信号的完整性,由奈奎斯特定理知采样频率需要大于信号中最高频率的2倍,因此该外设配置方法测量的信号频率不应大于218,750Hz。外设配置代码如下:

    GPIO_InitTypeDef GPIO_InitStructure;
    ADC_InitTypeDef ADC_InitStructure;
    ADC_CommonInitTypeDef ADC_CommonInitStructure; 
    DMA_InitTypeDef DMA_InitStructure;
    NVIC_InitTypeDef  NVIC_InitStructure;	
    
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2|RCC_AHB1Periph_GPIOC,ENABLE);	
    while(DMA_GetCmdStatus(DMA2_Stream0)!=DISABLE);				
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); 	
    RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE);  	
    RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE); 	
    //init GPIO ADC1, channel 14
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;	
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;					
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;			
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    	
    DMA_InitStructure.DMA_Channel = DMA_Channel_0;
    DMA_InitStructure.DMA_PeripheralBaseAddr = (unsigned int)&(ADC1->DR);
    DMA_InitStructure.DMA_Memory0BaseAddr = (unsigned int)&(fft.ADC_ConvertedValue[0]);
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
    DMA_InitStructure.DMA_BufferSize = 4096;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
    DMA_Init(DMA2_Stream0,&DMA_InitStructure);
    
    NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    
    DMA_ClearFlag(DMA2_Stream0,DMA_IT_TC);
    DMA_ITConfig(DMA2_Stream0,DMA_IT_TC,ENABLE);//使能数据流传输完成中断
    DMA_Cmd(DMA2_Stream0,ENABLE);
    
    ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
    ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
    ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;//84M/2 = 42M
    ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles;
    ADC_CommonInit(&ADC_CommonInitStructure);
    	
    ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
    ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfConversion = 1;
    ADC_Init(ADC1,&ADC_InitStructure);
    ADC_Cmd(ADC1,ENABLE);
    	
    ADC_RegularChannelConfig(ADC1,ADC_Channel_14,1,ADC_SampleTime_84Cycles);//转换时间84个ADC周期
     
    ADC_SoftwareStartConv(ADC1);
    ADC_DMARequestAfterLastTransferCmd(ADC1,ENABLE);
    ADC_DMACmd(ADC1,ENABLE);

    接下来,将ADC的采样值转换为对应的电压值,利用DSP库的FFT算法进行FFT运算,计算幅频特性。这里,我使用的是基4浮点FFT算法,基4的算法比基2的算法运算速度更快。代码如下:

    #define FFT_LENGTH 4096
    void FFTTestTask(void *arg)
    {
        OS_ERR err;
        CPU_TS ts;
        arm_cfft_radix4_instance_f32 scfft;
        int i = 0;
        unsigned char str[10];
    	
        arm_cfft_radix4_init_f32(&scfft,FFT_LENGTH,0,1);//FFT初始化
        while(1)
        {
            OSTaskSemPend(0,OS_OPT_PEND_BLOCKING,&ts,&err);//等待传输完成信号量
    	for(i=0;i<FFT_LENGTH;i++)
    	{
        	    fft.fft_input[2*i] = (float)fft.ADC_ConvertedValue[i]*3.3f/4096.0f;//实部为ADC采样值
    	    fft.fft_input[2*i+1] = 0;//虚部为0
    	}		
    	arm_cfft_radix4_f32(&scfft,fft.fft_input);//FFT运算
    	arm_cmplx_mag_f32(fft.fft_input,fft.fft_output,FFT_LENGTH);//计算每个点的模值
    	for(i=0;i<FFT_LENGTH;i++)
    	{
                sprintf((char*)str,"%.2f\r\n",fft.fft_output[i]);
    	    board.UART4Send(str,strlen((char*)str));//将数据打印至串口助手,便于观察
    	    OSTimeDly(1,OS_OPT_TIME_DLY,&err);
    	}
    	OSTimeDly(500,OS_OPT_TIME_DLY,&err);
    	board.ADC1_DMA2Enable();//重新启动ADC转换和DMA传输
        }
    }

    实验中,我用FPGA和DAC做了DDS信号发生器,生成波形函数为f= 1.65+1.65\cdot cos(2\cdot \pi \cdot 1937\cdot t)。用上述方法采集电压信号进行FFT运算,最后使用MATLAB绘制了部分幅频特性曲线。直流分量的理论幅值为6758.4,实际值7168.2;基波分量的理论幅值为3379.2,实际值3454.3。

    不足之处请大佬指正。

    代码下载: STM32F4 ADC采样FFT运算测试代码

     

     

    展开全文
  • ADC采样频率计算与时钟频率选择

    万次阅读 多人点赞 2016-01-16 15:48:07
    ADC10每次采样转换的总时间是: 采样时间+转换时间 其中采样时间可以设置成若干个ADC10CLK,转换时间手册中给出的是13个ADC10CLK,当然还有一个时钟同步时间tsync,但是这个时间小于一个ADC10CLK,粗略计算的话个人...


    ADC10每次采样转换的总时间是:

    采样时间+转换时间

    其中采样时间可以设置成若干个ADC10CLK,转换时间手册中给出的是13个ADC10CLK,当然还有一个时钟同步时间tsync,但是这个时间小于一个ADC10CLK,粗略计算的话个人感觉就可以忽略了。

    所以最终的计算公式是:(n+13)*ADC10CLK,其中n是通过软件设置的。

    假设ADC10CLK选择ACLK作为时钟源,ACLK的频率是32KHz,现在我想设置采样率是500Hz,那么一个采样转换时间就是1/500=2ms,那么(n+13)*ADC10CLK=2ms,可以看出ADC10CLK肯定小于2ms,也就是频率大于500Hz



    如果选用采样率是500,那么每秒钟采样转换完500次,每次获取一个数字量,数字量的大小是两个字节16位,所以每秒钟会产生16*500=8000位的数据,所以可以采用波特率为9600的传输速率。

    最终方案:ADC10选用辅助系统时钟,辅助系统时钟是在32KHz的外接低频晶振的基础上4分频,也就是8KHz,ADC10寄存器设置采样时间为4个时钟周期,最后出来的采用率是470Hz,对应9600波特率可以满足传输需求。

    不同的波特率对应不同的寄存器设置,从TI的官方例程中得到,2MHz的时钟频率,时钟源可以选择辅助系统时钟或者子系统时钟,设置U0BR0和U0BR1寄存器的不同值对应不同的波特率,这里2MHz频率、U0BR0=0xD0、U0BR1=0x00,对应波特率是9600。

    展开全文
  • STM32: ADC采样频率及相应时间的确定

    千次阅读 2020-07-21 10:05:41
    一、STM32 ADC 介绍  STM32 ADC 是一个12 位精度、 一种逐次逼近型模拟数字转换器。它有多达18个通道,可测量16个外部和2个内部信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行。 ADC的结果可以左...
  • STM32的ADC采样频率及相应时间的确定

    千次阅读 2021-02-22 11:08:45
     STM32 ADC 介绍  STM32 ADC 是一个12 位精度、 一种逐次逼近型模拟数字转换器。它有多达18个通道,可测量16个外部和2个内部信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行。 ADC的结果可以左对齐或...
  •  STM8S003单片机内部ADC为12位,A/D转换的各个通道可以执行单次和连续的转换模式。  单次转换模式的意思就是,ADC每次转换一次数据后,就会停止转换,如果还需要继续转换的话,就需要手动开启第二次转换功能。  ...
  • ADC转换就是输入模拟的信号量,单片机转换成数字量。读取数字量必须等转换完成后,完成一个通道的读取叫做...一 STM32 ADC采样频率的确定 1. :先看一些资料,确定一下ADC的时钟: (1),由时钟控制器提供的ADCCLK...
  • ... 版权声明:本文为博主原创文章,遵循 ...以上我是从很多人的理解中提炼出来的,我感觉是彻底说明白了定时器触发ADC采样中涉及到的一些问题,希望不懂的人可以理解,高手别笑话。
  • ADC转换就是输入模拟的信号量,单片机转换成数字量。读取数字量必须等转换完成后,完成一个通道的读取叫做采样周期。...一 STM32 ADC采样频率的确定 1. : 先看一些资料,确定一下ADC的时钟: (1...
  • ADC转换就是输入模拟的信号量,单片机转换成数字量。读取数字量必须等转换完成后,完成一个通道的读取...一 STM32 ADC采样频率的确定 :先看一些资料,确定一下ADC的时钟: (1),由时钟控制器提供的ADCCLK时钟...
  •  STM8S003单片机内部ADC为12位,A/D转换的各个通道可以执行单次和连续的转换模式。  单次转换模式的意思就是,ADC每次转换一次数据后,就会停止转换,如果还需要继续转换的话,就需要手动开启第二次转换功能。  ...
  • ADC转换就是输入模拟的信号量,单片机转换成数字量。读取数字量必须等转换完成后,完成一个通道的读取叫做采样周期。采样周期一般来说=转换时间+读取时间 。而转换时间=采样时间+12.5个时钟周期。采样时间是你...
  • [导读] 相信ADC的应用或多或少都会用到,在很多场合都有分辨率要求,要实现较高分辨率时,第一时间会想到采用一个较高位数的外置ADC去...在信号处理中,过采样是指以明显高于奈奎斯特速率的采样频率对信号进行采样。...
  • [导读] 相信ADC的应用或多或少都会用到,在很多场合都有分辨率要求,要实现较高分辨率时,第一时间会想到采用一个较高位数的... 在信号处理中,过采样是指以明显高于奈奎斯特速率的采样频率对信号进行采样。 从理论...
  • msp430fr2311单片机adc序列通道采样 使用P1.2、P1.3、P1.4、P1.5为采样通道,以demo的msp430fr231x_adc10_10.c文件为例。 1、将上述4个管脚配置为ADC模式: P1SEL0 |= BIT2 + BIT3 + BIT4 + BIT5; P1SEL1 |= ...
  • ADC采样对MIC的干扰

    千次阅读 2018-09-30 11:24:24
    使用EFM8SB的MCU做ADC采样,检测MIC Bias的...增大ADC采样频率到30KHz, 声音变得更加尖锐,幅度变小,但是听起来很不舒服。 减少到10Hz, 噪声幅度变大,噪声频率跟随到低频。 MicBias增加RC滤波器, ADC恢复到初...
  • 2812片内ADC采样时间计算设置方式方法的详细介绍
  • STM32单片机ADC采集

    千次阅读 2020-08-10 10:04:04
    采样频率ADC精度: 源码下载链接:https://taileliekaishi.lanzous.com/imzD8fgvtxe 工程项目结构: 其中画红色方框部分为重要函数实现功能 ADC.c: #include "ADC/ADC.h" #include "DELAY/Delay.h" ...
  • TC377ADC采样延时实测

    2021-04-13 13:45:07
    龙邱库函数 初始化代码: 理论采样带宽10000Hz,100us刷新一次结果 测试代码: second跑在ccu6定时器中断里,1000us进一次,作为毫秒计时。...2、ADC采样频率没跑到10000hz。 3、那一小坨计数代码开销太大。 ...
  • 单片机 adc 阻抗计算

    2021-06-05 13:24:35
    之前从STM32切换到华大单片机时,在adc的阻抗问题上踩过坑;最近测试瑞萨单片机时,又忘记了阻抗怎么计算。所以专门写个笔记,来做个记录。
  •   简单的说就是这个模拟看门狗可以实时监控ADC采样的数据,当采样的数据值小于设置的最小值或者大于设置的最大值时,单片机就会触发ADC中断。这个在温度监控中非常实用,比如现在要监控设备的温度值,当温度值不在...
  • 关注+星标公众号,不错过精彩内容转自 | 嵌入式客栈相信ADC的应用或多或少都会用到,在很多场合都有分辨率要求,要实现较高分辨率时,第一时间会想到采用一个较高位数的外置ADC去实现。可是高...
  • 写在前面的婆婆妈妈的话 本人大三,参加过数次电赛,来CSDN好久, 每次都是在绝望中从这里找到了希望,每次都仿佛一个即将被打翻...使用STM32F4系列单片机(本次使用的是STM32F429,此程序F4全系列使用,只需注意修改好

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,754
精华内容 701
关键字:

单片机adc采样频率