新闻中心

EEPW首页>嵌入式系统>设计应用> STM32学习心得(3)

STM32学习心得(3)

作者: 时间:2016-11-25 来源:网络 收藏


中断代码:

voidTIM2_IRQHandler(void)

{

if(TIM_GetITStatus(TIM2,TIM_IT_CC4)!=RESET)//判断中断来源

{

TIM_ClearITPendingBit(TIM2,TIM_IT_CC4);//清除中断标志

GPIO_WriteBit(GPIOB,GPIO_Pin_11,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_11)));//变换LED色彩

IC4value=TIM_GetCapture4(TIM2);//获取捕捉数值

}

}

i)简单应用:

//改变占空比

TIM_SetCompare4(TIM3,变量);

j)注意事项:

管脚的IO输出模式是根据应用来定,比如如果用PWM输出驱动LED则应该将相应管脚设为AF_PP,否则单片机没有输出

我的测试程序可以发出不断循环三种波长并捕获,对比结果如下:

捕捉的稳定性很好,也就是说,同样的方波捕捉到数值相差在一两个数值。

捕捉的精度跟你设置的滤波器长度有关,在这里

TIM_ICInitStructure.TIM_ICFilter=0x4;//滤波设置,经历几个周期跳变认定波形稳定0x0~0xF

这个越长就会捕捉数值越小,但是偏差几十个数值,下面是0、4、16个周期滤波的比较,out是输出的数值,in是捕捉到的。

现在有两个疑问:

1、在TIM2的捕捉输入通道初始化里面这句

TIM_SelectInputTrigger(TIM2,TIM_TS_TI2FP2);//选择时钟触发源

按照硬件框图,4通道应该对应TI4FP4。可是实际使用TI1FP1,TI2FP2都行,其他均编译错误未注册。这是为什么?

2、关闭调试器和IAR程序,直接供电跑出来的结果第一个周期很正常,当输出脉宽第二次循环变小后捕捉的数值就差的远了。不知道是为什么







时钟不息工作不止,systic时钟应用

a)目的:使用系统时钟来进行两项实验——周期执行代码与精确定时延迟。

b)初始化函数定义:

voidSysTick_Configuration(void);

c)初始化函数调用:

SysTick_Configuration();

d)初始化函数:

voidSysTick_Configuration(void)

{

SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);//时钟除8

SysTick_SetReload(250000);//计数周期长度

SysTick_CounterCmd(SysTick_Counter_Enable);//启动计时器

SysTick_ITConfig(ENABLE);//打开中断

}

e)在NVIC的初始化函数里面增加以下代码打开相关中断:

NVIC_SystemHandlerPriorityConfig(SystemHandler_SysTick,1,0);//中断等级设置,一般设置的高一些会少受其他影响

f)在stm32f10x_it.c文件中找到voidSysTickHandler函数

voidSysTickHandler(void)

{

执行代码

}

g)简单应用:精确延迟函数,因为systic中断往往被用来执行周期循环代码,所以一些例程中使用其中断的启动和禁止来编写的精确延时函数实际上不实用,我自己编写了精确计时函数反而代码更精简,思路更简单。思路是调用后,变量清零,然后使用时钟来的曾变量,不断比较变量与延迟的数值,相等则退出函数。代码和步骤如下:

i.定义通用变量:u16Tic_Val=0;//变量用于精确计时

ii.在stm32f10x_it.c文件中相应定义:

externu16Tic_Val;//在本文件引用MAIN.c定义的精确计时变量

iii.定义函数名称:voidTic_Delay(u16Tic_Count);//精确延迟函数

iv.精确延时函数:

voidTic_Delay(u16Tic_Count)//精确延时函数

{Tic_Val=0;//变量清零

while(Tic_Val!=Tic_Count){printf("");}//计时

}

v.在stm32f10x_it.c文件中voidSysTickHandler函数里面添加

Tic_Val++;//变量递增

vi.调用代码:Tic_Delay(10);//精确延时

vii.疑问:如果去掉计时行那个没用的printf("");函数将停止工作,这个现象很奇怪

C语言功底问题。是的,那个“注意事项”最后的疑问的原因就是这个

Tic_Val应该改为vu16

