Chinaunix首页 | 论坛 | 博客
  • 博客访问: 957724
  • 博文数量: 173
  • 博客积分: 3436
  • 博客等级: 中校
  • 技术积分: 1886
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-07 09:29
文章分类

全部博文(173)

文章存档

2016年(6)

2015年(10)

2014年(14)

2013年(8)

2012年(36)

2011年(63)

2010年(19)

2009年(17)

分类: 嵌入式

2011-02-26 22:52:38

转载的人家用stm32f107的总结,感觉要比我弄的深入呀。。。

 

           第一次接触CORTEX-M3系列的东西,从入手到现在项目基本开发完成,总的感觉,这玩意儿还是挺好使的。性价比高,零售STMF101RBT6也就20左右,内置FLASH 128 KRAM 16K36M1.25 DMIPS/Hz,哈佛结构,三级流水线, PLL16个中断优先级最高支持16级嵌套,43个可屏蔽中断,324位通用定时器,一个时基定时器,带独立波特率发生器的两个串口,RTC,内部时钟,独立看门狗和窗口看门狗,GPIO可配,大量耐5VIO12ADC18M SPI,内部电压监控,时钟监控,怎么样,够使了吧?还不够?那就选F103吧,72MUSBCAN,高级定时器(给电机控制用),I2C,全整上,相当给力。

 

       在硬件开发上没花什么心思也没费什么劲。但是做嵌入式嘛,软硬件没法也不能分的太开,得综合考虑。笼统来说,值得注意的有这么几点:

 

1.      时钟。看懂下面这个图就了解时钟了。注意别以为F101支持36M就在外面接36M,外部晶体只能在4-16M之间,内部有PLL,外面当然不用接太高,高了难以控制EMC性能撒。我是接了个12M晶体,内部PLL3,便宜啊。另外注意读写FLASH的延迟周期,手册上说系统时钟0-24M等待周期为024-48M148-72M2,果断设为1

 

 

 

1 STMF10xx时钟系统框图

 

2.      复位。不能不说它的复位比较独特,如果没用电池供备份寄存器的话,只要复位,不管是内部复位源还是外部复位源,所有SRAM区全部清零,这一点和单片机是不太一样的。所以寄希望于内部看门狗复位后全局变量值保持不变是比较困难的。如果非要保持不变呢?困难是有,解决起来也是会者不难,赵MM教我的方法,是在TARGET设置里,在RAM区分配几个字节令其值不复位(noint),然后将要保持不变的全局变量放在这写RAM区里就OK了,注意这样做之后上电后这些全局变量的初值就有可能不再是0而是随机值了。

 

如果外边有几个复位源,得注意一下复位电路。我开始是将JLINK的复位和外部电压监控(老大说外面监控更可靠,就没用内部的了…)接与门后连到NRST管脚,这个对普通单片机没什么问题,但是对这玩意儿来说就不行,因为内部复位源复位后从下面的示意图来看,得把自己的NRST管脚拉低系统才能认为该复位了,若此时外部电压正常即给NRST的电平为高,那压降全部落在三极管上,system nreset读出来还是高,就复位不了了。解决办法是在与门和NRST间串个电阻,我用的4.7k,没什么问题,考虑到复位信号的质量,升级时改串了一个三态缓冲门1G07。另外外部复位时间最小为300ns,内部复位拉低2.5ms

 

 

 

                            2  STM32Fxxx的复位口

 

3.      资源的配置。资源配置如果参考固件库的话,相当傻瓜。注意的一是时钟,为了省功耗,STM32基于其时钟树开关每个“外设”(其实就是自己的资源,只不过集成进来了),如定时器或GPIO这些,操作它们时记得要打开它们的时钟先。我是在初始化RCC时把要用的一并打开,反正我的用了就不会关。二是要注意配置的先后顺序。有些东西是互相关联的,比如中断分组,不用前后重复配置造成无意间的覆盖。

 

4.      固件库的使用。固件库咋一看非常让人恼火,为了保证兼容性,那帮牛人写了N多结构体和函数,看得人头晕眼花云里雾里,对习惯操作寄存器的人来说,难以下咽,而且相当担心其执行效率。但是那多寄存器,若开发时间紧根本来不及细看。我不管三七二十八,先用库,把工程建好,写个测试程序找找成就感再说。正式敲代码时,强烈建议把每个要用的库函数都读懂。不然出了问题很难查出来。如设置串口波特率时死活不对,后来发现要修改rcc.cHSE_Value的值,默认8M,我的外部晶体是16M,当然不对撒。还有定时器和串口CLERA标志位的库函数,它的写法实际也有点问题,需要自己修改一下。

 

