Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Programming structure in C

Status
Not open for further replies.

demestav

Member
Hello,
I have a quick question if somebody can help me.

I am writing a program for 16f628 in C. In this project I want to use the timer0 overflow interrupt for several purposes. So lets assume this is my program

Code:
Timer0_Interrupt
{
  if timer was started by [turnon_lights] then call turnoff_lights
  if timer was started by [turnon_TV] then call turnoff_TV
}

turnon_lights
{
  portb=0xFF;
  Start Timer0;
}

turnoff_lights
{
  prortb=0x00;
}

turnon_TV
{
  porta=0xff;
  Start Timer0
}

turnoff_TV
{
  porta=0x00;
}


So somehow I have to store the value of the function I want to be called in a variable so when the interrupt occurs that function will be called.

I hope you understand!!! Thank you!
 
That's a big processor way to do things. If you look at the generated code for an indirect function call you'll be amazed at the bloat.

You have already encoded the information in the values of PORTA and PORTB. What is less clear is if it is possible to start Timer0 twice before it expires once. In this case you might want to check both conditions, call the appropriate routine AND have an error recovery procedure for when the timer expires and nothing needs to be done. This is called a spurious interrupt.

You will find that using a bit in a file register is way more efficient and straightforward then storing and calling relocatable functions.
 
Thnx for the reply.

Actually the functions will run one after another so there is no way to start the timer twice.

If I understood correctly you mean that I should have a register which according to its value the timer will run a particular function. So if for example the register has value of:
0x00 -----------> call turnoff_lights
0x01 -----------> call turnoff_TV

I guess I could do that. But I wanted something more flexible (?). So if I have many functions doing that I will not need a big IF list in the interrupt function. Instead the interrupt will call the address stored in the variable and go directly to the function that is supposed to go.
 
Again you need to look at the generated code to see what is happening. In a Harvard architecture machine like the PIC family the size of a file register or data byte is 8 bits. The size of a program memory address 14 bits for the mid-range family (16F series). Nested IF-ELSE is not the only construct you could use. The switch statement may have an efficient implementation on the PIC. It is important to remember that there is in fact no efficient indirect GOTO or CALL instruction in the midrange architecture. This is not the case for big processors. Let me repeat myself. If you're going to program in C you sometimes have to look at the generated code to see what is going on. You will be amazed and mystified by what you see. Just because you can code it in C, doesn't mean it is always a good thing to do.
 
Last edited:
I think Ronald Reagan's advice on nuclear weapons applies to C compilers. He said, "Trust -- but verify".
 
Papabravo said:
Again you need to look at the generated code to see what is happening. In a Harvard architecture machine like the PIC family the size of a file register or data byte is 8 bits. The size of a program memory address 14 bits for the mid-range family (16F series). Nested IF-ELSE is not the only construct you could use. The switch statement may have an efficient implementation on the PIC. It is important to remember that there is in fact no efficient indirect GOTO or CALL instruction in the midrange architecture. This is not the case for big processors. Let me repeat myself. If you're going to program in C you sometimes have to look at the generated code to see what is going on. You will be amazed and mystified by what you see. Just because you can code it in C, doesn't mean it is always a good thing to do.

Thank you for the valuable information. I agree with you that you need to know what is under the hood!

To be honest, this project I am doing right now, is a test to see how easier it is for me to develop in C instead of machine language.

So back to the original question. Do you think it is better to do it with switch?
 
Depends on the application, if you're doing higher end apps you'll be using bigger chip with more memory and resources so C is easier. On simple or apps on the cheap you may be trying to squeeze every last ounce of resource out of a device and ASM might be the better route. It's usually not good to 'switch' but to use each one where it's strengths lay. Most C compilers have allowances for inline assembler though which makes 'switching' not so difficult, as if you find you need to bit twiddle a few things to safe some code space you can just toss a few lines of ASM in.
 
In addition to what has been said,
Timer0_Interrupt
{
if timer was started by [turnon_lights] then call turnoff_lights
if timer was started by [turnon_TV] then call turnoff_TV
}

The big problem with this is that you are calling code from within an interrupt.

Better to set a flag which you check in main. You want your interrupt to be as short as possible.

Do as PapaBravo is suggesting; try compiling then looking at the assembly your compiler produces. That will tell you how your C is being translated to assembly, and you will be able to see which routines are more efficient.

Remember, too, the '628 has only 2k program memory.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top