stm8s 定时器1 延时_试了一下STM8S定时器TIM2的使用

本文介绍了如何使用STM8S的TIM2定时器实现1秒延时,通过配置时钟分频和定时器寄存器,使LED灯循环亮1秒灭1秒。在中断处理函数中,当计数达到1000次时,LED状态翻转。在调试过程中,发现未配置主时钟导致初始延时错误,修正后得到正确代码。但存在一个问题,当HSE故障时,STM8S会停止运行,目前计划通过中断处理该情况。
摘要由CSDN通过智能技术生成

昨日快下班的时候抽空调了手头的三合一体验套装,目标明确,直奔TIM2而去。翻了翻STM8S Reference Manual,感觉TIM1不好对付,先从简单的TIM2下手。让LED循环亮1s灭1s吧,写了程序如下:

/*************************

**文件名称:main.c

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

**         LD3----PD2

**         LD4----PD0

**外部晶振:8MHz

**************************/

#include"stm8s105c_s.h"

void CLK_Init(void)

{

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

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

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

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

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

CLK_SWCR |=0x02;    // 使能HSI

}

void GPIO_Init(void)

{

PD_DDR |=0x0D;

PD_CR1 |=0x0D; // 配置PD0、PD2、PD3为推挽输出    PD_CR2  =0x00; // 摆率2MHz}

void TIM2_Init(void)

{

TIM2_PSCR =0x03; // TIM2的时钟频率=fCK_PSC/2^3,即8分频,得到1us时基    TIM2_ARRH =0x03;

TIM2_ARRL =0xE7; // TIM2_ARR初值设定为0x03e7=999,计数1000

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

main()

{

_asm("sim"); // 禁止中断    CLK_Init();

GPIO_Init();

TIM2_Init();

_asm("rim");  // 开启中断   while(1);

}

/************************************************

**文件名称:stm8s_interrupt_verctor.c

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

*************************************************/

#include"stm8s105c_s.h"

// 代码省略

unsigned int count =0;

@far @interrupt void TIM2_1US(void)

{

count++;

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

if(count ==1000)    // 1s时间到    {

count =0;

PD_ODR ^=0x0D;  // LED翻转     }

return;

}

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

struct interrupt_vector const _vectab[] = {

{0x82, (interrupt_handler_t)_stext},/* reset */ {0x82, NonHandledInterrupt}, /* trap  */ {0x82, NonHandledInterrupt}, /* irq0  */ {0x82, NonHandledInterrupt}, /* irq1  */ {0x82, NonHandledInterrupt},/* irq2  */ {0x82, NonHandledInterrupt},/* irq3  */ {0x82, NonHandledInterrupt}, /* irq4  */ {0x82, NonHandledInterrupt}, /* irq5  */ {0x82, NonHandledInterrupt}, /* irq6  */ {0x82, NonHandledInterrupt}, /* irq7  */ {0x82, NonHandledInterrupt}, /* irq8  */ {0x82, NonHandledInterrupt}, /* irq9  */ {0x82, NonHandledInterrupt},/* irq10 */ {0x82, NonHandledInterrupt}, /* irq11 */ {0x82, NonHandledInterrupt}, /* irq12 */ {0x82, TIM2_1US},            /* irq13 */ {0x82, NonHandledInterrupt},/* irq14 */ {0x82, NonHandledInterrupt}, /* irq15 */

// 以下内容省略

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

};

调试中遇到的问题一开始让我迷茫: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就会傻傻地一直在哪儿等着,这个问题还没解决,初步想法是交给中断去处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值