stm32开发问题集锦

来源:本站
导读:目前正在解读《stm32开发问题集锦》的相关信息,《stm32开发问题集锦》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《stm32开发问题集锦》的详细说明。
简介:本文介绍了STM32开发过程中遇到的一些问题以及解决方法。

1 在flash中跑程序时,能进入中断,但在ram中跑时,进不了中断的原因。

看以下的中断配置函数可以知道,要在ram中调试程序,需要定义VECT_TAB_RAM。

定义方法a:在ProjectOptions for taget 'xxx' 的对话框的c/c++中定义宏VECT_TAB_RAM

定义方法b:在程序中直接定义

void NVIC_Configuration(void)

{

NVIC_InitTypeDef NVIC_InitStructure;

#ifdef VECT_TAB_RAM

/* Set the Vector Table base location at 0x20000000 */

NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);

#else /* VECT_TAB_FLASH */

/* Set the Vector Table base location at 0x08000000 */

NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);

#endif

/* Configure and enable ADC interrupt */

NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQChannel;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

2 SysTickHandler 函数不能进入。

原先初始化的语句为

SysTick_Config();

修改为以下时可以进入

SysTick_Config();

SysTick_CounterCmd(SysTick_Counter_Enable);

3 如何解决链接时错误"..objLowCostDA.axf: Error: L6218E: Undefined symbol assert_failed (referred from stm32f10x_flash.o)."?

如果所加入的库是STM32F10xD.LIB(即调试模式库),则需要在无论什么得放添加函数定义

void assert_failed(u8* file, u32 line)

{

/* User can add his own implementation to report the file name and line number,

ex: printf("Wrong parameters value: file %s on line %drn", file, line) */ /* Infinite loop */

while (1)

{

}

}

如果所加入的库是STM32F10xR.LIB(即发布模式库),则不会报错。

4 打开中断的时机不正确,导致无法进行任务切换。

由于我过早地打开了 SysTick 中断,而我在SysTickHandler 中有如下语句:

{

...

OS_ENTER_CRITICAL(); /* Tell uC/OS-II that we are starting an ISR */

OSIntNesting++;

OS_EXIT_CRITICAL();

OSTimeTick(); /* Call uC/OS-II's OSTimeTick() */

OSIntExit();

...

}

因为打开过早,因此 OSIntNesting++ 能够执行,而OSIntExit函数却没有把OSIntNesting减1.因此,导致了无法进行任务切换。

注意2点可以避免该情况:

a 同时使用 OSIntExit(); 和OSIntEnter(); 而不是像我这样使用OSIntNesting++ 和OSIntExit()。

b 开中断要在操作系统初始化后完成,即在OSStart之后。

5 程序中只要使用了printf函数,就会执行到BKTP语句挂掉。

解决方法:ProjectOptions Target选项页中选中 Use MicroLIB

6 关于堆栈对齐的问题

程序中出现了一个奇怪的问题

char g_cpTask2Buffer[200];

void Task2(void *arg)

{

...

sprintf(g_cpTask2Buffer,"%.3f", ADCInfoArray[0].m_fVolt);

...

}

ADCInfoArray[0].m_fVolt是一个float值。

在执行完 sprintf 后,无论m_fVolt是多少,始终得到的g_cpTask2Buffer的内容都是"0.000"。

调试了好几天的汇编终于解决了问题,根源竟然是ucos的堆栈需要以8字节对齐。

Task2是一个ucos的任务,Stack2 是Task2的任务堆栈。

如果是以下形式则出错:

Stack2 0x200084ac Data 804 main.o(.bss)

Stack3 0x200087d0 Data 800 main.o(.bss)

如果是以下形式则不出错:

Stack2 0x200084ac Data 800 main.o(.bss)

Stack3 0x200087cc Data 800 main.o(.bss)

为什么 sprintf在Task2 的中,但是执行结果的正确与否却看起来似乎与Task3的任务堆栈Stack3相关?

原因是,任务 Task2 的堆栈顶实际上位于Stack2 + (Stack2STKSIZE - 1),该值正好与Stack3

相连。

为什么堆栈必须要8字节对齐?

因为在汇编中有这样的语句:

BIC r0,r2,#0x07

该句得到double型值(在处理过程中,m_fVolt先从float被转换为double型) 的存储地址。

该汇编的意思是把r2的最低一个字节的二进制最后3位清零,即把r2变为形如16进制xxxxxxx0或者xxxxxxx8,然后放入r0。

可以看到该地址必然是8字节对齐的。

最根本的原因我仍然没有找到,但算是解决了问题。

7 外部sram用作堆栈的一个问题

系统中使用了ucos,由于任务堆栈的空间需要的比较多,因此把其放到了外部sram中,使用这样的语句:

OS_STK Stack1[STKSIZE] __at (Bank1_SRAM3_ADDR) ;

但是没有想到的是,在使用sdio方式操作sd卡时,总是出现SDIO_IT_TXUNDERR 中断。

没有好的解决办法,只能老老实实地把任务堆栈放入片内的sram。

想来,恐怕原因是系统在和SD卡交换数据时用到了任务堆栈区,而任务堆栈区所在的片外的sram速度不够快导致的问题。

虽然问题凑合解决了,但是问题仍然存在:

外部sram到底能怎么用? 如果外部sram能和片内的sram一样方便地使用就好了。

看到这篇博客的朋友,有没有什么好的解决办法?

8 闹钟中断的问题(RTCAlarm)

打算在standby模式下使用闹钟中断,但由于standby模式调试不方便 ,因此在正常运行状态下先测试闹钟中断。

没想到遇到了问题:

关掉了RTC_IRQHandler,只打开RTCAlarm_IRQHandler。但是依然能进入RTC_IRQHandler中断函数,但不是正常状态下的进,而是不停地进中断,

而且RTC_GetITStatus(RTC_IT_SEC)得到状态也确实不是秒中断发生。

同时,也会进RTCAlarm_IRQHandler中断,也不是正常状态下的进,而是不停地进中断,而且RTC_GetITStatus(RTC_IT_ALR)得到状态也确实不是闹钟中断发生。

最终找到了问题所在:

一定要在RTCAlarm_IRQHandler函数中有这句:EXTI_ClearITPendingBit(EXTI_Line17);

提醒:《stm32开发问题集锦》最后刷新时间 2024-03-14 00:57:35,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《stm32开发问题集锦》该内容的真实性请自行鉴别。