基本信息
源码名称:九齐单片机,三按键独立控制 RGB LED 亮度
源码大小:0.01M
文件格式:.c
开发语言:C#
更新时间:2026-05-01
   友情提示:(无需注册或充值,赞助后即可获取资源下载链接)

     嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):78630559

本次赞助数额为: 2 元 
   源码介绍

这段代码实现了基于 NY8BE62D 微控制器的 RGB LED 三键独立调光系统,核心功能如下:

一、硬件资源映射

引脚 功能 外设
PA4 红色LED PWM2
PA7 绿色LED PWM3
PB1 蓝色LED PWM1
PA6/PA0/PA1 红/绿/蓝按键 内部上拉输入

二、主要功能特点

1. 独立三通道控制

  • 三个按键分别控制红、绿、蓝LED亮度
  • 每通道支持 8级亮度(0~7循环)
  • 亮度值通过 brightness_R/G/B 变量保存

2. 硬件PWM实现

  • 使用芯片内置的 PWM1/PWM2/PWM3 模块
  • PWM分辨率 10位(0~1023)
  • 支持动态频率调节(20Hz ~ 10kHz

3. 按键扫描机制

  • 采用状态机实现按键消抖与长按检测
  • 短按:切换亮度等级(0→1→…→7→0)
  • 内置延时判断,避免重复触发

4. 定时系统

  • Timer0 产生100μs中断
  • 每10次中断(1ms)触发一次按键扫描
  • 同时提供1ms/10ms/100ms软件定时标志

三、核心函数说明

函数 作用
PWM_Init() 初始化三路PWM,默认1kHz频率
PWM_SetFrequency() 动态修改PWM频率(全局生效)
PWM_UpdateDuty_*() 将亮度等级转换为占空比(0~1023)
KeyScan_*() 各按键独立扫描与亮度更新
TIMR0_Init() 配置100μs定时中断

四、亮点设计

  • 频率独立可调:修改 pwm_freq_hz 变量并调用 PWM_SetFrequency() 即可
  • 看门狗保护:主循环中定期喂狗,增强系统稳定性
  • 低功耗预留:WakeUpFlag 变量为休眠唤醒预留接口
  • 代码模块化:红绿蓝三通道逻辑独立,便于维护

五、使用方式

  1. 上电后所有LED熄灭(亮度0)
  2. 按下某颜色按键 → 该通道亮度 1(循环0-7)
  3. 如需改变PWM频率,在main中调用 PWM_SetFrequency(5000) 即可

这是一个典型的嵌入式多任务状态机设计,充分利用了MCU硬件PWM资源,避免了软件模拟PWM对CPU的占用。

/*===========================================================================*/

// 文件名: main.c
// 芯片型号: NY8BE62D (SOP16)
// 功能描述: 三按键独立控制 RGB LED 亮度 (硬件PWM, 8级亮度, 频率可调 20Hz~10kHz)
// 引脚映射:
//   PWM2(PA4) -> 红色LED
//   PWM3(PA7) -> 绿色LED
//   PWM1(PB1) -> 蓝色LED
//   按键R(PA6), 按键G(PA0), 按键B(PA1) (内部上拉, 低电平有效)
// 频率设置: 修改全局变量 pwm_freq_hz 后调用 PWM_SetFrequency() 即可
// 编译环境: Nyquest NYC 编译器 / SDCC (包含 ny8be62d.h 和 ny8common.h)
//===========================================================================*/

#include <ny8be62d.h>
#include <ny8common.h>

// 数据类型
#define  u8     unsigned char
#define  u16    unsigned int
#define  u32    unsigned long

// 硬件引脚映射
#define  LED_R       PA4             // 红色LED -> PWM2
#define  LED_G       PA7             // 绿色LED -> PWM3
#define  LED_B       PB1             // 蓝色LED -> PWM1

#define  KEY_R       PA6
#define  KEY_G       PA0
#define  KEY_B       PA1

// PWM 参数
#define  PWM_RESOLUTION      1024
#define  BRIGHTNESS_LEVELS   8
#define  INSTRUCTION_FREQ    1000000UL   // 1MHz (16MHz/4T)
#define  MIN_PWM_FREQ        20
#define  MAX_PWM_FREQ        10000

// T0MD 寄存器配置值 (PS0WDT=0 给 Timer0, PS0SEL=2 对应 1:4 分频)
#define  T0MD_CONFIG         0x02

// PCON1 寄存器位掩码
#define  PCON1_TOEN          0x01        // bit0: Timer0 使能

// Timer1/PWM 控制位
#define  T1EN                0x80
#define  T1RL                0x40
#define  PWM1OE              0x20
#define  T1PS_1              0x00
#define  PWMxEN              0x80
#define  PWMxS_TMR1          0x00

// 全局变量
unsigned char key0;
__sbit delay_1ms_fig   = key0:0;
__sbit delay_10ms_fig  = key0:1;
__sbit delay_100ms_fig = key0:2;

unsigned char key1;
__sbit KeySubStep_R    = key1:0;
__sbit KeySubStep_G    = key1:1;
__sbit KeySubStep_B    = key1:2;
__sbit WakeUpFlag      = key1:3;

volatile u8 brightness_R = 0;
volatile u8 brightness_G = 0;
volatile u8 brightness_B = 0;
volatile u16 pwm_freq_hz = 1000;

u16 keyDelay_R = 0, keyDelayTimr_R = 0;
u16 keyDelay_G = 0, keyDelayTimr_G = 0;
u16 keyDelay_B = 0, keyDelayTimr_B = 0;
u8  tmr0_100us_cnt = 0;

// 函数声明
void TIMR0_Init(void);
void PWM_Init(void);
void PWM_SetFrequency(u16 freq_hz);
void PWM_UpdateDuty_R(void);
void PWM_UpdateDuty_G(void);
void PWM_UpdateDuty_B(void);
void IO_Init(void);
void KeyScan_R(void);
void KeyScan_G(void);
void KeyScan_B(void);

/*===========================================================================*/
// 函数名称: TIMR0_Init
// 功能描述: 初始化Timer0, 产生100us中断
/*===========================================================================*/
void TIMR0_Init(void)
{
    // 关闭 Timer0 (清除 TOEN 位)
    PCON1 &= ~PCON1_TOEN;

    TMR0 = 231;                         // 100us 中断初值 (1us指令周期, 4分频)

    // 配置 T0MD: 预分频器0分配给Timer0, 分频比1:4
    T0MD = T0MD_CONFIG;

    INTEbits.T0IE = 1;                  // 使能 Timer0 中断

    // 启用 Timer0 (置位 TOEN)
    PCON1 |= PCON1_TOEN;
}

/*===========================================================================*/
// 函数名称: PWM_Init
// 功能描述: 初始化三路硬件PWM (PWM1/PWM2/PWM3)
/*===========================================================================*/
void PWM_Init(void)
{
    u16 period_val;

    // 关闭 Timer1
    T1CR1 = 0x00;
    T1CR2 = 0x00;

    // 计算周期值
    period_val = (u16)(INSTRUCTION_FREQ / pwm_freq_hz) - 1;
    if(period_val > 1023) period_val = 1023;
    if(period_val < 1)    period_val = 1;

    // 写入周期值 (低8位在TMR1, 高2位在TMRH[1:0])
    TMR1 = (u8)(period_val & 0xFF);
    TMRH = (TMRH & 0xFC) | ((u8)(period_val >> 8) & 0x03);

    // 使能 Timer1, 重载模式, PWM1输出, 预分频1:1
    T1CR1 = T1EN | T1RL | PWM1OE | T1PS_1;

    // 配置 PWM2 (红色)
    P2CR1 = PWMxEN | PWMxS_TMR1;
    PWM2DUTY = 0x00;
    TMRH &= 0xF3;                       // 清零PWM2高2位 (TMRH[3:2])

    // 配置 PWM3 (绿色)
    P3CR1 = PWMxEN | PWMxS_TMR1;
    PWM3DUTY = 0x00;
    TM4RH &= 0xF3;                      // 清零PWM3高2位 (TM4RH[3:2])

    // 配置 PWM1 (蓝色)
    PWM1DUTY = 0x00;
    TMRH &= 0xFC;                       // 清零PWM1高2位 (TMRH[1:0])
}

/*===========================================================================*/
// 函数名称: PWM_SetFrequency
// 功能描述: 动态修改三路PWM的频率
/*===========================================================================*/
void PWM_SetFrequency(u16 freq_hz)
{
    u16 period_val;

    if(freq_hz < MIN_PWM_FREQ) freq_hz = MIN_PWM_FREQ;
    if(freq_hz > MAX_PWM_FREQ) freq_hz = MAX_PWM_FREQ;
    pwm_freq_hz = freq_hz;

    period_val = (u16)(INSTRUCTION_FREQ / freq_hz) - 1;
    if(period_val > 1023) period_val = 1023;
    if(period_val < 1)    period_val = 1;

    TMR1 = (u8)(period_val & 0xFF);
    TMRH = (TMRH & 0xFC) | ((u8)(period_val >> 8) & 0x03);
}

/*===========================================================================*/
// 函数名称: PWM_UpdateDuty_R / _G / _B
// 功能描述: 根据亮度等级更新占空比 (0~1023)
/*===========================================================================*/
void PWM_UpdateDuty_R(void)
{
    u16 duty = (u16)((u32)brightness_R * 1023 / (BRIGHTNESS_LEVELS - 1));
    PWM2DUTY = (u8)(duty & 0xFF);
    TMRH = (TMRH & 0xF3) | ((u8)(duty >> 6) & 0x0C);
}

void PWM_UpdateDuty_G(void)
{
    u16 duty = (u16)((u32)brightness_G * 1023 / (BRIGHTNESS_LEVELS - 1));
    PWM3DUTY = (u8)(duty & 0xFF);
    TM4RH = (TM4RH & 0xF3) | ((u8)(duty >> 6) & 0x0C);
}

void PWM_UpdateDuty_B(void)
{
    u16 duty = (u16)((u32)brightness_B * 1023 / (BRIGHTNESS_LEVELS - 1));
    PWM1DUTY = (u8)(duty & 0xFF);
    TMRH = (TMRH & 0xFC) | ((u8)(duty >> 8) & 0x03);
}

/*===========================================================================*/
// 函数名称: IO_Init
// 功能描述: 初始化IO口方向及上下拉电阻
/*===========================================================================*/
void IO_Init(void)
{
    // 开漏全部关闭
    BODCON = 0x00;

    // 下拉全部关闭 (1=关)
    ABPLCON = 0xFF;
    PCONbits.PLPA4 = 1;                 // PA4 下拉关
    APHCON |= 0x20;                     // PA5 下拉关 (位5置1)

    // PA口上拉: PA6,PA0,PA1 开启上拉 (0=开)
    APHCON = 0xFF;                      // 先全部关闭
    APHCON &= ~((1<<6) | (1<<0) | (1<<1));

    // PB口上拉全部关闭
    BPHCON = 0xFF;

    // 方向设置: PB1 输出, 其余输入
    IOSTB = 0xFD;                       // 0b11111101
    PORTB = 0x00;

    // PA4,PA7 输出; PA6,PA0,PA1 输入
    IOSTA = (1<<6) | (1<<0) | (1<<1);   // 1=输入
    PORTA = 0x00;
}
以下不内容详见附档文件