#include
#include "stdlib.h"
#include
#include
#include "derivative.h"
#pragma LINK_INFO DERIVATIVE "MC68HC908QT4"
// --------------------- 系统配置 ---------------------
#define SYS_CLK 3200000UL // 系统时钟3.2MHz
#define PWM_PRESCALER 4 // PWM分频系数(定时器时钟=800kHz)
#define FILTER_DELAY 100 // 滤波器切换后稳定时间(ms)
//#define uint16 unsigned int
#define uint8 unsigned char
#define uint16 unsigned short int
#define uint32 unsigned long int
#define max(x,y) ((x) > (y) ? (x) :(y))
#define min(x,y) ((x) < (y) ? (x) : (y))
// --------------------- 数据结构定义 ---------------------
typedef struct {
volatile uint16 r; // 红色通道频率
volatile uint16 g; // 绿色通道频率
volatile uint16 b; // 蓝色通道频率
} RGB_Data;
typedef struct {
uint8 r; // 红色通道(0-255)
uint8 g; // 绿色通道(0-255)
uint8 b; // 蓝色通道(0-255)
} RGB_8Bit;
typedef struct{
unsigned int h; //[0,360]
unsigned char s; //[0,100]
unsigned char l; //[0,100]
}COLOR_HSL;//HSL
typedef struct {
float lower_hue;
float upper_hue;
const char* color_name;
} ColorRange;
// --------------------- TCS3200控制参数 ---------------------
typedef enum {
TCS_FILTER_RED = 0, // S2=0, S3=0 → 红色滤波器
TCS_FILTER_BLUE = 1, // S2=1, S3=0 → 蓝色滤波器
TCS_FILTER_GREEN = 2, // S2=0, S3=1 → 绿色滤波器
TCS_FILTER_CLEAR = 3 // S2=1, S3=1 → 无滤波器
} TCS_ColorFilter;
// --------------------- 全局变量 ---------------------
volatile uint16 g_pulse_count = 0; // 脉冲计数器
volatile uint8 g_current_filter = 0; // 当前滤波器:0-Red,1-Green,2-Blue
RGB_8Bit g_rgb_8bit; // 存储归一化后的RGB值
RGB_Data g_rgb; // 存储RGB测量结果
COLOR_HSL hsl; //HSL
volatile uint16 g_pwm_freq = 5200; // PWM目标频率(默认1kHz)
ColorRange color_ranges[] = {
{0, 15, "Red"},
{15, 30, "Red-Orange"},
{30, 45, "Orange"},
{45, 60, "Yellow-Orange"},
{60, 75, "Yellow"},
{75, 90, "Yellow-Green"},
{90, 150, "Green"},
{150, 180, "Blue-Green"},
{180, 210, "Cyan"},
{210, 240, "Indigo"},
{240, 270, "Blue"},
{270, 300, "Magenta"},
{300, 330, "Purple-Red"},
{330, 360, "Red"} // 共14项
};
// --------------------- 函数声明 ---------------------
void SystemInit(void);
void TCS3200_Init(void);
void TCS3200_SetFilter(TCS_ColorFilter filter);
void PWM_Init(uint16 freq);
void InputCapture_Init(void);
void Read_RGB(void);
uint16 Measure_Frequency(void);
void Set_PWM_Freq(uint16 target_freq);
void Delay_ms(uint16 ms);
void RGBtoHSL(RGB_Data *Rgb, COLOR_HSL *Hsl);
void judgeColor(RGB_Data *Rgb) ;
uint8 flag =0 ;
// ===================== 中断服务程序 =====================
#pragma CODE_SEG __NEAR_SEG NON_BANKED
// 输入捕获中断(统计脉冲)
void interrupt 5 TCH1_ISR(void) {
if(TSC1 & 0x80) { // 检测到上升沿
flag = 1;
// g_pulse_count++; // 累加脉冲计数
TSC1 &= ~0x80; // 清除捕获标志
}
}
#pragma CODE_SEG DEFAULT
/******************** 主程序 ********************/
void main(void)
{
SystemInit(); // 系统初始化
TCS3200_Init(); // 初始化TCS3200
PWM_Init(g_pwm_freq); // 初始化PWM(默认1kHz)
InputCapture_Init(); // 初始化输入捕获
for(;;) {
// Read_RGB(); // 更新RGB测量值到g_rgb
if(flag){
Set_PWM_Freq (1200);}
// 示例:根据红色通道亮度调整PWM频率
}
}
/******************** RGB测量函数 ********************/
void Read_RGB(void)
{
uint16 current_max;
TCS3200_SetFilter(TCS_FILTER_RED);
g_pulse_count = 0;
Delay_ms(FILTER_DELAY);
g_rgb.r = g_pulse_count;
TCS3200_SetFilter(TCS_FILTER_GREEN);
g_pulse_count = 0;
Delay_ms(FILTER_DELAY);
g_rgb.g = g_pulse_count;
TCS3200_SetFilter(TCS_FILTER_BLUE);
g_pulse_count = 0;
Delay_ms(FILTER_DELAY);
g_rgb.b = g_pulse_count;
current_max = max(g_rgb.r, max(g_rgb.g, g_rgb.b));
if (current_max == 0) current_max = 1; // 避免除以零
// 计算各通道的8位值
g_rgb_8bit.r = (uint8)(((uint32)g_rgb.r * 255) / current_max);
g_rgb_8bit.g = (uint8)(((uint32)g_rgb.g * 255) / current_max);
g_rgb_8bit.b = (uint8)(((uint32)g_rgb.b * 255) / current_max);
}
/******************** TCS3200控制函数 ********************/
void TCS3200_Init(void)
{
DDRA |= 0x30; // PA4(S2)、PA5(S3)设为输出
PTA &= ~0x30; // 初始状态:红色滤波器
}
void TCS3200_SetFilter(TCS_ColorFilter filter)
{
switch(filter) {
case TCS_FILTER_RED: PTA = (PTA & ~0x30) | 0x00; break;
case TCS_FILTER_BLUE: PTA = (PTA & ~0x30) | 0x20; break;
case TCS_FILTER_GREEN: PTA = (PTA & ~0x30) | 0x30; break;
case TCS_FILTER_CLEAR: PTA = (PTA & ~0x30) | 0x10; break;
}
}
void PWM_Init(uint16 freq)
{
uint16 tmod;
// 配置PA0为PWM输出(TCH0功能)
DDRA |= 0x01; // PA0设为输出
// 计算周期和比较值(占空比50%)
tmod = (SYS_CLK / (PWM_PRESCALER * freq)) - 1;
TMODH = (tmod >> 8) & 0xFF;
TMODL = tmod & 0xFF;
TCH0H = (tmod / 2) >> 8;
TCH0L = (tmod / 2) & 0xFF;
// 定时器通道0配置:输出比较,翻转电平
TSC0 = 0x16; // TOV=0, CHMAX=0, MS0A=1, ELS0=2(翻转模式)
TSC = 0x02; // 分频4,启动定时器
}
/******************** PWM输出函数(PA0引脚) ********************/
void Set_PWM_Freq(uint16 target_freq)
{
uint16 tmod;
tmod = (SYS_CLK / (PWM_PRESCALER * target_freq)) - 1;
DisableInterrupts;
TMODH = (tmod >> 8) & 0xFF;
TMODL = tmod & 0xFF;
TCH0H = (tmod / 2) >> 8;
TCH0L = (tmod / 2) & 0xFF;
EnableInterrupts;
}
/******************** 输入捕获函数(PA1引脚) ********************/
void InputCapture_Init(void)
{
DDRA &= ~0x02; // PA1设为输入(TCS3200 OUT)
TSC1 = 0x44; // 输入捕获,上升沿触发
TSC |= 0x02; // 分频4(与PWM共用定时器)
}
/******************** 系统初始化函数 ********************/
void SystemInit(void)
{
OSCTRIM = *(uint8*)0xFFC0; // 时钟微调
CONFIG1 = 0x00; // 关闭看门狗
CONFIG2 = 0x40; // 启用IRQ中断
}
/******************** 简单延时函数 ********************/
void Delay_ms(uint16 ms)
{
uint16 i,j;
for( i=0; ir, Rgb->g), Rgb->b);
int rgbMin = min(min(Rgb->r, Rgb->g), Rgb->b);
// printf("\n Rgb->r, Rgb->g, Rgb->b =%d =%d =%d\n ",Rgb->r, Rgb->g, Rgb->b);
int temp,temp2;
//hue[flatten]
temp2=(rgbMax - rgbMin);
if (abs(rgbMax - rgbMin) < precision) // max == min
{
Hsl->h = 0;
}
else if (abs(rgbMax - Rgb->r) < precision) // max == r
{
temp = Rgb->g - Rgb->b;// / (rgbMax - rgbMin);
temp*=60;
temp/=temp2;
if (Rgb->g < Rgb->b)
temp += 360;
Hsl->h=(uint16)temp;
}
else if (abs(rgbMax - Rgb->g) < precision) // max == g
{
temp=Rgb->b - Rgb->r;
temp*=60;
temp/=temp2;
temp += 120;
Hsl->h=(uint16)temp;
//Hsl->h = 60 * (Rgb->b - Rgb->r) / (rgbMax - rgbMin) + 120;
}
else if (abs(rgbMax - Rgb->b) < precision) // max == b
{
temp=Rgb->r - Rgb->g;
temp*=60;
temp/=temp2;
temp += 240;
Hsl->h=(uint16)temp;
//Hsl->h = 60 * (Rgb->r - Rgb->g) / (rgbMax - rgbMin) + 240;
}
// light
temp= (rgbMax + rgbMin) / 2;
Hsl->l=(uint8)temp;
// saturation
if (temp <= precision || abs(rgbMax - rgbMin) < precision)
{
Hsl->s = 0;
}
else if (temp > 0 && temp <= 0.5)
{
temp=rgbMax - rgbMin;
temp2=rgbMax + rgbMin;
temp/=temp2;
Hsl->s=(uint16)temp;
//Hsl->s = (rgbMax - rgbMin) / (rgbMax + rgbMin);
}
else if (temp > 0.5)
{
temp=rgbMax - rgbMin;
temp*=100;
temp2=rgbMax + rgbMin;
temp2=510-temp2;
temp/=temp2;
Hsl->s=(uint16)temp;
//Hsl->s = (rgbMax - rgbMin) / (2 - (rgbMax + rgbMin));
}
}
// 2. 修正函数实现
void judgeColor(RGB_Data *Rgb)
{
unsigned int ColorVoltage[16]={12000,11000,10000,9000,9500,8500,8000,7000,6500,6000,5000,4000,3000,2500,2000,12000};
int num_ranges,i;
RGBtoHSL(&Rgb, &hsl);
// Define the color range array
num_ranges= sizeof(color_ranges) / sizeof(ColorRange);
for ( i = 0; i < num_ranges; i++)
{
if (hsl.h >= color_ranges[i].lower_hue && hsl.h < color_ranges[i].upper_hue)
{
//输出频率
Set_PWM_Freq(ColorVoltage[i] );
}
}
}
完整代码如上
#include
#include "stdlib.h"
#include
#include
#include "derivative.h"
#pragma LINK_INFO DERIVATIVE "MC68HC908QT4"
// --------------------- 系统配置 ---------------------
#define SYS_CLK 3200000UL // 系统时钟3.2MHz
#define PWM_PRESCALER 4 // PWM分频系数(定时器时钟=800kHz)
#define FILTER_DELAY 100 // 滤波器切换后稳定时间(ms)
//#define uint16 unsigned int
#define uint8 unsigned char
#define uint16 unsigned short int
#define uint32 unsigned long int
#define max(x,y) ((x) > (y) ? (x) :(y))
#define min(x,y) ((x) < (y) ? (x) : (y))
// --------------------- 数据结构定义 ---------------------
typedef struct {
volatile uint16 r; // 红色通道频率
volatile uint16 g; // 绿色通道频率
volatile uint16 b; // 蓝色通道频率
} RGB_Data;
typedef struct {
uint8 r; // 红色通道(0-255)
uint8 g; // 绿色通道(0-255)
uint8 b; // 蓝色通道(0-255)
} RGB_8Bit;
typedef struct{
unsigned int h; //[0,360]
unsigned char s; //[0,100]
unsigned char l; //[0,100]
}COLOR_HSL;//HSL
typedef struct {
float lower_hue;
float upper_hue;
const char* color_name;
} ColorRange;
// --------------------- TCS3200控制参数 ---------------------
typedef enum {
TCS_FILTER_RED = 0, // S2=0, S3=0 → 红色滤波器
TCS_FILTER_BLUE = 1, // S2=1, S3=0 → 蓝色滤波器
TCS_FILTER_GREEN = 2, // S2=0, S3=1 → 绿色滤波器
TCS_FILTER_CLEAR = 3 // S2=1, S3=1 → 无滤波器
} TCS_ColorFilter;
// --------------------- 全局变量 ---------------------
volatile uint16 g_pulse_count = 0; // 脉冲计数器
volatile uint8 g_current_filter = 0; // 当前滤波器:0-Red,1-Green,2-Blue
RGB_8Bit g_rgb_8bit; // 存储归一化后的RGB值
RGB_Data g_rgb; // 存储RGB测量结果
COLOR_HSL hsl; //HSL
volatile uint16 g_pwm_freq = 5200; // PWM目标频率(默认1kHz)
ColorRange color_ranges[] = {
{0, 15, "Red"},
{15, 30, "Red-Orange"},
{30, 45, "Orange"},
{45, 60, "Yellow-Orange"},
{60, 75, "Yellow"},
{75, 90, "Yellow-Green"},
{90, 150, "Green"},
{150, 180, "Blue-Green"},
{180, 210, "Cyan"},
{210, 240, "Indigo"},
{240, 270, "Blue"},
{270, 300, "Magenta"},
{300, 330, "Purple-Red"},
{330, 360, "Red"} // 共14项
};
// --------------------- 函数声明 ---------------------
void SystemInit(void);
void TCS3200_Init(void);
void TCS3200_SetFilter(TCS_ColorFilter filter);
void PWM_Init(uint16 freq);
void InputCapture_Init(void);
void Read_RGB(void);
uint16 Measure_Frequency(void);
void Set_PWM_Freq(uint16 target_freq);
void Delay_ms(uint16 ms);
void RGBtoHSL(RGB_Data *Rgb, COLOR_HSL *Hsl);
void judgeColor(RGB_Data *Rgb) ;
uint8 flag =0 ;
// ===================== 中断服务程序 =====================
#pragma CODE_SEG __NEAR_SEG NON_BANKED
// 输入捕获中断(统计脉冲)
void interrupt 5 TCH1_ISR(void) {
if(TSC1 & 0x80) { // 检测到上升沿
flag = 1;
// g_pulse_count++; // 累加脉冲计数
TSC1 &= ~0x80; // 清除捕获标志
}
}
#pragma CODE_SEG DEFAULT
/******************** 主程序 ********************/
void main(void)
{
SystemInit(); // 系统初始化
TCS3200_Init(); // 初始化TCS3200
PWM_Init(g_pwm_freq); // 初始化PWM(默认1kHz)
InputCapture_Init(); // 初始化输入捕获
for(;;) {
// Read_RGB(); // 更新RGB测量值到g_rgb
if(flag){
Set_PWM_Freq (1200);}
// 示例:根据红色通道亮度调整PWM频率
}
}
/******************** RGB测量函数 ********************/
void Read_RGB(void)
{
uint16 current_max;
TCS3200_SetFilter(TCS_FILTER_RED);
g_pulse_count = 0;
Delay_ms(FILTER_DELAY);
g_rgb.r = g_pulse_count;
TCS3200_SetFilter(TCS_FILTER_GREEN);
g_pulse_count = 0;
Delay_ms(FILTER_DELAY);
g_rgb.g = g_pulse_count;
TCS3200_SetFilter(TCS_FILTER_BLUE);
g_pulse_count = 0;
Delay_ms(FILTER_DELAY);
g_rgb.b = g_pulse_count;
current_max = max(g_rgb.r, max(g_rgb.g, g_rgb.b));
if (current_max == 0) current_max = 1; // 避免除以零
// 计算各通道的8位值
g_rgb_8bit.r = (uint8)(((uint32)g_rgb.r * 255) / current_max);
g_rgb_8bit.g = (uint8)(((uint32)g_rgb.g * 255) / current_max);
g_rgb_8bit.b = (uint8)(((uint32)g_rgb.b * 255) / current_max);
}
/******************** TCS3200控制函数 ********************/
void TCS3200_Init(void)
{
DDRA |= 0x30; // PA4(S2)、PA5(S3)设为输出
PTA &= ~0x30; // 初始状态:红色滤波器
}
void TCS3200_SetFilter(TCS_ColorFilter filter)
{
switch(filter) {
case TCS_FILTER_RED: PTA = (PTA & ~0x30) | 0x00; break;
case TCS_FILTER_BLUE: PTA = (PTA & ~0x30) | 0x20; break;
case TCS_FILTER_GREEN: PTA = (PTA & ~0x30) | 0x30; break;
case TCS_FILTER_CLEAR: PTA = (PTA & ~0x30) | 0x10; break;
}
}
void PWM_Init(uint16 freq)
{
uint16 tmod;
// 配置PA0为PWM输出(TCH0功能)
DDRA |= 0x01; // PA0设为输出
// 计算周期和比较值(占空比50%)
tmod = (SYS_CLK / (PWM_PRESCALER * freq)) - 1;
TMODH = (tmod >> 8) & 0xFF;
TMODL = tmod & 0xFF;
TCH0H = (tmod / 2) >> 8;
TCH0L = (tmod / 2) & 0xFF;
// 定时器通道0配置:输出比较,翻转电平
TSC0 = 0x16; // TOV=0, CHMAX=0, MS0A=1, ELS0=2(翻转模式)
TSC = 0x02; // 分频4,启动定时器
}
/******************** PWM输出函数(PA0引脚) ********************/
void Set_PWM_Freq(uint16 target_freq)
{
uint16 tmod;
tmod = (SYS_CLK / (PWM_PRESCALER * target_freq)) - 1;
DisableInterrupts;
TMODH = (tmod >> 8) & 0xFF;
TMODL = tmod & 0xFF;
TCH0H = (tmod / 2) >> 8;
TCH0L = (tmod / 2) & 0xFF;
EnableInterrupts;
}
/******************** 输入捕获函数(PA1引脚) ********************/
void InputCapture_Init(void)
{
DDRA &= ~0x02; // PA1设为输入(TCS3200 OUT)
TSC1 = 0x44; // 输入捕获,上升沿触发
TSC |= 0x02; // 分频4(与PWM共用定时器)
}
/******************** 系统初始化函数 ********************/
void SystemInit(void)
{
OSCTRIM = *(uint8*)0xFFC0; // 时钟微调
CONFIG1 = 0x00; // 关闭看门狗
CONFIG2 = 0x40; // 启用IRQ中断
}
/******************** 简单延时函数 ********************/
void Delay_ms(uint16 ms)
{
uint16 i,j;
for( i=0; ir, Rgb->g), Rgb->b);
int rgbMin = min(min(Rgb->r, Rgb->g), Rgb->b);
// printf("\n Rgb->r, Rgb->g, Rgb->b =%d =%d =%d\n ",Rgb->r, Rgb->g, Rgb->b);
int temp,temp2;
//hue[flatten]
temp2=(rgbMax - rgbMin);
if (abs(rgbMax - rgbMin) < precision) // max == min
{
Hsl->h = 0;
}
else if (abs(rgbMax - Rgb->r) < precision) // max == r
{
temp = Rgb->g - Rgb->b;// / (rgbMax - rgbMin);
temp*=60;
temp/=temp2;
if (Rgb->g < Rgb->b)
temp += 360;
Hsl->h=(uint16)temp;
}
else if (abs(rgbMax - Rgb->g) < precision) // max == g
{
temp=Rgb->b - Rgb->r;
temp*=60;
temp/=temp2;
temp += 120;
Hsl->h=(uint16)temp;
//Hsl->h = 60 * (Rgb->b - Rgb->r) / (rgbMax - rgbMin) + 120;
}
else if (abs(rgbMax - Rgb->b) < precision) // max == b
{
temp=Rgb->r - Rgb->g;
temp*=60;
temp/=temp2;
temp += 240;
Hsl->h=(uint16)temp;
//Hsl->h = 60 * (Rgb->r - Rgb->g) / (rgbMax - rgbMin) + 240;
}
// light
temp= (rgbMax + rgbMin) / 2;
Hsl->l=(uint8)temp;
// saturation
if (temp <= precision || abs(rgbMax - rgbMin) < precision)
{
Hsl->s = 0;
}
else if (temp > 0 && temp <= 0.5)
{
temp=rgbMax - rgbMin;
temp2=rgbMax + rgbMin;
temp/=temp2;
Hsl->s=(uint16)temp;
//Hsl->s = (rgbMax - rgbMin) / (rgbMax + rgbMin);
}
else if (temp > 0.5)
{
temp=rgbMax - rgbMin;
temp*=100;
temp2=rgbMax + rgbMin;
temp2=510-temp2;
temp/=temp2;
Hsl->s=(uint16)temp;
//Hsl->s = (rgbMax - rgbMin) / (2 - (rgbMax + rgbMin));
}
}
// 2. 修正函数实现
void judgeColor(RGB_Data *Rgb)
{
unsigned int ColorVoltage[16]={12000,11000,10000,9000,9500,8500,8000,7000,6500,6000,5000,4000,3000,2500,2000,12000};
int num_ranges,i;
RGBtoHSL(&Rgb, &hsl);
// Define the color range array
num_ranges= sizeof(color_ranges) / sizeof(ColorRange);
for ( i = 0; i < num_ranges; i++)
{
if (hsl.h >= color_ranges[i].lower_hue && hsl.h < color_ranges[i].upper_hue)
{
//输出频率
Set_PWM_Freq(ColorVoltage[i] );
}
}
}
完整代码如上
举报