STC15W204S-35I SOP16 - 定时器 0,工作模式 0,16 位自动重装定时器

定时器 0

在这里插入图片描述

原理图

在这里插入图片描述

工作模式 0

配置定时器 0:

  • 工作模式 0,16 位自动重装定时器;
  • 时钟源来自内部系统时钟 / 12
  • 允许其在计数溢出之后请求中断;
  • 每次 T0 中断,反转一次 P1.1 的输出电平。

main.c 文件:

/**
 * Interrupt Registers Definition
 */
sfr IE = 0xA8; /* Interrupt Enable Register */

/**
 * Interrupt Registers Bits Definition
 */
/** IE */
#define GLOBAL_IE_EA    (0x80)
#define T0_IE_ET0       (0x02)


/**
 * Timer 0 Registers Definition
 */
sfr TCON = 0x88; /* Timer 0 & Timer 1 Control Register */
sfr TMOD = 0x89; /* Timer 0 & Timer 1 Working Mode */
sfr TL0 = 0x8A; /* Timer 0 Counter Low Register */
sfr TH0 = 0x8C; /* Timer 0 Counter High Register */
sfr AUXR = 0x8E; /* Auxiliary Register */

/**
 * Timer 0 Registers Bits Definition
 */
/** TCON */
#define T0_TCON_TF0     (0x20) /* Timer 0 - Overflow Flag */
#define T0_TCON_TR0     (0x10) /* Timer 0 - Run Control */
/** TMOD */
#define T0_TMOD_GATE    (0x08) /* Timer 0 - Gate Control */
#define T0_TMOD_CT      (0x04) /* Timer 0 - Counter or Timer Selection */ 
#define T0_TMOD_M1      (0x02) /* Timer 0 - Mode Selection Bit 1 */
#define T0_TMOD_M0      (0x01) /* Timer 0 - Mode Selection Bit 0 */
/** AUXR */
#define T0_AUXR_T0x12   (0x80) /* Timer 0 - Speed Control */


/**
 * Port 1 Registers Definition
 */
sfr P1 = 0x90; /* Port 1 Register */

sbit LED = P1^1; 


void main() {
    TMOD &= ~T0_TMOD_GATE;
    TMOD &= ~T0_TMOD_CT; // T0 acts as a timer
    TMOD &= ~(T0_TMOD_M1 | T0_TMOD_M0); // Mode 0: 16-bit auto-reload
    
    TH0 = (65536 - 10000) >> 8; // 8 MSB
    TL0 = (65536 - 10000) & 0xFF; // 8 LSB
    
//    AUXR |= T0_AUXR_T0x12; // T0's clock source is divided by 1
    
    TCON &= ~T0_TCON_TF0; // Clear T0 overflow flag
    TCON |= T0_TCON_TR0; // T0 run
    
    IE |= T0_IE_ET0; // Enable T0 overflow interrupt request
    
    IE |= GLOBAL_IE_EA; // Enable global interrupt
    
    while(1) {}
}

void Timer0InterruptService() interrupt 1 {
    LED = !LED;
}

使用 STC-ISP 下载程序,频率设为 12.000 MHz

注意:虽然 STC-ISP 提示下载失败!但是,我发现单片机仍然按照我的设想执行程序,这里可能是 STC-ISP 有问题。

在这里插入图片描述

T0 的时钟源进行 12 分频(AUXR &= ~T0_AUXR_T0x12;),测量 P1.1 输出:

注意:虽然在原理图中,我给单片机的电源符号是 5V,但是在实际测试中,我使用的是 USB 转串口模块上提供的 3.3V(实测没有 3.3V),这并不妨碍单片机正常运行。

在这里插入图片描述

不对 T0 的时钟源进行分频(AUXR |= T0_AUXR_T0x12;),测量 P1.1 输出:

在这里插入图片描述

模块化处理

