CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Interrupt control problem - BAM example

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
spark



Joined: 03 Jan 2012
Posts: 17

View user's profile Send private message MSN Messenger

Interrupt control problem - BAM example
PostPosted: Wed Jan 04, 2012 11:39 am     Reply with quote

Hello
I'm trying to create 8 independently dimming LED's with BAM.
(what BAM is)

I'm struggling with the code, at the moment the interrupts are creating problems. The idea is to make 8 interrupts, each is half as long as the one before. So if one cycle would take one second (in reality it would be 1/150 seconds), the first cycle would be 1/2 sec, the 2nd 1/4, the 3rd 1/8, (and so on...) and the last one 1/256 sec. The cycles should be controlled be an interrupt of a timer. After each cycle LATB will set new data (taken from an array of bytes). Now I need help to set the timer to create a new interrupt.

I checked to web and to manual for an example, but I didn't find anything simple that I understood and that covers setting the timer to a new time. I would be really glad if somebody could post me an example or help me with the code. Thanks so much.
temtronic



Joined: 01 Jul 2010
Posts: 9164
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Jan 04, 2012 12:22 pm     Reply with quote

You should learn how to use 'Google' better.

Asking for BAM C code examples pulled up over 3 million hits, within the first 3-4 pages was complete code, very easily converted to CCS style C.

The 'Net' is a wonderful place, chock full of interesting stuff....
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Wed Jan 04, 2012 1:35 pm     Reply with quote

b-a-m--interesting but I think no sale.
I did some work on a long life battery power light backup system for a military application - and in order to defeat problems with "flicker persistence" - seen as fine points of patterned light "flashes" -
while moving your gaze through the LED light field - I had to use a
multiplexing frequency of 100 kHz.

The low, and variable duty cycle of b-a-m worries me greatly on that issue.

The real possibility of saturating your PIC 's interrupt structure follows closely as a concern.
spark



Joined: 03 Jan 2012
Posts: 17

View user's profile Send private message MSN Messenger

PostPosted: Wed Jan 04, 2012 2:03 pm     Reply with quote

???
I asked google for "BAM C code examples". It didn't bring up anything useful at all. I checked the first five links though I doubted that it could be useful. In fact it showed C code but nothing had anything to do with Bit Angle Modulation. Please check the links first before you're saying something like that. Post me a link if you discover something completly different.

@asmboy: Would you say, it won't work? Do you think the processor is to slow to switch the ports that fast? PWM wouldn't work for that many channels.

I would be really glad if somebody could post me a simple example for the interrupts with setting timers and so on. If you have a useful link, please post it, but please don't just refer on google - belive me, I used it!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jan 04, 2012 2:43 pm     Reply with quote

AVR code:
http://www.batsocks.co.uk/readme/art_bcm_3.htm

ATMega8 code:
http://www.hownottoengineer.com/down/viewdownload/4/15.html

Sample BAM isr code for a PIC in C (not CCS), from "Mike":
http://www.electro-tech-online.com/microcontrollers/116913-bam-test.html

I found all this with Google. I'm sure there is more. You should search.
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Wed Jan 04, 2012 3:35 pm     Reply with quote

Quote:

Do you think the processor is to slow to switch the ports that fast? PWM wouldn't work for that many channels.


yes a slow PIC IMHO - has no hope of doing this - with enuf speed- to do anything BUT flash the leds ( annoyingly ) && maybe not even that...

you might pull the data sheet for the 18f2450 // 4450 -

which i believe can be operated with external oscillator or combo +PLL
@ up to Fosc =48mhz

if i was going to TRY to do this - i would probably start by using the timer0 interrupt ONLY -and then manipulate the prescalar //manipulate initial && rollover timer load - in a variable way - and lastly craft the tightest state machine code i could inside the ISR to flip the pins up and down;-))

i just don't see how external interrupts can play a useful role in what you want to do. no matter what -- this is NOT A BEGINNER Project you are considering.
temtronic



Joined: 01 Jul 2010
Posts: 9164
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Jan 04, 2012 3:48 pm     Reply with quote

Only looking at 5 links of the 3 million hits really isn't good enough, I scanned a few pages and found some applicable code but haven't time to list them all...
Google is extemely powerful if you ask Google right, it is surprising what it can find. if you only want CCS C code, you have to specify that. Any AVR code will not be shown. 'BAM' might not be good enough, also add Bit Angle Modulation to the search parameters.
Odds are real good, if you give Google say 15-120 keywords it'll come up with what you want. PCM pgmr found the AVR and non CCS C code easily.

