STC15W204S-35I SOP16 - 定时器 2:16 位自动重装定时器

定时器 2

原理图

在这里插入图片描述

示例

配置定时器 2:

  • 16 位自动重装定时器;
  • 时钟源等于内部系统时钟;
  • 允许其在计数溢出之后请求中断;
  • 每次中断反转一次 P1.1 的输出电平。

main.c 文件:

/**
 * STC15W204S-35I SOP16
 * Timer 2 - 16 bit, auto-reload
 */

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

/**
 * Interrupt Registers Bits Definition
 */
/** IE */
#define GLOBAL_IE_EA    (0x80)
/** IE2 */
#define T2_IE2_ET2      (0x04) /* Timer 2 interrupt enable */


/**
 * Timer 2 Registers Definition
 */
sfr T2L = 0xD7; /* Timer 2 Counter Low Register */
sfr T2H = 0xD6; /* Timer 2 Counter High Register */
sfr AUXR = 0x8E; /* Auxiliary Register */

/**
 * Timer 2 Registers Bits Definition
 */
/** AUXR */
#define T2_AUXR_T2R     (0x10) /* Timer 2 - Run Control */
#define T2_AUXR_T2CT    (0x08) /* Timer 2 - Counter or Timer Selection */
#define T2_AUXR_T2x12   (0x04) /* Timer 2 - Speed Control */


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

sbit LED = P1^1;


void main() {
    AUXR &= ~T2_AUXR_T2CT; // T2 acts as a timer
//    AUXR |= T2_AUXR_T2x12; // T2's clock source is divided by 1
    
    T2H = (65536 - 10000) >> 8; // 8 MSB
    T2L = (65536 - 10000) & 0xFF; // 8 LSB
    
    AUXR |= T2_AUXR_T2R; // T2 run
    
    IE2 |= T2_IE2_ET2; // Enable T2 overflow interrupt request
    
    IE |= GLOBAL_IE_EA; // Enable global interrupt
    
    while(1) {}
}

void timer2InterruptService() interrupt 12 {
    LED = !LED;
}

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

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

在这里插入图片描述

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

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

在这里插入图片描述

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

在这里插入图片描述

模块化处理

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

  • 将 6 ~ 40 行提取到 stc15w204s.h 头文件中;
  • 将 46 ~ 54 行封装成函数,在 timer2.c 文件中实现,在 timer2.h 头文件中声明。

工程结构:

在这里插入图片描述

stc15w204s.h 头文件:

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


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

/**
 * Interrupt Registers Bits Definition
 */
/** IE */
#define GLOBAL_IE_EA    (0x80)
/** IE2 */
#define T2_IE2_ET2      (0x04) /* Timer 2 interrupt enable */


/**
 * Timer 2 Registers Definition
 */
sfr T2L = 0xD7; /* Timer 2 Counter Low Register */
sfr T2H = 0xD6; /* Timer 2 Counter High Register */
sfr AUXR = 0x8E; /* Auxiliary Register */

/**
 * Timer 2 Registers Bits Definition
 */
/** AUXR */
#define T2_AUXR_T2R     (0x10) /* Timer 2 - Run Control */
#define T2_AUXR_T2CT    (0x08) /* Timer 2 - Counter or Timer Selection */
#define T2_AUXR_T2x12   (0x04) /* Timer 2 - 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

timer2.h 头文件:

#ifndef __STC15W204S_TIMER_2_H
#define __STC15W204S_TIMER_2_H


#include "stc15w204s.h"


typedef enum {
    TIMER2_PRESCALER_DIVIDED_BY_1   = ((unsigned char)0x00),
    TIMER2_PRESCALER_DIVIDED_BY_12  = ((unsigned char)0x01)
} Timer2Prescaler;


typedef struct {
    void (*asTimer)(boolean);
    void (*setCounter)(unsigned int);
    void (*setTimer)(unsigned int);
    void (*setPrescaler)(Timer2Prescaler);
    void (*start)(boolean);
    void (*enableInterrupt)(boolean);
} Timer2;


extern Timer2 timer2;


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


#endif

timer2.c 文件:

#include "timer2.h"


Timer2 timer2;


/**
 * If true, timer 2 acts as timer,
 * otherwise it acts as counter.
 */
void asTimer(boolean isTimer) {
    if(isTimer) {
        AUXR &= ~T2_AUXR_T2CT;
    } else {
        AUXR |= T2_AUXR_T2CT;
    }
}

