在单片机中,我用定时器中断进行adc采集,同时用低频时钟中断来计时,两个中断系统会对相互有影响吗,有的话要怎么解决,没的话给一个程序例子
时间: 2023-09-18 17:15:46 浏览: 155
在单片机中,定时器中断和低频时钟中断会同时在中断向量表中占据一个位置,因此它们是互斥的。当一个中断正在执行时,另一个中断将被阻塞。因此,在设计中断服务程序时,需要注意它们的优先级和执行时间,以避免冲突和延迟。
下面是一个基于STM32F4的程序例子,其中使用了两个中断:TIM3定时器中断和RTC低频时钟中断。TIM3中断用于定时器计数,而RTC中断用于计时。两个中断都会更新相应的计数器,并将结果打印到串口终端上。需要注意的是,TIM3中断的优先级比RTC中断高,因为它需要更快地响应。
```C
#include "stm32f4xx.h"
#include "stdio.h"
volatile uint32_t g_tick = 0; // 定时器计数器
volatile uint32_t g_time = 0; // 低频时钟计数器
void TIM3_IRQHandler(void)
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
g_tick++;
printf("Tick = %ld\r\n", g_tick);
}
}
void RTC_WKUP_IRQHandler(void)
{
if (RTC_GetITStatus(RTC_IT_WUT) != RESET)
{
RTC_ClearITPendingBit(RTC_IT_WUT);
g_time++;
printf("Time = %ld\r\n", g_time);
}
}
void TIM_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_InitStruct.TIM_Prescaler = 41999; // 84MHz / (41999 + 1) = 2kHz
TIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_InitStruct.TIM_Period = 999; // 2kHz / (999 + 1) = 2Hz
TIM_InitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM3, &TIM_InitStruct);
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
NVIC_InitStruct.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
TIM_Cmd(TIM3, ENABLE);
}
void RTC_Config(void)
{
RTC_InitTypeDef RTC_InitStruct;
RTC_TimeTypeDef RTC_TimeStruct;
RTC_AlarmTypeDef RTC_AlarmStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
PWR_BackupAccessCmd(ENABLE);
RCC_LSEConfig(RCC_LSE_ON);
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
RCC_RTCCLKCmd(ENABLE);
RTC_InitStruct.RTC_HourFormat = RTC_HourFormat_24;
RTC_InitStruct.RTC_AsynchPrediv = 0x7F;
RTC_InitStruct.RTC_SynchPrediv = 0xFF;
RTC_Init(&RTC_InitStruct);
RTC_TimeStruct.RTC_Hours = 0;
RTC_TimeStruct.RTC_Minutes = 0;
RTC_TimeStruct.RTC_Seconds = 0;
RTC_SetTime(RTC_Format_BIN, &RTC_TimeStruct);
RTC_AlarmStruct.RTC_AlarmTime.RTC_Hours = 0;
RTC_AlarmStruct.RTC_AlarmTime.RTC_Minutes = 2;
RTC_AlarmStruct.RTC_AlarmTime.RTC_Seconds = 0;
RTC_AlarmStruct.RTC_AlarmMask = RTC_AlarmMask_None;
RTC_SetAlarm(RTC_Format_BIN, RTC_Alarm_A, &RTC_AlarmStruct);
RTC_ClearITPendingBit(RTC_IT_WUT);
RTC_WakeUpCmd(DISABLE);
RTC_ITConfig(RTC_IT_WUT, ENABLE);
NVIC_InitStruct.NVIC_IRQChannel = RTC_WKUP_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
RTC_WakeUpClockConfig(RTC_WakeUpClock_CK_SPRE_16bits);
RTC_WakeUpCmd(ENABLE);
}
int main(void)
{
TIM_Config();
RTC_Config();
while (1)
{
}
}
```
阅读全文