用iar仿真stm32f103 iar例程时为什么没反应

[STM32例程分析]在main()之前,IAR都做了啥?
我的图书馆
[STM32例程分析]在main()之前,IAR都做了啥?
最近要在Cortex-M3上写一个简单的操作系统,打算使用IAR,为了写好启动代码,花了一些时间了解了IAR在main()以前做了些什么事。首先系统复位时,Cortex-M3从代码区偏移0x处获取栈顶地址,用来初始化MSP寄存器的值。接下来从代码区偏移0x获取第一个指令的跳转地址。这些地址,是CM3要求放置中断向量表的地方。这里是一个程序的启动区的反汇编:__vector_table:& 00 & & && 00 & & && E1D & & && 00 & &&这个程序是由IAP程序来启动的,IAP程序获取0x处的MSP值(0x),并设置为MSP的值,即主堆栈最大范围是0xx2000'25FF。接下来IAP程序获取0x处的Reset_Handler的地址(0xD),并跳转到Reset_Handler()执行。IAP在这里完全是模仿了Cortex-M3的复位序列,也就是说,在没有IAP的系统上,CM3只能从0x获取MSP,从0x获取第一条指令所处地址。而IAP就存在在0x这个地址上,IAP的启动,已经消耗掉了这个复位序列,所以IAP要启动UserApp程序的时候,也是完全模仿Cortex-M3的复位序列的。接下来我们看看复位后第一句指令——Reset_Handler()函数里有什么。若我们使用的是ST公司标准外设库,那么已经有了现成的Reset_Handler,不过他是弱定义——PUBWEAK,可以被我们重写的同名函数覆盖。一般来说,我们使用的都是ST提供的Reset_Handler,在V3.4版本的库中,可以在startup_stm32f10x_xx.s中找到这个函数:&& & & & PUBWEAK Reset_Handler& & & & SECTION .text:CODE:REORDER(2)Reset_Handler& & & & LDR & & R0, =SystemInit& & & & BLX & & R0& & & & LDR & & R0, =__iar_program_start& & & & BX & & &R0看来ST没有做太多的事,他只调用了自家库提供的SystemInit函数进行系统时钟、Flash读取的初始化,并把大权交给了__iar_program_start这个IAR提供的“内部函数”了,我们就跟紧这个__iar_program_start跳转,看看IAR做了什么,上面一段代码的反汇编如下:& & & &Reset_Handler:__iar_section$$root:& 08007E1C &4801 & & &LDR & & & & &R0, [PC, #0x4]; LDR & & R0, =SystemInit& 08007E1E &4780 & & &BLX & & & & &R0;BLX & & R0& 01 & & &LDR & & & & &R0, [PC, #0x4];LDR & & R0, =__iar_program_start& 00 & & &BX & & & & & R0;BX & & &R0& C69 & & && 00 & & && D8D & & && 08007E2A &0800 & &&细心的观众会发现地址是0xC,比我们查到的0xD差了1,这是ARM家族的遗留问题,因为ARM处理器的指令至少是半字对齐的(16位THUMB指令集 or 32位ARM指令集),所以PC指针的LSB是常为0的,为了充分利用寄存器,ARM公司给PC的LSB了一个重要的使命,那就是在执行分支跳转时,PC的LSB=1,表示使用THUMB模式,LSB=0,表示使用ARM模式,但在最新的Cortex-M3内核上,只使用了THUMB-2指令集挑大梁,所以这一位要常保持1,所以我们查到的地址是0xD(C=1100,D=1101),放心,我们的CM3内核会忽略掉LSB(除非为0,那么会引起一个fault),从而正确跳转到0xC。从0x处的加载指令,我们可以算出__iar_program_start所处的位置,就是当前PC指针(0x),再加上4,即0x处的所指向的地址——0xD(0xC),我们跟紧着跳转,__iar_program_start果然在这里:__iar_program_start:& 08007D8C &F000F88C &BL & & & & & __low_level_init& 00 & & &CMP & & & & &R0, #0x0& 08007D92 &D001 & & &BEQ & & & & &__iar_init$$done& 08007D94 &F7FFFFDE &BL & & & & & __iar_data_init2& 00 & & &MOVS & & & & R0, #0x0& 08007D9A &F7FDFC49 &BL & & & & & main我们看到IAR提供了__low_level_init这个函数进行了“底层”的初始化,进一步跟踪,我们可以查到__low_level_init这个函数做了些什么,不是不是我们想象中的不可告人。__low_level_init:& 001 & & &MOVS & & & & R0, #0x1& 08007EAA &4770 & & &BX & & & & & LR__low_level_init出乎想象的简单,只是往R0寄存器写入了1,就立即执行"BX LR"回到调用处了,接下来,__iar_program_start检查了R0是否为0,为0,则执行__iar_init$$done,若不是0,就执行__iar_data_init2。__iar_init$$done这个函数很简单,只有2句话,第一句是把R0清零,第二句就直接"BL main",跳转到main()函数了。不过既然__low_level_init已经往R0写入了1,那么我们还是得走下远路——看看__iar_data_init2做了些什么,虽然距离main只有一步之遥,不过这中间隐藏了编译器的思想,我们得耐心看下去。__iar_data_init2:& 08007D54 &B510 & & &PUSH & & & & {R4,LR}& 04 & & &LDR & & & & &R0, [PC, #0x10]& C04 & & &LDR & & & & &R4, [PC, #0x10]& 08007D5A &E002 & & &B & & & & & &0x8007D62& 08007D5C &F8501B04 &LDR & & & & &R1, [R0], #0x4& 88 & & &BLX & & & & &R1& A0 & & &CMP & & & & &R0, R4& 08007D64 &D1FA & & &BNE & & & & &0x8007D5C& 08007D66 &BD10 & & &POP & & & & &{R4,PC}& C78 & & && 08007D6A &0800 & & && 08007D6C &7C9C & &&& 08007D6E &0800 & &&看来IAR迟迟不执行main()函数,就是为了执行__iar_data_init2,我们来分析分析IAR都干了些什么坏事~首先压R4,LR入栈,然后加载0x至R0,0xC至R4,马上跳转到0x执行R0,R4的比较,结果若是相等,则弹出R4,PC,然后立即进入main()。不过IAR请君入瓮是自不会那么快放我们出来的——结果不相等,跳转到0xC执行,在这里,把R0指向的地址——0x中的值——0x加载到R1,并且R0中的值自加4,更新为0xC,并跳转到R1指向的地址处执行,这里是另一个IAR函数:__iar_zero_init2:__iar_zero_init2:& 00 & & &MOVS & & & & R3, #0x0& 08007D72 &E005 & & &B & & & & & &0x8007D80& 08007D74 &F8501B04 &LDR & & & & &R1, [R0], #0x4& 08007D78 &F8413B04 &STR & & & & &R3, [R1], #0x4& 08007D7C &1F12 & & &SUBS & & & & R2, R2, #0x4& 08007D7E &D1FB & & &BNE & & & & &0x8007D78& 08007D80 &F8502B04 &LDR & & & & &R2, [R0], #0x4& A00 & & &CMP & & & & &R2, #0x0& 08007D86 &D1F5 & & &BNE & & & & &0x8007D74& 70 & & &BX & & & & & LR& 08007D8A &0000 & & &MOVS & & & & R0, R0__iar_data_init2还没执行完毕,就跳转到了这个__iar_zero_inti2,且看我们慢慢分析这个帮凶——__iar_zero_inti2做了什么。__iar_zero_inti2将R3寄存器清零,立即跳转到0x执行'LDR & & & & &R2, [R0], #0x4',这句指令与刚才在__iar_data_init2见到的'LDR & & & & &R1, [R0], #0x4'很类似,都为“后索引”。这回,将R0指向的地址——0xC中的值——0x加载到R2寄存器,然后R0中的值自加4,更新为0x。接下来的指令检查了R2是否为0,显然这个函数没那么简单想放我我们,R2的值为2F4,我们又被带到了0x处,随后4条指令做了如下的事情:1、将R0指向的地址——0x中的值——0x加载到R1寄存器,然后R0中的值自加4,更新为0x。2、将R1指向的地址——0x中的值——改写为R3寄存器的值——0,然后R1中的值自加4,更新为0x。3、R2自减44、检查R2是否为0,不为0,跳转到第二条执行。不为,则执行下一条。这简直就是一个循环!——C语言的循环for(r2=0x2F4;r2-=4;r!=0){...},我们看看循环中做了什么。第一条指令把一个地址加载到了R1——0x 是一个RAM地址,以这个为起点,在循环中,对长度为2F4的RAM空间进行了清零的操作。那为什么IAR要做这个事情呢?消除什么记录么?用Jlink查看这片内存区域,可以发现这片区域是我们定义的全局变量的所在地。也就是说,IAR在每次系统复位后,都会自动将我们定义的全局变量清零0。清零完毕后,接下来的指令"LDR & & & & &R2, [R0], #0x4"将R0指向的地址——0x中的值——0加载到R2寄存器,然后R0中的值自加4,更新为0x。随后检查R2是否为0,这里R2为0,执行'BX LR'返回到__iar_data_init2函数,若是不为0,我们可以发现又会跳转至“4指令”处进行一个循环清零的操作。读到这里,我们应该可以猜到IAR的意图了:__iar_data_init2一开始加载了0x至R0,0xC至R4,[R0,R4]就是一段启动代码区,在这个区域内保存了要“处理”的所有地址与信息——执行的函数地址或者参数,实际上,这片区域也有一个名字,叫做:Region$$Table$$。在这个区域内,程序以R0为索引,R4为上限,当R0=R4,__iar_data_init2执行完毕,跳转至main()函数。好了,保持我们这个猜想,继续跟踪我们的PC指针——我们回到了__iar_data_init2函数中,第一件事就是比较R0,R4的值,可惜的是,仍然不相等,我们又被带到了0xC,至此,我们应该能看出这是一个__iar_data_init2的“主循环”,这也验证了我们对IAR意图的猜想~& __iar_data_init2中的“主循环”:& 08007D5C &F8501B04 &LDR & & & & &R1, [R0], #0x4& 88 & & &BLX & & & & &R1& A0 & & &CMP & & & & &R0, R4我们可以等价写为:for(r0=0x,r4=0xC;r0!=r4;r0+=4){...}此时,我们的R0为0x,经过“指令1”,R0变为0xC,R1为0x。我们来看看,7C55处,IAR又要执行何种操作。__iar_copy_init2:& 08007C54 &B418 & & &PUSH & & & & {R3,R4}& 08007C56 &E009 & & &B & & & & & &0x8007C6C& 08007C58 &F8501B04 &LDR & & & & &R1, [R0], #0x4& 08007C5C &F8502B04 &LDR & & & & &R2, [R0], #0x4& 08007C60 &F8514B04 &LDR & & & & &R4, [R1], #0x4& 08007C64 &F8424B04 &STR & & & & &R4, [R2], #0x4& F1B & & &SUBS & & & & R3, R3, #0x4& 08007C6A &D1F9 & & &BNE & & & & &0x8007C60& 08007C6C &F8503B04 &LDR & & & & &R3, [R0], #0x4& B00 & & &CMP & & & & &R3, #0x0& 08007C72 &D1F1 & & &BNE & & & & &0x8007C58& 08007C74 &BC12 & & &POP & & & & &{R1,R4}& 70 & & &BX & & & & & LR这是一个名为__iar_copy_init2的函数,他执行了什么"copy"操作呢?首先压R3,R4入栈,然后跳转到0xC,从R0——Region$$Table$$Base中取出参数0x238放入R3,接下来的指令大家应该都熟悉了,0x238不为0,所以我们被带至7C58处,再次从Region$$Table$$Base中取出参数0x放入R1,从Region$$Table$$Base取出参数0x放入R2处。细心的观众应该能察觉这和__iar_zero_init2中取参数的几乎一样:先取出大小,随后取出了地址——只不过这里多出了1个地址,没错这就是"copy",随后的指令& 08007C60 &F8514B04 &LDR & & & & &R4, [R1], #0x4& 08007C64 &F8424B04 &STR & & & & &R4, [R2], #0x4& F1B & & &SUBS & & & & R3, R3, #0x4& 08007C6A &D1F9 & & &BNE & & & & &0x8007C60则是另一个“4指令”,指令1将R1指向地址的数据读到R4,指令2将R2指向地址的数据改写为R4的数据,指令3、4是完成一个循环。说到这里大家都应该明白了——这就是一个"copy"的操作,从Flash地址0x起,将长度0x238的数据拷贝到RAM地址0x中。通过Jlink,我们可以看到这片区域是我们定义的并且已初始化的全局变量。也就是说,每次复位后,IAR在此处进行全局变量的初始化。在这“4指令”执行完毕后,再次从Region$$Table$$Base中取出参数,为0,比较之后条件符合,函数返回__iar_data_init2。此时的R0已经为0xC与R4相等,__iar_data_init2终于完成它的使命。& 00 & & &MOVS & & & & R0, #0x0& 08007D9A &F7FDFC49 &BL & & & & & main将R0清零以后,IAR放弃主动权,把PC指针交给了用户程序的入口——main()。但请注意,这里使用的是BL指令进行main跳转,也就是说,main函数只是IAR手中的一个子程序,若是main函数执行到了结尾,接下来则会执行exit等IAR提供的“退出”函数。这些函数,等待下回分解~总之,IAR在启动main()函数以前,执行了Reset_Handler,调用SystemInit()(ST库提供)进行时钟,Flash读取初始化,并转入__iar_program_start中执行__low_level_init与__iar_data_init2,并在__iar_data_init2中,先后调用__iar_zero_init2与__iar_copy_init2对全局变量、全局已初始化变量进行相应的初始化操作。最后,调用main()函数执行。这就是IAR在启动main()函数之前做的事情,它并没有那么神秘,只要花些时间,就可以跟跟踪分析出这个过程。若是有帮助,留个言支持下,我会继续写一些个人的经验与大家分享~欢迎留言交流问题与经验~若是有错误,还请指正!
发表评论:
TA的最新馆藏[转]&[转]&[转]&[转]&[转]&[转]&21ic官方微信-->
后使用快捷导航没有帐号?
查看: 10277|回复: 27
请问mdk和IAR哪个用来开发STM32比较好啊!
&&已结帖(5)
主题帖子积分
资深技术员, 积分 410, 距离下一级还需 90 积分
资深技术员, 积分 410, 距离下一级还需 90 积分
主题帖子积分
专家等级:结帖率:45%
主题帖子积分
资深技术员, 积分 410, 距离下一级还需 90 积分
资深技术员, 积分 410, 距离下一级还需 90 积分
本帖最后由 枫叶gbwz 于
17:31 编辑
请问mdk和IAR哪个用来开发STM32比较好啊!
最近学习STM32 ,主要是用mdk来开发的。但是学长说用IAR比较好,我想听听大家的意见和看法,请大家直言,我在这里不是一味的想知道那个好,也是想通过高手对不同开发工具的分析来知道自己的着眼点应该放在哪里
满意回复+3
这两个我都用过,除了iar得编译速度比mdk快些(程序越大越明显)。这个是最明显的区别,剩下的基本没啥差距。那些从51转过来的新手建议用mdk,用一阵子之后熟练 ...
我两个都用过,感觉MDK的模拟仿真更直观一些,IAR的编辑器比MDK做的好,尤其是中文字符的处理
主题帖子积分
主题帖子积分
专家等级:结帖率:33%打赏:0.00受赏:9.00
主题帖子积分
奔驰车和宝马车哪个好呢?
道理一样,适合自己的最好。
I do not teach, but I coach. I do not feed, but I seed.
欢迎访问我的博客:/BLOG_OWNER_199055.HTM
主题帖子积分
资深技术员, 积分 410, 距离下一级还需 90 积分
资深技术员, 积分 410, 距离下一级还需 90 积分
主题帖子积分
专家等级:结帖率:45%
主题帖子积分
资深技术员, 积分 410, 距离下一级还需 90 积分
资深技术员, 积分 410, 距离下一级还需 90 积分
香水城 但事物各有利弊,每种开发工具都有自己的优势和特点,我在这里不是一味的想知道那个好,也是想通过高手对不同开发工具的分析来知道自己的着眼点应该放在那里,只有通过分析,我以后再去选择软件的时候才会更有主见啊,是吧。
也许宝马再好,我还是会开自己的小熊猫,但是我想知道他好在哪里。
主题帖子积分
实习生, 积分 36, 距离下一级还需 14 积分
实习生, 积分 36, 距离下一级还需 14 积分
主题帖子积分
专家等级:结帖率:0%
主题帖子积分
实习生, 积分 36, 距离下一级还需 14 积分
实习生, 积分 36, 距离下一级还需 14 积分
mdk好吧?它是keil ,给arm公司收购了...
主题帖子积分
高级技术员, 积分 528, 距离下一级还需 472 积分
高级技术员, 积分 528, 距离下一级还需 472 积分
主题帖子积分
专家等级:结帖率:0%
主题帖子积分
高级技术员, 积分 528, 距离下一级还需 472 积分
高级技术员, 积分 528, 距离下一级还需 472 积分
比较习惯 IAR。
入门玩单片机C++
主题帖子积分
高级工程师, 积分 7150, 距离下一级还需 850 积分
高级工程师, 积分 7150, 距离下一级还需 850 积分
主题帖子积分
专家等级:结帖率:13%
主题帖子积分
高级工程师, 积分 7150, 距离下一级还需 850 积分
高级工程师, 积分 7150, 距离下一级还需 850 积分
都可以,适合自己就好
主题帖子积分
资深工程师, 积分 10265, 距离下一级还需 9735 积分
资深工程师, 积分 10265, 距离下一级还需 9735 积分
主题帖子积分
专家等级:结帖率:0%
主题帖子积分
资深工程师, 积分 10265, 距离下一级还需 9735 积分
资深工程师, 积分 10265, 距离下一级还需 9735 积分
已经习惯用IAR开发了
主题帖子积分
中级工程师, 积分 4393, 距离下一级还需 607 积分
中级工程师, 积分 4393, 距离下一级还需 607 积分
主题帖子积分
专家等级:结帖率:38%打赏:0.00受赏:1.00
主题帖子积分
中级工程师, 积分 4393, 距离下一级还需 607 积分
中级工程师, 积分 4393, 距离下一级还需 607 积分
都装就知道还是IAR好。
上联:subway railway highway,way way to die
下联:investigator officer announcer,sir sir to lie
横批:welcome to china
主题帖子积分
技术达人, 积分 9594, 距离下一级还需 406 积分
技术达人, 积分 9594, 距离下一级还需 406 积分
主题帖子积分
专家等级:结帖率:5%
主题帖子积分
技术达人, 积分 9594, 距离下一级还需 406 积分
技术达人, 积分 9594, 距离下一级还需 406 积分
主题帖子积分
高级工程师, 积分 7076, 距离下一级还需 924 积分
高级工程师, 积分 7076, 距离下一级还需 924 积分
主题帖子积分
专家等级:结帖率:23%
主题帖子积分
高级工程师, 积分 7076, 距离下一级还需 924 积分
高级工程师, 积分 7076, 距离下一级还需 924 积分
用IAR吧,遇到问题还可以问问学长
主题帖子积分
技术达人, 积分 8545, 距离下一级还需 1455 积分
技术达人, 积分 8545, 距离下一级还需 1455 积分
主题帖子积分
专家等级:结帖率:64%
主题帖子积分
技术达人, 积分 8545, 距离下一级还需 1455 积分
技术达人, 积分 8545, 距离下一级还需 1455 积分
这两个我都用过,除了iar得编译速度比mdk快些(程序越大越明显)。这个是最明显的区别,剩下的基本没啥差距。那些从51转过来的新手建议用mdk,用一阵子之后熟练了再用iar.
主题帖子积分
主题帖子积分
专家等级:结帖率:33%打赏:0.00受赏:9.00
主题帖子积分
一个萝卜,一个白菜
主题帖子积分
资深工程师, 积分 11952, 距离下一级还需 8048 积分
资深工程师, 积分 11952, 距离下一级还需 8048 积分
主题帖子积分
专家等级:结帖率:89%
主题帖子积分
资深工程师, 积分 11952, 距离下一级还需 8048 积分
资深工程师, 积分 11952, 距离下一级还需 8048 积分
性能还是IAR好些,喜欢用哪个好那是萝卜白菜看个人所爱了.
是不是经济不KUA,房价下不来?
高房价只能带来“实体经济挤出效应”。
主题帖子积分
高级工程师, 积分 6495, 距离下一级还需 1505 积分
高级工程师, 积分 6495, 距离下一级还需 1505 积分
主题帖子积分
专家等级:结帖率:95%
主题帖子积分
高级工程师, 积分 6495, 距离下一级还需 1505 积分
高级工程师, 积分 6495, 距离下一级还需 1505 积分
我两个都用过,感觉MDK的模拟仿真更直观一些,IAR的编辑器比MDK做的好,尤其是中文字符的处理
主题帖子积分
高级技术员, 积分 841, 距离下一级还需 159 积分
高级技术员, 积分 841, 距离下一级还需 159 积分
主题帖子积分
专家等级:结帖率:72%
主题帖子积分
高级技术员, 积分 841, 距离下一级还需 159 积分
高级技术员, 积分 841, 距离下一级还需 159 积分
IAR 有个可以仿真UCOS II的模块
主题帖子积分
高级技术员, 积分 841, 距离下一级还需 159 积分
高级技术员, 积分 841, 距离下一级还需 159 积分
主题帖子积分
专家等级:结帖率:72%
主题帖子积分
高级技术员, 积分 841, 距离下一级还需 159 积分
高级技术员, 积分 841, 距离下一级还需 159 积分
LZ你先下个MDK把STM32用的差不多之后再下个IAR用个几天,到时你再看呗。
主题帖子积分
初级技术员, 积分 87, 距离下一级还需 13 积分
初级技术员, 积分 87, 距离下一级还需 13 积分
主题帖子积分
专家等级:结帖率:0%
主题帖子积分
初级技术员, 积分 87, 距离下一级还需 13 积分
初级技术员, 积分 87, 距离下一级还需 13 积分
我觉得用啥都行, 对初学者来说, 关键是编辑环境, stm32的库挺复杂的, 好的编辑环境会使入门更快; 至于编译速度,代码优化,产生的文件的大小等可不用在意; 我推荐CoIDE+GCC, 编辑环境很好, 调试不如Keil.
主题帖子积分
主题帖子积分
专家等级:结帖率:85%
主题帖子积分
提示: 作者被禁止或删除 内容自动屏蔽
主题帖子积分
助理工程师, 积分 1382, 距离下一级还需 618 积分
助理工程师, 积分 1382, 距离下一级还需 618 积分
主题帖子积分
专家等级:结帖率:80%
主题帖子积分
助理工程师, 积分 1382, 距离下一级还需 618 积分
助理工程师, 积分 1382, 距离下一级还需 618 积分
如果你现在是初学者,那就跟着大家用。。。
你周围最历害的那个人或是肯教你的那个人用什么,你就用什么?
事情就这么简单。。
主题帖子积分
高级工程师, 积分 7421, 距离下一级还需 579 积分
高级工程师, 积分 7421, 距离下一级还需 579 积分
主题帖子积分
专家等级:结帖率:88%
主题帖子积分
高级工程师, 积分 7421, 距离下一级还需 579 积分
高级工程师, 积分 7421, 距离下一级还需 579 积分
你旁边的人用什么你就用什么,就这么简单,你第一个用的话,你想用那个就用哪个,有犹豫的时间,换一个新的也该入门了。
时间类勋章
技术奇才奖章
人才类勋章
涓涓之细流
发帖类勋章
荣誉元老奖章
等级类勋章
坚毅之洋流
发帖类勋章
时间类勋章
技术领袖奖章
人才类勋章
技术导师奖章
人才类勋章
突出贡献奖章
等级类勋章
沉静之湖泊
发帖类勋章
精英会员奖章
等级类勋章
奔腾之江水
发帖类勋章
核心会员奖章
等级类勋章
时间类勋章
无冕之王奖章
等级类勋章
欢快之小溪
发帖类勋章
时间类勋章
甘甜之泉水
发帖类勋章
社区建设奖章
等级类勋章2108人阅读
分享(216)
单片机(79)
一开始建立了工程,然后程序下载都很正常。不知道什么情况自己下载代码之后,再重新下载代码无法成功。
我按照提示找了一下FlashStm32f30x8.flash这个文件,却发现IAR的目录下没并没有。又怀疑是IAR文件丢失。
重新安装IAR,却发现问题仍然继续. & ~~~~感觉像是芯片坏了~~~
于是通过STVP工具,读取一下。 奇迹发生了,竟然可以读取程序。 &嗯~~那可以排除芯片的问题。
好吧,那我重新用IAR下载应该可以吧。 &于是重新下载程序, 晕~~~居然还是弹出那个错误。
难道自己的程序竟然会引起这样的错误???
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
于是通过STVP将FLASH全部清空,再用IAR下载调试。嗯~~~成功了....
既然成功了,那就用F5全速跑一下吧。 &晕,程序跑飞了。。。。。。。。。。
此时,我再用IAR下载时候,发现又弹出刚开始的错误了。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
再通过STVP将FLASH全部清空,再用IAR下载调试,一步一步调试。发现程序跑到ST官方的库文件里面就出不来了。
继续跟踪,原来库在GPIO_OType参数的时候,没有判断值,直接就赋值给变量了.
我的代码中确实没有对GPIO_OType变量进行赋值,因为感觉该口作用串口的输入输出应该不需要赋值.
后面对该值赋值后,问题再也没有重现了.
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9,GPIO_AF_7);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10,GPIO_AF_7);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_Init(GPIOA,&GPIO_InitStructure);
看来库,还是得小心使用,否则出问题的时候.查死你啦~~~
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:629859次
积分:7727
积分:7727
排名:第2070名
原创:235篇
转载:137篇
评论:153条
(2)(2)(2)(4)(4)(1)(1)(8)(6)(2)(6)(3)(12)(3)(3)(8)(8)(12)(15)(5)(8)(2)(7)(14)(28)(9)(14)(6)(4)(6)(3)(15)(2)(1)(3)(1)(2)(1)(1)(1)(3)(2)(7)(30)(18)(23)(26)(20)(10)}

我要回帖

更多关于 iar stm32工程模板 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信