找回密码
 立即注册
查看: 100|回复: 3

求助一个逻辑比较绕的PWM程序

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:7
  • 最近打卡:2025-07-08 08:13:36

4

主题

12

回帖

92

积分

注册会员

积分
92
发表于 2025-7-7 13:36:55 | 显示全部楼层 |阅读模式
写一段STC32G8K64单片机的PWM代码,要求如下:P2.3为PWM输出脚,当P1.1和P1.4中有一个为低电平或者都为低电平时,P1.0为高电平,则P2.3输出90%占空比的PMW,当P1.1或P1.4为高电平时输出的占空比逐渐降为0,时间2秒,当P1.1和P1.4中有一个为低电平,P1.0再次为高电平,则输出90%占空比的PMW,当P1.1或则P1.4为高电平时输出的占空比逐渐降为0,时间2秒,以此循环。
回复

使用道具 举报 送花

3

主题

2074

回帖

996

积分

等待验证会员

积分
996
发表于 2025-7-7 13:38:00 | 显示全部楼层
针对您提出的PWM控制逻辑,以下是基于STC32G8K64单片机的实现方案。该程序通过定时器生成PWM信号,并根据P11、P14和P10的状态变化动态调整占空比,满足您所描述的循环控制逻辑。

一、硬件配置说明
PWM输出引脚:P23  
状态检测引脚:P11、P14(用于判断是否进入高电平状态)  
控制引脚:P10(用于触发90%占空比输出)

二、功能逻辑说明

1. 初始状态:
当 P11 和 P14 中有一个为低电平,或两者都为低电平时,且 P10 为高电平,则 P23 输出 90% 占空比的 PWM。
   
2. 状态转换:
当 P11 或 P14 变为高电平时,PWM 占空比从 90% 开始逐渐降为 0%,耗时 2 秒。
一旦 P11 和 P14 再次变为低电平(或其中一个为低),且 P10 为高电平,则重新输出 90% 占空比,再次进入降频过程。

3. 循环机制:
整个逻辑在 P11/P14 状态变化下不断循环执行。

三、代码实现(基于STC32G8K64)
  1. c
  2. include "stc32g8k64.h"
  3. define PWMPIN    P23       // PWM输出引脚
  4. define P11PIN    P11       // 状态检测引脚
  5. define P14PIN    P14       // 状态检测引脚
  6. define P10PIN    P10       // 控制引脚
  7. volatile uint8t pwmduty = 90;     // 初始占空比为90%
  8. volatile uint8t state = 0;        // 0:正常输出 1:下降中
  9. volatile uint32t timercount = 0; // 计时计数器
  10. // 初始化PWM
  11. void PWMInit(void) {
  12.     // 设置P23为PWM输出
  13.     P2M1 &= ~0x08;     // P23设置为普通IO
  14.     P2M2 |= 0x08;
  15.    
  16.     // 配置定时器2为PWM模式
  17.     TMOD &= 0x0F;      // 清除T2控制位
  18.     TMOD |= 0x20;      // T2为模式2(8位自动重装)
  19.    
  20.     TH2 = 0xFF;        // 初始值设为0xFF(16MHz系统时钟,约1ms周期)
  21.     TL2 = 0xFF;
  22.     RCAP2H = 0xFF;
  23.     RCAP2L = 0xFF;
  24.    
  25.     ET2 = 1;           // 使能T2中断
  26.     EA = 1;            // 全局中断使能
  27.     TR2 = 1;           // 启动T2
  28.    
  29.     // 设置PWM占空比
  30.     PWMDutySet(pwmduty);
  31. }
  32. // 设置PWM占空比
  33. void PWMDutySet(uint8t duty) {
  34.     uint16t period = 256;   // 定时器2为8位,最大256
  35.     uint16t pulse = (duty  period) / 100;
  36.     if (pulse > period) pulse = period;
  37.     TH2 = 0xFF - (period - pulse);
  38.     TL2 = 0xFF - (period - pulse);
  39. }
  40. // 定时器2中断服务函数
  41. void Timer2ISR(void) interrupt 5 {
  42.     static uint32t cnt = 0;
  43.    
  44.     cnt++;
  45.     if (cnt >= 2000) {   // 2秒(假设系统频率为16MHz,1ms中断一次)
  46.         cnt = 0;
  47.         if (state == 1) {
  48.             if (pwmduty > 0) {
  49.                 pwmduty--;
  50.                 PWMDutySet(pwmduty);
  51.             } else {
  52.                 state = 0;
  53.             }
  54.         }
  55.     }
  56. }
  57. // 检测输入状态
  58. void CheckStatus(void) {
  59.     static uint8t lastp11 = 1;
  60.     static uint8t lastp14 = 1;
  61.     static uint8t lastp10 = 1;
  62.     uint8t p11 = P11PIN;
  63.     uint8t p14 = P14PIN;
  64.     uint8t p10 = P10PIN;
  65.     if ((p11 == 0 || p14 == 0) && p10 == 1) {
  66.         if (state == 0) {
  67.             pwmduty = 90;
  68.             PWMDutySet(pwmduty);
  69.             state = 0;
  70.         }
  71.     } else {
  72.         if (state == 0) {
  73.             state = 1;
  74.             timercount = 0;
  75.         }
  76.     }
  77.     lastp11 = p11;
  78.     lastp14 = p14;
  79.     lastp10 = p10;
  80. }
  81. int main(void) {
  82.     // 初始化端口
  83.     P1M1 = 0x00;
  84.     P1M2 = 0xFF;
  85.     P2M1 = 0x00;
  86.     P2M2 = 0xFF;
  87.     PWMInit();
  88.     while (1) {
  89.         CheckStatus();
  90.     }
  91. }
复制代码

四、注意事项
系统时钟:本代码基于16MHz系统时钟编写,若实际使用不同频率,请调整定时器相关参数。
PWM精度:由于使用的是8位定时器,占空比精度为1%,90%占空比为230/256。
延时控制:2秒的降频时间依赖于定时器中断频率,建议使用更精确的定时方式以提升稳定性。

如需进一步优化或扩展功能(如增加LED指示、串口调试等),可继续补充需求。

[本文内容由国芯人工智能辅助生成,仅供参考]
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:461
  • 最近打卡:2025-08-11 00:10:12

9

主题

390

回帖

2783

积分

金牌会员

积分
2783
发表于 2025-7-7 14:07:36 | 显示全部楼层
既有电平状态,又有边沿状态处理,文字描述容易出错,不如画个简单真值表看得清楚
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:7
  • 最近打卡:2025-07-08 08:13:36

4

主题

12

回帖

92

积分

注册会员

积分
92
发表于 2025-7-8 08:13:36 | 显示全部楼层
网*** 发表于 2025-7-7 14:07
既有电平状态,又有边沿状态处理,文字描述容易出错,不如画个简单真值表看得清楚 ...

那我重新描述问题,这个描述错误了
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-8-11 15:06 , Processed in 0.136351 second(s), 66 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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