while(Tic_Val!=Tic_Count){printf("");}//计时

就可以改为:

while(Tic_Val!=Tic_Count);//检查变量是否计数到位

STM32笔记之十三:恶搞,两只看门狗

a)目的:

了解两种看门狗(我叫它:系统运行故障探测器和独立系统故障探测器,新手往往被这个并不形象的象形名称搞糊涂)之间的区别和基本用法。

b)相同:

都是用来探测系统故障,通过编写代码定时发送故障清零信号(高手们都管这个代码叫做“喂狗”),告诉它系统运行正常。一旦系统故障,程序清零代码(“喂狗”)无法执行,其计数器就会计数不止,直到记到零并发生故障中断(狗饿了开始叫唤),控制CPU重启整个系统(不行啦,开始咬人了,快跑……)。

c)区别:

独立看门狗Iwdg——我的理解是独立于系统之外,因为有独立时钟,所以不受系统影响的系统故障探测器。(这条狗是借来的,见谁偷懒它都咬!)主要用于监视硬件错误。

窗口看门狗wwdg——我的理解是系统内部的故障探测器,时钟与系统相同。如果系统时钟不走了,这个狗也就失去作用了。(这条狗是老板娘养的,老板不干活儿他不管!)主要用于监视软件错误。

d)初始化函数定义:鉴于两只狗作用差不多,使用过程也差不多初始化函数栓一起了,用的时候根据情况删减。

voidWDG_Configuration(void);

e)初始化函数调用:

WDG_Configuration();

f)初始化函数

voidWDG_Configuration()//看门狗初始化

{

//软件看门狗初始化

WWDG_SetPrescaler(WWDG_Prescaler_8);//时钟8分频4ms

//(PCLK1/4096)/8=244Hz(~4ms)

WWDG_SetWindowValue(65);//计数器数值

WWDG_Enable(127);//启动计数器,设置喂狗时间

//WWDGtimeout=~4ms*64=262ms

WWDG_ClearFlag();//清除标志位

WWDG_EnableIT();//启动中断

//独立看门狗初始化

IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);//启动寄存器读写

IWDG_SetPrescaler(IWDG_Prescaler_32);//40K时钟32分频

IWDG_SetReload(349);//计数器数值

IWDG_ReloadCounter();//重启计数器

IWDG_Enable();//启动看门狗

}

g)RCC初始化:只有软件看门狗需要时钟初始化,独立看门狗有自己的时钟不需要但是需要systic工作相关设置。

RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE);

h)独立看门狗使用systic的中断来喂狗,所以添加systic的中断打开代码就行了。软件看门狗需要在NVIC打开中断添加如下代码:

NVIC_InitStructure.NVIC_IRQChannel=WWDG_IRQChannel;//通道

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//占先中断等级

NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;//响应中断优先级

NVIC_Init(&NVIC_InitStructure);//打开中断

i)中断程序,软件看门狗在自己的中断中喂狗,独立看门狗需要使用systic的定时中断来喂狗。以下两个程序都在stm32f10x_it.c文件中。

voidWWDG_IRQHandler(void)

{

WWDG_SetCounter(0x7F);//更新计数值

WWDG_ClearFlag();//清除标志位

}

voidSysTickHandler(void)

{IWDG_ReloadCounter();//重启计数器(喂狗)

}

j)注意事项:

i.有狗平常没事情可以不理,但是千万别忘了喂它,否则死都不知道怎么死的!

ii.初始化程序的调用一定要在systic的初始化之后。

iii.独立看门狗需要systic中断来喂,但是systic做别的用处不能只做这件事,所以我写了如下几句代码,可以不影响systic的其他应用,其他systic周期代码也可参考:

第一步:在stm32f10x_it.c中定义变量

intTic_IWDG;//喂狗循环程序的频率判断变量

第二步:将SysTickHandler中喂狗代码改为下面:

Tic_IWDG++;//变量递增

if(Tic_IWDG>=100)//每100个systic周期喂狗

{IWDG_ReloadCounter();//重启计数器(喂狗)

Tic_IWDG=0;//变量清零

}

本文引用地址://m.amcfsurvey.com/article/201611/321206.htm

上一页 1 2 3 下一页

关键词:STM32学习心

评论


技术专区

关闭