/**
 * Set the initial value of the counter
 * or the timer.
 */
void setCounter(unsigned int counter) {
    T2H = (counter) >> 8;
    T2L = (counter) & 0xff;
}

/**
 * Set the prescaler of the timer 2.
 */
void setPrescaler(Timer2Prescaler prescaler) {
    switch(prescaler) {
        case TIMER2_PRESCALER_DIVIDED_BY_1:
            AUXR |= T2_AUXR_T2x12;
            break;
        case TIMER2_PRESCALER_DIVIDED_BY_12:
            AUXR &= ~T2_AUXR_T2x12;
            break;
    }
}

/**
 * If true, start the timer 2 to run,
 * othewise, stop.
 */
void start(boolean start) {
    if(start) {
        AUXR |= T2_AUXR_T2R;
    } else {
        AUXR &= ~T2_AUXR_T2R;
    }
}

/**
 * If true, enable timer 2 overflow
 * interrupt request, othewise, disable.
 */
void enableInterrupt(boolean enable) {
    if (enable) {
        IE2 |= T2_IE2_ET2;
    } else {
        IE2 &= ~T2_IE2_ET2;
    }
}

/**
 * First call to this function to initialize
 * the <code>timer2</code> variable.
 */
void Timer2Constructor() {
    timer2.asTimer = &asTimer;
    timer2.setCounter = &setCounter;
    timer2.setTimer = &setCounter;
    timer2.setPrescaler = &setPrescaler;
    timer2.start = &start;
    timer2.enableInterrupt = &enableInterrupt;
}

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

/**
 * STC15W204S-35I SOP16
 * Timer 2 - 16 bit, auto-reload
 */

#include "timer2.h"


sbit LED = P1^1;


void main() {
    Timer2Constructor();
    timer2.asTimer(TRUE);
    timer2.setPrescaler(TIMER2_PRESCALER_DIVIDED_BY_1);
    timer2.setTimer(65536 - 10000);
    timer2.start(TRUE);
    timer2.enableInterrupt(TRUE);
    
//    IE |= GLOBAL_IE_EA; // Enable global interrupt
    enableInterrupts(TRUE);
    
    while(1) {}
}

void timer2InterruptService() interrupt 12 {
    LED = !LED;
}

参考

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

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
欢迎新手学习,老手指教。 1.使用STC15W408AS。DS1302时钟,闹钟,管码管,掉电模式(进入掉电模式电流<10ua,使用18650供电,3.7-5V电池也可通用)。 2.详细注释,非常适合新手学习。如: sfr WKTCL = 0xaa; //掉电唤醒定时器计时低字节 sfr WKTCH = 0xab; */ //掉电唤醒定时器计时高字节 //----------------------------------------------- //sbit P37 = P3^7; //+分。 //sbit P36 = P3^6; //+时。 //sbit P35 = P3^5; //调闹钟。 //sbit P34 = P3^4; //调时间。//-调时间-按P34按P36放P34放P36才能调时间- //sbit P33 = P3^3; //延时18小时。置值65535. //sbit P32 = P3^2; //确认--延时200S。 //sbit P31 = P3^1; //开关闹钟。 sbit TSCLK = P1^5;//时钟线 接到P37上用杜邦线 sbit TIO = P1^6;//数据线,接到P36上 sbit TRST = P1^7;//使能端,接到P35上 //sbit P54 = P5^4;//运行指示灯 //sbit P55 = P5^5; //蜂鸣器。 //------函数声明---------------- void delayms(uint z); //STC15W204S单片机即1MS延时=0.9989MS-11.0592 void qingling(); //P3清零 void Display(uchar Sec, Min);//显示 void Write_DS1302_DAT(uchar cmd, uchar dat);//写DS1302数据 uchar Read_DS1302_DAT(uchar cmd);////读DS1302数据 uchar Dat_Chg_BCD(uchar dat);//数据转BCD码 uchar BCD_Chg_Dat(uchar dat);//BCD码转换为数据 void tiaotime(); //调时间。 uchar duchi();//读一次小时数 uchar dufen();//读分钟数。 ---------------------------------- / ge = ii; //求余-求里面除整数10后的余数 // shi = ii/10; //求模-求里面有多少个整数倍10. -------------------------------- P11 = 0;//点亮第二数码管 if(Sec1==1) //在调用显示前用求余法确定Sec1是0还是1 { uu=table[Hour]<>1; //再右移一左补0,即改变第7变成0。目的显示:两点。 P2 = uu;//显示第二数。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值