stm32怎么修改延时没有用,程序始终那么快
stm32可以使用systick定时器来实现延时的功能,不需要这么写,具体可以看一下正点原子开发板的例程或者野火的。
如果非要这么写,也没关系。
使用MDK软件设定好当前MCU的时钟频率,使用软件仿真,单独执行自己写的for循环延时,会在左边的寄存器窗口出现具体使用了多少时间,你可以根据这个情况修改for循环里的变量参数。
如何包装stm32通用定时器的延时函数
SysTick的初始化设置:void Init_SysTick(void){if(SysTick_Config(SystemCoreClock / 1000)) //注意:3.5库中 SystemFrequency 被 SystemCoreClock 取代。
while(1);}延时函数:__IO uint32_t TimingDelay;void delay_ms(__IO uint32_t nTime){TimingDelay = nTime;while(TimingDelay != 0);}中断函数:extern __IO uint32_t TimingDelay;void SysTick_Handler(void){if (TimingDelay != 0x00){ TimingDelay--;}}delay_ms(1000);
STM32delay函数延时如何计算
展开全部 单片机编程过程中经常用到延时函数,最常用的莫过于微秒级延时delay_us( )和毫秒级delay_ms( )。
1.普通延时法这个比较简单,让单片机做一些无关紧要的工作来打发时间,经常用循环来实现,不过要做的比较精准还是要下一番功夫。
下面的代码是在网上搜到的,经测试延时比较精准。
//粗延时函数,微秒 void delay_us(u16 time) { u16 i=0; while(time--) { i=10; //自己定义 while(i--) ; } } //毫秒级的延时 void delay_ms(u16 time) { u16 i=0; while(time--) { i=12000; //自己定义 while(i--) ; } }2.SysTick 定时器延时CM3 内核的处理器,内部包含了一个SysTick 定时器,SysTick 是一个24 位的倒计数定时器,当计到0 时,将从RELOAD 寄存器中自动重装载定时初值。
只要不把它在SysTick 控制及状态寄存器中的使能位清除,就永不停息。
SysTick 在STM32 的参考手册里面介绍的很简单,其详细介绍,请参阅《Cortex-M3 权威指南》。
这里面也有两种方式实现:a.中断方式 如下,定义延时时间time_delay,SysTick_Config()定义中断时间段,在中断中递减time_delay,从而实现延时。
volatile unsigned long time_delay; // 延时时间,注意定义为全局变量 //延时n_ms void delay_ms(volatile unsigned long nms) { //SYSTICK分频--1ms的系统时钟中断 if (SysTick_Config(SystemFrequency/1000)) { while (1); } time_delay=nms;//读取定时时间 while(time_delay); SysTick->CTRL=0x00; //关闭计数器 SysTick->VAL =0X00; //清空计数器 } //延时nus void delay_us(volatile unsigned long nus) { //SYSTICK分频--1us的系统时钟中断 if (SysTick_Config(SystemFrequency/1000000)) { while (1); } time_delay=nus;//读取定时时间 while(time_delay); SysTick->CTRL=0x00; //关闭计数器 SysTick->VAL =0X00; //清空计数器 } //在中断中将time_delay递减。
实现延时void SysTick_Handler(void) { if(time_delay) time_delay--;
MDK5对stm32编程为什么延时函数一直没执行?
展开全部 下面我们就通过简单的三个步骤就可以让你随意的使用4—16MHz之内任何频点的晶振,我们以STM32F10x_StdPeriph_Lib_V3.4.0为例说明。
第一步,打开stm32f10x.h,将 #define HSE_VALUE ((uint32_t)8000000) 修改为: #define HSE_VALUE ((uint32_t)12000000) 第二步,打开system_stm32f10x.c,修改PLL参数,将 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9); 修改为: RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL6); 至此,原文件已经修改完成,如果你想将主频修改至其他频率,请自行修改。
但是,到现在,如果您直接编译调试的话,就会出现上文所说的USART的波特率不正确,Systick走时不准等问题,原因就是我们需要进行第三部的修改,这个修改不是在原文件中,而是在编译环境中。
我们已Keil MDK为例说明。
第三步,打开你已经建立的STM32工程,选择Projects-〉Options for target ***,找到Target标签,你会发现,外接的晶振默认还是8MHz,我们将外接的晶振参数修改为12MHz,确定保存,再编译,调试,你就会发现,所有的参数都回归的正常轨道,设置波特率为9600,它也不会跑到14400,设置Systick为1ms中断,它不会1.5ms中断。
...
stm32关于系统滴答定时器(systick)
你在中断处理函数中调用延时函数。
是可以的。
关键这个延时函数不可以使用到别的中断。
stm32在中断处理中只能同时处理一个中断。
如果该中断不处理完。
即使有别的高级别中断产生也不会执行处理函数。
你说你在你的延时函数中使用了systemtick,在你EXTI0_1_IRQHandler执行的时候,systemtick的中断处理不能执行。
你的系统计时也不会增加,就导致你的延时函数永远等不到结束。
如果你一定要延时的话,可以使用空循环。
STM32中断功能的实现
//GPIO中断实验,按键KEY1接上拉电阻,通过PC3做为中断输入,DS1(PF10)做为中断指示,中断一次,亮灭状态改变一次。
#include "stm32f10x.h"u8 count=0;//软件延时寄存器。
//**********************************************函数声明void Delay_ms(vu16 nCount); //ms级延时函数声明。
void Delay_10us(vu16 nCount);//10us级延时函数声明。
void GPIO_PC_Init(void);void GPIO_PF_Init(void);void EXTI_Line3_Init(void);void NVIC_Configuration(void);//*******************************************初始化子程序void GPIO_PC_Init(void)//PC3初始化子程序{ GPIO_InitTypeDef GPIO_InitStructure; //声明一个名为GPIO_InitStructure的结构体,其原型由GPIO_InitTypeDef确定。
只能放在一个函数的最前面。
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//选择待初始化的端口号 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入模式(因为外部有上拉电阻)。
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;//管脚速度设定。
GPIO_Init(GPIOC,&GPIO_InitStructure);//用以上参数初始化GPIOC。
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource3);//指定用作外部中断线路的管脚。
}void GPIO_PF_Init(void)//PC3初始化子程序{ GPIO_InitTypeDef GPIO_InitStructure; //声明一个名为GPIO_InitStructure的结构体,其原型由GPIO_InitTypeDef确定。
只能放在一个函数的最前面。
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;//开漏输出模式。
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;//管脚速度设定。
GPIO_Init(GPIOF,&GPIO_InitStructure);//用以上参数初始化GPIOF。
}void EXTI_Line3_Init(void)//中断线PC3的配置。
{ EXTI_InitTypeDef EXTI_InitStructure;//声明一个名为EXTI_InitStructure的结构体,其原型由EXTI_InitTypeDef确定。
只能放在一个函数的最前面。
EXTI_InitStructure.EXTI_Line=EXTI_Line3;//选择待初始化的外部中断端口 EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;//设置EXTI线路为中断请求。
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;//设置输入线路中断请求为下降沿触发。
EXTI_InitStructure.EXTI_LineCmd=ENABLE;//中断线使能。
EXTI_Init(&EXTI_InitStructure);//用以上参数初始化外部中断。
}void NVIC_Configuration(void)//NVIC嵌套向量中断控制器配置。
{ NVIC_InitTypeDef NVIC_InitStructure;//声明一个名为NVIC_InitStructure的结构体,其原型由NVIC_InitTypeDef确定。
NVIC_InitStructure.NVIC_IRQChannel=EXTI3_IRQn;//指定要配置的中断源。
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//设置先占优先级. NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;//设置从优先级。
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//使能中断 NVIC_Init(&NVIC_InitStructure);//用以上参数初始化中断控制器。
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//设置优先级分组位长度.}int main(void){ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOF|RCC_APB2Periph_AFIO, ENABLE);//开启GPIOC,GPIOF,AFIO(复用时钟)的时钟。
//要配置stm32的事件输出/外部中断/重映射的时候.就必须开启复用时钟. GPIO_PC_Init(); GPIO_PF_Init(); EXTI_Line3_Init(); NVIC_Configuration(); while(1);//等待中断。
}void EXTI3_IRQHandler(void)//外部中断线3的中断服务程序。
{ if(EXTI_GetITStatus(EXTI_Line3)==SET);//检测指定线路的中断请求是否产生。
{ Delay_ms(10);//去抖延时 while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)==0);//等待按键释放 GPIO_WriteBit(GPIOF, GPIO_Pin_10, (BitAction)(1-GPIO_ReadOutputDataBit(GPIOF, GPIO_Pin_10)));//对GPIOF_10脚输出取反。
Delay_ms(100); } EXTI_ClearFlag(EXTI_Line3);//与EXTI_ClearITPendingBit(EXTI_Line3);等效 清除中断标注后,下次中断才能进入。
}/******************************************************************************** 函数功能:1ms延时,8M晶振*******************************************************************************/void Delay_ms(vu16 nCount){ vu16 i; for(; nCount >0; nCount--) for(i=10276;i!=0;i--);}/******************************************************************************** 函数功能:10us延时,8M晶振*******************************************************************************/void Delay_10us(vu16 nCount){ vu16 i; for(; nCount >0; nCount--) for(i=74;i!=0;i--);}只要将相应的端口改为你自己的端口就OK了。
转载请注明出处51数据库 » stm32软件延时函数