#include "adc.h"
u8 UpdataTIM = 0; //更新TIM2定时器标志
u16 CurrentFreq = 500;//默认市电频率,单位为0.1hz
ADBASE_TYPE uAD_Buff_A[ADC_CHANNEL]; //ADC采集缓存A
ADBASE_TYPE uAD_Buff_B[ADC_CHANNEL]; //ADC采集缓存B
//考虑到可能出现的数据处理时间较长的问题,临时添加缓存
//u16 uAD_IN_BUFF[ADC_BUFFSIZE][ADC_CHANNEL];
ADBASE_TYPE *CurrentBuffPtr = NULL; //当前缓存指针
static void ADCInit_GPIO(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//使能GPIOF时钟
//ADC通道初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8| \
GPIO_Pin_9|GPIO_Pin_10; //PF3,PF4,PF5,PF6,PF7,PF8,PF9,PF10 ADC通道
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; //模拟输入
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //不带上下拉
GPIO_Init(GPIOF, &GPIO_InitStructure); //初始化
}
static void ADCInit_ADC(void)
{
ADC_CommonInitTypeDef ADC_CommonInitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE); //使能ADC3时钟
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC3,ENABLE); //ADC3复位
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC3,DISABLE); //复位结束
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; //两个采样阶段之间的延迟5个时钟(三重模式或双重模式下使用)
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //DMA失能(对于多个ADC模式)
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;//预分频4分频。ADCCLK=PCLK2/4=84/4=21Mhz,ADC时钟最好不要超过36Mhz
ADC_CommonInit(&ADC_CommonInitStructure);//初始化
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE;//扫描模式(多通道ADC采集要用扫描模式)
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//关闭连续转换
// ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; //软件触发
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising; //上升沿触发
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO; //定时器事件2触发ADC
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐
ADC_InitStructure.ADC_NbrOfConversion = ADC_CHANNEL; //8个转换在规则序列中
ADC_Init(ADC3, &ADC_InitStructure);//ADC初始化
//连续模式下,通道的配置
ADC_RegularChannelConfig(ADC3, ADC_Channel_9, 1, ADC_SampleTime_15Cycles); //PF3,VIN1,通道9,UA,rank=1,表示连续转换中第一个转换的通道,采样时间15个周期(如果数据不稳定可以延时采样时间)
ADC_RegularChannelConfig(ADC3, ADC_Channel_14, 2, ADC_SampleTime_15Cycles); //PF4,VIN2,通道14,UB
ADC_RegularChannelConfig(ADC3, ADC_Channel_15, 3, ADC_SampleTime_15Cycles); //PF5,VIN3,通道15,AC220
ADC_RegularChannelConfig(ADC3, ADC_Channel_4, 4, ADC_SampleTime_15Cycles); //PF6,VIN4,通道4,I0
ADC_RegularChannelConfig(ADC3, ADC_Channel_5, 5, ADC_SampleTime_15Cycles); //PF7,VIN5,通道5,IA
ADC_RegularChannelConfig(ADC3, ADC_Channel_6, 6, ADC_SampleTime_15Cycles); //PF8,VIN6,通道6,IB
ADC_RegularChannelConfig(ADC3, ADC_Channel_7, 7, ADC_SampleTime_15Cycles); //PF9,VIN7,通道7,IC
ADC_RegularChannelConfig(ADC3, ADC_Channel_8, 8, ADC_SampleTime_15Cycles); //PF10,VIN8,通道8,暂时未接入信号
ADC_DMARequestAfterLastTransferCmd(ADC3, ENABLE); //连续使能DMA
ADC_DMACmd(ADC3, ENABLE); //使能ADC_DMA
ADC_Cmd(ADC3, ENABLE);//开启AD转换器
}
static void ADCInit_DMA(void)
{
DMA_InitTypeDef DMA_InitStructure;
//时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
//DMA设置
DMA_InitStructure.DMA_Channel = DMA_Channel_2; //选择通道号
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(ADC3->DR); //外围设备地址,ADC_DR_DATA规则数据寄存器
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)(u16 *)uAD_Buff_A; //DMA存储器地址,自己设置的缓存地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; //传输方向,外设->存储器
DMA_InitStructure.DMA_BufferSize = ADC_BUFFSIZE * ADC_CHANNEL; //DMA缓存大小,数据传输量32*8
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设是否为增量模式
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //存储器是否为增量模式
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设数据长度半个字(16位)
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //存储器数据长度半字(16位)
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //DMA模式,普通模式、循环模式,还有双缓冲模式,需要特殊设置
DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA优先级,高优先级
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; //不使用FIFO
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; //FIFO阈值
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; //存储器突发,单次传输
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //外设突发,单次传输
DMA_Init(DMA2_Stream0, &DMA_InitStructure); //初始化DMA2_Stream0,对应为ADC3
//双缓冲模式设置
DMA_DoubleBufferModeConfig(DMA2_Stream0,(uint32_t)(u16 *)(uAD_Buff_B),DMA_Memory_0); //DMA_Memory_0首先被传输
DMA_DoubleBufferModeCmd(DMA2_Stream0,ENABLE);
//设置DMA中断
DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TC); //清除中断标志
DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE); //传输完成中断
DMA_Cmd(DMA2_Stream0, ENABLE); //使能DMA
}
void ADCInit_Timer(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
//时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
//失能定时器
TIM_Cmd(TIM2, DISABLE);
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); //初始化定时器
//定时器设置,T=(84 * 625) / 84M = 625us = 20ms/32,50Hz信号,每周期采样32个点,采样频率1600
TIM_TimeBaseStructure.TIM_Prescaler = 84-1; //分频系数,TIM2时钟在分频系数不为1时,时钟是APB1时钟的两倍84M
TIM_TimeBaseStructure.TIM_Period = 312500/CurrentFreq - 1; //周期值1M/32=31250,CurrentFreq单位为0.1hz,因此需扩大10倍
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //时钟分频因子
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up ; //向上计数模式
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //初始化定时器2
//使能定时器中断
TIM_ARRPreloadConfig(TIM2, ENABLE); //允许TIM2定时重载
TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update); //选择TIM2的UPDATA事件更新为触发源
// TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); //配置TIM2中断类型
//使能TIM2
TIM_Cmd(TIM2, ENABLE);
DebugLog("Enable TIM2, Set frequency is %d.", CurrentFreq);
}
static void ADCInit_Nvic(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
//定时器中断设置
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //定时器TIM2中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1; //抢占优先级0
NVIC_InitStructure.NVIC_IRQChannelSubPriority =1; //子优先级1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化NVIC寄存器
//DMA中断设置
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn; //DMA2_Stream0中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0; //抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority =1; //子优先级1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化NVIC寄存器
}
void ADCInit(void)
{
ADCInit_GPIO();
ADCInit_DMA();
ADCInit_ADC();
ADCInit_Nvic();
DebugLog("ADC Init is finish.");
}
void TIM2_IRQHandler(void)
{
OSIntEnter(); //进入中断
if(TIM_GetITStatus(TIM2, TIM_IT_Update)) //判断发生update事件中断
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update); //清除update事件中断标志
// ADC_SoftwareStartConv(ADC1);
}
OSIntExit(); //退出中断
}
void DMA2_Stream0_IRQHandler(void)
{
u16 period = 0;
OSIntEnter(); //进入中断
if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0)) //判断DMA传输完成中断
{
DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
// DMA_Cmd(DMA2_Stream0, ENABLE); //使能DMA,连续模式下不需要该使能
//数据转移程序
if(DMA_GetCurrentMemoryTarget(DMA2_Stream0) == DMA_Memory_0)
{
CurrentBuffPtr = uAD_Buff_A;
}
else
{
CurrentBuffPtr = uAD_Buff_B;
}
//遥测任务等待该信号量
OSSemPost(SemAD);
//判断是否更新TIM2
if(UpdataTIM)
{
period = 312500/CurrentFreq - 1; //计算采样频率1M/32=31250;32为采样点数,31250/freq=采样周期
TIM_ARRPreloadConfig(TIM2, DISABLE); //关闭TIM2定时重载
TIM2->ARR = period ; //更新定时器周期
TIM_ARRPreloadConfig(TIM2, ENABLE); //打开TIM2定时重载
}
}
OSIntExit(); //退出中断
}
上一篇:Stm32f103rct6ADC电压采集简介及注意点
下一篇:STM32如何实现可调频率、占空比的PWM波形
推荐阅读
史海拾趣
随着智能手机市场的不断成熟和发展,手机射频前端对频段的支持、开关速度的变化以及天线调谐方向提出了更高的要求。迦美信芯紧抓这一市场机遇,早在2014年就开始布局射频前端芯片领域,专注该领域芯片的研发与设计。经过多年的努力和发展,迦美信芯已成为国内领先的手机品牌在天线开关以及天线调谐器方面的主要供应商之一,为全球TOP 5的手机终端客户提供大量优质产品。
在竞争激烈的电子行业中,CMS始终保持着持续创新的态势。他们不断投入研发资源,推出了一系列具有创新性的产品。例如,他们开发了一款基于人工智能技术的智能家居控制系统,该系统能够通过语音控制实现家电设备的智能化管理。这一产品的推出进一步巩固了CMS在智能家居领域的领先地位。
艾为电子自成立以来,一直致力于技术研发和产品创新。公司研发团队不断攻克技术难题,推出了一系列具有竞争力的产品。其中,音频功放芯片作为公司的主打产品之一,凭借出色的性能和稳定的品质,赢得了市场的广泛认可。此外,艾为还在信号链、电源管理等领域取得了显著的技术突破,为公司的持续发展奠定了坚实的基础。
Diodes公司积极实施全球化战略,不断拓展海外市场。公司在以色列、加利福尼亚、得克萨斯和日本等地设立了制造工厂,形成了覆盖全球的生产和销售网络。这些工厂不仅为Diodes提供了充足的产能支持,也为公司赢得了更多国际客户的青睐。同时,Diodes还积极参加国际展会和交流活动,加强与国际同行的合作与交流,不断提升公司的国际化水平。
随着电子行业的快速发展,AZM公司意识到只有不断创新才能在激烈的市场竞争中立于不败之地。因此,公司加大了对研发的投入,积极引进高端人才,建立了完善的研发体系。通过持续的技术创新,AZM公司成功推出了一系列具有领先水平的微电子产品,不仅提升了公司的市场竞争力,也为整个电子行业的发展做出了贡献。
一、背景 路由信息协议(RIP)是以跳数作为metric的距离向量协议。RIP广泛用于全球因特网的路由,是一种内部网关协议(interior gateway protocol),即在自治系统内部执行路由功能。外部网关路由协议(exterior gateway protocol),如边缘网关协议 ...… 查看全部问答∨ |
|
很早就想写这篇文章了,但都不知如何入手,今天在华禹工控的群内讨论了一下,再把他写下来,就比较容易了。 先谈硬件思维,以我为代表。 本人从小接触电子,主要家里一堆电子垃圾天天有得玩,再加上我爸买了一本电工学,没事干就看书,第一章就是 ...… 查看全部问答∨ |
|
大家帮帮忙,2812的调理模块怎样设计? 我现在正在做2812的板子,现在遇到了问题,请各位大虾帮帮忙啊。。。。 放大和调理模块将信号放大并过滤掉噪声, 然后将模拟信号的电压幅值调整到F2812DSP芯片允许的范围之内(0-3V),然后 ...… 查看全部问答∨ |