As for examples of using timers and ISRs, CCS has lots in their 'examples' folder.
spark



Joined: 03 Jan 2012
Posts: 17

View user's profile Send private message MSN Messenger

PostPosted: Wed Jan 04, 2012 4:09 pm     Reply with quote

ok, thanks for the links. I will make a more advanced search (though I was usually successful with my method - but for now I'll try more keywords). I was struggling with the code I found (in the links) but I'll try it again.
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

Why BAM and not PWM.
PostPosted: Thu Jan 05, 2012 5:01 am     Reply with quote

Please supply more detail of why you have to use BAM.

If you are only driving 8 LEDs then you may be able to use a simple PWM system and only one interrupt.

It all depends on the required performance level.

How many brightness levels do you want for each LED?
What is the lowest brightness modulation frequency you can tolerate?
etc.

OR

Why not interrupt at the highest rate required. In the 1st cycle use the 1st interrupt then ignore the next 127, for the 2nd cycle ignore next 63 .........none for the 8th?

Mike
spark



Joined: 03 Jan 2012
Posts: 17

View user's profile Send private message MSN Messenger

PostPosted: Thu Jan 05, 2012 10:18 am     Reply with quote

I'm using BAM because it allows me to set individual brightness levels for each LED. I don't think that this is possible with PWM.

I'm using the internal oscillator which provides a maximum frequency of 8 Mhz. I planned to use an 8 bit timer (so I'd have 16 levels) at 150 hz. With the 16 bit timer I'd have 256 levels, but the maximum frequency would be 61.04 hz (4Mhz/65536).

I prefer the bigger framerate over the bigger resolution.

I think it doesn't matter if I use more interrupts or just the ones required (or does it?) - what I'm struggling with is the general interrupt and timer setup (ok... basic stuff... sry).

That's what I have so far:
Code:
#include "18F4550.H"
//#include <math.h>
#use standard_io(B)
#use delay (internal=8000000)
#fuses INTXT

#byte LATB=getenv("SFR:LATB")

#int_timer0


int8 j[14] = {0b01110000,0b10110000,0b11010000,0b11100000,0b11111000,
                0b00001011,0b11111101,0b00000001,0b11110010,0b11110100,
               0b11111000,0b00011111,0b11010000,0b01001111};
int16 i = 0;
int16 frames = 0;
int16 k = 0xFFFF;
int32 z = 0;
setup_timer1(TMR_INTERNAL);
void main(void)         
{
   enable_interrupts (INT_TIMER0);
      enable_interrupts(GLOBAL);
    while (1);
}

void timer0_isr(void)
{
if(z > 149){
        z = 0;
        frames++;
}
z++;
if(i>6*(frames))
   i = 0;
else
   i++;
output_b(j[i]);
if(k == 1)
   k = 0xFFFF;
else
   k = k/2;
set_timer1(0xFFFF-k); // clear the timer register
}

For some reason it doesn't work, I don't know why.
jeremiah



Joined: 20 Jul 2010
Posts: 1322

View user's profile Send private message

PostPosted: Thu Jan 05, 2012 11:27 am     Reply with quote

I haven't gone through it extensively, but here are some things that stuck out:

Code:
#int_timer0


needs to be right above the isr code I think:
Code:


#int_timer0
void timer0_isr(void)
{
   if(z > 149){
      z = 0;
      frames++;
   }
   z++;

   if(i>6*(frames))
      i = 0;
   else
      i++;

   output_b(j[i]);

   if(k == 1)
      k = 0xFFFF;
   else
      k = k/2;

   set_timer1(0xFFFF-k); // clear the timer register
}


Also,
Code:
setup_timer1(TMR_INTERNAL);


should be placed in the main (at the beginning of it)
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Thu Jan 05, 2012 1:11 pm     Reply with quote

Quote:

set individual brightness levels for each LED


the whole premise of what you want to do is being hampered by pesky old physics & human biology.

in a "white light LED" project i did some time ago - i found that a wide range of PWM led drive variation produced a very linear difference of light
measured on a solar cell light METER- B U T - when VIEWED by the human eye - it is QUITE different. I could vary the PWM duty over a 40% range - from 100% heading down - with very little perceived dimming when the rate was 100khz. even motion persistence strobing is minimal.

