datasheet

STM32定时器和外部触发同步的应用

2019-07-12来源: eefocus关键字:STM32  定时器  外部触发同步

一、定时器和外部触发的同步

TIMx定时器能够在多种模式下和一个外部的触发同步:复位模式、门控模式和触发模式。


从模式:复位模式

复位模式时序图如下所示:



配置通道1以检测TI1的上升沿,配置定时器为复位模式,计数器为向上计数模式,选择T1位输入源。每一个计数器时钟周期计数器寄存器自增。当TI1产生一个上升沿时,计数器寄存器清0重新开始计数。


从模式:门控模式

门控模式时序图如下所示:



配置通道1以检测TI1的低电平,配置定时器为门控模式,计数器为向上计数模式,选择T1为输入源。每一个计数器时钟周期计数器寄存器自增。只要TI1为低,计数器开始依据内部时钟计数,在TI1为高电平时停止计数。


从模式:触发模式


配置通道2检测TI2的上升沿。配置定时器为触发模式,选择TI2为输入源。当TI2出现一个上升沿时,计数器开始在内部时钟的驱动下计数。


二、利用复位模式串口接收不定长数据

利用复位模式串口接收不定长数据的思路为:将定时器通道引脚与串口RX引脚硬件上连接,串口接收使用DMA方式,定时器在串口未收到数据时不工作,当串口收到数据时,配置定时器,关闭串口中断,当串口上还有数据未接收完成时,计数器不断清0重新开始计数,一旦串口无接收数据时,计数器不再复位,知道产生计数器中断,然后将收到的数据读出。


串口配置:

这里都是些常规配置。


/***************************************************************************

 * @fn          Usart1_Configuration

 *     

 * @brief       

 *     

 * @data        

 *     

 * @param       BaudRate - 

 *              NewState - ENABLE/DISABLE

 *              

 * @return      void

 ***************************************************************************

 */ 

void Usart1_Configuration(uint32_t BaudRate,uint16_t parity, uint16_t wordlength, uint16_t stopbits,FunctionalState NewState)

{

  USART_InitTypeDef USART_InitStructure;        

  GPIO_InitTypeDef GPIO_InitStructure;

  

  /* config USART1 clock */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);

  

  /* USART1 GPIO config */

  /* Configure USART1 Tx (PA.9) as alternate function push-pull */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;

  GPIO_Init(GPIOA, &GPIO_InitStructure);    

 

  /* Configure USART1 Rx (PA.10) as input floating */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

  

  USART_DeInit(USART1);

  

  USART_InitStructure.USART_BaudRate            = BaudRate ;         //

  USART_InitStructure.USART_WordLength          = wordlength;  //

  USART_InitStructure.USART_StopBits            = stopbits;   //´

  USART_InitStructure.USART_Parity              = parity ;   //

  USART_InitStructure.USART_HardwareFlowControl =        USART_HardwareFlowControl_None;//Ó²¼þÁ÷ʧÄÜ

  USART_InitStructure.USART_Mode                = USART_Mode_Rx | USART_Mode_Tx; //

  USART_Init(USART1, &USART_InitStructure);               //´

  USART_ITConfig(USART1,USART_IT_RXNE,NewState);              //

 

  __nop(); __nop();

  USART_Cmd(USART1, NewState);                          //

}

 

 

 

/***************************************************************************

 * @fn          USART1_NVIC_Configuration

 *     

 * @brief       ÅäÖô®¿Ú1Öжϡ£

 *              USART1ÖжÏ×éΪµÚ3×飬ÇÀÕ¼ÓÅÏȼ¶1£¬ÏìÓ¦ÓÅÏȼ¶0

 *

 * @data        2015Äê08ÔÂ05ÈÕ

 *     

 * @param       NewState - ENABLE/DISABLE

 *     

 * @return      void

 ***************************************************************************

 */

void USART1_NVIC_Configuration(FunctionalState NewState)

{

  NVIC_InitTypeDef NVIC_InitStructure;

  

  NVIC_SetVectorTable (NVIC_VectTab_FLASH, NVIC_VECTTAB_FLASH_OFFSET);  

  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;  

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelCmd = NewState;

  NVIC_Init(&NVIC_InitStructure);

  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;  

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;  

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  

  NVIC_Init(&NVIC_InitStructure); 

}

/***************************************************************************

 * @fn          Usart1_DMA_Configuration

 *     

 * @brief       ÅäÖÃUSART1µÄDMA½ÓÊպͷ¢ËÍ,USART2->TXʹÓÃDMA1_Channel6,

 *              USART2->RXʹÓÃDMA1_Channel7¡£

 *     

 * @data        2015Äê08ÔÂ05ÈÕ

 *     

 * @param       void

 *     

 * @return      void

 ***************************************************************************

 */ 

 

void Usart1_DMA_Configuration(void)

{

  DMA_InitTypeDef DMA_InitStructure;

  /* DMA clock enable */

  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//DMA1

  

  /* DMA1 Channel5 (triggered by USART1 Rx event) Config */

  DMA_DeInit(DMA1_Channel5);  

  DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40013804;

  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)usart1_recv_data.RecvData;

  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

  DMA_InitStructure.DMA_BufferSize = USART1_DMA_BUFFER_SIZE;

  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//DMA_Mode_Circular;

  DMA_InitStructure.DMA_Priority = DMA_Priority_High;

  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

  DMA_Init(DMA1_Channel5, &DMA_InitStructure);

  //DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE);

  //DMA_ITConfig(DMA1_Channel6, DMA_IT_TE, ENABLE);

  

  /* Enable USART1 DMA RX request */

  USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);

  DMA_Cmd(DMA1_Channel5, ENABLE);  

}

定时器配置:

