VI已告一段落,RM905的问题也解决了,这周开始学习EK-STM32F的开发板,从零开始。以前没玩过这板子,手上除了这块开发板和一张ST官方的光盘外,别无资源,连标配的串口线和USB线都没,真得从零开始!
先熟悉一下开发板的硬件,它的MCU是ST公司的STM32F103VB,核心属于ARM Coretex M3系列,板载了ULINK-II仿真器,外围接口也很丰富,包括两个串口、CAN口、LCD、SD、USB等,板子做得很不错,据说促销时才卖199RMB,相当超值。
由于标配的资源都没了,所以先在网上一阵狂搜,包括开发环境、开发板原理图和配套演示程序、芯片的Datasheet等,基本上想要的都载到了。
先说开发环境的安装。我先后安装了RVMDK、IAR5.2,但发现这两款IDE都不支持板载的仿真器,最后安装IAR4.42的版本,据说它能支持EK-STM32F板载的仿真器,事实证明,确实如此。安装IAR时碰到如下几个问题:
1. 安装文件解压缩时,提示C盘空间不足,事实上C盘还有nG可用空间。原因是系统的环境变量设置有问题,我将TMP目录设置到D盘了,改回C盘就没问题。
2. 安装IAR4.42,使用Keygen时须要注意,输入的十六进制的ID号必须大写,开始我没注意,用小写生成了一堆KEY,试了N个后,终于安装通过,结果编译时提示Licence有问题。Licence Manager也不管用,后来卸了重装,用大写的ID号生成的KEY,就没有问题了。
开发环境的熟悉,比较顺利。与ADS不同的是,IAR在设置中,需要选择MCU类型,
IAR无须在IDE中设置RO Base、RW Base等信息,它用xcf配置文件完成这些配置。
支持板载仿真器的配置,也比较简单,具体设置如下图所示,首先在Debugger中选择第三方驱动,
然后在第三方驱动中,选择STM32的驱动程序,
1 void ScrollString(char *str);
2 void ScrollString(char *str)
3 {
4 int i = 4;
5 int dir = 0;
6
7 while(*str++)
8 {
9 write_string(str);
10 delay();
11
12 if(!dir)
13 {
14 GPIO_SetBits(GPIOC, 1<<i++);
15 if(i==8)
16 dir = 1;
17 }
18 else
19 {
20 GPIO_ResetBits(GPIOC, 1<<i--);
21 if(i==3)
22 dir = 0;
23 }
24 }
25 }
26
开发环境配置完成后,运行了万利提供的几个Sample,LCD、ADC和USART的。LCD、ADC运行没有问题,USART始终没过。折腾了半天,最后也没弄明白。原理图上使用的是PD5、6,但MCU 的Datasheet中PD5、6并不用作USART,难道是用GPIO模拟?但从代码中看起来,它就是把PD5、6当作USART2来用的。
简单说一下这几个Sample,LCD代码中原来的显示部分有点怪,修改如下:
Code
1 void ScrollString(char *str);
2 void ScrollString(char *str)
3 {
4 int i = 4;
5 int dir = 0;
6
7 while(*str++)
8 {
9 write_string(str);
10 delay();
11
12 if(!dir)
13 {
14 GPIO_SetBits(GPIOC, 1<<i++);
15 if(i==8)
16 dir = 1;
17 }
18 else
19 {
20 GPIO_ResetBits(GPIOC, 1<<i--);
21 if(i==3)
22 dir = 0;
23 }
24 }
25 }
26
ring(char *str);
2 void ScrollString(char *str)
3 {
4 int i = 4;
5 int dir = 0;
6
7 while(*str++)
8 {
9 write_string(str);
10 delay();
11
12 if(!dir)
13 {
14 GPIO_SetBits(GPIOC, 1<<i++);
15 if(i==8)
16 dir = 1;
17 }
18 else
19 {
20 GPIO_ResetBits(GPIOC, 1<<i--);
21 if(i==3)
22 dir = 0;
23 }
24 }
25 }
26 主函数中调用如下:
Code
1 while(1)
2 {
3 ScrollString("EK-STM32F HELLO WORLD 2008-11-11");
4 }
5
ADC的Sample中,也对显示做了修改,并且增加了ADC Value对LED的控制,代码如下:
Code
1 sprintf(display,"%04X",value);
2 write_string(display);
3 delay();
4
5 i = value/0x300;
6 i = 1<<i;
7 i--;
8 i = i<<4;
9 GPIO_SetBits(GPIOC,i);
10 GPIO_ResetBits(GPIOC,~i);
11
USART的实验没有跑通,后来修改成UART0和PC串口通信,实现回发接收到的数据。需要注意的是UASRT的配置,如果数据位配置成9位,板子发送没有问题,但接收会乱码,数据位配置成8位,收发正常。另外,万利的UART0和PC的串口使用两头孔的交叉线相连,因为我没有标配的线,先用示波器测UART0,确定3引脚为TXD,然后用3根串口线接成了一个两头孔的交叉线,测试通过。
开发环境基本了解了,接下来认识一下Coretex M3和STM32F103VB。先说STM32F103VB吧,因为没太多好说的,MCU的Datasheet中先说指标很强,然后就介绍产品的电气特性,基本没有关于寄存器的介绍,不像2410和270的文档讲的很仔细。整篇文档中,一张memory map的图应该是最有用的。当然,ST提供了另外的文档和Sample,说明如何使用各硬件。FirmwareLib基本涵盖了所有硬件的代码封装,方便应用程序的开发人员使用。
下面介绍一下Coretex M3。Coretex M3,很好,很先进。它是ARMv7的架构,注意,不是ARM7!ARM7是ARMv4的内核,S3C2410和PXA270等也都属于ARMv4的ARM9。Coretex是ARM公司继ARM11之后推出的最新的ARM内核,只不过没叫ARM12而已。
Coretex M3性能强劲。这一点应该得益于它全新的指令集。Coretex摒弃了ARM+THUMB指令集结构,而采用了THUMB2指令集。只有放下包袱,才能走的更远。采用新的指令集提高了代码密度,增加了性能,也无须象ARMv4中需要处理ARM和Thumb之间的切换。
Coretex M3实时性好。这一点应该得益于它新的中断处理机制。Coretex M3中不再有FIQ,它采用了超多的可嵌套的IRQ。中断控制器在内核层面上,比传统芯片级的中断控制器更先进。
Coretex M3使用方便。虽然它采用了全新的指令集,但对于应用程序开发人员来说,并没有增加工作量,用新的编译器即可。开发方式也跟传统的单片机并无太大区别。Coretex M3就是一个具有ARM内核的32位单片机,并且它在内核中加入了Debug的支持。
Coretex M3价格便宜。这是它最大的利好。现在金融危机闹这么凶,极具性价比的的往往比较抢手。也许过两年,单片机市场将由它来主宰。价格上,它比8位、16位的单片机贵不了多少,但接口丰富,性能强劲,在很多场合比16位的单片机有更好的表现。
更详细的资料,请到这里下载权威文档。
学习一个新的处理器,主要得学习它的指令集、内存管理、中断管理。汇编指令在应用开发中用的较少,一般用时再查。当然精通汇编代码对于嵌入式系统的开发大有裨益。
32位的特性,使Coretex M3支持4GB的存储空间,而内存空间的分配,内核本身做了一些约束,芯片厂商在此基础上做自己的设计。
Coretex M3的中断管理,采用了Nest Vector Interrupt Control,NVIC是在内核层面上的,比传统的中断控制器要高级。它也有一张中断向量表,发生中断后,会通过查表执行相应的处理。
Coretex除了M3的版本外,还有两款针对不同应用的版本:R4、A8。R4的实时性更好,A8中包括了MMU,针对应用市场。
学习Coretex M3的主要目的是想把它应用在GPS Tracker上,所以为它移植一个uC/OS-II很有必要。到Micrium官网载了一个跟EK-STM32F开发版最相似的uC/OS-II 2.86版,准备移植。这种移植,跟WinCE的移植大同小异,先跑内核,这一块基本无须修改代码,内核跑起来,再调试外围器件,针对开发板硬件修改相关代码即可。想得很美,但一入手却发现了问题,原来最新版的uC/OS-II使用的IDE是IAR5.x,IAR4.x无法打开高版本的工程。受仿真器的牵制,没别的办法,硬着头皮,从高版本往低版本改。IAR5.x的帮助中,有一篇专门讲如何从4.x移植到5.x的方法,详细看了一下,基本确定逆向移植是可实施的。IAR5.x和IAR4.x的最大区别在于Linker,Linker配置文件也由xcf变成icf。要做退化,先改这两处。
用IAR4.42新建了一个工程,将相关的文件都添加进来,不相关的代码删掉或注释掉,配置工程设置,编译,N个Error逐一修改,最主要的修改代码如下:
Code
1 //++added by hjb
2 #pragma location = "INTVEC"
3 //--added by hjb
4
5 //++changed by hjb
6 //__root const APP_INTVECT_ELEM __vector_table[] @ ".intvec" = {
7 __root const APP_INTVECT_ELEM AppVectTbl[] = {
8 //--changed by hjb
9 { .Ptr = (void *)__sfe( "CSTACK" )},/*0, SP start value. */
10 //++changed by hjb
11 // __iar_program_start, /* 1, PC start value.*/
12 __program_start,
13 //--changed by hjb
14
这段代码是IAR5.x和4.x的主要区别处。解决掉所有的Error后,下载到板上,只见两个LED一闪一闪的,难道就这么跑通了?比移植WinCE简单不少啊!
改造LED的控制,标准版和EK-STM32F板用的IO不一样;添加EK板的LCD显示,创建一个任务用于循环显示信息;在BSP中添加了USART的处理,并创建一个任务实现回发接收到的数据;添加对外部中断的处理,标准版的BSP没有操作外部中断示例,但对中断的封装很好,比以前2410上的uC/OS-II强很多,感觉有点象WinCE的中断管理结构。简单描述一下uC/OS-II的中断工作方式,首先它也有一个中断向量表,存储各中断处理函数。初始化中断向量表的时,所有中断的ISR都使用BSP_IntHandlerDummy()。实现自己的中断ISR后,可以通过BSP_IntVectSet()完成中断ISR注册。理清这个关系后,开始写代码。在GPIO的配置中加入中断引脚的配置,使用NVIC函数配置外部中断的工作方式,并注册中断服务程序,在自己的ISR中清除中断标志位。下载Debug,工作得相当好。实验效果:按下KEY2、KEY后,LCD上会有显示,提示按键信息,并控制4个LED的亮灭。
IAR在线调试的界面如下,
EK-STM32F的入门就到这里,板上还有很多好玩的东西,如JoyStick、SD卡、USB等等,以后有时间再慢慢学习。就目前的应用需求来看,实现两个串口通讯、外部中断的控制就差不多了,GPS Tracker的核心也就是接收GPS、GSM信息,解析处理。
最后,再次感谢那些无私奉献的同志,你们的分享让我这样的入门者少走了很多弯路。这里,我也分享一下自己的经验——众人拾柴,火焰高。刚入门,难免有失当的地方,敬请指正。
EK-STM32F学习资料的下载地址:http://download.csdn.net/source/779687,里面包括IAR4.42的KeyGen、uC/OS-II 2.86版(基于IAR4.42移植)和经过改造的一些演示程序。