用M8控制RGBLED测试了一下,效果不错。并做了一个上位机软件,通过USB控制,现将资料整理上传与君共享!
原理图
源代码
/******************************************************************************
* rgbCtrl.h
*
* Copyright XiaoCui' Products
*
* DESCRIPTION:
*
* modification history
* --------------------
* 01a, 01jan2008, cuiqingwei written
* --------------------
******************************************************************************/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/wdt.h>
#include "usbdrv.h"
/* Explanation of the HSV color space:
H: Hue - 色调(如红,蓝,黄,绿...)
S: Saturation - 饱和度
V: Value - 亮度
Scaling of the HSV values:
H: [0-255] 0 = red, 42 = yellow, 85 = green, 128 = turquoise, 171 = blue, 214 = purple
S: [0-255] 0 = white, 255 = pure colors
V: [0-255] 0 = off, 255 = maximum brightness */
typedef struct {
unsigned char r;
unsigned char g;
unsigned char b;
} RGB;
#define Ledport PORTD // RGB Led Port
#define DDR_Ledport DDRD
#define R_PIN 5 // R Output
#define G_PIN 6 // G
#define B_PIN 7 // B
/* 函数声名 */
void init(void);
void hsv_to_rgb (unsigned char h, unsigned char s, unsigned char v, RGB * out);
/* 全局变量 */
RGB lamp = {0,0,0};
unsigned char type,H,S,V;
//-----------------------------------------------------------------------------
// Init
//-----------------------------------------------------------------------------
void init(void)
{
PORTD = 0;
PORTB = 0; // no pullups on USB and ISP pins
DDRD = ~(1 << 2); // all outputs except PD2 = INT0
DDRB = 0; // all USB and ISP pins inputs
DDR_Ledport = (1<<R_PIN)|(1<<G_PIN)|(1<<B_PIN);
TCCR0 = 1;
TIMSK = (1<<TOIE0); // Overflow Interrupt f/256
}
uchar usbFunctionSetup(uchar data[8])
{
usbRequest_t *rq = (void *)data;
if( rq->bRequest )
{
type = 1;
H = rq->wValue.bytes[0];
S = rq->wValue.bytes[1];
V = rq->wValue.bytes[2];
}
else
{
type = 0;
lamp.r = rq->wValue.bytes[0];
lamp.g = rq->wValue.bytes[1];
lamp.b = rq->wValue.bytes[2];
}
//computeOutputStatus();
return 0;
}
//-----------------------------------------------------------------------------
// Main
//-----------------------------------------------------------------------------
int main(void)
{
cli();
init();
usbInit();
sei();
H = 180;
S = 255;
V = 355;
type = 1;
for(;;)
{
usbPoll();
if ( type )
{
type = 0;
hsv_to_rgb(H,S,V,&lamp);
}
}
return 0;
}
//-----------------------------------------------------------------------------
// Converts HSV to RGB
//-----------------------------------------------------------------------------
void hsv_to_rgb (unsigned char h, unsigned char s, unsigned char v, RGB * out)
{
unsigned char r=0,g=0,b=0, i, f;
unsigned int p, q, t;
if( s == 0 )
{
r = g = b = v;
}
else
{
i=h/43;
f=h%43;
p = (v * (255 - s))/256;
q = (v * ((10710 - (s * f))/42))/256;
t = (v * ((10710 - (s * (42 - f)))/42))/256;
switch( i )
{
case 0:
r = v; g = t; b = p; break;
case 1:
r = q; g = v; b = p; break;
case 2:
r = p; g = v; b = t; break;
case 3:
r = p; g = q; b = v; break;
case 4:
r = t; g = p; b = v; break;
case 5:
r = v; g = p; b = q; break;
}
}
out->r=r; out->g=g; out->b=b;
}
//-----------------------------------------------------------------------------
// Timer 0 Interrupt, f/256
//-----------------------------------------------------------------------------
SIGNAL (SIG_OVERFLOW0)
{
static unsigned char PWM_cnt;
static unsigned char prescale;
if(prescale++)
{
prescale=0; // Used to halve the PWM frequency
return;
}
if (PWM_cnt <lamp.r)
Ledport |= (1 << R_PIN);
else
Ledport &=~(1 << R_PIN);
if (PWM_cnt <lamp.g)
Ledport |= (1 << G_PIN);
else
Ledport &=~(1 << G_PIN);
if (PWM_cnt <lamp.b)
Ledport |= (1 << B_PIN);
else
Ledport &=~(1 << B_PIN);
PWM_cnt++;
}
/*-----------------------------------------------------------------------------
0ooo
ooo0 ( )
( ) ) /
\ ( (_/
\_) By:cuiqingwei [gary]
-----------------------------------------------------------------------------*/
PC软件界面
调光效果
调试一角
资料包
发表链接
amoBBS 阿莫电子论坛 http://www.amobbs.com/thread-883719-1-1.html