定时器配置比较重要,我这里设置了输出比较,并且开了CC2中断,当计数器寄存器的值达到输出比较寄存器的值时会产生中断。然后选择TI2为输入源,且为复位模式,当TI2有信号时则计数器清零,这样不会产生CC1比较中断。


/***************************************************************************

 * @fn          TIM4_Configuration

 *     

 * @brief       TIM4ÅäÖÃ,ʹÓø´Î»Ä£Ê½¡£TIM4µÄ²¶»ñ/±È½ÏÊäÈë2ºÍ´®¿Ú2µÄRXÔÚÓ²¼þ

 *              ÉÏÏàÁ¬, ´®¿ÚÓÐÊý¾Ýʱ£¬TIM4Ò»Ö±¸´Î»£¬Ò»µ©´®¿ÚûÓÐÊý¾Ý£¬ÔòTIM4

 *              ²»ÔÙ¸´Î»¡£TIM4³¬Ê±ºó£¬»á²úÉúÒ»¸ö³¬Ê±Öжϡ£

 *     

 * @data        2015Äê08ÔÂ05ÈÕ

 *     

 * @param       void

 *     

 * @return      void

 ***************************************************************************

 */ 

void TIM4_Configuration(uint32_t bandrate)

{

  

uint16_t tim_pluse = bandrate == 2400?  80: 40;//2400²¨ÌØÂÊʱ ¼ÆÊý80¸öÖÜÆÚ ÆäÓà40¸öÖÜÆÚ

  /* TIM4 configuration -------------------------------------*/ 

  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

  TIM_OCInitTypeDef  TIM_OCInitStructure;

  TIM_ICInitTypeDef  TIM_ICInitStructure;

  NVIC_InitTypeDef NVIC_InitStructure;   

      /* Enable TIM4 clock */

 

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4 , ENABLE);

  TIM_DeInit(TIM4);

  TIM_TimeBaseStructure.TIM_Period = 65535;                           //65535

TIM_TimeBaseStructure.TIM

[1] [2]

关键字:STM32  定时器  外部触发同步

编辑:什么鱼 引用地址:http://www.eeworld.com.cn/mcu/ic467519.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:STM32定时器映射及其通道
下一篇:STM32学习笔记——5个串口的使用方法

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM32 Systick定时器在实现1us延时时的问题与解决

问题:使用systick_config()函数来实现计数,这个函数在下面代码中的 SysTick_CTRL_TICKINT_Msk 开启了中断。不论系统时钟为72Mhz或36Mhz若设置STM32每10us进入一次中断,计时是可以的;而每1us进入中断,由于中断指令较多,那么程序就会困在中断里出不来。static __INLINE uint32_t SysTick_Config(uint32_t ticks){   if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /
发表于 2019-07-17

stm32 ADC知识总结(二)

关于STM32的ADC的一些重要特点需要记住: 1)STM32F103系列至少有2个ADC,这些ADC可以独立使用,也可以使用双重模式(提高采样率); 2)STM32的ADC是12位逐次逼近型的模数转换器,一共有18个通道,可以测量16个外部信号和2个内部信号源; 3)每个通道的ADC可以在单次、连续、扫描或者间断模式下进行; 4)前面讲过STM32的ADC是12位的,结果存储在16位的数据寄存器中,有4位用不到,所以ADC存在左对齐或右对齐的方式; 5)模拟看门狗允许应用程序检测输入电压是否超出用户定义的高低阈值; 6)STM32的ADC最大的转换速率为1MHz
发表于 2019-07-17
stm32 ADC知识总结(二)

stm32f070 stop 模式 rtc定时启动调试总结

stm32f070 stop 模式 rtc定时启动调试总结。1.在进stoop模式之前一定对gpio进行配置。/* GPIO Ports Clock Enable */__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_GPIOF_CLK_ENABLE();/Configure GPIO pins : GPIO_PIN_All/GPIO_InitStruct.Pin = GPIO_PIN_All;GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;GPIO_InitStruct.Pull = GPIO_NOPULL
发表于 2019-07-17

RTC_WakeUp中断唤醒STM32F4停止模式

RTC_WakeUp唤醒STM32F4停止模式(借鉴的是原子哥写的代码): 首先我们先初始化RTC配置://RTC初始化u8 MyRTC_Init(void){    RTC_InitTypeDef RTC_InitStructrue;    u16 retry=0x1FFF;    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);//使能PWR时钟    PWR_BackupAccessCmd(ENABLE);//使能后备寄存器    if
发表于 2019-07-17

关于stm32stop模式下,串口唤醒中的问题及解决办法

首先讲一下应用场景:STM32F1 + HAL库+ Freertos ,STOP模式下利用串口引脚唤醒。stop mode 处理内容如下:1,配置所有引脚为模拟输入(参考官方代码)2,配置串口接收引脚为外部中断3,进入stop mode4,初始化串口等外设现象:第一次从stop模式唤醒时串口能正常通信,判断一段时间后无数据则再一次进入stop mode,然后再一次唤醒,此时串口无法输出。最后发现原因是串口重新初始化时HAL_UART_Init()函数中会判断if(huart->State == HAL_UART_STATE_RESET),此时才会执行HAL_UART_MspInit(huart),配置串口IO口。解决办法
发表于 2019-07-17

STM32开发笔记1: STM32F407时钟配置

单片机型号:STM32F407    本文讲解STMF407时钟的使用及其配置方法。        1、STM32F407的分类        a、LSI是低速内部时钟,RC震荡器,频率为32KHz左右。供独立看门狗和自动唤醒单元使用。        b、LSE是低速外部时钟,接频率为32.768KHz的石英晶体。这个主要是RTC的时钟源。        c、HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围
发表于 2019-07-17
STM32开发笔记1: STM32F407时钟配置

小广播

何立民专栏

单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved