[STM8]

STM8S定时器TIM2的使用

[复制链接]
1356|3
手机看帖
扫描二维码
随时随地手机跟帖
zhuomuniao110|  楼主 | 2017-6-23 12:02 | 显示全部楼层 |阅读模式
让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);
}




zhuomuniao110|  楼主 | 2017-6-23 12:02 | 显示全部楼层
/************************************************

**文件名称:stm8s_interrupt_verctor.c

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

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

#include"stm8s105c_s.h"

// 代码省略

unsigned int count =0;

[url=home.php?mod=space&uid=1095855]@far[/url] [url=home.php?mod=space&uid=422518]@interrupt[/url] 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的中断级别也不错。

};

使用特权

评论回复
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 | 显示全部楼层

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

188

主题

3237

帖子

10

粉丝