我先完全用库函数写了个初稿,然后对代码执行效率有要求如操作IO,中断函数等地方改为直接操作寄存器,同时避免自己定义的子函数体里去调用库函数,直接去库里把该库函数有用的几条语句拷过来即可,不然这进出函数也太多了….

 

总体来说,这个库函数还是相当好用的,虽然越用你最后直接调用库函数可能会越少,但是它函数体里的东西真的可以帮你省不少时间去挨个找寄存器。

 

5.      USART。串口用起来很简单,只有串口1可以进行ISP下载,注意的是其速度,对应F101而言两个串口速度一样,对于F103而言,因为挂在不同的总线上,串口1极限速度比串口2快一倍,个人认为这个设计比较二,速度快的不直接给用户而去给下载口。关于串口中断,有个问题是ORE即溢出中断,当开RXNE中断后这个中断就如影随形的跟着开了,要注意根据自己设计目的对其正确处理,当然它不出现最好,但是我这个程序里它会出现1次,怎么都消不了,我每次都及时读了哇,唉,再研究研究。

 

6.      定时器。定时器相当好使,注意一个问题,就是重启定时器时最好把当前计数值count0。另外SYSTEMTICK这个定时器也非常非常不错,用于精确延时很合适。注意一点是最好不要在中断和主函数里同时调用,因为如果在主函数里调用它时突然中断来了,中断又不幸也要调用它,这时候中断返回后计数寄存器VALUE值就成中断的那个值了,可能会导致一次定时不准。

 

7.      GPIO。这个比较狠,有很多配置方式可选,但是内部上拉一般在40K左右,有点弱了。可配置成各种方式的输入输出,也可配置成双向。作为双向口时要注意,在读口状态时要先写1,防止上次写0后现在读出来一直是0。另外很多管脚号称抗5v,还是串了个330Ω电阻,比较可靠,另外若是直接对外的IO口,也有防静电的作用。还有就是IO口的拉灌电流均为25mA,能力很强啊。而且此单片机功耗也比较低,全速跑最高444mW,我的板子上下拉N多,100mA吧,主要其实取决于外围的功耗,芯片本身功耗很低,若设了低功耗模式应该更低。

 

8.      SPI还没用,用了再总结。手册上说支持三线制,果断不用NSS,那头是X5045嘛,只能由这头作主了。

 

9.      调试和下载。要是IO实在不够用,那就用原始的ISP吧,JTAG省出来,用示波器调…够的话还是留出来,调试时相当爽。另外它还支持SW,所谓的两线制(JTAG5线制),其实也不占用太多资源。话说SWD模式很好用,速度很快,用JLINK正版V8测了一下,SW最高10MJTAG最高只能到3M

 

注意官方的那个ISP下载软件不太好使,正确配置了BOO0BOOT1,我的板子也老连不上,后来搞了个MCUISP.EXE,就好了哇。

 

比较2的设计是启动模式问题。BOOT1:BOOT0x0时从用户程序即FLASH启动;为01时从bootloader启动,用于串口下载;为11时从SRAM启动,应该是用于小规模代码的高速仿真。说它2的原因,是CPUReset后的第4个时钟周期就记住了BOOT1BOOT0的值,若为01即从bootloader启动,则只要没给他进行ISP串口下载,就一直死在那里等。唉,为什么没有个跳出机制去执行用户程序咧,像AT89C51P89V51等可都是这样的。

 

10.  代码效率和规模。这个就是就是优化的问题了,开始赵MM的代码编译出来规模比我小一半,那个寒。以为是我volatile加多了,仔细去了一些,还是这样。后来发现原来是堆栈设置和优化等级问题。目前1130日版堆和栈规模都已改为1k0x0400),改了RAM耗用明显变小,在stm32f10x_vector.sconfiguration wizard里就可以改。够用了。     

 

优化等级里赵勾选了microLIB,优化等级为3,最高级,勾选one ELF per function,瓦赛,够狠,难怪代码那么小。研究一番,发现还是不要勾选microLIB,与别的文件当然关联越小越好,优化等级我以前是0,难怪那么大,MDK默认是2,那就2吧,看帮助文档最多会带来一些debugcasm对不上的问题,因为asm是优化过的撒。one ELF per function大致的意思是链接时给每个用到的函数分配一个ELF,而不是C文件,这样很多库里没用的函数就不会占空间了,单独勾选这项,代码顿时小了5k作用,果断勾选之。代码效率的优化最好还是自改程序吧,当然也可以勾选那个optimize for time,但是作为开发人员,还是自己知道在哪里改比较好,不然源程序和实际优化过的很不一致, 出了问题查起来费劲啊。所谓的优化方法无非就是在实现同样目的的前提下减少循环次数,少做无用功。

阅读(9538) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~