NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Everything Else » Interface with other MCUs

February 26, 2011
by amartinez
amartinez's Avatar

2 questions, if you can help I would greatly appreciate it.

I have another microcontroller that accepts data at 9600 baud, 8 bits, No- Parity, and 1 stop bit (8, N, 1) and non-inverted, (RS-232 is inverted).

Question 1, can I configure any pin on the Atmega 168 to send data or is it just pin 3 (PD1)

Question 2, does the Atmega 168 send non-inverted data by default? If not, is there a setting for this? I can always use a MAX232 but that's adding complexity to a simple link from chip A to chip B.

Thanking you in advance for your help

Al

February 26, 2011
by 6ofhalfdozen
6ofhalfdozen's Avatar

Hi Al,

Since I haven't seen anyone else chime in, I will toss out a quick answer. I am definately not an expert, but I should be able to point you in the right direction untill a real expert chimes in.

Something that might help, is to read the datasheet on the other yC to see if it really sends via RS232 or via TTL compatible UART. If it communicates via TTL compatible UART, ideally you should just be able to match the baud rates, send an RX from one chip to the TX of the other, and fire them up.

Q1. As far as I know, to use the standard UART to communicate, like when you program your NK, you need to use the same pins as when you program it. There might be something else about that hidden in the datasheet, but thats not something I have hunted for yet. Since 9600 is a pretty slow speed, assuming you can handle taking the mcu's time, you can definately similate the uart to "bit-bang" using any of the other digital out capable ports. ("bit-banging" is using specific code to toggle the port Hi/Lo at the proper speed to transmit the bits you want..)

Q2. I haven't checked my 168 datasheet recently, but I believe the NK yC does send standard/Non-Inverted output from the UART, which is why you need to invert to send over RS-232. There might be a setting for switching it if you must, but running a Hex inverter/NotGate would be MUCH easier and cheaper than the max232 chip. hopefully that helps

February 27, 2011
by amartinez
amartinez's Avatar

Ok, so basically from what I gather is that I can just hook up the TX on the 168 (pin 6) to the other MCU. No problem, they both speak the same language of sort. Heck, worse comes to worse I just replace the chip, I have a few just in case.

The PDF for the Atmega 168 is over 350 pages, I can do a search for some key words but I just wanted to see if anyone out there has done this before. I understand the bit banging but I would need an oscilliscope and lots of patience. Then I would have to convert every character in to an 8 bit signal with possibly 2 bits for CRC, I'd rather get nanites take over my body as I get asymilated in to the collective.

Thank you 6/1/2dozen. That's a Borg designation, you are number 6 of a crew of 6.

February 28, 2011
by amartinez
amartinez's Avatar

Two follow up questions.

1- I will be uploading code from my computer to the Atmega 168 via USB provided by NK. Once the code is loaded, I have to disconnect pin 2 and 3 (RX/TX) then connect the Atmega 168 to the other MCU using the same pins. So experimenting with code in this case will mean a lot of wire manipulation, correct? If so I can devise a simple switch to isolate wires as needed. What I'm asking is basically if there is a better way.

2- This questions concerns UART. Is there an existing Nerdkit project (code) which uses this function providing the UART datastream protocol? I know data can be sent to the LCD but it's at 4 bit nibbles, unlike the same protocol used in RS232. I need someting to help me understand the code needed to send data this way.

Thank you

Sleepless in my livingroom turned in to an electronics lab

February 28, 2011
by Noter
Noter's Avatar

I think you are correct on the wire manipulation. Maybe you will be happier to leave the RS232 decicated to communicating with your PC and use the SPI interface to communicate between your controllers. Take a look at chapter 18 on SPI in the ATmega documentation and see what you think.

February 28, 2011
by Noter
Noter's Avatar

If your other microcontroller must use rs232 then you could add a SPI uart that would basically convert the SPI to RS232 which would still allow your main uart to remain dedicated to the PC. Here's a SPI<-->RS232 chip that might do what you want.

February 28, 2011
by n3ueaEMTP
n3ueaEMTP's Avatar

If you are using two ATMega 168s or 328s (or any combination) you could also use the I2C (TWI) interface. There are many tutorials on the web and here. There are also a number of libaries online (Peter Flurey's comes to mind) that make implimenting the I2C protocol realitively painless.

February 28, 2011
by amartinez
amartinez's Avatar

All of your suggestions are much appreciated. Thank you. I now have something to base my research on. Lots of good stuff.

My second question was on source code. If any of you have a link or can provide simple C source code where I can test the connection by sending a string of characters like "ABC" to the other side, I would greatly appreciate it. I'm not trying to grub, but this is a help forum and all I need is a nudge then I can ride the bike alone.

Thanks again

May 10, 2011
by amartinez
amartinez's Avatar

Back to this thread after leaving the project for a while.

Ok, after much research here is my code. I'm getting the Atmega 168 to send something, I just don't know if it's communicating at 9600,n,8,1 out of pin PD1. I'm communicating with another chip requiring the same com settings. When I run the code, The other chip spits out garbage. I know the other chip works so I have this question:

Is there any way I can hard set the com settins to 9600,n,8,1 on the Atmega 168? You can see from my code where I attempted to do that and I got some errors.

#define F_CPU 14745600

#include <stdio.h>
#include <math.h>

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <inttypes.h>

#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"
#include "../libnerdkits/uart.h"

// This program works, I'm not sure it's communicating in 9600,n,8,1
// supposedly the default communications rate of the Atmega 186

char data;

int main(){

    uart_init();
    FILE uart_stream = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);
    stdin = stdout = &uart_stream;

    // uartSetBaudRate(9600);// This returns an "undefined reference" error in make

    while(1){
        delay_ms(1000);
        printf_P(PSTR("A"));
        delay_ms(500);
        printf_P(PSTR("B"));
        delay_ms(500);
        printf_P(PSTR("C"));
    }

    return 0;
}

