stm32--入门笔记

江协科技的stm32视频课程学习笔记 传送门

点亮PC13小灯

// 开启时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;    // gpio工作模式
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13;          // gpio编号
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;   // 工作频率
// 初始化gpio
GPIO_Init(GPIOC, &GPIO_InitStruct);
// 设置特定io口输出低电平。
GPIO_ResetBits(GPIOC, GPIO_Pin_13);

对射式红外传感器计次

清除AFIO相关的配置。
void GPIO_AFIODeInit(void);

锁定某个引脚的配置,防止被意外修改。
void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

引脚重映射(重映射方式, 新的状态)
void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);

配置AFIO的数据选择器,选择想要的中断引脚。Selects the GPIO pin used as EXTI Line.
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);

清除EXTI配置,恢复到上电时的状态。
void EXTI_DeInit(void);

根据传入的 EXTI_InitStruct 结构体,初始化EXTI。
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);

给机构体 EXTI_InitStruct 设置默认值。
void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct);

软件触发外部中断
void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);

主程序里查看和清除标志位用EXTI_GetFlagStatus、EXTI_ClearFlag;
中断函数里查看和清除标志位EXTI_GetITStatus、EXTI_ClearITPendingBit。

获取指定中断线状态。Checks whether the specified EXTI line flag is set or not.
FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);

指定中断线标志位置0。Clears the EXTI's line pending flags.
void EXTI_ClearFlag(uint32_t EXTI_Line);

获取指定中断标志位状态。Checks whether the specified EXTI line is asserted or not.
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);

清除中断挂起标志位。Clears the EXTI's line pending bits.
void EXTI_ClearITPendingBit(uint32_t EXTI_Line);

配置中断分组,整个程序只配置一次。
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);

根据 NVIC_InitStruct 内容初始化NVIC
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);

设置中断向量表
void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset);
系统低功耗配置
void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState);

关键代码如下。

#include "stm32f10x.h"
#include "CountSensor.h"


uint16_t CountSensor_Count = 0;


void CountSensor_Init(void)
{
    // 开启时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

    // EXTI、NVIC开启时钟,这两个默认开启,不用体现在代码里,也没法体现在代码里。

    // 初始化配置GPIOB 14号引脚。
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD;
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStruct);

    // 配置AFIO
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);

    // 配置EXTI
    EXTI_InitTypeDef EXTI_InitStruct;
    EXTI_InitStruct.EXTI_Line = EXTI_Line14;
    EXTI_InitStruct.EXTI_LineCmd = ENABLE;
    EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_Init(&EXTI_InitStruct);

    // 配置NVIC内核外设
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    NVIC_InitTypeDef NVIC_InitStruct;
    NVIC_InitStruct.NVIC_IRQChannel = EXTI15_10_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
    NVIC_Init(&NVIC_InitStruct);
}


uint16_t CountSensor_Get()
{
    return CountSensor_Count;
}


void EXTI15_10_IRQHandler(void)
{
    if (EXTI_GetITStatus(EXTI_Line14) == SET)
    {
        CountSensor_Count++;
        EXTI_ClearITPendingBit(EXTI_Line14);
    }
}
int main(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &GPIO_InitStruct);
	GPIO_ResetBits(GPIOC, GPIO_Pin_13);

	OLED_Init();
	CountSensor_Init();
	OLED_ShowString(1, 1, "Count");
	while(1)
	{
		// Count = ;
		OLED_ShowNum(2, 1, CountSensor_Get(), 5);
	}
}

定时中断

在这里插入图片描述

配置时基单元
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);

结构体变量赋初值
void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);

使能计数器,运行控制。
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);

使能中断输出信号,中断输出控制。
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);

选择内部时钟
void TIM_InternalClockConfig(TIM_TypeDef* TIMx);

选择ITRx(其他定时器的时钟)
void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);

选择捕获通道的时钟
void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource, uint16_t TIM_ICPolarity, uint16_t ICFilter);

ETR通过外部模式1作为时钟
void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);

ETR通过外部模式2作为时钟
void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);

配置ETR引脚的预分频器、滤波器等
void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);

单独配置预分频值
void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);

单独配置计数器的计数模式
void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode);

自动重装器预装功能配置。
void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);

给计数器设定一个值
void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter);

给自动重装器设定一个值
void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload);

获取当前计数器的值
uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);

获取当前预分频器的值
uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx);

关键代码

void Timer_Init(void)
{
	// 开启时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	// 配置定时器二的时钟为内部时钟,默认是内部时钟,所以可以不写。
	TIM_InternalClockConfig(TIM2);
	// 配置定时器的分频、触发方式、溢出值
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStruct.TIM_Period = 10000 - 1;
	TIM_TimeBaseInitStruct.TIM_Prescaler = 7200 - 1;
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;		// 高级定时器才有
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);
	// 清除更新事件标志
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);
	// 配置定时器溢出时触发更新中断,而非其它。
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
	// NVIC优先级分组、优先等级、请求中断的通道配置。
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStruct);
	// 开启定时器。
	TIM_Cmd(TIM2, ENABLE);
}
uint16_t Count = 0;
void TIM2_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
	{
		Count++;
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}

定时中断——外部时钟

void Timer_Init(void)
{
	// 开启时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStruct);

	TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 9);
	// 配置定时器的分频、触发方式、溢出值
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStruct.TIM_Period = 10 - 1;
	TIM_TimeBaseInitStruct.TIM_Prescaler = 1 - 1;
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);
	// 清除更新事件标志
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);
	// 配置定时器溢出时触发更新中断,而非其它。
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
	// NVIC优先级分组、优先等级、请求中断的通道配置。
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStruct);
	// 开启定时器。
	TIM_Cmd(TIM2, ENABLE);
}


uint16_t Timer_GetCounter(void)
{
	return TIM_GetCounter(TIM2);
}

TIM输出比较

英文缩写英文全称中文名称
OCOutput Compare输出比较
ICInput Capture输入捕获
CCCapture/Compare输入捕获和输出比较单元

输出比较有8种模式,有两种可用于生成PWM波形。
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值