在好例子网,分享、交流、成长!
您当前所在位置:首页C# 开发实例C#语言基础 → 九齐单片机,三按键独立控制 RGB LED 亮度

九齐单片机,三按键独立控制 RGB LED 亮度

C#语言基础

下载此实例 编辑此实例
  • 开发语言:C#
  • 实例大小:0.01M
  • 下载次数:2
  • 浏览次数:0
  • 发布时间:2026-05-01
  • 实例类别:C#语言基础
  • 发 布 人:七星.
  • 文件格式:.c
  • 所需积分:2
 相关标签: LED RGB GB 亮度 控制

实例介绍

这段代码实现了基于 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;
}
以下不内容详见附档文件

标签: LED RGB GB 亮度 控制

实例下载地址

九齐单片机,三按键独立控制 RGB LED 亮度

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警