BUT , the same persistence of vision that makes watching a scanned CRT work - or leaves a bright spot after a bright flash -- greatly hampers all pulsed LED attempts at brightness control.

IN short - i think you will find that to get much apparent dimming - to the human eye- only when you get to very VERY low duty cycles will you see much difference in brightness for you efforts.

U C ., I've BT, DT , && GT-TS
regards Very Happy
spark



Joined: 03 Jan 2012
Posts: 17

View user's profile Send private message MSN Messenger

PostPosted: Thu Jan 05, 2012 5:18 pm     Reply with quote

Finally I got a working example. The difference between the LED's is not that big (and not I think not linear yet, but I'll change that). Eventually I'll take the 16 bit timer (but use just 10 bits) to get a darker first level. Thanks for helping. Any ideas for improvements (EDIT: especially how to store the animation data?)?

Code:
#include "18F4550.H"
//#include <math.h>
#use standard_io(B)
#use delay (internal=8000000)
#fuses INTXT

#byte LATB=getenv("SFR:LATB")

int8 j[16] = {0b10000000, 0b11000000, 0b11100000, 0b11110000, 0b11111000, 0b11111100, 0b11111110, 0b11111111,
          0b00000001, 0b00000011, 0b00000111, 0b00001111, 0b00011111, 0b00111111, 0b01111111, 0b11111111};
int16 currScene = 0
int16 arr = 0;//current arraynumber = current output
int8 time = 0xFF;
int16 currFrame = 0;
const int8 maxScenes = 2;

#int_timer0
void timer0_isr(void)
{

      if(time == 1){
      if(currFrame == 15625){//15625 = frameRate, 15625 frames = 1 scene = 1 sec
         currFrame = 0;
         if(currScene == maxScenes-1)
            currScene = 0;
         else
               currScene++;
      }else{
          currFrame++;
      }
      arr = currScene*8;
       time = 0xFF;
   }else{
      arr++;
         time = time/2;
   }
   output_b(j[arr]);
   set_timer0(0xFF-time);
}
void main(void)         
{
setup_timer_0(RTCC_INTERNAL|RTCC_8_BIT|RTCC_DIV_4);
   enable_interrupts (INT_TIMER0);
      enable_interrupts(GLOBAL);
    while (1);
}
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PWM vs BAM
PostPosted: Fri Jan 06, 2012 3:15 am     Reply with quote

Quote:

the whole premise of what you want to do is being hampered by pesky old physics & human biology.

in a "white light LED" project i did some time ago - i found that a wide range of PWM led drive variation produced a very linear difference of light
measured on a solar cell light METER- B U T - when VIEWED by the human eye - it is QUITE different. I could vary the PWM duty over a 40% range - from 100% heading down - with very little perceived dimming when the rate was 100khz. even motion persistence strobing is minimal.

What asmboy is telling you is that human brightness perception is logarithmic (like most other human senses). I.e. linear brightness changes are less noticable at higher intensities.

Quote:

I'm using BAM because it allows me to set individual brightness levels for each LED. I don't think that this is possible with PWM.


You can achieve PWM by creating a regular timed interrupt, then turn each LED on/off for an integral number of interrupt periods.

For the above PWM scheme and your BAM scheme each ON period is an integral number of interrupt periods.

The best resolution you can achieve is set by the shortest achievable interrupt interval which will be roughly the same for either method.

There is the possiblity of a fiddle you can do to improve resolution. In the olden days, UK TVs had a true frame rate of 25Hz, which should have produced noticable flicker. On one scan of the screen only odd number lines were drawn, on the next scan even numbered lines were drawn. Each scan took 20msec. The human eye percieved the frame rate as 50Hz even though only half a complete picture was drawn on each scan. With either PWM or BAM you may be able to get the illusion of a half bit resolution by modulating the duty ratio on alternate frames. So when the duty should be say 35/256 you use 35/256 on all frames. To get 35.5/256 you use 35/256 on one frame then 36/256 on the next. It's possible that the mild flicker will not be noticed and you get say 9 bit resolution with an 8 bit system.

[This fiddle was also used to create tones for electronic musical instruments. A high frequency clock (MHz region) was divided by integers to generate a chromatic scale. More accurate scales were achieved by dividing alternately by adjacent integers when needed. In practice very few people noticed the minor pitch modulation.]


Mike
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group