Max487 weird reset

Go To Last Post
12 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Heya freaks!
Im trying to make a keyboard (lcd 4X20 and a keypad connected to an atmega16) and connect it to an atmega1281 through RS485. Everything runs smoothly except keyboard resets from time to time for no obvious reasons. From my tests this only happens when i put the MAX485 on. I have connect both bias (A-->640Ohm-->Vcc, B-->640Ohm-->Gnd) and a 120Ohm termination resistor. The reset occurs even with the same power supply. The trouble seams not to be software since there is no reset when i remove MAX487 and connect the 2 USARTS. I have grounded the RE PIN in both chips. Is there any chance of data collisions to create these weird resets?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Since you grounded re, this will give you loopback. I'd be suspecting the code. If there are collisions on the 485 bus, the max chips will pull some current that might also be upsetting things.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Does your code start with:

		if( (mcusr_mirror & _BV(BORF)) && !(mcusr_mirror & _BV(PORF)) ){	//when BOR and !POR
			//We have over-current or unstable powering.
			__breakpoint(0);
		}

?

No RSTDISBL, no fun!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I changed the keyboard code not to send back and the reset continues. That means that collisions are not the fault. I ll tie RE-DE together in order not to loop data back and check the code again. Thanks kartman for the help!

Quote:

Does your code start with:
Code:
if( (mcusr_mirror & _BV(BORF)) && !(mcusr_mirror & _BV(PORF)) ){ //when BOR and !POR
//We have over-current or unstable powering.
__breakpoint(0);
}

?


Nop, but this looks great!!! I'll ckeck it and impant it for sure :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

After all its not a problem caused by MAX487. As I said, I tied RE-DE, i changed the code so there was no interupt, I checked MCUCSR in case something resets the uC, I unplugged MAX487 and resets still persist. At last I used the VBandGag to measure Vcc and it seems there is a little hardware problem with my voltage :(
Thank you for the self_monitoring idea Brute and thanks for the correction kartman!
Time to change some resistors! :roll:

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I checked MCUCSR in case something resets the uC, I unplugged MAX487 and resets still persist

Any conclusions? What was the MCUCSR value of this weird reset?
I also assume you face some typical design error like a sag of power rails or RESET pin issues, and not a catastrophic latch-up or a total power rails short (because then asm("break") will not help to read out MCUCSR).

No RSTDISBL, no fun!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Im afraid I have no confirmed faults yet. MCUCSR was 0 after every reset. My master is an Atmega1281 on an STK501 with a MAX487 on a breadboard and the slave is a mega16 with an L7805 regulator with an LCD screen. The resets never occurs when mega1281 is unpluged even when i leave slave running for days. When data get tranfered slave resets about 1-3 times per minute. Their only connection is A-B data from MAX487 and a common ground.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
MCUCSR was 0 after every reset.

Then that rules out a hardware problem.
There is no way to hardware-reset chip with MCUCSR==0 (assuming you do not violate specification, like running the chip at 200 deg C, powering it at 7V, clocking at 40MHz etc).
Most likely you have a software bug that crashes the application. If it hits 0x0000 then quite possibly PC runs through FLASHEND and wraps around to 0x0000, initializes the chip and the play starts all over again.

No RSTDISBL, no fun!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

To be honest i have tried many times to find if there is a software problem but nothing till now. Im posting the code in case anyone can find the black spot. Back to work till the fault is eliminated :)
The code is written for CodeVision.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Try removing the "return;" from all non function void procedures.

It all starts with a mental vision.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
To be honest i have tried many times to find

Unwind the stack and try to find out what had happened prior 0x0000. It may be that SRAM is a total mess after that but typically with some luck SP points at some interesting location that was called prior crash. If it is only SP underflow then you are lucky because that is relatively easy to pinpoint with data breakpoint.

No RSTDISBL, no fun!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Try removing the "return;" from all non function void procedures.

Removed them all but nothing changed.
Quote:

Unwind the stack and try to find out what had happened prior 0x0000.

This seemed a little difficult :?
...so i decided to start over and see where the problem starts.
When i start poll PORTC for the key pressed everything seems to crash. Im using a 4X4 matrix keypad. I'm checking rx_counter constantly and it raises with every poll. Im using a usart interrupt with a buffer of 200 butes. Dont think that an overflow is the problem as usart stack is checking itself.
:?
Here is the keypad code

 struct kbdm {
   char inp;
   char outp[4];
   char key[4];
};

struct kbdm kbd_map[] = {
{ 0x7F, {0x7E, 0x7B, 0x6F, 0x3F}, {'*', '7', '4', '1' }},
{ 0xDF, {0x9F, 0xCF, 0xDB, 0xDE}, {'2', '5', '8', '0' }},
{ 0xF7, {0xB7, 0xE7, 0xF3, 0xF6}, {'3', '6', '9', '#' }},
{ 0xFD, {0xBD, 0xED, 0xF9, 0xFC}, {'A', 'B', 'C', 'D' }}
};

char active_key = 0;

char read_kbd() {
   int i, j=0;
   char temp_key;
   if (PINC != 0x55) {       //if there is any key pressed
      for (i=0; i<4; i++) {  //poll each of the pinc to find the key
        PORTC = kbd_map[i].inp;
        for(j=0; j<4; j++) {
            if (PINC == kbd_map[i].outp[j]) {             
             active_key = kbd_map[i].key[j];
             PORTC = 0x55;
             return 0;
            } 
        }
      }
      PORTC = 0x55;  
      
   }
    
   else if (active_key != 0) {
      temp_key = active_key;
      active_key = 0;
      return temp_key;
   }
   return 0;
}

void handle_keyboard() {
    char c;
    c = read_kbd();
    if (c != 0)  //see if there is any key pressed
        key_pressed = c;
}