SCT8H8K64U 单片机 写一个用PWMB的P2.0管脚控制LED灯亮度的程序,要求P3.0按下时,占空比提高10%,P3.1按下时,占空比减少10%
AI
好的,以下是基于 STC8H8K64U 的完整程序,使用 PWMB 通道5(PWM5) 从 P2.0 输出 PWM 驱动 LED,P3.0 按下占空比增加 10%,P3.1 按下占空比减少 10%。
完整程序代码
/*---------------------------------------------------------------------*/
/* --- STC8H8K64UPWMB(PWM5) 输出P2.0 控制LED亮度 */
/* --- P3.0 按下 → 占空比 +10%,P3.1 按下 → 占空比 -10% */
/* --- 主频: 24MHz (内部IRC) */
/*---------------------------------------------------------------------*/
#include "stc8h.h"
#include "intrins.h"
#define MAIN_Fosc 24000000L // 主时钟频率 24MHz
#define PWM_PERIOD 1000 // PWM周期 (ARR+1 = 1000)
#define DUTY_STEP 100 // 每步 10% (1000 × 10% = 100)
u16 pwm_duty; // 当前占空比比较值
//========================================================================
// 函数: Delay20ms()
// 描述: 按键消抖延时 (约20ms @ 24MHz)
//========================================================================
void Delay20ms(void)
{
unsigned int i;
for(i = 0; i < 60000; i++);
}
//========================================================================
// 函数: PWM_Init()
// 描述: PWMB 通道5(PWM5) 初始化,输出到 P2.0
//========================================================================
void PWM_Init(void)
{
P_SW2 |= 0x80; // 使能扩展寄存器(XFR)访问
/*--- 设置 I/O 口模式 ---*/
// P2.0 配置为推挽输出 (PWM输出)
P2M1 &= ~0x01;
P2M0 |=0x01;
// P3.0、P3.1 配置为准双向口 (按键输入,内部有弱上拉)
P3M1 &= ~0x03;
P3M0 &= ~0x03;
/*--- PWMB 通道5 (PWM5) 输出到 P2.0 ---*/
PWMB_PS = 0x00; // C5PS=00 → PWM5 输出到 P2.0
PWMB_CCER1 = 0x00; // 先关闭通道,才能配置 CCMR1
PWMB_CCMR1 = 0x60; // OC5M=110(PWM模式1) 向上计数时
// CNT<CCR5 输出高,否则输出低
// OC5PE=1(使能预装载)
// CC5S=00(输出模式)
PWMB_CCER1 = 0x01; // CC5E=1(使能通道5输出), CC5P=0(高电平有效)
// PWM频率 = 主频 / (PSCR+1) / (ARR+1)
// = 24MHz / 24 / 1000 = 1KHz
PWMB_PSCR = 24 - 1; // 预分频,得到 1MHz 时钟
PWMB_ARR= PWM_PERIOD - 1;// 自动重装载值 (周期 = 1000)
pwm_duty = 500; // 初始占空比 50%
PWMB_CCR5 = pwm_duty; // 写入比较值
PWMB_ENO= 0x01; // ENO5P=1 → 使能 PWM5 端口输出
PWMB_BKR= 0x80; // MOEB=1→ 使能主输出
PWMB_CR1= 0x81; // ARPE=1(ARR预装载), CENB=1(启动计时)
}
//========================================================================
// 函数: main()
// 描述: 主函数,循环检测按键并调整占空比
//========================================================================
void main(void)
{
PWM_Init();
while(1)
{
//---- 检测 P3.0 按下 (低电平有效) ----
if((P3 & 0x01) == 0)
{
Delay20ms(); // 去抖动
if((P3 & 0x01) == 0) // 确认按下
{
// 占空比增加 10%
if(pwm_duty + DUTY_STEP <= PWM_PERIOD)
pwm_duty += DUTY_STEP;
else
pwm_duty = PWM_PERIOD; // 上限 100%
PWMB_CCR5 = pwm_duty; // 更新比较值 → 立即改变占空比
// 等待按键释放
while((P3 & 0x01) == 0);
Delay20ms();
}
}
//---- 检测 P3.1 按下 (低电平有效) ----
if((P3 & 0x02) == 0)
{
Delay20ms(); // 去抖动
if((P3 & 0x02) == 0) // 确认按下
{
// 占空比减少 10%
if(pwm_duty >= DUTY_STEP)
pwm_duty -= DUTY_STEP;
else
pwm_duty = 0; // 下限 0%
PWMB_CCR5 = pwm_duty; // 更新比较值 → 立即改变占空比
// 等待按键释放
while((P3 & 0x02) == 0);
Delay20ms();
}
}
}
}
📋
程序说明
1. PWM 硬件配置
项目 配置 说明
PWMB 通道 通道5 (PWM5) PWMB 共有 4 个输出通道 (PWM5~PWM8)
输出引脚 P2.0 通过 PWMB_PS 的 C5PS=00 选择
PWM 模式 PWM 模式1 (OC5M=110) 向上计数时,CNT<CCR5 输出高,否则输出低
PWM 频率 1KHz 24MHz / (23+1) / (999+1) = 1KHz,适合 LED 调光
极性 高电平有效 (CC5P=0) PWM 高电平时间 = 占空比
2. 按键检测逻辑
P3.0 按下(接地) → pwm_duty += 100 → 占空比提高 10%
P3.1 按下(接地) → pwm_duty -= 100 → 占空比减少 10%
每次按键后等待释放再加 20ms 消抖,防止一次按下多次触发
占空比范围自动限制在 0 ~ 1000(对应 0% ~ 100%)
3. 初始状态
初始占空比设为 50%(pwm_duty = 500)
每次按键步进 10%(DUTY_STEP = 100)
4. 硬件接线
STC8H8K64U LED 电路
┌──────────┐
│ P2.0 ├─────┬───── LED ── 220Ω ── VCC (或 GND,取决于LED接法)
│ │ │
│ │
│ │
│ P3.0 ├───── 按键 ──── GND (按下=低电平,占空比+10%)
│ │
│ P3.1 ├───── 按键 ──── GND (按下=低电平,占空比-10%)
└──────────┘
📋
说明:由于程序配置为高电平有效(CC5P=0),LED 正极接 P2.0,负极串电阻到 GND 时,占空比越大 LED 越亮。若 LED 接法相反,可将 CC5P 改为 1(低电平有效)或硬件上改变 LED 方向。
关键寄存器参考(来自 STC8H 数据手册)
寄存器 地址 本程序设置值 作用
PWMB_PS FEB6H 0x00 C5PS=00,PWM5输出到P2.0()
PWMB_CCMR1 FEE8H 0x60 OC5M=110(PWM模式1),OC5PE=1(预装载)()
PWMB_CCER1 FEECH 0x01 CC5E=1(使能输出),CC5P=0(高有效)()
PWMB_ENO FEB5H 0x01 ENO5P=1(使能PWM5引脚输出)()
PWMB_BKR FEFDH 0x80 MOEB=1(主输出使能)()
PWMB_CR1 FEE0H 0x81 ARPE=1(ARR预装载),CENB=1(启动)()
编译下载提示:在 Keil 中使用 STC8H8K64U 头文件,下载时选择 24MHz 内部IRC时钟,硬件连接好 P3.0/P3.1 按键和 P2.0 LED 即可运行。
编译时提示错误 main.c(13): error C129: missing ';' before 'pwm_duty'
手动将 u16 pwm_duty; u16 pwm_duty;修改为 unsigned int pwm_duty; 编译通过。下载程序后,程序正常运行。
有问必答,
问 www.STCAIMCU.com【AI助手】:
AI8051U替代12C5A16S2注意事项
有问必答,
问 www.STCAIMCU.com【AI助手】:
STC15W408AS的系统时钟分频如何配置,怎样实现精准延时?
有问必答,
问 www.STCAIMCU.com【AI助手】:
如何测量72MHz以下的外部信号,STC32的144MHz的高速PWM
问 www.STCAIMCU.com【AI助手】:
--推荐一款可以用于汽车呼吸灯项目的单片机型号。
--AI助手回答内容可以采纳。
问 www.STCAIMCU.com【AI助手】:
STC32G144K246的CAN-FD的使用注意事项
有问必答,
问 www.STCAIMCU.com【AI助手】:
STC8H8K驱动8050三极管,IO口用什么模式
有问必答,
问 www.STCAIMCU.com【AI助手】:
使用型号STC8G1K08,帮我写一个P5.4输出时钟的例程
有问必答,
问 www.STCAIMCU.com【AI助手】:
STC8G1K08-SOP16取代8F1K08S2-SOP16的注意事项
有问必答,
问 www.STCAIMCU.com【AI助手】:
STC8H系列MCU的uart,即P30P31可以直接接3.3V吗?