[STM8] STM8S定时器TIM2的使用

[复制链接]
1733|3
 楼主| zhuomuniao110 发表于 2017-6-23 12:02 | 显示全部楼层 |阅读模式
让LED循环亮1s灭1s吧,写了程序如下:
  1. /*************************

  2. **文件名称:main.c

  3. **LED说明:LD2----PD3

  4. **         LD3----PD2

  5. **         LD4----PD0

  6. **外部晶振:8MHz

  7. **************************/

  8. #include"stm8s105c_s.h"

  9. void CLK_Init(void)

  10. {

  11.     CLK_ECKR |=0x01;    // 开启外部时钟

  12.     while(!(CLK_ECKR &0x02));    // 等待HSE准备就绪

  13.     CLK_CKDIVR &=0xF8;    // CPU时钟不分频

  14.     CLK_SWR =OxB4;   // 选择外部时钟

  15.     while(!(CLK_SWCR &0x08));    // 等待切换至HSE完成(STM8默认上电使用HSI)

  16.     CLK_SWCR |=0x02;    // 使能HSI

  17. }



  18. void GPIO_Init(void)
  19. {
  20.     PD_DDR |=0x0D;
  21.     PD_CR1 |=0x0D; // 配置PD0、PD2、PD3为推挽输出
  22.     PD_CR2  =0x00; // 摆率2MHz
  23. }



  24. void TIM2_Init(void)
  25. {
  26.     TIM2_PSCR =0x03; // TIM2的时钟频率=fCK_PSC/2^3,即8分频,得到1us时基
  27.     TIM2_ARRH =0x03;
  28.     TIM2_ARRL =0xE7; // TIM2_ARR初值设定为0x03e7=999,计数1000

  29.     TIM2_CR1 |=0x81; // 使能TIM2计数
  30.     TIM2_IER  =0x01; // 允许TIM2溢出中断
  31. }



  32. main()
  33. {
  34.     _asm("sim");  // 禁止中断
  35.     CLK_Init();
  36.     GPIO_Init();
  37.     TIM2_Init();
  38.     _asm("rim");  // 开启中断
  39.     while (1);
  40. }




 楼主| zhuomuniao110 发表于 2017-6-23 12:02 | 显示全部楼层
  1. /************************************************

  2. **文件名称:stm8s_interrupt_verctor.c

  3. **说明:以下内容为加入的部分,模板代码部分省略

  4. *************************************************/

  5. #include"stm8s105c_s.h"

  6. // 代码省略

  7. unsigned int count =0;

  8. [url=home.php?mod=space&uid=1095855]@far[/url] [url=home.php?mod=space&uid=422518]@interrupt[/url] void TIM2_1US(void)
  9. {
  10.     count++;

  11.     TIM2_SR1 &=~(0x01);    // 清除TIM2溢出中断标志位

  12.     if(count ==1000)    // 1s时间到
  13.     {
  14.          count =0;
  15.          PD_ODR ^=0x0D;  // LED翻转
  16.      }


  17.      return;
  18. }



  19. // TIM2在中断向量表中的定义

  20. struct interrupt_vector const _vectab[] = {
  21. {0x82, (interrupt_handler_t)_stext}, /* reset */
  22. {0x82, NonHandledInterrupt}, /* trap  */
  23. {0x82, NonHandledInterrupt}, /* irq0  */
  24. {0x82, NonHandledInterrupt}, /* irq1  */
  25. {0x82, NonHandledInterrupt}, /* irq2  */
  26. {0x82, NonHandledInterrupt}, /* irq3  */
  27. {0x82, NonHandledInterrupt}, /* irq4  */
  28. {0x82, NonHandledInterrupt}, /* irq5  */
  29. {0x82, NonHandledInterrupt}, /* irq6  */
  30. {0x82, NonHandledInterrupt}, /* irq7  */
  31. {0x82, NonHandledInterrupt}, /* irq8  */
  32. {0x82, NonHandledInterrupt}, /* irq9  */
  33. {0x82, NonHandledInterrupt}, /* irq10 */
  34. {0x82, NonHandledInterrupt}, /* irq11 */
  35. {0x82, NonHandledInterrupt}, /* irq12 */
  36. {0x82, TIM2_1US},            /* irq13 */
  37. {0x82, NonHandledInterrupt}, /* irq14 */
  38. {0x82, NonHandledInterrupt}, /* irq15 */
  39. // 以下内容省略

  40. {0x82, NonHandledInterrupt}, /* irq29 */   // 手册中的32个中断向量,这里才29个,因为用的是STM8S105S4这款片子的原因,可能没那么多吧,cosmic真的很傻很强大。顺便了解了TIM2的中断级别也不错。

  41. };
 楼主| zhuomuniao110 发表于 2017-6-23 12:03 | 显示全部楼层
调试中遇到的问题一开始让我迷茫:LED亮4s灭4s,只好根据现象去改TIM2_ARR的值,心想我定1s你亮4s,那我就TIM2_ARR =0x00F9,计数250个总该可以吧。一试还真的可以。不过这让我更想不通了,8MHz外部晶振到CPU是不分频,而fMASTER到TIM2是8分频,也就是刚好产生了1us的时钟基准。晚上想起来是没配置主时钟的缘故,没配置就默认使用了HSI 2MHz的 RC振荡器,结果还是把它8分频,定时时间相差4倍就不稀奇了。到此,问题基本了结。上面的代码是完整的正确代码。不过有个BUG,那就是如果HSE故障,那可怜的STM8S就会傻傻地一直在哪儿等着,这个问题还没解决,初步想法是交给中断去处理。
mmuuss586 发表于 2017-6-23 12:18 | 显示全部楼层
您需要登录后才可以回帖 登录 | 注册

本版积分规则

233

主题

3529

帖子

11

粉丝
快速回复 在线客服 返回列表 返回顶部