把所有的代码写在一个 main.c 文件是非常不好的习惯,我们需要将上例中的定时器 2 模块化处理:

  • 将 1 ~ 35 行提取到 stc15w204s.h 头文件中;
  • 将 47 ~ 59 行封装成函数,在 timer0.c 文件中实现,在 timer0.h 头文件中声明。

工程结构:

在这里插入图片描述

stc15w204s.h 头文件:

  • 声明有关定时器 0 的特殊功能寄存器;
  • 声明有关定时器 0 的特殊功能寄存器的位掩码;
  • 以及其他。
#ifndef __STC15W204S_H
#define __STC15W204S_H


/**
 * Interrupt Registers Definition
 */
sfr IE = 0xA8; /* Interrupt Enable Register */

/**
 * Interrupt Registers Bits Definition
 */
/** IE */
#define GLOBAL_IE_EA    (0x80)
#define T0_IE_ET0       (0x02) /* Timer 0 interrupt enable */


/**
 * Timer 0 Registers Definition
 */
sfr TCON    = 0x88; /* Timer 0 & Timer 1 Control Register */
sfr TMOD    = 0x89; /* Timer 0 & Timer 1 Working Mode */
sfr TL0     = 0x8A; /* Timer 0 Counter Low Register */
sfr TH0     = 0x8C; /* Timer 0 Counter High Register */
sfr AUXR    = 0x8E; /* Auxiliary Register */

/**
 * Timer 0 Registers Bits Definition
 */
/** TCON */
#define T0_TCON_TF0     (0x20) /* Timer 0 - Overflow Flag */
#define T0_TCON_TR0     (0x10) /* Timer 0 - Run Control */
/** TMOD */
#define T0_TMOD_GATE    (0x08) /* Timer 0 - Gate Control */
#define T0_TMOD_CT      (0x04) /* Timer 0 - Counter or Timer Selection */ 
#define T0_TMOD_M1      (0x02) /* Timer 0 - Mode Selection Bit 1 */
#define T0_TMOD_M0      (0x01) /* Timer 0 - Mode Selection Bit 0 */
/** AUXR */
#define T0_AUXR_T0x12   (0x80) /* Timer 0 - Speed Control */


/**
 * Port 1 Registers Definition
 */
sfr P1 = 0x90; /* Port 1 Register */


typedef enum {
    FALSE = 0,
    TRUE = !FALSE
} boolean;


#define enableInterrupts(enable)    if(enable) {                \
                                        IE |= GLOBAL_IE_EA;     \
                                    } else {                    \
                                        IE &= ~GLOBAL_IE_EA;    \
                                    }                           

#endif

timer0.h 头文件:

#ifndef __STC15W204S_TIMER_0_H
#define __STC15W204S_TIMER_0_H


#include "stc15w204s.h"


typedef enum {
    TIMER0_PRESCALER_DIVIDED_BY_1   = 1,
    TIMER0_PRESCALER_DIVIDED_BY_12  = 12
} Timer0Prescaler;

typedef enum {
    TIMER0_COUNTER_MODE_0   = ((unsigned char)0x00),
    TIMER0_COUNTER_MODE_1   = ((unsigned char)0x01),
    TIMER0_COUNTER_MODE_2   = ((unsigned char)0x02),
    TIMER0_COUNTER_MODE_3   = ((unsigned char)0x03)
} Timer0CounterMode;

typedef struct {
    void (*asTimer)(boolean);
    void (*setCounterMode)(Timer0CounterMode);
    void (*set8BitCounter)(unsigned char);
    void (*set16BitCounter)(unsigned int);
    void (*setPrescaler)(Timer0Prescaler);
    void (*start)(boolean);
    void (*enableInterrupt)(boolean);
} Timer0;


extern Timer0 timer0;


/**
 * First call to this function to initialize
 * the <code>timer0</code> variable.
 */
void Timer0Constructor();


#endif

timer2.c 文件:

