Electronic – LED Breathing Effect

cledpwm

Please consider the following code:

for(;;)
{
 int i=0;  
 TPM1C2VL  =~ (i<<1); // Channel Value(Lower)Register.
 TPM1C2VH +=TPM1C2VL; 
}

ALTERED CODE

unsigned long duty[420] = {<from zero to 65535>}

for(i = 0; i != 420; i++ )
   {
  TPM1C2VL =~ duty[i];
  TPM1C2VH += TPM1C2VL;
}
for( ; i != 0; i-- )
{
  TPM1C2VL =~ duty[i];
  TPM1C2VH += TPM1C2VL;
} 

After the alteration also, there is no effective change, as now the LED just blinks randomly

I just wanted to apply breathing effect on a LED. Just to test I wrote the code with basic intuition of how it is supposed to work, didnt expect it to work in one shot, but it does.

Now my question is, HOW TO REVERSE THIS EFFECT? i.e. Slowly the LED dies out to zero.
I am not able to induce a reversal of this effect. I am using PWM of MC9S08DZ60.
I have made the following settings:
Prescaler = 1.

Modulo Counter = 65535.

Period = 4.096ms.

Edge Aligned.

On Channel 1.

PWM:
Set OUtput on Compare.

Channel Duty = 4.095ms.

Best Answer

Here's a sample code that should get you started. You could implement the full 0 -> 65535 -> 0 16-bit count, but since your code only counts by 256 and seems to make half of the ramp you're looking for, I have done likewise.

It might be fun to write another experiment that picks log or other values from a table to see how the appearance changes, but if all you want is a simple ramp up and ramp down, something like this should do it.

TPM1C2VL = 0;       // not modifying the ...VL register, just zero it
for(;;){
   int i;

   // Up counter
   for(i = 0; i != 256; ++i ){
  TPM1C2VH = i;
  ;  // maybe some delay here
   }

   // Down counter
   for( ; i != 0; --i ){
  TPM1C2VH = i;
  ;  // maybe some delay here
   }
}