wx_Ip7KX 发表于 2026-7-8 21:46:20

定时器1和0的区别

用定时器0和1的区别,用定时器0就可以生成脉冲,用定时器1就不行
定时器0
/*************三路同步输出脉冲(6.73kHz,占空比 83%)*************
* 单片机:STC15W408AS
* 晶振:11.0592MHz
*
* 输出引脚:P3.7、P1.0、P1.1 同时输出相同波形
* 频率:约 6.73kHz(校准后)
* 占空比:83%
**********************************************/

#include "stc15.h"
#include <intrins.h>

#define FOSC 11059200L

// 定时器重装值(基于实测校准,约 6.95μs 中断)
#define TIMER0_RELOAD (65536 - 55)

// ★ 波形参数 ★
#define PERIOD 21       // 总周期 21 个中断
#define HIGH_TIME 17    // 高电平 17 个中断(≈81~83%)

// 引脚定义
sbit OUT1 = P3^7;   // 脉冲输出1

volatile unsigned char cnt = 0;

// ==================== 定时器0 初始化 ====================
void Timer0_Init(void) {
    AUXR |= 0x80;       // 1T模式
    TMOD &= 0xF0;
    TMOD |= 0x01;       // 模式1(16位定时器)
    TH0 = TIMER0_RELOAD >> 8;
    TL0 = TIMER0_RELOAD & 0xFF;
    ET0 = 1;
    TR0 = 1;
    EA = 1;
}

// ==================== 定时器0 中断服务 ====================
void Timer0_Isr() interrupt 1 {
    // 手动重装初值
    TH0 = TIMER0_RELOAD >> 8;
    TL0 = TIMER0_RELOAD & 0xFF;

    cnt++;
    if (cnt >= PERIOD) cnt = 0;

    // ★ 三路同步输出 ★
    if (cnt < HIGH_TIME) {
      OUT1 = 1;
    } else {
      OUT1 = 0;
   
    }
}

// ==================== 主函数 ====================
void main() {
    // 配置 P3.7、P1.0、P1.1 为推挽输出
    P3M0 |= 0x80;    // P3.7 推挽
    P3M1 &= ~0x80;

    P1M0 |= 0x03;    // P1.0、P1.1 推挽
    P1M1 &= ~0x03;

    // 初始低电平
    OUT1 = 1;


    Timer0_Init();

    while (1) {
      // 主循环空转,脉冲由中断产生
      // 如需停止脉冲:ET0 = 0;
      // 如需恢复脉冲:ET0 = 1;
    }
}
定时器1:
/*************三路同步输出脉冲(≈6.75kHz,占空比 81%)*************
* 单片机:STC15W408AS
* 晶振:11.0592MHz
* 输出引脚:P3.7、P1.0、P1.1 同时输出相同波形
* 频率:计算值 ≈6.75kHz(可微调 TIMER1_RELOAD 校准)
* 占空比:17/21 ≈ 80.95%
*
* 改动说明:将原定时器0方案改为定时器1,中断号改为3,寄存器对应更改。
********************************************************************/

#include "stc15.h"
#include <intrins.h>

#define FOSC 11059200L

// 定时器重装值(同原计算,中断周期 ≈7.05μs)
#define TIMER1_RELOAD (65536 - 78)   // 微调此值校准频率

#define PERIOD 21
#define HIGH_TIME 17

sbit OUT1 = P3^7;
sbit OUT2 = P1^0;
sbit OUT3 = P1^1;

volatile unsigned char cnt = 0;

// ==================== 定时器1 初始化 ====================
void Timer1_Init(void) {
    AUXR |= 0x40;       // 定时器1 1T模式(注意:AUXR的bit6控制T1,bit7控制T0)
    TMOD &= 0x0F;       // 清空高4位(定时器1模式位)
    TMOD |= 0x10;       // 定时器1模式1(16位定时器)
    TH1 = TIMER1_RELOAD >> 8;
    TL1 = TIMER1_RELOAD & 0xFF;
    ET1 = 1;            // 允许定时器1中断
    TR1 = 1;            // 启动定时器1
    EA = 1;
}

// ==================== 定时器1 中断服务 ====================
void Timer1_Isr() interrupt 3 {   // 中断号3 对应定时器1
    // 手动重装初值
    TH1 = TIMER1_RELOAD >> 8;
    TL1 = TIMER1_RELOAD & 0xFF;

    cnt++;
    if (cnt >= PERIOD) cnt = 0;

    // 三路同步输出
    if (cnt < HIGH_TIME) {
      OUT1 = 1;
      OUT2 = 1;
      OUT3 = 1;
    } else {
      OUT1 = 0;
      OUT2 = 0;
      OUT3 = 0;
    }
}

// ==================== 主函数 ====================
void main() {
    // 配置三路为推挽输出
    P3M0 |= 0x80;    P3M1 &= ~0x80;   // P3.7
    P1M0 |= 0x03;    P1M1 &= ~0x03;   // P1.0, P1.1

    // 初始高电平(让第一个高电平完整)
    OUT1 = OUT2 = OUT3 = 1;

    Timer1_Init();

    while (1) {
      // 主循环可加入其他任务
    }
}

梁工 发表于 2026-7-8 22:35:13

所有定时器都可以输出高速脉冲。

狂热主宰 发表于 2026-7-8 22:50:04

手册有详细描述
各定时器功能和限制
特殊功能部分定时器配备

晓飛飛 发表于 2026-7-8 23:04:33

除了专用引脚和中断优先级有所不同,其它没什么两样

wulin 发表于 2026-7-9 06:53:33

不同写法明显影响同步
void Timer0_Isr(void) interrupt 1
{
      cnt=~cnt;
//      if(cnt)P1&=0xf8;
//      else P1|=0x07;

      if(cnt)
      {
                OUT1=0;
                OUT2=0;
                OUT3=0;
      }
      else
      {
                OUT1=1;
                OUT2=1;
                OUT3=1;
      }
}









乘风飞扬 发表于 2026-7-9 09:04:20

我看你代码注释里面写的芯片型号是 STC15W408AS 这个系列只有定时器0/定时器2,没有定时器1:

页: [1]
查看完整版本: 定时器1和0的区别