您的位置 首页 分销

STM32学习记载19 定时器触发ADC

关于定时器出发ADC的问题一直比较迷惑,看各种资料讲的也很少。这里就那官方的例程来仔细分析一下吧。1:下面为官方例程,intmain(void){…

关于定时器动身ADC的问题一向比较利诱,看各种材料讲的也很少。这儿就那官方的例程来仔细分析一下吧。

1:下面为官方例程,
int main(void)
{
#ifdef DEBUG
debug();
#endif
/* System clocks configuration ———————————————*/
RCC_Configuration();
/* NVIC configuration ——————————————————*/
NVIC_Configuration();
/* GPIO configuration ——————————————————*/
GPIO_Configuration();
/* TIM1 configuration ——————————————————*/
/* Time Base configuration */
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Period = 0xFF;
TIM_TimeBaseStructure.TIM_Prescaler = 0x4;
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
/* TIM1 channel1 configuration in PWM mode */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0x7F;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
/* DMA1 Channel1 Configuration ———————————————-*/
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_RegularConvertedValueTab;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 32;
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_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
/* Enable DMA1 channel1 */
DMA_Cmd(DMA1_Channel1, ENABLE);
/* ADC1 configuration ——————————————————*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel14 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_13Cycles5);
/* Set injected sequencer length */
ADC_InjectedSequencerLengthConfig(ADC1, 1);
/* ADC1 injected channel Configuration */
ADC_InjectedChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_71Cycles5);
/* ADC1 injected external trigger configuration */
ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_None);
/* Enable automatic injected conversion start after regular one */
ADC_AutoInjectedConvCmd(ADC1, ENABLE);
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 external trigger */
ADC_ExternalTrigConvCmd(ADC1, ENABLE);
/* Enable JEOC interupt */
ADC_ITConfig(ADC1, ADC_IT_JEOC, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* Enable ADC1 reset calibaration register */
ADC_ResetCalibration(ADC1);
/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC1));
/* Start ADC1 calibaration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));
/* TIM1 counter enable */
TIM_Cmd(TIM1, ENABLE);
/* TIM1 main Output Enable */
TIM_CtrlPWMOutputs(TIM1, ENABLE);
/* Test on channel1 transfer complete flag */
while(!DMA_GetFlagStatus(DMA1_FLAG_TC1));
/* Clear channel1 transfer complete flag */
DMA_ClearFlag(DMA1_FLAG_TC1);
/* TIM1 counter disable */
TIM_Cmd(TIM1, DISABLE);
while (1)
{
}
}
2:关于AD的DMA暂时不介绍,首要介绍定时器和ADC的相关,下面是例程中两者的要害函数
/* TIM1 configuration ——————————————————*/
/* Time Base configuration */
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Period = 0xFF;
TIM_TimeBaseStructure.TIM_Prescaler = 0x4;
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
/* TIM1 channel1 configuration in PWM mode */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0x7F;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* TIM1 counter enable */
TIM_Cmd(TIM1, ENABLE);
/* TIM1 main Output Enable */
TIM_CtrlPWMOutputs(TIM1, ENABLE);
/* TIM1 counter disable */
TIM_Cmd(TIM1, DISABLE);

下面分条解说,解说之前需求了解一下ADC外部触发的相关常识:
2.1首要ADC的外部触发有必要是上升沿才能够发动转化。
那么怎么得到上升沿呢?需求看一下定时器的内容
2.2定时器中有这么一段话:输出部分发生一个中心波形OCxRef(高有用)作为基准,链的结尾决议终究输出信号的极性。 也便是说OCxREF仅仅一个中心信号,咱们关怀的是终究的信号。
那么终究一句话中终究信号的极性怎么确认呢?持续往下看:

2.3结尾终究信号的极性确认

从图中能够看到中中心参看信号OC1REF通过TIM1_CCER_CCIE TIM1_CCER_CCIP终究决议OC1的输出极性。看一下数据手册,输出形式中形似只要PWM形式能够满意2.1中说到的,能够发生一个上升沿来触发AD转化。
现在能够解说代码了,结合官网的源文件和寄存器来阐明一下会愈加的深入吧!
3 代码解说
3.1 定时器设定为PWM形式
/* TIM1 configuration ——————————————————*/
/* Time Base configuration */
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Period = 0xFF;
TIM_TimeBaseStructure.TIM_Prescaler = 0x4;
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);//上面的代码就不需求解说了,首要便是设置定时器的周期,需求留意的是定时器设置为向上计数模式。下面的代码逐条解说
/* TIM1 channel1 configuration in PWM mode */
①TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //TIM1 脉冲宽度调制形式 1
②TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //使能输出比较状况
TIM_OCInitStructure.TIM_Pulse = 0x7F;
③TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //TIM1 输出比较极性低
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
①头文件中
#define TIM_OCMode_PWM1((uint16_t)0x0060) 赋值给TIMx->CCMR1,比照下面的文档,能够看出是设置为PWM形式1

②头文件中界说
#define TIM_OutputState_Enable((uint16_t)0x0001)赋值给TIMx->CCER寄存器

,对照文档看出是使能OC1的输出。

③头文件中界说
#define TIM_OCPolarity_Low((uint16_t)0x0002)赋值给TIMx->CCER,对照文档看出

OC1是低电平有用,这一点非常重要,阐明在终究的输出端口是低电平有用的,

TIMx_ARR:主动装载寄存器, 确认PWM的频率,
TIM_CCRx:捕获/比较寄存器,确认只占空比
TIMx_CNT:计数器寄存器。
也便是说当CNT

3.2 定时器和PWM翻开

/* TIM1 counter enable */
TIM_Cmd(TIM1, ENABLE);
/* TIM1 main Output Enable */
TIM_CtrlPWMOutputs(TIM1, ENABLE);
/* TIM1 counter disable */
TIM_Cmd(TIM1, DISABLE);
上面代码相对简略,便是翻开定时器,使能PWM输出。需求留意的是必定要有TIM_CtrlPWMOutputs(TIM1, ENABLE);函数的调用。其间便是使能了TIMx_BDTR_MOE。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/bandaoti/fenxiao/272530.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部