这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » BRUCEG ARM-DIY进程贴(串口控制LED)

共54条 3/6 1 2 3 4 5 6 跳转至
工程师
2012-03-31 10:39:35     打赏
21楼
楼主的帖子得跟踪了 有想法、、、

工程师
2012-03-31 10:47:11     打赏
22楼
楼层链接的问题,昨晚上刚尝试明白。
举个例子,比如回帖在3楼 第一步:那么点三楼内容进入编辑状态,然后在开头(或者任意位置)点击“插入/编辑锚点链接”→给锚点取个名称,比如3,然后发表;
第二步:在一楼进入编辑状态,选中你要链接到3楼的文字,点击“插入/编辑超链接”,弹出对话框,在“地址”下文本框中输入“#3”,确定,发表;
就OK了,不知说的明不明白。

菜鸟
2012-03-31 11:04:56     打赏
23楼

非常感谢,好了,能解决了


高工
2012-03-31 11:08:16     打赏
24楼


菜鸟
2012-03-31 12:24:25     打赏
25楼

STM32 的延时:
在51的时期,我们习惯用循环来做延时这个事情,比较才12M的晶振,指令周期再12分 也就1M,循环个数百次到千次。
但STM32F103 的工作频率是比较高的,建议最高频率达72MHz,当然最高肯定不只72MHz(后面开专题研究超频),而且有些单条指令只占2~3 个时钟周期,速度奇快。
当然我也用循环来做延时8调 delay(1000),里面的K值还贼大,这才出了个有点像1S 的延时。坑爹吧!
死磕的童鞋肯定磕不出什么好办法,作为一届网民,我们还是有利器的,谷歌、度娘。“STM32 延时” 然后新关键词就出现了Systick。多余的我不说了,我不是做教程的也没必要。作为一名工程师要学会的就是自己解决问题,问回来的答案永远不是自己的。

systick 寄存器作用如下


CTRL寄存器中 有CLKSOURCE这么一控制位,控制的是使用内部时钟或是外部时钟,当初我以为的是使用片外晶振和片内晶振这么一个控制,后来迷惑了,翻看了数遍stm32的时钟关系,发现原来并非这么回事,M3 是STM32的一个内核,时钟控制外设,整片上系统的时钟好比树的主干,而外设是挂在主干上面的各个分支,同样M3 也是,M3使用的是系统主干的系统时钟。而systick 可以有两个时钟一个是和M3 同一个也就是所谓的内部时钟,另一个是系统主干时钟8分频后的外部输入时钟。这也好理解了网上众多教程中所说的要除8的原因。
——————————————————————————————————————

什么??你说你参考网上的教程例子 那个systick 库的程序编译好多错误?当然如果你有一份中文版的STM32 固件库使用手册对照了数百遍也还是没发现那里写错吧。我可以回答你,大哥你真的一句代码都没写错。原因在于你使用的是3.0后的固件库!在网上很多教程中都是写得一个死样的(这里我怀疑曾经有一个高手做出了好的教程,然后后面无数模仿的商家,真实一直被模仿从未被超越。),都是3.0之前的固件库。新的固件库对于systick 有了一个很大的改动。管网中有一份2.0 到3.0固件库升级的说明文档
2.0与3.0固件库对比.pdf
在新固件库下也有一个文档"stm32f10x_stdperiph_lib_um", 搜systick 也可以找到相关的用法,库中给出调用的函数是
if (SysTick_Config (SystemCoreClock / 1000))  ; { /* Setup SysTick for 1 msec interrupts */
 while (1);
  }

所以延时1ms 我们使用方法是
  if (SysTick_Config (SystemCoreClock / 1000))
  {  while (1); }                 //1ms 的延时计数
  TimeCount=nCount;      // 时间累加
  while(TimeCount);
  SysTick->CTRL=0x00;  // 关闭计数器
  SysTick->VAL =0X00;   // 清除计数器