#include "timer0.h"


Timer0 timer0;


/**
 * If true, timer 0 acts as timer,
 * otherwise it acts as counter.
 */
static void asTimer(boolean isTimer) {
    if(isTimer) {
        TMOD &= ~T0_TMOD_CT;
    } else {
        TMOD |= T0_TMOD_CT;
    }
}

/**
 * Set the counter mode of the timer 0.
 */
static void setCounterMode(Timer0CounterMode mode) {
    switch(mode) {
        case TIMER0_COUNTER_MODE_0:
            TMOD &= ~(T0_TMOD_M1 | T0_TMOD_M0);
            break;
        case TIMER0_COUNTER_MODE_1:
            TMOD &= ~T0_TMOD_M1;
            TMOD |= T0_TMOD_M0;
            break;
        case TIMER0_COUNTER_MODE_2:
            TMOD |= T0_TMOD_M1;
            TMOD &= ~T0_TMOD_M0;
            break;
        case TIMER0_COUNTER_MODE_3:
            TMOD |= (T0_TMOD_M1 | T0_TMOD_M0);
            break;
    }
}

/**
 * Set the initial value of the counter
 * or the timer 0, This only for mode 2.
 */
static void set8BitCounter(unsigned char counter) {
    TH0 = counter;
    TL0 = TH0;
}

/**
 * Set the initial value of the counter
 * or the timer 0.
 */
static void set16BitCounter(unsigned int counter) {
    TH0 = (counter) >> 8;
    TL0 = (counter) & 0xff;
}

/**
 * Set the prescaler of the timer 0.
 */
static void setPrescaler(Timer0Prescaler prescaler) {
    switch(prescaler) {
        case TIMER0_PRESCALER_DIVIDED_BY_1:
            AUXR |= T0_AUXR_T0x12;
            break;
        case TIMER0_PRESCALER_DIVIDED_BY_12:
            AUXR &= ~T0_AUXR_T0x12;
            break;
    }
}

/**
 * If true, start the timer 0 to run,
 * othewise, stop.
 */
static void start(boolean start) {
    if(start) {
        TCON |= T0_TCON_TR0;
    } else {
        TCON &= ~T0_TCON_TR0;
    }
}

/**
 * If true, enable timer 0 overflow
 * interrupt request, othewise, disable.
 */
static void enableInterrupt(boolean enable) {
    if (enable) {
        IE |= T0_IE_ET0;
    } else {
        IE &= ~T0_IE_ET0;
    }
}

/**
 * First call to this function to initialize
 * the <code>timer0</code> variable.
 */
void Timer0Constructor() {
    timer0.asTimer = &asTimer;
    timer0.setCounterMode = &setCounterMode;
    timer0.set8BitCounter = &set8BitCounter;
    timer0.set16BitCounter = &set16BitCounter;
    timer0.setPrescaler = &setPrescaler;
    timer0.start = &start;
    timer0.enableInterrupt = &enableInterrupt;
}

将定时器 0 的功能模块化处理之后,main.c 文件如下:

/**
 * STC15W204S-35I SOP16
 * Timer 0 - Mode 0: 16 bit, auto-reload
 */

#include "timer0.h"


sbit LED = P1^1;


void main() {
    Timer0Constructor();
    
    timer0.asTimer(TRUE);
    timer0.setCounterMode(TIMER0_COUNTER_MODE_0);
    timer0.setPrescaler(TIMER0_PRESCALER_DIVIDED_BY_1);
//    timer0.set8BitCounter(256 - 100);
    timer0.set16BitCounter(65536 - 10000);
    timer0.start(TRUE);
    timer0.enableInterrupt(TRUE);
    
    enableInterrupts(TRUE);
    
    while(1) {}
}

void timer0InterruptService() interrupt 1 {
    LED = !LED;
}

参考

宏晶科技 STC - STC15 系列单片机器件手册

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值