Thank you for your help.

Al

May 10, 2011
by 6ofhalfdozen
6ofhalfdozen's Avatar

Heya Al,

A couple suggestions.

An easy way to see if you are sending at 9600 8n1 from the NK is to send it to your computer. If you set up the computer terminal program to read at 9600 8n1 and your messages come through legibly with all appropriate letters in the right place, then you are sending at at/near 9600 8n1. If you set up your terminal to read 9600 8n1 but you are sending at something else (28800) your message will be messed up. Letters shifted, letters missing, sometimes lines of nothing or gibberish.. Crude, but it usually works..

Second Thing.. If you want to set the UART to send at a specific speed/settings you will need to set them using the registers. I haven't seen the "uartSetBaudRate" syntax you used in the above code, so I don't know if that will work or not. In the datasheet, the uart stuff starts in the 190's. The table on page 198 shows the settings you need in the UBRRn to get specific baud rates.. so 9600 with the standard NK14.7456MHz, UBRRRn = 95. Page 193 goes over the UCSRnC which has the 8n1 stuff. Once you set those registers to the proper settings, hopefully you will be all set. hope that helps..

May 11, 2011
by amartinez
amartinez's Avatar

6 1/2 12

Thank you for your input. I tried hyperterminal on a Windows XP connected to the Atmega 168. I also program the chip using the same computer with the nerdkit supplied USB / RS232 connector. It uploads programs to the chip well, however, when I ask the chip to send the data using the abovementioned program, I see nothin on the screen. I've done hyperterminal connectivity with many devices but never a direct connect to a chip. I set the hyperterminal to 9600, n, 8, 1 and tried differnt flow controls including hardware and none. Nothing showed up, but the chip seems to communicate fine with the AVR software using COM 4. I checked the settings on the USB, hyperterminal and port settings, they are all 9600, n, 8, 1.

I don't like setting registers if I don't have to and since my other MCU defaults at 9600, I may need to think about the non-inverted portion of the protocol.

The chip I'm trying to connect to is a read-only chip and calls for Serial TTL Data, then has a pin for "serial flow control" but that is not connected. I don't know where to connect that to the Atmega 168. I tried the RX (PD0) but that didn't work.

The documentation says the receive pin on the MCU is expecting a logical level (non-inverted) signal... ????

Sorry for the long post but this may help others. The documentation says that the MCU does not accept actual RS232A signal levels, a level shifter is needed in the form of a transistor or comm chip. RS232 is inverted and the MCU calls for non-inverted. The documentation is a bit sketchy so I'm going on what I remembered over a decade ago when I was configuring routers and switches using similar interfaces.

I'm going to give this one a shot.

May 11, 2011
by Rick_S
Rick_S's Avatar

Try setting your speed to 115200 in hyperterminal, N,8,1 with no flow control. That is what the uart is set at by default in a NK chip using their cable. Connect the NK cable the same way you would to program the chip. Set Hyperterminal to use the same com port you use for programming the chip with the above settings. If your proram is correct, you'll communicate.

Rick

May 12, 2011
by amartinez
amartinez's Avatar

Rick, it worked. Thank you. No problems with that. Forgive my ignorance, I'm new at this level of hardware communication.

I have to follow up with another question, the AVR programmer on the PC is set to 9600 but 3 is set at 115200? Is pin 2 set at this rate as well? In other words, is the physical USB RS232 connector at the PC communicating at 9600 at the USB interface but transmitting 115200 on the wire to the NK?

This also begs the question, how does one set pin 3 (PD1) TX to 9600? This is preplexing. Is there any code out there that would do this without damage? I don't want to mess anything up. Unfortunately my other chip jumps from 9600 to 19200, no 115200 setting on that. I like to keep com speeds the same, preferably at 9600 all the way through.

Thank you for your help on this. I'm one step closer now (many steps to go)

With much appreciation

Al

May 12, 2011
by 6ofhalfdozen
6ofhalfdozen's Avatar

Heya Al,

Ok.. a couple more things, my apologies if I cover something you already know, but it sounds like you are floundering due to missing info. trying to help you get to where you can understand this stuff, not trying to offend or irritate. Hopefully I answer some of your questions along the way.