另外我们只要在中断函数中加入
void SysTick_Handler(void)
{    TimeCount--; }
延时1S  就是TimeCount=1000,1000个1ms就行了
1ns 的延时就写成 if (SysTick_Config (SystemCoreClock / 1000000)) 
让倒数值再减少3个0就行了
——————————————————————————————————————
纠结这个库是如何实现的呢,继续近一步分析库函数:
(先去打个水喝)


菜鸟
2012-03-31 13:09:34     打赏
26楼

学到东西了,多谢赐教!


助工
2012-03-31 15:46:53     打赏
27楼
学习了,不错的文章。

高工
2012-03-31 18:06:20     打赏
28楼
很有探索精神.
另,验证码打错,点返回后,内容一般还会在的。

菜鸟
2012-03-31 20:19:08     打赏
29楼
= =  突然打个水完了发现已经是晚上了,继续。

systick 固件库的函数使用已经从手册中找到了,那么其原理是如何实现的呢?
上面寄存器中,有个重载寄存器RELOAD 满值是0xFFFFFF, 即最大值是16777215, 因为是倒数的,所以倒数72000000 次就是1S 了,当然是在72MHz 系统时钟下使用M3核系统时钟,可是没那么大的框,所以装 72000000/1000=72000 这个数进去就好了,倒数完一次是1ms。
       顺着库函数很清楚做的就是SysTick_Config (SystemCoreClock / 1000) 这函数运算。然后跳转导core_cm3.h 这个文件来了,然后看到下面这段代码
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{
  if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /* Reload value impossible */
                                                              
  SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /* set reload register */
  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Cortex-M0 System Interrupts */
  SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */
  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
                   SysTick_CTRL_TICKINT_Msk   |
                   SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */
  return (0);                                                  /* Function successful */
}


进入函数后第一件事是把输入的变量和SysTick_LOAD_RELOAD_Msk 做了一次比较,这是个什么数呢再跳
#define SysTick_LOAD_RELOAD_Pos             0                                             /*!< SysTick LOAD: RELOAD Position */
#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos)        /*!< SysTick LOAD: RELOAD Mask */
看到0xFFFFFF 熟悉吧,正是的,RELOAD寄存器能装置的最大值,后面多了个ul? 怎么回事,查了好多资料,基本很少有讲,大致意思是定义的这个数是一个 unsigned long 类型.当我们输入的计数值大于积存能装载的最大值将会返回一个 值为1的错误返回。当然if (SysTick_Config (SystemCoreClock / 1000))  { while (1); }  直接死循环,调试的时候我们就会发现在这个函数跳不出去,因而找到错误。固件库中设置了好多这样的安全关口,保证我们自调试的时候能快速找到问题所在点。
     再看载入值 (ticks & SysTick_LOAD_RELOAD_Msk) - 1; 与上一个全F当然出来的是我们填入的数例如72000,但疑问来了,为什么要-1啊~!! 为什么啊~!! 这其实算是一个C 语言的小毛病,Data[5]最大的那个数组是Data[4] 而不是Data[5]吧,是的还有个Data[0] 呢。
    剩下的语句基本动作:中断设置、计数器清零、设定控制并且开始,相关寄存器控制位自己看表了。
    回头再讲一个差点忘了的东西,我们除了那个除数从来可没给他输入过别的计数值啊。再跳SysTick_Config (SystemCoreClock / 1000) ,SystemCoreClock 跳转到systme_stm32f10x.h后看到uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz;  噢,原来这里定义了它等于72MHz,还没到底呢,继续SYSCLK_FREQ_72MHz,再跳
#define SYSCLK_FREQ_72MHz  72000000。结束! 把这些最原始的值代入我们的程序就成了最原始的程序了,所有的计算方法以及寄存器控制灯

今天到此为止,下一章,另类玩转串口,是另类的哦~ 和你们的教程可都不一样的哦。请密切关注,谢谢。THINK YOU

菜鸟
2012-04-01 09:29:59     打赏
30楼
非常感谢你的焊接指导,对我们这种没焊过的人来说挺好的!

共54条 3/6 1 2 3 4 5 6 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]