liuxingyu 发表于 2026-1-20 20:02:08

单一多档位切换占空比 PWM控制

#include "stc8.h"

// --- 定义引脚 ---
sbit LED_PIN = P1^0;   // LED 接在 P1.0
sbit KEY_PIN = P3^2;   // 按键接在 P3.2

// --- 定义状态 ---
#define STATE_OFF   0// 0档:灭
#define STATE_LOW   1// 1档:低亮
#define STATE_HIGH2// 2档:高亮

// --- 全局变量 ---
unsigned char current_state = STATE_OFF; // 初始状态为关闭
unsigned char key_pressed = 0;         // 按键标志位

/**
* @brief 简单的毫秒级延时函数
*/
void Delay_ms(unsigned int ms) {
    unsigned int i, j;
    for(i = ms; i > 0; i--)
      for(j = 115; j > 0; j--); // 11.0592MHz 约等于1ms
}

/**
* @brief 按键扫描函数 (带消抖)
* @return 1表示按下,0表示未按下
*/
unsigned char Scan_Key() {
    if(KEY_PIN == 0) {      // 电平检测
      Delay_ms(10);      // 软件消抖延时
      if(KEY_PIN == 0) {
            while(KEY_PIN == 0); // 等待按键释放
            return 1;         // 确认按下
      }
    }
    return 0;
}

/**
* @brief 模拟PWM输出函数
* @param duty 占空比 (0-100)
*/
void PWM_Output(unsigned char duty) {
    if(duty >= 100) {
      LED_PIN = 1; // 全亮
      return;
    }
    if(duty <= 0) {
      LED_PIN = 0; // 全灭
      return;
    }

    // 核心PWM逻辑:周期设为10ms,分100份
    unsigned int i;
    for(i = 0; i < 100; i++) {
      if(i < duty) {
            LED_PIN = 1; // 亮的时间
      } else {
            LED_PIN = 0; // 灭的时间
      }
      Delay_ms(1);   // 精确延时10us (此处仅为示意,实际需微调或用定时器)
    }
}

/**
* @brief 主函数
*/
void main() {
    P1M0 = 0x01; P1M1 = 0x00; // P1.0 设置为推挽输出 (增强驱动)
    P3M0 = 0x00; P3M1 = 0x00; // P3.2 设置为准双向口
   
    LED_PIN = 0; // 初始关闭
    KEY_PIN = 1; // 上拉使能

    while(1) {
      // 1. 检测按键
      if(Scan_Key()) {
            // 改变状态 (0 -> 1 -> 2 -> 0 ...)
            current_state = (current_state + 1) % 3;
      }

      // 2. 核心逻辑:使用 switch-case 根据状态执行不同操作
      switch(current_state) {
            case STATE_OFF:
                LED_PIN = 0; // 直接熄灭
                // 注意:这里不能加大的延时,否则按键响应会卡顿
                break;

            case STATE_LOW:
                // 这里使用 if 语句来决定具体行为
                if(1) { // 条件恒真,只是为了演示 if 的用法
                  PWM_Output(30); // 30% 亮度
                }
                break;

            case STATE_HIGH:
                // 也可以用 if-else
                if(current_state == STATE_HIGH) {
                  PWM_Output(80); // 80% 亮度
                }
                break;

            default:
                current_state = STATE_OFF; // 异常状态复位
                break;
      }
    }
}

页: [1]
查看完整版本: 单一多档位切换占空比 PWM控制