STM32
直播中

李萍

7年用户 1427经验值
私信 关注
[问答]

如何去实现STM32定时器每1S中断一次呢

如何去实现STM32定时器每1S中断一次呢?用到的函数功能有哪些呢?

回帖(2)

李杨

2021-11-24 15:37:00
  定时器实验:
  透过配置定时器相关寄存器的配置,实现定时器2每1S中断一次,通过数码管将时间实时的显示出来。
  用到的函数功能如下:
  (1) 利用TIM_Delnit()函数将Timer设置为默认缺省值;
  (2) TIM_InternalClockConfig()选择TIMx来设置内部时钟源;
  (3) TIM_Perscaler来设置预分频系数;
  (4) TlM_CIockDivision来设置时钟分割;
  (5) TIM_CounterMode来设置计数器模式;
  (6) TIM_Period来设置自动装入的值;
  (7) TIM_ARRPerloadConfig()来设置是否使用预装载缓冲器;
  (8) TIM_ITConfig()来开启 TIMx 的中断。
  注:时钟源一般分三种:内部时钟、外部脉冲、其他定时器形成级联。
  库函数
  
  
  
  跟输入相关(输入捕获)
  
  程序待添加
  代码(主要几个函数)
  main.c
  /********************************************************************
  * 文件 :main.c
  * 描述 :定时器2的中断配置
  * 说明 :通过配置定时器相关寄存器的配置,实现定时器2每1S中断一次通过数码管将时间实时的显示出来
  ********************************************************************/
  #include“stm32f10x_lib.h”
  #include《stdio.h》
  /*--------------函数的声明---------------*/
  void Delay_Ms(u16 time); //延时函数
  void RCC_Configuration(void);//RCC时钟配置函数
  void NVIC_Configuration(void); //NVIC中断向量表
  /*------------外部函数的声明--------------*/
  extern void SMG_Init(void); //数码管的初始化
  //extern void SMG_Display(u32 data,u8 dot); //数码管的显示函数
  extern NumbTube_Display(u32 data,u8 radix_point); //数码管的现实函数
  extern void TIM_Configuration(void); //TIM2的配置函数
  extern u8 CountValue; //全局变量 定时器每1S发生一次中断,此变量就加1,
  /* Private functions ---------------------------------------------------------*/
  /*******************************************************************************
  * Function Name : main
  * Description : Main program.
  * Input : None
  * Output : None
  * Return : None
  *******************************************************************************/
  int main(void)
  {
  #ifdef DEBUG
  debug();
  #endif
  /*----------初始化-------------*/
  RCC_Configuration(); //时钟
  NVIC_Configuration(); //中断
  TIM_Configuration(); //定时器
  SMG_Init(); //数码管
  while(1)
  {
  // SMG_Display(CountValue,1);
  NumbTube_Display(CountValue,3); //显示时间,3代表小数点的位置
  }
  }
  /*******************************************************************************
  * Function Name : Delay_Ms
  * Description : delay 1 ms.
  * Input : time (ms)
  * Output : None
  * Return : None
  *******************************************************************************/
  void Delay_Ms(u16 time) //延时函数
  {
  u16 i,j;
  for(i=0;i《time;i++)
  for(j=10000;j》0;j--);
  }
  /*******************************************************************************
  * Function Name : RCC_Configuration
  * Description : Configures the different system clocks.
  * Input : None
  * Output : None
  * Return : None
  *******************************************************************************/
  void RCC_Configuration(void)
  {
  /*------使用外部RC晶振----------*/
  RCC_DeInit(); //时钟默认初始化
  RCC_HSEConfig(RCC_HSE_ON);//使能外部的高速时钟
  while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);//等待外部的高速时钟就绪
  FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //使能指令预存取
  FLASH_SetLatency(FLASH_Latency_2); //等待两个周期
  RCC_HCLKConfig(RCC_SYSCLK_Div1); //设置AHB时钟为系统时钟
  RCC_PCLK2Config(RCC_HCLK_Div1); //设置APB2时钟为AHB时钟
  RCC_PCLK1Config(RCC_HCLK_Div2); //设置APB1时钟为AHB/2时钟
  RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9); //设置PLL时钟为外部高速时钟的9倍频
  RCC_PLLCmd(ENABLE); //使能PLL时钟
  while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //等待PLL时钟使能就绪
  RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //配置PLL时钟为系统时钟
  while(RCC_GetSYSCLKSource()!=0x08); //等待PLL时钟作为系统时钟
  }
  /*******************************************************************************
  * Function Name : void NVIC_Configuration(void)
  * Description :
  * Input : None
  * Output : None
  * Return : None
  *******************************************************************************/
  void NVIC_Configuration(void)
  {
  NVIC_InitTypeDef NVIC_InitStructure;
  #ifdef VECT_TAB_RAM
  NVIC_SetVectorTable(NVIC_VectTab_RAM,0x0); //向量表存放在RAM中
  #else
  NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x0); //向量表存放在FLASH中
  #endif
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //选择向量优先级组
  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQChannel; //选择中断向量通道为定时器2的通道
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先优先级为0
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //亚优先级为0
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中断向量
  NVIC_Init(&NVIC_InitStructure); //完成初始化
  }
