找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6|回复: 0
收起左侧

STC单片机PWM脉冲求教

[复制链接]
ID:757824 发表于 2026-7-8 21:40 | 显示全部楼层 |阅读模式
用定时器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) {
        // 主循环可加入其他任务
    }
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表