找回密码
 立即注册
查看: 153|回复: 0

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

[复制链接]
  • 打卡等级:以坛为家I
  • 打卡总天数:272
  • 最近打卡:2026-03-23 07:57:52
已绑定手机

4

主题

87

回帖

389

积分

中级会员

积分
389
发表于 2026-1-20 20:02:08 | 显示全部楼层 |阅读模式
  1. #include "stc8.h"
  2. // --- 定义引脚 ---
  3. sbit LED_PIN = P1^0;   // LED 接在 P1.0
  4. sbit KEY_PIN = P3^2;   // 按键接在 P3.2
  5. // --- 定义状态 ---
  6. #define STATE_OFF   0  // 0档:灭
  7. #define STATE_LOW   1  // 1档:低亮
  8. #define STATE_HIGH  2  // 2档:高亮
  9. // --- 全局变量 ---
  10. unsigned char current_state = STATE_OFF; // 初始状态为关闭
  11. unsigned char key_pressed = 0;           // 按键标志位
  12. /**
  13. * @brief 简单的毫秒级延时函数
  14. */
  15. void Delay_ms(unsigned int ms) {
  16.     unsigned int i, j;
  17.     for(i = ms; i > 0; i--)
  18.         for(j = 115; j > 0; j--); // 11.0592MHz 约等于1ms
  19. }
  20. /**
  21. * @brief 按键扫描函数 (带消抖)
  22. * @return 1表示按下,0表示未按下
  23. */
  24. unsigned char Scan_Key() {
  25.     if(KEY_PIN == 0) {      // 电平检测
  26.         Delay_ms(10);        // 软件消抖延时
  27.         if(KEY_PIN == 0) {
  28.             while(KEY_PIN == 0); // 等待按键释放
  29.             return 1;           // 确认按下
  30.         }
  31.     }
  32.     return 0;
  33. }
  34. /**
  35. * @brief 模拟PWM输出函数
  36. * @param duty 占空比 (0-100)
  37. */
  38. void PWM_Output(unsigned char duty) {
  39.     if(duty >= 100) {
  40.         LED_PIN = 1; // 全亮
  41.         return;
  42.     }
  43.     if(duty <= 0) {
  44.         LED_PIN = 0; // 全灭
  45.         return;
  46.     }
  47.     // 核心PWM逻辑:周期设为10ms,分100份
  48.     unsigned int i;
  49.     for(i = 0; i < 100; i++) {
  50.         if(i < duty) {
  51.             LED_PIN = 1; // 亮的时间
  52.         } else {
  53.             LED_PIN = 0; // 灭的时间
  54.         }
  55.         Delay_ms(1);     // 精确延时10us (此处仅为示意,实际需微调或用定时器)
  56.     }
  57. }
  58. /**
  59. * @brief 主函数
  60. */
  61. void main() {
  62.     P1M0 = 0x01; P1M1 = 0x00; // P1.0 设置为推挽输出 (增强驱动)
  63.     P3M0 = 0x00; P3M1 = 0x00; // P3.2 设置为准双向口
  64.    
  65.     LED_PIN = 0; // 初始关闭
  66.     KEY_PIN = 1; // 上拉使能
  67.     while(1) {
  68.         // 1. 检测按键
  69.         if(Scan_Key()) {
  70.             // 改变状态 (0 -> 1 -> 2 -> 0 ...)
  71.             current_state = (current_state + 1) % 3;
  72.         }
  73.         // 2. 核心逻辑:使用 switch-case 根据状态执行不同操作
  74.         switch(current_state) {
  75.             case STATE_OFF:
  76.                 LED_PIN = 0; // 直接熄灭
  77.                 // 注意:这里不能加大的延时,否则按键响应会卡顿
  78.                 break;
  79.             case STATE_LOW:
  80.                 // 这里使用 if 语句来决定具体行为
  81.                 if(1) { // 条件恒真,只是为了演示 if 的用法
  82.                     PWM_Output(30); // 30% 亮度
  83.                 }
  84.                 break;
  85.             case STATE_HIGH:
  86.                 // 也可以用 if-else
  87.                 if(current_state == STATE_HIGH) {
  88.                     PWM_Output(80); // 80% 亮度
  89.                 }
  90.                 break;
  91.             default:
  92.                 current_state = STATE_OFF; // 异常状态复位
  93.                 break;
  94.         }
  95.     }
  96. }
复制代码


回复

使用道具 举报 送花

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

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-3-23 23:08 , Processed in 0.099249 second(s), 43 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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