举报

李继明

2021-11-24 15:38:20
timer.c
  /********************************************************************
  * 文件 :timer.c
  * 说明 :通过配置定时器相关寄存器的配置,实现定时器2每1S中断一次通过数码管将时间实时的显示出来
  ********************************************************************/
  #include“stm32f10x_lib.h”
  /******************************************************
  * 函数名称 :void TIM_Configuration(void)
  * 函数功能 :定时器的相关配置
  * 入口参数 : 无
  * 出口参数 :无
  * 返回值 :无
  ******************************************************/
  void TIM_Configuration(void)
  {
  /*-----------定义结构体变量----------------*/
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  TIM_OCInitTypeDef TIM_OCInitStructure;
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//开启定时器时钟
  TIM_DeInit(TIM2);
  TIM_InternalClockConfig(TIM2);
  /*-----------Configures TIM2 -------------*/
  TIM_TimeBaseStructure.TIM_Period = 2000; //下个更新事件发生时自动装载的周期值
  TIM_TimeBaseStructure.TIM_Prescaler = 35999; //时钟的分频值为35999,则时钟分频36000
  TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; //设置时钟分割
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
  TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing; //输出比较时间模式
  // TIM_OCInitStructure.TIM_Pulse = 0x0; //脉冲值 设置待转入捕获寄存器的脉冲值(定时器模式配置为输出比较模式)
  TIM_OC1Init(TIM2,&TIM_OCInitStructure);
  TIM_Cmd(TIM2,ENABLE);//使能TIM2
  TIM_PrescalerConfig(TIM2,35999,TIM_PSCReloadMode_Immediate);//让定时器预分频值立即装入
  TIM_ClearFlag(TIM2,TIM_FLAG_Update); //清除中断标志
  TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); //使能定时器中断
  }
  SMG_Display.c
  #include“stm32f10x_lib.h”
  /*---数码管从左至右为SMG1,SMG2,SMG3,SMG4,分别对应的GPIO引脚为PC8,PB15,PC9,PE8 --*/
  /*-----------------数码管显示的数据(0~9)的段码-------------------*/
  u8 const Display_TAB[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
  /*-----------------外部函数的声明----------------------*/
  extern void SPI_74HC595_Init(void);
  extern void SPI_74HC595_SendData(u8 data);
  /*******************************************************************************
  * Function Name : void SMG_Init(void))
  * Description : 对数码管的初始化
  * Input : None
  * Output : None
  * Return : None
  *******************************************************************************/
  void SMG_Init(void)
  {
  GPIO_InitTypeDef GPIO_InitStructure; //声明一个结构体变量
  SPI_74HC595_Init(); //初始化595
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //使能时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOE,&GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOC,&GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOB,&GPIO_InitStructure);
  }
  /*******************************************************************************
  * Function Name : void SMG_Bit(u8 data)
  * Description : 选择数码管的位选
  * Input : u8 data --------0x01:选择左边第一个数码管
  0x02:第二个数码管
  0x04:第三个数码管
  0x08:第四个数码管
  * Output : None
  * Return : None
  *******************************************************************************/
  void SMG_Bit(u8 data)
  {
  if((data & 0x01)!= 0) GPIO_ResetBits(GPIOC,GPIO_Pin_8);
  else GPIO_SetBits(GPIOC,GPIO_Pin_8);
  if((data & 0x02)!= 0) GPIO_ResetBits(GPIOB,GPIO_Pin_15);
  else GPIO_SetBits(GPIOB,GPIO_Pin_15);
  if((data & 0x04)!= 0) GPIO_ResetBits(GPIOC,GPIO_Pin_9);
  else GPIO_SetBits(GPIOC,GPIO_Pin_9);
  if((data & 0x08)!= 0) GPIO_ResetBits(GPIOE,GPIO_Pin_8);
  else GPIO_ResetBits(GPIOE,GPIO_Pin_8);
  }
  /*******************************************************************************
  * Function Name : void SMG_Display(u32 data,u8 dot)
  * Description :
  * Input : data:
  要显示的数据
  dot:
  显示小数点的位置
  * Output : None
  * Return : None
  *******************************************************************************/
  void SMG_Display(u32 data,u8 dot)
  {
  u32 one,ten,hundred,thousand; //个,十,百,千
  u32 j,n;
  thousand = data / 1000;
  hundred = (data % 1000) / 100;
  ten = (data % 100) / 10;
  one = data % 10;
  //----------------显示数据-------------------------
  for(n=0;n《20;n++)
  {
  if(4==dot) SPI_74HC595_SendData(Display_TAB[thousand]&0x7f);
  else SPI_74HC595_SendData(Display_TAB[thousand]);
  SMG_Bit(0x01);
  for(j=0;j《1500;j++);
  SMG_Bit(0x00);
  if(3==dot) SPI_74HC595_SendData(Display_TAB[hundred]&0x7f);
  else SPI_74HC595_SendData(Display_TAB[hundred]);
  SMG_Bit(0x02);
  for(j=0;j《1500;j++);
  SMG_Bit(0x00);
  if(2==dot) SPI_74HC595_SendData(Display_TAB[ten]&0x7f);
  else SPI_74HC595_SendData(Display_TAB[ten]);
  SMG_Bit(0x04);
  for(j=0;j《1500;j++);
  SMG_Bit(0x00);
  SPI_74HC595_SendData(Display_TAB[one]);
  SMG_Bit(0x08);
  for(j=0;j《1500;j++);
  SMG_Bit(0x00);
  }
  }
  /**************************************************************************
  * 名称:NumbTube_Bit(uint8 data)
  * 功能:选择数码管的位选。
  * 入口参数: data 选择码
  * 出口参数: 无
  **************************************************************************/
  void NumbTube_Bit(u8 data)
  {
  if((data & 0x01) != 0) GPIO_ResetBits(GPIOC, GPIO_Pin_8);
  else GPIO_SetBits(GPIOC, GPIO_Pin_8);
  if((data & 0x02) != 0) GPIO_ResetBits(GPIOB, GPIO_Pin_15);
  else GPIO_SetBits(GPIOB, GPIO_Pin_15);
  if((data & 0x04) != 0) GPIO_ResetBits(GPIOC, GPIO_Pin_9);
  else GPIO_SetBits(GPIOC, GPIO_Pin_9);
  if((data & 0x08) != 0) GPIO_ResetBits(GPIOE, GPIO_Pin_8);
  else GPIO_SetBits(GPIOE, GPIO_Pin_8);
  }
  /****************************************************************************
  * 名称:NumbTube_Display(uint32 data,uint8 radix_point)
  * 功能:控制数码管显示数据。
  * 入口参数: data 需要显示的数据
  * radix_point 小数点的位置
  * 出口参数: 无
  ****************************************************************************/
  void NumbTube_Display(u32 data,u8 radix_point)
  { u32 one,ten,hundred,thousand; //个,十,百,千,的变量声明
  u32 j,n; //时间,的变量声明
  thousand = data / 1000; //计算千位
  if(thousand != 0) data -= thousand*1000;//计算百位
  hundred = data / 100;
  if(hundred != 0) data -= hundred*100; //计算十位
  ten = data / 10;
  if(ten != 0) data -= ten*10; //计算个位
  one = data % 10;
  //-------------------显示数据----------------
  for(n=0;n《20;n++)
  {
  if(radix_point==4) SPI_74HC595_SendData(Display_TAB[thousand] & 0x7f);
  else SPI_74HC595_SendData(Display_TAB[thousand]);
  NumbTube_Bit(0x01);
  for(j=0;j《1500;j++);
  NumbTube_Bit(0x00);
  if(radix_point==3) SPI_74HC595_SendData(Display_TAB[hundred] & 0x7f);
  else SPI_74HC595_SendData(Display_TAB[hundred]);
  NumbTube_Bit(0x02);
  for(j=0;j《1500;j++);
  NumbTube_Bit(0x00);
  if(radix_point==2) SPI_74HC595_SendData(Display_TAB[ten] & 0x7f);
  else SPI_74HC595_SendData(Display_TAB[ten]);
  NumbTube_Bit(0x04);
  for(j=0;j《1500;j++);
  NumbTube_Bit(0x00);
  SPI_74HC595_SendData(Display_TAB[one]);
  NumbTube_Bit(0x08);
  for(j=0;j《1500;j++);
  NumbTube_Bit(0x00);
  }
  }
举报

更多回帖

发帖
×
20
完善资料,
赚取积分