ATMega168 vs 328 USART -- what's different?

I'm working on a DMX receiver circuit that I originally developed for the ATMega168 chip (I'm using bare chips and my own boards). When I reordered more chips I got the ATMega328 instead, thinking that the only difference was more memory. My problem is that the ATMega168 chip works and the ATMega328 chip doesn't, even though I'm uploading the same sketch and using the same board.

The ATMega168 will properly receive the DMX signal coming in on the RX pin (via an SN75176). The ATMega328, however, freezes when it sees anything on the RX pin. Is there something different about the USART on the 328?

I'll keep browsing through the forum here, but if anyone can help me figure out what's different between the 168 and 328 I'd love to hear from you. I'm currently using Arduino-0018 on Xubuntu Linux.

Jeremy

I'm using DMX code based on this thread (post #20):
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1223117506/15

Jeremy

Did you change the Board setting to a 328 in the IDE?

Yes, I got an upload error message if I didn't.

For the ATMega328, I used "Arduino Duemilanove or Nano w/ ATmega328".
For the ATMega168, I used "Arduino Diecimila, Duemilanove, or Nano w/ ATmega168".

Otherwise everything else is the same -- hardware board, parallel programming cable, sketch, etc.

Jeremy

OK, I think I found the problem. The name of the interrupt handler needed to be changed from:

SIGNAL(SIG_USART_RECV) { // for ATMega168
...
}

to:
SIGNAL(USART_RX_vect) { // for ATMega328
...
}

Ironically both names seem to work fine for the ATMega168. I realized something was wrong with the interrupt handler routine because the compiled sketch was staying the same size even when I commented out parts of the routine.

Good news is that I did learn a few things about the inner workings of the chip in the process -- little did I know that the full datasheet was 500+ pages long... yikes! Looks like I've got some more reading to do.

Jeremy

While you're at it:

Deprecated:
    Do not use SIGNAL() in new code. Use ISR() instead.

http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html#g67cd0dea412157775c2f2a3ffe9fb8ff

Good to know -- I have changed my code to use ISR(), and everything appears to be working great. Thanks for the tip!

Jeremy