This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

AT89C51 ADC in Timer Interrupt Problem

Hi there,

This may be a compiler/driver issue or it may be a hardware issue but I am wondering if anyone else has seen a similar problem to this.

We have code to read an ADC channel and this works fine. We have code to generate timer interrupts and handle CAN communications and this works fine.

However, when we call the ADC channel read from inside a timer interrupt (timer1, specially used just for this) it appears to completely screw up the CAN transmission. We get transmission on odd channels, bad data, all sorts.

Before I post lots of code as each system is quite complex, has anyone ever heard of this or a similar problem ? I have checked all the 89C51 errata sheets and gone through the assembly code produced by the Kiel and nowhere does there seem to be any connection between the two. Even with the ADC read in the interrupt it only occupies 2% of the processor time so I don't think it's to do with load or latency. I have made sure the ADC interrupt is off so it doesn't create an interrupt within an interrupt.

Thanks for any help,

Dirk

Parents
  • Thanks for the ideas but I have already been down most of these.

    1. Register bank issues.
    Using the Kiel default, all non-interupts are on 0. I have two timers on 1 & 2 and the CAN interrupt on 2 also. I have moved the call to the ADC between the two timer interrupts and the behaviour is the same.

    2. Priorities
    These are default and I can't see any reason to change them in that they are correct for what I want them to do. Using a DSO I have traced the times in and out of the timer interupts and they don't clash, I have even altered the periods so they are slightly different and hence "drift" apart.

    The very odd thing here is that we have used more or less all this code in quite a few projects and have never had a problem like this. It looks more and more like a hardware problem but I know from experience that it's very rare that you actually find a real hardware problem.

    Cheers,

    Dirk

Reply
  • Thanks for the ideas but I have already been down most of these.

    1. Register bank issues.
    Using the Kiel default, all non-interupts are on 0. I have two timers on 1 & 2 and the CAN interrupt on 2 also. I have moved the call to the ADC between the two timer interrupts and the behaviour is the same.

    2. Priorities
    These are default and I can't see any reason to change them in that they are correct for what I want them to do. Using a DSO I have traced the times in and out of the timer interupts and they don't clash, I have even altered the periods so they are slightly different and hence "drift" apart.

    The very odd thing here is that we have used more or less all this code in quite a few projects and have never had a problem like this. It looks more and more like a hardware problem but I know from experience that it's very rare that you actually find a real hardware problem.

    Cheers,

    Dirk

Children
  • It is unwise to make function calls from an interrupt to code that is used outside the interrupt. They are likely to use separate stack space last I checked. These are CO Routines you need to consider the PC term "thread safe" you should call only functions in the interrupt that are used only by the interrupt. Data is the only thing to consider outside them. Even then the data should only be accessed when a semaphore is set.

    Stephen

  • Thanks Stephen,

    However I don't think this applies here. We only call the ADC read function once, and this is from inside the timer interrupt. I have called it from other places to test if it works in those situations and also in other products it is called outside of the timer.

    As the Kiel and the 89C51 are not the best at multi threaded operation we avoid it completely and don't allow multiple calls as you pointed out.

    As it is at the moment I am not even bothering with the data read form the ADC as I want to crack as to why even accessing the ADC screws the CAN up.

    Anyway, thanks for the interest. Any help is appreciated.