用定时器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) {
// 主循环可加入其他任务
}
} |