警告:Warning[25]: Label ‘NMI_Handler’ is defined pubweak in a section implicitly declared root
该警告存在于IAR7.0以上版本环境下的STM32的启动文件xxx.s中,根据百度搜索的回复是高版本IAR取消使用STM32固件库提供的内核文件,即core_cm3。确实也是如此,在IAR中不需要该文件工程也一样正常编译运行。
解决方法:
在所有SECTION后方添加NOROOT语句,修改如下:
SECTION .text:CODE:REORDER:NOROOT(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无法正常工作。
解决方法:
对定时器结构体参数TIM_RepetitionCounter进行赋值,按照固件库给出注释理解应该是定时多少次才进入中断,该值从 0x00 到 0xFF,仅高级定时器使用(F103下为TIM1、TIM8)。
猜想及验证:既然值从0到255,而且又是定时多少次进入中断,那么会不会是因为没有赋值所以导致其为255(在Keil5中默认为0?),通过减小定时频率,最终验证确实是这个原因。
IAR环境下烧录报错如下:查找CPU失败
同时,在Keil5环境下的Debugger中也找不到芯片。
问题分析:
接线问题、电源问题、SWD错选成JTAG,将这三个问题进行排除后依旧无法正常下载程序,那就基本能够确认是软件关闭了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引脚拉高->上电->下载程序