STM32踩坑笔记

一、IAR开发7.0以上版本

警告:Warning[25]: Label ‘NMI_Handler’ is defined pubweak in a section implicitly declared root
该警告存在于IAR7.0以上版本环境下的STM32的启动文件xxx.s中,根据百度搜索的回复是高版本IAR取消使用STM32固件库提供的内核文件,即core_cm3。确实也是如此,在IAR中不需要该文件工程也一样正常编译运行。
解决方法:
在后方添加NOROOT语句,修改如下:

SECTION .text:CODE:REORDER:NOROOT(1)

二、STM32定时器1运行异常

该问题在Keil5(MDK V5.37.0.0)环境下没有出现,定时器1代码如下:

void TIM1_Init(u16 arr,u16 psc)    
{  
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);	//使能定时器1时钟
	 
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

	TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE);
	
	//中断优先级NVIC设置
	NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;  //TIM1中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //抢占优先级0级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  //从优先级3级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器
	TIM_Cmd(TIM1, ENABLE); 
}

void TIM1_UP_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)  
		{
			TIM_ClearITPendingBit(TIM1, TIM_IT_Update);  //清除TIMx更新中断标志 
			if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_10))
				GPIO_ResetBits(GPIOA,GPIO_Pin_10);
			else
				GPIO_SetBits(GPIOA,GPIO_Pin_10);
		}
	
}

正常来说PA10上的LED应该按照定时频率进行闪烁,在上述Keil5环境下确实也是如此,但是当移植代码到IAR环境(IAR -ARM 8.11.2)下时,定时器1无法正常工作。
解决方法:
对定时器结构体参数进行赋值,按照固件库给出注释理解应该是定时多少次才进入中断,该值从 0x00 到 0xFF,仅高级定时器使用(F103下为TIM1、TIM8)。
猜想及验证:既然值从0到255,而且又是定时多少次进入中断,那么会不会是因为没有赋值所以导致其为255(在Keil5中默认为0?),通过减小定时频率,最终验证确实是这个原因。

三、STM32程序烧录异常

IAR环境下烧录报错如下:查找CPU失败
STM32踩坑笔记-LMLPHP
同时,在Keil5环境下的Debugger中也找不到芯片。
问题分析:
、、,将这三个问题进行排除后依旧无法正常下载程序,那就基本能够确认是软件关闭了SWD导致的无法正常下载程序,检查程序中是否存在如下语句

GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE);				--------语句1
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);			--------语句2

由于STM32的部分引脚是JTAG、SWD的调试引脚,如PB3、PB4、PA15、PA13、PA14等,为了将JTAG的引脚解放出来作为不同GPIO使用,通常会在程序中禁用掉JTAG(此时SWD是正常使能的),如果把语句2不小心错写成了语句1就会导致SWD被禁用,无法正常下载程序。
STM32的gpio头文件中有如下宏,如注释所示:第一个是SWD、JTAG全部使能,第二个是使能SWD、失能JTAG,第三个是SWD、JTAG全部失能。

#define GPIO_Remap_SWJ_NoJTRST      ((uint32_t)0x00300100)  /*!< Full SWJ Enabled (JTAG-DP + SW-DP) but without JTRST */
#define GPIO_Remap_SWJ_JTAGDisable  ((uint32_t)0x00300200)  /*!< JTAG-DP Disabled and SW-DP Enabled */
#define GPIO_Remap_SWJ_Disable      ((uint32_t)0x00300400)  /*!< Full SWJ Disabled (JTAG-DP + SW-DP) */

解决方法:
进行如下操作即可,注意在下载程序前要将工程中禁用JTAG的语句去掉。
断电->STM32的BOOT0引脚拉高->上电->下载程序

01-18 16:43