基于STM32F103实现通过开关量控制led亮灭,并统计次数的的程序
时间: 2024-02-05 18:11:32 浏览: 79
以下是基于STM32F103的开关量控制LED并统计次数的程序,其中使用了GPIO口控制LED,外部中断控制开关量,计时器统计次数。
```c
#include "stm32f10x.h"
int count = 0; // 定义计数器变量
void EXTI0_IRQHandler(void) // 定义外部中断0的中断处理函数
{
if (EXTI_GetITStatus(EXTI_Line0) != RESET) // 判断是否为外部中断0
{
GPIO_WriteBit(GPIOC, GPIO_Pin_13, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_13))); // 翻转LED
count++; // 计数器加1
EXTI_ClearITPendingBit(EXTI_Line0); // 清除中断标志位
}
}
void TIM2_IRQHandler(void) // 定义定时器2的中断处理函数
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) // 判断是否为定时器2的更新中断
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // 清除中断标志位
}
}
int main(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); // 使能GPIOC时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // 使能AFIO时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; // LED对应的GPIO口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 50MHz时钟速度
GPIO_Init(GPIOC, &GPIO_InitStructure); // 初始化GPIOC
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 使能定时器2时钟
TIM_TimeBaseStructure.TIM_Period = 999; // 计时器周期为1000
TIM_TimeBaseStructure.TIM_Prescaler = 7199; // 定时器分频系数为7200
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 时钟分频系数为1
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数模式
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); // 初始化定时器2
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); // 使能定时器2的更新中断
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; // 定时器2中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 抢占优先级为0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 子优先级为1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能中断
NVIC_Init(&NVIC_InitStructure); // 初始化NVIC
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 使能GPIOA时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // 开关对应的GPIO口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 50MHz时钟速度
GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化GPIOA
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); // 将GPIOA0连接到中断线0
EXTI_InitStructure.EXTI_Line = EXTI_Line0; // 中断线0对应的外部中断
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; // 中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE; // 使能中断线0
EXTI_Init(&EXTI_InitStructure); // 初始化外部中断0
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; // 外部中断0
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 抢占优先级为1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 子优先级为0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能中断
NVIC_Init(&NVIC_InitStructure); // 初始化NVIC
TIM_Cmd(TIM2, ENABLE); // 启动定时器2
while (1)
{
// 等待中断
}
}
```
在此程序中,我们使用了GPIO口控制LED,外部中断控制开关量,计时器统计次数。其中,当外部中断0触发时,我们会翻转LED,并将计数器加1;而当定时器2的更新中断触发时,我们不做任何操作。在程序中,我们使用了定时器2来统计次数,定时器周期为1000,定时器分频系数为7200,因此每1秒钟会触发一次更新中断,我们可以在更新中断中进行计数器的读取和清零操作。
阅读全文