网站建设合同按什么交印花税,青岛网站建设多少钱,青海建设云网站,网站做的好的公司名称主要参考学习资料#xff1a; B站江协科技 STM32入门教程-2023版 细致讲解 中文字幕 开发资料下载链接#xff1a;https://pan.baidu.com/s/1h_UjuQKDX9IpP-U1Effbsw?pwddspb 单片机套装#xff1a;STM32F103C8T6开发板单片机C6T6核心板 实验板最小系统板套件科协 目录 PWR… 主要参考学习资料 B站江协科技 STM32入门教程-2023版 细致讲解 中文字幕 开发资料下载链接https://pan.baidu.com/s/1h_UjuQKDX9IpP-U1Effbsw?pwddspb 单片机套装STM32F103C8T6开发板单片机C6T6核心板 实验板最小系统板套件科协 目录 PWR简介电源框图电压监测了解上电复位和掉电复位可编程电压监测器 低功耗模式模式选择睡眠模式停机模式待机模式 函数详解PWR_DeInit函数PWR_PVDCmd函数PWR_PVDLevelConfig函数PWR_WakeUpPinCmd函数PWR_EnterSTOPMode函数PWR_EnterSTANDBYMode函数标志位函数 实验30 修改主频接线图system_stm32f10x文件主程序 实验31 睡眠模式串口发送接收接线图主程序 实验32 停机模式对射式红外传感器计次接线图主程序 实验33 待机模式实时时钟接线图主程序 PWR简介
PWRPower Control电源控制PWR负责管理STM32内部的电源供电部分可以实现可编程电压监测器和低功耗模式的功能。可编程电压监测器PVD可以监控VDD电源电压当VDD下降到PVD阈值以下或上升到PVD阈值之上时PVD会触发中断用于执行紧急关闭任务非本节重点。低功耗模式包括睡眠模式Sleep、停机模式Stop和待机模式Standby可在系统空闲时降低STM32的功耗延长设备使用时间。主频和电流消耗大致呈正比降低主频也能显著降低功耗。
电源框图 上图为STM32供电方案可分为模拟部分供电VDDA、数字部分供电VDD1.8V和后备供电。各供电区域负责的设备已列出。
VDDA供电区域主要负责模拟部分的供电供电正极为VDDA负极为VSSA。其中AD转换器还有参考电压供电引脚VREF和VREF-在引脚多的芯片型号会单独引出而在F103C8T6中已经在内部分别接到了VDDA和VSSA。
中间部分分为VDD供电区域和1.8V供电区域VDD经电压调节器降压到1.8V提供给1.8V供电区域。后备供电区域中低电压检测器控制开关在VDD有电时由VDD供电VDD没电时由VBAT供电。
电压监测了解
上电复位和掉电复位 当VDD或VDDA电压过低时STM32内部电路直接产生复位。电压小于下限PDR时复位大于上限POR时解除复位中间有40mV的迟滞电压防抖复位信号Reset低电平有效。POR、PDR和复位滞后时间均可在芯片数据手册查询。
可编程电压监测器 可编程电压监测器的工作流程与上电/掉电复位类似但阈值电压可以手动调节调节范围可在芯片数据手册查询一般高于上电/掉电复位电压。PVD输出在电压过低时为1电压正常时为0可在上升/下降沿申请外部中断提醒程序进行适当处理。
低功耗模式 上表对三种低功耗模式进行了详细的对比。其中第二列为进入对应模式所需的配置第三列为进入对应模式后的唤醒方法后三列为进入对应模式后关闭的电路电压调节器相当于1.8V供电区域的电源。三种模式从上到下关闭的电路越来越多也越来越省电越来越难唤醒。对于具体的省电效果正常模式和睡眠模式电流消耗数量级均在10mA停机模式为10 μ \mu μA待机模式为1 μ \mu μA。
模式选择
执行WFIWait For Interrupt或WFEWait For Event指令后STM32进入低功耗模式。在触发低功耗模式之前配置寄存器进行模式选择的方式如下图所示其中寄存器的每个位已由库函数封装好无需自行配置。 睡眠模式
执行完WFI/WFE指令后STM32进入睡眠模式程序暂停运行唤醒后程序从暂停的地方继续运行。SLEEPONEXIT位决定STM32执行完WFI或WFE后是立刻进入睡眠还是等STM32从最低优先级的中断处理程序中退出时进入睡眠。在睡眠模式下所有的I/O引脚都保持它们在运行模式时的状态。WFI指令进入睡眠模式可被任意一个NVIC响应的中断唤醒。WFE指令进入睡眠模式可被唤醒事件唤醒。
停机模式
执行完WFI/WFE指令后STM32进入停机模式程序暂停运行唤醒后程序从暂停的地方继续运行。1.8V供电区域的所有时钟都被停止PLL、HSI和HSE被禁止SRAM和寄存器内容被保留下来。在停机模式下所有的I/O引脚都保持它们在运行模式时的状态。当一个中断或唤醒事件导致退出停机模式时HSI被选为系统时钟因此唤醒后需重新启动HSE配置主频为72MHz。当电压调节器处于低功耗模式下系统从停机模式退出时会有一段额外的启动延时。WFI指令进入停机模式可被任意一个EXTI中断唤醒。WFE指令进入停机模式可被任意一个EXTI事件唤醒。
待机模式
执行完WFI/WFE指令后STM32进入待机模式唤醒后程序从头开始运行。整个1.8V供电区域被断电PLL、HSI和HSE也被断电SRAM和寄存器内容丢失只有备份的寄存器和待机电路维持供电。在待机模式下所有的I/O引脚变为高阻态浮空输入。WKUP引脚的上升沿、RTC闹钟事件的上升沿、NRST引脚上外部复位、IWDG复位退出待机模式。
函数详解
PWR_DeInit函数
简介恢复缺省配置。
参数void
PWR_PVDCmd函数
简介使能可编程电压监测器。
参数使能/失能
PWR_PVDLevelConfig函数
简介配置PVD阈值。
参数阈值
PWR_PVDLevel_2V2/.../92.2~2.9VPWR_WakeUpPinCmd函数
简介使能WKUP引脚PA0配合待机模式的WKUP上升沿唤醒。
参数使能/失能
PWR_EnterSTOPMode函数
简介进入停机模式。
参数一电压调节器状态
PWR_Regulator_ON开启
PWR_Regulator_LowPower低功耗参数二唤醒方式
PWR_STOPEntry_WFI/WFE中断/事件PWR_EnterSTANDBYMode函数
简介进入待机模式。
参数void
标志位函数
PWR_GetFlagStatus函数
PWR_ClearFlag函数
参数PWR标志位
PWR_FLAG_WU/SB/PWDO唤醒/待机/电压监测器输出实验30 修改主频
接线图 system_stm32f10x文件
system文件提供了两个外部可调用的函数和一个外部可调用的变量
SystemInit函数配置时钟树复位后在启动文件中自动调用。SystemCoreClock变量主频频率。SystemCoreClockUpdate函数更新主频频率。
源文件system_stm32f10x.c中如下部分可更改主频的宏定义解除对应的注释即可选择想要的系统主频。其中else之前的部分为VL超值系列可选主频。当前主频为72MHz。
#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
/* #define SYSCLK_FREQ_HSE HSE_VALUE */#define SYSCLK_FREQ_24MHz 24000000
#else
/* #define SYSCLK_FREQ_HSE HSE_VALUE */
/* #define SYSCLK_FREQ_24MHz 24000000 */
/* #define SYSCLK_FREQ_36MHz 36000000 */
/* #define SYSCLK_FREQ_48MHz 48000000 */
/* #define SYSCLK_FREQ_56MHz 56000000 */
#define SYSCLK_FREQ_72MHz 72000000
#endif若文件为只读状态可以在文件资源管理器中右键对应文件更改属性取消勾选只读。
SystemInit()首先启动HSI并恢复缺省配置随后调用SetSysClock()函数会根据不同的宏定义执行相应的SetSysClockToxx()函数完成相应的时钟配置。
主程序
以下代码显示主频并以72MHz下的1s为周期闪烁Running字符串。
#include stm32f10x.h
#include Delay.h
#include OLED.hint main(void)
{OLED_Init();OLED_ShowString(1, 1, SYSCLK:);OLED_ShowNum(1, 8, SystemCoreClock, 8);while(1){OLED_ShowString(2, 1, Running);Delay_ms(500);OLED_ShowString(2, 1, );Delay_ms(500);}
}此时Running以现实的1s为周期闪烁。
现通过宏定义修改主频为36MHz
#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
/* #define SYSCLK_FREQ_HSE HSE_VALUE */#define SYSCLK_FREQ_24MHz 24000000
#else
/* #define SYSCLK_FREQ_HSE HSE_VALUE */
/* #define SYSCLK_FREQ_24MHz 24000000 */
#define SYSCLK_FREQ_36MHz 36000000
/* #define SYSCLK_FREQ_48MHz 48000000 */
/* #define SYSCLK_FREQ_56MHz 56000000 */
/* #define SYSCLK_FREQ_72MHz 72000000 */
#endif此时Running闪烁周期延长一倍。
由于修改主频会要求很多涉及精准计时的计算做好匹配工作一般不建议采用。
实验31 睡眠模式串口发送接收
接线图 主程序
在实验21 串口发送接收的基础上修改。
#include stm32f10x.h
#include Delay.h
#include OLED.h
#include Serial.huint8_t RxData;int main(void)
{OLED_Init();Serial_Init();OLED_ShowString(1, 1, RxDara:);while(1){if (Serial_GetRxFlag()){RxData Serial_GetRxData();Serial_SendByte(RxData);OLED_ShowHexNum(1, 8, RxData, 2);}//监测低功耗状态OLED_ShowString(2, 1, Running);Delay_ms(100);OLED_ShowString(2, 1, );Delay_ms(100);//默认配置开启睡眠模式__WFI();}
}此时只有当我们向串口发送数据时Running才会闪烁一次并回传一次数据。
程序运行时第一次循环即进入睡眠状态程序停止在WFI指令CPU睡眠但各个外设例如USART仍处于工作状态。USART外设在收到数据时产生中断唤醒CPU程序在暂停的地方继续运行先进入中断服务函数再回到主循环执行一轮循环进入下一次睡眠如此循环往复。
实验32 停机模式对射式红外传感器计次
接线图 主程序
在实验6 对射式红外传感器计次的基础上修改。
原驱动程序中博主采用了延时100ms消抖经实测中断处理时间过长会导致唤醒失败因此将中断服务函数修改如下
//中断函数名称在启动文件startup_stm32f10x_md.s中规定
void EXTI15_10_IRQHandler(void)
{//检查中断挂起标志位if(EXTI_GetITStatus(EXTI_Line14) SET){//再次判断引脚电平if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) 0){CountSensor_Count ;}EXTI_ClearITPendingBit(EXTI_Line14);}
}主程序修改如下
#include stm32f10x.h
#include Delay.h
#include OLED.h
#include CountSensor.hint main(void)
{OLED_Init();CountSensor_Init();//开启PWR时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);OLED_ShowString(1, 1, Count:);while(1){OLED_ShowNum(1, 7, CountSensor_Get(), 5);//监测低功耗状态OLED_ShowString(2, 1, Running);Delay_ms(100);OLED_ShowString(2, 1, );Delay_ms(100);//进入停机模式电压调节器开启中断唤醒PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFI);}
}此时每遮挡一次对射式红外传感器计数加一Running闪烁一次。有时闪烁两次是因为信号抖动导致遮挡和移开均产生中断信号。
除此之外复位后Running第一次闪烁时间短暂后续遮挡Running闪烁变慢这是由于前文介绍的停机模式唤醒后HSI被选为系统时钟只需在进入停机模式之后加上 SystemInit(); \texttt{SystemInit();} SystemInit();重新配置时钟为HSE即可。
实验33 待机模式实时时钟
接线图 主程序
在实验29 实时时钟的基础上修改。
#include stm32f10x.h
#include Delay.h
#include OLED.h
#include MyRTC.hint main(void)
{OLED_Init();MyRTC_Init();//开启PWR时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);//更改显示布局//计数值OLED_ShowString(1, 1, CNT :);//闹钟值OLED_ShowString(2, 1, ALR :);//闹钟标志位OLED_ShowString(3, 1, ALRF:);//设置闹钟值为复位10秒后//闹钟寄存器只写不读先定义变量存储闹钟值uint32_t Alarm RTC_GetCounter() 10;RTC_SetAlarm(Alarm);OLED_ShowNum(2, 6, Alarm, 10);while(1){OLED_ShowNum(1, 6, RTC_GetCounter(), 10);//显示闹钟标志位OLED_ShowNum(3, 6, RTC_GetFlagStatus(RTC_FLAG_ALR), 1);//监测低功耗状态OLED_ShowString(4, 1, Running);Delay_ms(100);OLED_ShowString(4, 1, );Delay_ms(100);//待机前关闭所有外部耗电电路以达到省电目的OLED_Clear();PWR_EnterSTANDBYMode();}
}待机模式唤醒后程序从头开始运行因此该程序现象为复位后OLED闪烁一次十秒之后触发闹钟事件再次闪烁往后每隔十秒闪烁一次。
在while循环之前加上 PWR_WakeUpPinCmd(ENABLE); \texttt{PWR\_WakeUpPinCmd(ENABLE);} PWR_WakeUpPinCmd(ENABLE);可实现WKUP引脚PA0唤醒此时每次将该引脚用跳线接到高电平即可观察到OLED闪烁。