|
many people working with multi-color LEDs utilize PWM to control LED light intensity, and color combinations when multi-color LEDs are utilized.
here is an example of utilizing PIC and firmware to create PWM on 3 channels.
The chip used is a 12F675 (8pdip), it is written to drive 3 channels of independent PWM output, 256 stepping. Each channel is programmed for its own duty cycle that varies with time / channel. The intensity (duty cycle) for example channel goes up or down by the stepping. the duty cycle goes up and then down, to create smooth lighting / color transitions.
it can be easily adapted to drive more channels, with different stepping, or on different mcus.
enjoy.
======code, in picc===============
#include <htc.h>
#define PWM_PORT GPIO //LED on GPIO
#define Max_Tick 0x7f //max number of steps
#define Max_Ch 3 //number of pwm channels
#define PWM_SET(x) PWM_PORT |= (x) //turn on xth bit
#define PWM_CLR(x) PWM_PORT &=~(x) //turn off xth bit
#define PWM_FLP(x) PWM_PORT ^= (x) //flip xth bit
__CONFIG(MCLRDIS & WDTDIS & BORDIS & INTIO);
typedef struct {
unsigned char ch; //PWM pin/ch
unsigned char on; //on tick
char stepping; //increment to on;
} PWM_type;
PWM_type PWM_Info[Max_Ch]={
{1<<0, 0x2d, 10},
{1<<2, 0x10, 20},
{1<<1, 0x11, -3}};
unsigned char PWM_Ch_mask=0;
void mcu_init(void) {
unsigned char i;
ANSEL=0x00; //turn off analog input
CMCON=0x07; //turn off comparators
for (i=0; i<Max_Ch; i++)
PWM_Ch_mask |= PWM_Info.ch;
TRISIO &= ~PWM_Ch_mask;
}
void PWM_Update_Stepping(void) {
unsigned char ch;
signed char tmp;
for (ch=0; ch<Max_Ch; ch++) {
tmp=PWM_Info[ch].on + PWM_Info[ch].stepping;
if (PWM_Info[ch].stepping > 0) //stepping > 0
if (tmp > Max_Tick) PWM_Info[ch].stepping = - PWM_Info[ch].stepping; //reverse stepping direction;
else //stepping < 0
if (tmp < 0) PWM_Info[ch].stepping = - PWM_Info[ch].stepping; //reverse stepping direction;
PWM_Info[ch].on += PWM_Info[ch].stepping;
}
}
void
main(void)
{
unsigned char ch, tick, mask;
mcu_init();
TRIS5=0; GPIO5=0; //GPIO5 set up as cycle indicator
while (1){
//TODO Auto-generated main function
PWM_PORT=PWM_Ch_mask;
for (tick=0; tick<Max_Tick; tick++) {
for (mask=0x00, ch=0; ch<Max_Ch; ch++) //reset mask, and check for bits to be turned off
mask |= (tick==PWM_Info[ch].on)? PWM_Info[ch].ch:0; //identify the bit to be turned off
//mask = (tick==PWM_Info[0].on)? PWM_Info[0].ch:0 + (tick==PWM_Info[1].on)? PWM_Info[1].ch:0 + (tick==PWM_Info[2].on)? PWM_Info[2].ch:0;
PWM_PORT ^= mask;
}
PWM_Update_Stepping();
GPIO5 ^= 1; //flip gpio5
}
}
(原文件名:12F675 LEDs PWM v2.PNG) |
阿莫论坛20周年了!感谢大家的支持与爱护!!
一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。
|