It sounds like you are missing some info on RS232. RS232 works with at least two wires, so PD0 and PD1 are a pair. Most hardware automatically sets them the same...PD1 (aka TX, short for Transmit) is the NK mcu sending to the computer or other things. PD0 (aka RX, short for Receive) is the computer or other things sending to the mcu. These two work as a pair, and to the best of my knowledge there is not a way to set one to one speed and the other to another speed on the MCU. The only way I know to change the speed of the pair on the mcu is through the registers I mentioned previously. More on this later...

As for the settings, there are a couple extra confusing bits here. If you are going from NK to NK converter to USB to PC to Hyperterminal, you have a few extra steps and things in the middle that might be confusing things over all. The NK will send at whatever speed you tell it to, using the registers. By default the NK guys set it to 115200 8n1. The NK converter/cable "should" pretty much be invisible, it should send what it gets appropriately to how it got it. The USB connects are also nearly invisible, but where it connects to the OS on your PC it adds a little confusion. On the prolific driver setup where it states com port and such(in device manager), there are sections to "set/change" the speed and settings. This is a confusing and somewhat misleading section. This doesn't set the device speed, this just sets how the data is gated from the USB bus into your system. This is why most times, you are told to set this to the "max speed" (usually 115200 for most hardware), and use the same setup as your data stream. (setting it to 7n2 will make a 8n1 stream go bananas, unless the system catches it and resets the driver settings automatically) The settings in hyperterminal tell the program how to read the data coming in from the system and how to send the data out to the system. This is why my rough test previously catches when Nk is sending a speed that hyperterminal is not set to, the data is "gated" wrong and ends up all chopped up funny. The most important ones are the settings on the NK and in the hyperterminal, they definately must match to be able to communicate properly. The intermediate settings aren't as sensitive, but work better when they match or are in a "complimentary" setup (ie 115200 for the usb-system setting) Clear as mud, right??

So for in your questions, I have to follow up with another question, the AVR programmer on the PC is set to 9600 but 3 is set at 115200?

   Unless you have changed the NK registers, 3 will be sending at 115200 regardless of what the AVR programmer on the PC is set to.

Is pin 2 set at this rate as well? In other words, is the physical USB RS232 connector at the PC communicating at 9600 at the USB interface but transmitting 115200 on the wire to the NK?

Pin 2 is set to 115200, so the nerdkit is waiting for 115200 8n1 signals. If you have the AVR programmer set to 9600, the PC will be sending 9600 to the NK. So if the avr programmer sends a 9600 signal to the NK, that is what it will be showing up on pin 2. If the NK is expecting a 115200 signal it will most likely go "WHAT?? Huh??"

On to changing the mcu uart speed. You repeatedly mention not wanting to damage the mcu. Changing the registers doesn't "hurt" the mcu, as thats how you turn on the ADC and ports and all that. "Fuses" are the scarey ones you don't want to mess with unless you know exactly what you are doing.(or you want to see the magic blue smoke escape). The only "warning" about changing the registers relating to the UART settings, is that it is hard to change them back if you don't plan ahead. You might want to ask the NK guys or one of the pros around here, but I would think that if you set it up in code you might be able to toggle it like the program pin at start up.. Pros, Any thoughts?
pseudocode for doing something like this:

 if SOMEPIN (PD6 maybe?) is low
     set uart registers for 9600 8n1
 elseif SOMEPIN is high
     set uart to NK default 115200 8n1
 end if

So for instance if you choose PD6 as your "115200 or 9600" choice pin, if you connect PD6 to Vcc the uart is set to default 115200 on start up. If you tie PD6 to ground, it switches to 9600 on start up. This way you don't lose your method of reprogramming the NK. (ok, pros here is a real question for you, could you set it up in code so that PB0 works as both your program the chip pin but also your set to 115200 pin for programming only?? so the muc lives in 9600 mode unless being reprogrammed?? or would that not work?? ) anyhow.. those are some thoughts.

May 12, 2011
by amartinez
amartinez's Avatar

6 of 1/2 12 (borg designation?)

I thoroughly enjoyed your response and it was full of good info. In short, we have TX and RX both running at 115200 not at different speeds (which makes sense) so a direct wire connection from an NK to an MCU that runs at 9600 will not work (of course). I got some bad info then, I went to another Atmel forum (I confess) and somebody said it should be no problem as the Atmega168's com ports communicates at 9600 so a direct connect should work great.... (WELL IT DIDN'T).

As for the damage comment, I did read warnings about fuses and some about baud rate settings, the chip won't be damaged per se but what I meant was that I may not be able to communicate with it again.

There is some code on the Atmel data sheet (I think page 176?) but I'm afraid to use it because it will change the com speed on TX and RX. I don't like bit banging but the ground pin (PD6) idea sounds good.

Followup question, doesn't the Atmel bypass any code and goes to program mode when pin PD6 is grounded? Therefore any programmed settings will be ignored (unless they are pre set in the bootloader).... stretching my neck out here... Pros? Is my hypothesys correct?

One more thing. I do go on other forums and I find this forum the most informative and accurate... fun too.

Thanks again

Al

Post a Reply

Please log in to post a reply.

Did you know that NerdKits has been featured on Slashdot, Hack A Day, Hacked Gadgets, the MAKE blog, and other DIY-oriented websites? Learn more...