好的,我已经获取了所有必要的外设信息。现在开始编写这个一体化演示工程。由于代码量较大,我将分多个文件输出。
AI8051U 一体化演示工程
文件清单
| 文件名 |
说明 |
main.c |
主程序,包含初始化、主循环调度 |
uart_cmd.c / uart_cmd.h |
串口命令解析系统 |
pwm_rgb.c / pwm_rgb.h |
6路PWM RGB彩灯控制(渐变呼吸/色彩循环/固定亮度) |
adc_volt.c / adc_volt.h |
ADC电压采集 |
ext_int.c / ext_int.h |
外部电平中断+软件消抖 |
iap_flash.c / iap_flash.h |
Flash读写操作 |
config.h |
全局配置和头文件包含 |
文件1:config.h
/*
* config.h - AI8051U 一体化演示工程 全局配置头文件
*
* 硬件平台:AI8051U 系列单片机
* 编译器:Keil C251 (8位模式)
* 系统时钟:24MHz (内部IRC)
*
* 引脚分配:
* UART1: P3.0(RxD), P3.1(TxD) - 串口命令交互
* PWM输出(6路RGB):
* PWMA_CH1(PWM1P) -> P1.0 - R通道
* PWMA_CH2(PWM2P) -> P1.1 - G通道
* PWMA_CH3(PWM3P) -> P1.2 - B通道
* PWMA_CH4(PWM4P) -> P1.3 - R2通道
* PWMB_CH1(PWM5) -> P1.4 - G2通道
* PWMB_CH2(PWM6) -> P1.5 - B2通道
* ADC输入: P1.6 (ADC通道6)
* 外部中断: P3.2 (INT0, 下降沿触发)
*
* 串口参数:115200, 8N1
*/
#ifndef __CONFIG_H__
#define __CONFIG_H__
#include "Ai8051U.H" // AI8051U 头文件
#include "intrins.h" // _nop_() 等内建函数
#include <stdio.h> // sprintf, sscanf
/* 系统时钟频率 */
#define FOSC 24000000UL
/* 串口波特率 */
#define BAUD_RATE 115200UL
#define BRT_VALUE (65536 - (FOSC / 4 / BAUD_RATE))
/* 串口接收缓冲区大小 */
#define UART_BUF_SIZE 64
/* PWM 周期 (ARR值) */
#define PWM_PERIOD 1000
/* ADC 参考电压 (mV) */
#define ADC_VREF 3300UL
/* 软件消抖时间 (ms) */
#define DEBOUNCE_MS 20
/* IAP/EEPROM 起始地址 (扇区0) */
#define IAP_START_ADDR 0x0000
/* RGB LED 数量 */
#define RGB_LED_NUM 2
/* PWM 模式枚举 */
typedef enum {
PWM_MODE_BREATH = 0, /* 渐变呼吸模式 */
PWM_MODE_CYCLE = 1, /* 色彩循环模式 */
PWM_MODE_FIXED = 2 /* 固定亮度模式 */
} PWM_Mode;
#endif /* __CONFIG_H__ */
文件2:uart_cmd.h
/*
* uart_cmd.h - 串口命令解析系统
*
* 命令格式: <命令前缀><参数>\r\n
* 读写Flash: F<地址:4位HEX>,<数据:2位HEX> 或 F<地址:4位HEX>R
* 调节PWM: P<通道:1位>,<占空比:0-1000> 或 P<模式:0-2>
* 采集ADC: A<通道:0-15>
* 帮助: H
*/
#ifndef __UART_CMD_H__
#define __UART_CMD_H__
/* 命令类型 */
typedef enum {
CMD_NONE = 0,
CMD_FLASH = 1, /* Flash 操作 */
CMD_PWM = 2, /* PWM 操作 */
CMD_ADC = 3, /* ADC 操作 */
CMD_HELP = 4 /* 帮助 */
} CmdType;
/* 命令解析结果结构体 */
typedef struct {
CmdType type; /* 命令类型 */
unsigned char param1; /* 参数1 */
unsigned int param2; /* 参数2 */
unsigned char is_read; /* Flash: 1=读, 0=写 */
} CmdResult;
/* 初始化串口1 (115200bps, 定时器2做波特率发生器) */
void UART1_Init(void);
/* 发送一个字节 (阻塞) */
void UART1_SendByte(unsigned char dat);
/* 发送字符串 */
void UART1_SendString(char *str);
/* 发送缓冲区数据 (指定长度) */
void UART1_SendBuffer(unsigned char *buf, unsigned char len);
/* 发送一个整数 (十进制) */
void UART1_SendInt(int val);
/* 解析串口接收到的命令字符串 */
unsigned char UART1_ParseCmd(char *cmd_str, CmdResult *result);
/* 获取接收缓冲区中是否收到完整一行 (以\r\n结尾) */
unsigned char UART1_GetLine(char *buf, unsigned char max_len);
/* 串口中断服务函数声明 (在main.c或uart_cmd.c中实现) */
void Uart1_Isr(void) interrupt 4;
#endif /* __UART_CMD_H__ */
文件3:uart_cmd.c
/*
* uart_cmd.c - 串口命令解析系统实现
*
* 基于手册"串口1使用定时器2做波特率发生器"范例编写
* 参考手册章节:19 2组USART-LIN/SPI,同步/异步串口通信
*/
#include "config.h"
#include "uart_cmd.h"
/* 串口环形缓冲区 */
static unsigned char rx_buffer[UART_BUF_SIZE];
static unsigned char rx_wptr = 0;
static unsigned char rx_rptr = 0;
static unsigned char rx_line_ready = 0; /* 收到完整一行标志 */
/* 发送忙标志 */
static bit tx_busy = 0;
/*
* UART1_Init - 初始化串口1
* 模式1 (8位数据, 可变波特率)
* 定时器2做波特率发生器, 1T模式
* 波特率 = FOSC / 4 / (65536 - BRT_VALUE)
*/
void UART1_Init(void)
{
/* 设置串口1为模式1: 8位数据, 可变波特率, 允许接收 */
SCON = 0x50; /* SM0=0, SM1=1, REN=1 */
/* 选择定时器2作为波特率发生器 */
S1BRT = 1;
/* 设置定时器2重装值 */
T2L = (unsigned char)(BRT_VALUE);
T2H = (unsigned char)(BRT_VALUE >> 8);
/* 定时器2 1T模式, 启动 */
T2x12 = 1;
T2R = 1;
/* 初始化缓冲区指针 */
rx_wptr = 0;
rx_rptr = 0;
rx_line_ready = 0;
tx_busy = 0;
/* 使能串口1中断 */
ES = 1;
}
/*
* UART1_SendByte - 发送一个字节 (阻塞查询方式)
*/
void UART1_SendByte(unsigned char dat)
{
while (tx_busy); /* 等待上次发送完成 */
tx_busy = 1;
SBUF = dat; /* 写入SBUF触发发送 */
}
/*
* UART1_SendString - 发送字符串
*/
void UART1_SendString(char *str)
{
while (*str != '\0')
{
UART1_SendByte((unsigned char)(*str));
str++;
}
}
/*
* UART1_SendBuffer - 发送指定长度的数据
*/
void UART1_SendBuffer(unsigned char *buf, unsigned char len)
{
unsigned char i;
for (i = 0; i < len; i++)
{
UART1_SendByte(buf[i]);
}
}
/*
* UART1_SendInt - 发送十进制整数
*/
void UART1_SendInt(int val)
{
char buf[12];
sprintf(buf, "%d", val);
UART1_SendString(buf);
}
/*
* UART1_GetLine - 从接收缓冲区取一行 (以\r\n结尾)
* 返回1表示成功获取一行, 0表示无完整行
*/
unsigned char UART1_GetLine(char *buf, unsigned char max_len)
{
unsigned char i = 0;
unsigned char dat;
if (!rx_line_ready)
{
return 0; /* 无完整行 */
}
/* 关闭中断保护 */
ES = 0;
while (rx_rptr != rx_wptr)
{
dat = rx_buffer[rx_rptr];
rx_rptr = (rx_rptr + 1) & (UART_BUF_SIZE - 1);
if (dat == '\n')
{
/* 遇到换行符, 行结束 */
buf[i] = '\0';
rx_line_ready = 0;
ES = 1;
return 1;
}
else if (dat != '\r') /* 忽略回车符 */
{
if (i < max_len - 1)
{
buf[i++] = (char)dat;
}
}
}
/* 理论上不会到这里, 但以防万一 */
rx_line_ready = 0;
ES = 1;
buf[i] = '\0';
return 1;
}
/*
* UART1_ParseCmd - 解析命令字符串
*
* 命令格式:
* F<地址4位HEX>,<数据2位HEX> - 写Flash
* F<地址4位HEX>R - 读Flash
* P<通道1位>,<占空比0-1000> - 设置PWM通道占空比
* P<模式0-2> - 设置PWM模式
* A<通道0-15> - 读取ADC
* H - 帮助
*
* 返回1表示解析成功, 0表示格式错误
*/
unsigned char UART1_ParseCmd(char *cmd_str, CmdResult *result)
{
unsigned char prefix;
unsigned int addr;
unsigned int data_val;
unsigned char ch;
unsigned int duty;
unsigned char mode;
if (cmd_str == 0 || result == 0)
{
return 0;
}
/* 跳过前导空格 */
while (*cmd_str == ' ' || *cmd_str == '\t')
{
cmd_str++;
}
prefix = (unsigned char)(*cmd_str);
if (prefix == '\0')
{
return 0;
}
switch (prefix)
{
case 'F':
case 'f':
/* Flash操作: F<地址4位HEX>,<数据2位HEX> 或 F<地址4位HEX>R */
result->type = CMD_FLASH;
if (sscanf(cmd_str + 1, "%4x", &addr) != 1)
{
return 0;
}
result->param1 = (unsigned char)(addr & 0xFF);
result->param2 = addr;
/* 检查是否为读命令 (以R或r结尾) */
{
char *p = cmd_str + 1;
while (*p >= '0' && *p <= '9' || *p >= 'A' && *p <= 'F' || *p >= 'a' && *p <= 'f')
{
p++;
}
if (*p == 'R' || *p == 'r')
{
result->is_read = 1;
}
else if (*p == ',')
{
/* 写命令: 解析数据 */
result->is_read = 0;
if (sscanf(p + 1, "%2x", &data_val) != 1)
{
return 0;
}
result->param2 = (unsigned int)data_val;
}
else
{
return 0;
}
}
return 1;
case 'P':
case 'p':
/* PWM操作: P<通道>,<占空比> 或 P<模式> */
result->type = CMD_PWM;
if (sscanf(cmd_str + 1, "%d,%d", &ch, &duty) == 2)
{
/* 设置通道占空比 */
result->param1 = (unsigned char)ch;
result->param2 = duty;
}
else if (sscanf(cmd_str + 1, "%d", &mode) == 1)
{
/* 设置模式 */
result->param1 = 0xFF; /* 标记为模式设置 */
result->param2 = (unsigned int)mode;
}
else
{
return 0;
}
return 1;
case 'A':
case 'a':
/* ADC操作: A<通道> */
result->type = CMD_ADC;
if (sscanf(cmd_str + 1, "%d", &ch) != 1)
{
return 0;
}
result->param1 = (unsigned char)ch;
result->param2 = 0;
return 1;
case 'H':
case 'h':
result->type = CMD_HELP;
return 1;
default:
return 0;
}
}
/*
* Uart1_Isr - 串口1中断服务函数
* 中断向量号4
*/
void Uart1_Isr(void) interrupt 4
{
unsigned char dat;
if (TI) /* 发送中断 */
{
TI = 0;
tx_busy = 0;
}
if (RI) /* 接收中断 */
{
RI = 0;
dat = SBUF;
/* 存入环形缓冲区 */
rx_buffer[rx_wptr] = dat;
rx_wptr = (rx_wptr + 1) & (UART_BUF_SIZE - 1);
/* 检测到换行符, 标记行就绪 */
if (dat == '\n')
{
rx_line_ready = 1;
}
}
}
文件4:pwm_rgb.h
/*
* pwm_rgb.h - 6路PWM RGB彩灯控制
*
* 使用PWMA (通道1~4) 和 PWMB (通道1~2) 共6路PWM
* 支持三种模式: 渐变呼吸、色彩循环、固定亮度
*
* 参考手册章节:29 16位高级PWM定时器
*/
#ifndef __PWM_RGB_H__
#define __PWM_RGB_H__
#include "config.h"
/* RGB LED 通道索引 */
#define RGB_R1 0 /* PWMA_CH1 -> P1.0 */
#define RGB_G1 1 /* PWMA_CH2 -> P1.1 */
#define RGB_B1 2 /* PWMA_CH3 -> P1.2 */
#define RGB_R2 3 /* PWMA_CH4 -> P1.3 */
#define RGB_G2 4 /* PWMB_CH1 -> P1.4 */
#define RGB_B2 5 /* PWMB_CH2 -> P1.5 */
/* 初始化高级PWM (PWMA + PWMB) */
void PWM_Init(void);
/* 设置单个PWM通道占空比 (0 ~ PWM_PERIOD) */
void PWM_SetDuty(unsigned char channel, unsigned int duty);
/* 设置RGB LED1 颜色 (R, G, B 各 0~PWM_PERIOD) */
void PWM_SetRGB1(unsigned int r, unsigned int g, unsigned int b);
/* 设置RGB LED2 颜色 (R, G, B 各 0~PWM_PERIOD) */
void PWM_SetRGB2(unsigned int r, unsigned int g, unsigned int b);
/* 设置PWM工作模式 */
void PWM_SetMode(PWM_Mode mode);
/* PWM主循环处理 (在main循环中周期调用) */
void PWM_Task(void);
#endif /* __PWM_RGB_H__ */
文件5:pwm_rgb.c
/*
* pwm_rgb.c - 6路PWM RGB彩灯控制实现
*
* PWMA: 通道1~4 (PWM1P~PWM4P) 映射到 P1.0~P1.3
* PWMB: 通道1~2 (PWM5~PWM6) 映射到 P1.4~P1.5
*
* 参考手册章节:29 16位高级PWM定时器
* 以及手册中"使能高级PWM的高速模式(异步模式)"范例
*/
#include "config.h"
#include "pwm_rgb.h"
/* 当前PWM模式 */
static PWM_Mode current_mode = PWM_MODE_BREATH;
/* 当前RGB值 (用于固定亮度模式) */
static unsigned int rgb1_val[3] = {PWM_PERIOD, 0, 0}; /* R1, G1, B1 */
static unsigned int rgb2_val[3] = {0, PWM_PERIOD, 0}; /* R2, G2, B2 */
/* 呼吸/循环模式变量 */
static unsigned int breath_step = 0;
static unsigned int cycle_phase = 0;
/*
* PWMA_WriteReg - 异步写PWMA寄存器 (高速模式)
* 参考手册"HSPWM地址寄存器"章节
*/
static void PWMA_WriteReg(unsigned char addr, unsigned char dat)
{
while (HSPWMA_ADR & 0x80); /* 等待前一次异步操作完成 */
HSPWMA_DAT = dat; /* 准备数据 */
HSPWMA_ADR = addr & 0x7F; /* 设置地址, 写操作 */
}
/*
* PWMA_ReadReg - 异步读PWMA寄存器 (高速模式)
*/
static unsigned char PWMA_ReadReg(unsigned char addr)
{
unsigned char dat;
while (HSPWMA_ADR & 0x80); /* 等待前一次异步操作完成 */
HSPWMA_ADR = addr | 0x80; /* 设置地址, 读操作 */
while (HSPWMA_ADR & 0x80); /* 等待当前读取完成 */
dat = HSPWMA_DAT; /* 读取数据 */
return dat;
}
/*
* PWMB_WriteReg - 异步写PWMB寄存器
*/
static void PWMB_WriteReg(unsigned char addr, unsigned char dat)
{
while (HSPWMB_ADR & 0x80);
HSPWMB_DAT = dat;
HSPWMB_ADR = addr & 0x7F;
}
/*
* PWMB_ReadReg - 异步读PWMB寄存器
*/
static unsigned char PWMB_ReadReg(unsigned char addr)
{
unsigned char dat;
while (HSPWMB_ADR & 0x80);
HSPWMB_ADR = addr | 0x80;
while (HSPWMB_ADR & 0x80);
dat = HSPWMB_DAT;
return dat;
}
/*
* PWM_Init - 初始化高级PWM
*
* PWMA: 使用系统时钟, 不分频, ARR=1000
* 通道1~4: PWM模式1 (CNT<CCR时输出有效)
* PWMB: 同PWMA配置
*/
void PWM_Init(void)
{
unsigned char i;
/* 设置PWM输出引脚为推挽输出 */
P1M0 |= 0x3F; /* P1.0~P1.5 推挽输出 */
P1M1 &= ~0x3F;
/* 使能PWMA异步访问 (高速模式) */
HSPWMA_CFG = 0x03;
/* ---- PWMA 配置 ---- */
/* 关闭所有通道输出 */
PWMA_WriteReg((unsigned char)&PWMA_CCER1, 0x00);
PWMA_WriteReg((unsigned char)&PWMA_CCER2, 0x00);
/* 配置通道1~4为PWM输出模式 (OCxREF输出PWM) */
/* CCMR1: 通道1, 模式: PWM模式1 (110) */
PWMA_WriteReg((unsigned char)&PWMA_CCMR1, 0x60); /* OC1M=110, 预装载使能 */
PWMA_WriteReg((unsigned char)&PWMA_CCMR2, 0x60); /* 通道2 */
PWMA_WriteReg((unsigned char)&PWMA_CCMR3, 0x60); /* 通道3 */
PWMA_WriteReg((unsigned char)&PWMA_CCMR4, 0x60); /* 通道4 */
/* 使能通道输出 (CCER1: CC1E, CC2E; CCER2: CC3E, CC4E) */
PWMA_WriteReg((unsigned char)&PWMA_CCER1, 0x55); /* 使能CC1/CC1N, CC2/CC2N */
PWMA_WriteReg((unsigned char)&PWMA_CCER2, 0x55); /* 使能CC3/CC3N, CC4/CC4N */
/* 使能PWM信号输出到端口 */
PWMA_WriteReg((unsigned char)&PWMA_ENO, 0x0F); /* ENO1~ENO4 使能 */
/* 使能主输出 */
PWMA_WriteReg((unsigned char)&PWMA_BKR, 0x80); /* MOE=1 */
/* 设置PWM周期 (ARR) */
PWMA_WriteReg((unsigned char)&PWMA_ARRH, (unsigned char)(PWM_PERIOD >> 8));
PWMA_WriteReg((unsigned char)&PWMA_ARRL, (unsigned char)(PWM_PERIOD));
/* 设置预分频器 (不分频) */
PWMA_WriteReg((unsigned char)&PWMA_PSCRH, 0x00);
PWMA_WriteReg((unsigned char)&PWMA_PSCRL, 0x00);
/* 设置各通道初始占空比为0 */
for (i = 1; i <= 4; i++)
{
unsigned char addr_h, addr_l;
switch (i)
{
case 1: addr_h = (unsigned char)&PWMA_CCR1H; addr_l = (unsigned char)&PWMA_CCR1L; break;
case 2: addr_h = (unsigned char)&PWMA_CCR2H; addr_l = (unsigned char)&PWMA_CCR2L; break;
case 3: addr_h = (unsigned char)&PWMA_CCR3H; addr_l = (unsigned char)&PWMA_CCR3L; break;
case 4: addr_h = (unsigned char)&PWMA_CCR4H; addr_l = (unsigned char)&PWMA_CCR4L; break;
default: continue;
}
PWMA_WriteReg(addr_h, 0x00);
PWMA_WriteReg(addr_l, 0x00);
}
/* 启动PWMA计数器 */
PWMA_WriteReg((unsigned char)&PWMA_CR1, 0x01); /* CEN=1 */
/* ---- PWMB 配置 ---- */
HSPWMB_CFG = 0x03;
PWMB_WriteReg((unsigned char)&PWMB_CCER1, 0x00);
/* 通道1~2为PWM输出 */
PWMB_WriteReg((unsigned char)&PWMB_CCMR1, 0x60);
PWMB_WriteReg((unsigned char)&PWMB_CCMR2, 0x60);
PWMB_WriteReg((unsigned char)&PWMB_CCER1, 0x11); /* 使能CC1, CC2 */
/* PWMB没有ENO寄存器, 直接输出 */
PWMB_WriteReg((unsigned char)&PWMB_BKR, 0x80);
PWMB_WriteReg((unsigned char)&PWMB_ARRH, (unsigned char)(PWM_PERIOD >> 8));
PWMB_WriteReg((unsigned char)&PWMB_ARRL, (unsigned char)(PWM_PERIOD));
PWMB_WriteReg((unsigned char)&PWMB_PSCRH, 0x00);
PWMB_WriteReg((unsigned char)&PWMB_PSCRL, 0x00);
PWMB_WriteReg((unsigned char)&PWMB_CCR1H, 0x00);
PWMB_WriteReg((unsigned char)&PWMB_CCR1L, 0x00);
PWMB_WriteReg((unsigned char)&PWMB_CCR2H, 0x00);
PWMB_WriteReg((unsigned char)&PWMB_CCR2L, 0x00);
PWMB_WriteReg((unsigned char)&PWMB_CR1, 0x01);
/* 设置默认模式为呼吸模式 */
current_mode = PWM_MODE_BREATH;
breath_step = 0;
cycle_phase = 0;
}
/*
* PWM_SetDuty - 设置单个PWM通道占空比
* channel: 0~5 对应 RGB_R1 ~ RGB_B2
* duty: 0 ~ PWM_PERIOD
*/
void PWM_SetDuty(unsigned char channel, unsigned int duty)
{
unsigned char addr_h, addr_l;
if (duty > PWM_PERIOD)
{
duty = PWM_PERIOD;
}
switch (channel)
{
case RGB_R1: /* PWMA_CH1 */
addr_h = (unsigned char)&PWMA_CCR1H;
addr_l = (unsigned char)&PWMA_CCR1L;
PWMA_WriteReg(addr_h, (unsigned char)(duty >> 8));
PWMA_WriteReg(addr_l, (unsigned char)(duty));
break;
case RGB_G1: /* PWMA_CH2 */
addr_h = (unsigned char)&PWMA_CCR2H;
addr_l = (unsigned char)&PWMA_CCR2L;
PWMA_WriteReg(addr_h, (unsigned char)(duty >> 8));
PWMA_WriteReg(addr_l, (unsigned char)(duty));
break;
case RGB_B1: /* PWMA_CH3 */
addr_h = (unsigned char)&PWMA_CCR3H;
addr_l = (unsigned char)&PWMA_CCR3L;
PWMA_WriteReg(addr_h, (unsigned char)(duty >> 8));
PWMA_WriteReg(addr_l, (unsigned char)(duty));
break;
case RGB_R2: /* PWMA_CH4 */
addr_h = (unsigned char)&PWMA_CCR4H;
addr_l = (unsigned char)&PWMA_CCR4L;
PWMA_WriteReg(addr_h, (unsigned char)(duty >> 8));
PWMA_WriteReg(addr_l, (unsigned char)(duty));
break;
case RGB_G2: /* PWMB_CH1 */
addr_h = (unsigned char)&PWMB_CCR1H;
addr_l = (unsigned char)&PWMB_CCR1L;
PWMB_WriteReg(addr_h, (unsigned char)(duty >> 8));
PWMB_WriteReg(addr_l, (unsigned char)(duty));
break;
case RGB_B2: /* PWMB_CH2 */
addr_h = (unsigned char)&PWMB_CCR2H;
addr_l = (unsigned char)&PWMB_CCR2L;
PWMB_WriteReg(addr_h, (unsigned char)(duty >> 8));
PWMB_WriteReg(addr_l, (unsigned char)(duty));
break;
default:
break;
}
}
/*
* PWM_SetRGB1 - 设置RGB LED1 颜色
*/
void PWM_SetRGB1(unsigned int r, unsigned int g, unsigned int b)
{
PWM_SetDuty(RGB_R1, r);
PWM_SetDuty(RGB_G1, g);
PWM_SetDuty(RGB_B1, b);
rgb1_val[0] = r;
rgb1_val[1] = g;
rgb1_val[2] = b;
}
/*
* PWM_SetRGB2 - 设置RGB LED2 颜色
*/
void PWM_SetRGB2(unsigned int r, unsigned int g, unsigned int b)
{
PWM_SetDuty(RGB_R2, r);
PWM_SetDuty(RGB_G2, g);
PWM_SetDuty(RGB_B2, b);
rgb2_val[0] = r;
rgb2_val[1] = g;
rgb2_val[2] = b;
}
/*
* PWM_SetMode - 设置PWM工作模式
*/
void PWM_SetMode(PWM_Mode mode)
{
current_mode = mode;
breath_step = 0;
cycle_phase = 0;
if (mode == PWM_MODE_FIXED)
{
/* 固定亮度模式: 恢复保存的颜色值 */
PWM_SetRGB1(rgb1_val[0], rgb1_val[1], rgb1_val[2]);
PWM_SetRGB2(rgb2_val[0], rgb2_val[1], rgb2_val[2]);
}
}
/*
* PWM_Task - PWM主循环处理
* 在main循环中周期调用, 实现呼吸/循环效果
*/
void PWM_Task(void)
{
unsigned int r1, g1, b1;
unsigned int r2, g2, b2;
unsigned int val;
switch (current_mode)
{
case PWM_MODE_BREATH:
/*
* 渐变呼吸模式:
* 所有LED同步呼吸, 亮度从0渐变到PWM_PERIOD再回到0
* breath_step: 0~1999, 0~999上升, 1000~1999下降
*/
if (breath_step < PWM_PERIOD)
{
val = breath_step; /* 上升阶段 */
}
else
{
val = 2 * PWM_PERIOD - breath_step; /* 下降阶段 */
}
/* LED1: 红色呼吸, LED2: 蓝色呼吸 */
PWM_SetRGB1(val, 0, 0);
PWM_SetRGB2(0, 0, val);
breath_step++;
if (breath_step >= 2 * PWM_PERIOD)
{
breath_step = 0;
}
break;
case PWM_MODE_CYCLE:
/*
* 色彩循环模式:
* 使用相位偏移实现彩虹效果
* cycle_phase: 0~2999
*/
{
unsigned int phase = cycle_phase % 1000;
/* LED1: 红->绿->蓝 循环 */
if (cycle_phase < 1000)
{
r1 = PWM_PERIOD - phase;
g1 = phase;
b1 = 0;
}
else if (cycle_phase < 2000)
{
r1 = 0;
g1 = PWM_PERIOD - phase;
b1 = phase;
}
else
{
r1 = phase;
g1 = 0;
b1 = PWM_PERIOD - phase;
}
/* LED2: 相位偏移500, 实现不同颜色 */
{
unsigned int phase2 = (cycle_phase + 500) % 3000;
unsigned int p2 = phase2 % 1000;
if (phase2 < 1000)
{
r2 = PWM_PERIOD - p2;
g2 = p2;
b2 = 0;
}
else if (phase2 < 2000)
{
r2 = 0;
g2 = PWM_PERIOD - p2;
b2 = p2;
}
else
{
r2 = p2;
g2 = 0;
b2 = PWM_PERIOD - p2;
}
}
PWM_SetRGB1(r1, g1, b1);
PWM_SetRGB2(r2, g2, b2);
}
cycle_phase++;
if (cycle_phase >= 3000)
{
cycle_phase = 0;
}
break;
case PWM_MODE_FIXED:
/* 固定亮度模式: 不做变化, 保持已有设置 */
break;
default:
break;
}
}
由于代码量较大,我先输出到这里。接下来继续输出 adc_volt.c/h、ext_int.c/h、iap_flash.c/h 和 main.c。请告诉我"继续",我将输出剩余文件。
🔍 搜索 "STC AI8051U 串口交互 命令系统"
⏱️ 查找用时 22.4s | 总回答用时 69.2s