## Atmega328p UART and EM-18 (RFID Reader)

10 posts / 0 new
Author
Message

So im still pretty new at this, but im trying to make sure im learning to understand datasheets..and basically being able to implement them in the simplest way possible. UART was the first "communication protocol" I learned on the AVR. It seems pretty simple (at least so far, im sure im missing something). From my understanding:

UART: Hardware for sending RS232 Signals

RS232: Standard for Communicating through serial.

The UART is responsible for adjusting the voltage levels to RS232 levels correct...or can it only send TTL Serial Levels?

From my understanding TTL Serial is 0 to Vcc (so 5v or 3.3v), and we would use a MAX232 to actually adjust from a 5v level to 232v level (MAX does this through charge pumps, which im not sure how "precisely" these work...but I understand the general concept). Otherwise the MAX232 is essentially just a shift register right? Taking a 5v level, turning it into +/- ~12V level (Although I think it's inverted from my reading, IE: 0v TTL is +12V and 5v TTL is -12V?). Or does it literally just convert logic levels and thats it. (Maybe im thinking that the UART is essentially a shift register....anyways)

So anyways assuming I have the idea of serial transmission (hopefully im not super far off) I was trying to figure out the UART on the Atmega328p (along with the EM-18 RFID Reader). From my understanding from the UART Initialization I would need to do something like this:

(Assume my Clock is running at 1MHz, default chip setup)

```/* Set Baud Rate */
/*
Pretending I want a Baud of 9600
Formula's taken from Datasheet:
F_CPU = 1000000UL I assume?
UBRRN = F_CPU/((9600*16)-1)
(So like around 6.51, datasheet mentions 6 for 1MHz, so I guess thats close?)

Sidequestion: Why does the Datasheet also literally have a BAUD calculation?
*/

void init_usart0(void) {
// Don't need to touch UCSR0C Since Async Operation
#define UBRRN  F_CPU/((9600*16)-1) //So 00000110 (6 right?)
UCSR0B = (1 << RXEN0); /* Im only receiving RFID */
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00) /* 8 bits ASCII data according to EM-18 */
// 1 Stop bit is default, so no need to set USBS0
//UCPOL0 not needed since synchronous
UBRR0L = UBRRN // 00000110
UBRR0H = UBRRN >> 4 //Says it needs upper most 4 bits? and the rest zero? (I feel like im wrong here somehow)
/* Done Initializing */
}

int main(void)
{
char letter;

// -------- Inits --------- //
init_usart0();
/* --- Event Loop --- */
while (1)
{
loop_until_bit_is_set(UCSR0A, RXC0);          /* wait until done */
letter = UDR0;							/* Pull in Byte from UART */
LCDPrint(letter_hex_or_ascii); // Pretend I have a LCD hooked up w/driver and have converted it
}
return 0;
}```

Ok it's not glorious code, but it's what i've gathered from just looking at the datasheet. Im a bit confused on the `UDR0` reading part......does `RXC0` get reset when we read from `UDR0`. Based off the datasheet that seems to be correct. Is this really all there is? (as far as reading the data). It seems pretty simple (which scares me, since im still new to a lot of this).

From the EM-18 datasheet it's sending 10 bytes (ascii characters that are 8 bits). haven't quite figured out how i'll convert them, but this is just SUPER SIMPLE basic usage of just reading a RFID chip/device. Is this accurate hopefully for a basic setup? Has anyone used the EM-18 before (I see other RFID readers/writers but they seem super complex).

I hate just using a library without understanding how it works, so hopefully im close.

Thanks all!

The max232 does the inversion and level shift - no shift registers. RS232 specifies the connector and voltages - not what is sent down the wire.

```F_CPU = 1000000UL I assume?
UBRRN = F_CPU/((9600*16)-1) ```

What does the data sheet say about 1MHz and 9600 baud?

The error rate is way too high, this seems to catch all beginners!

Also you must have an accurate and stable clock source, so be sure your using a external xtal + 2 caps on your M328 with proper fuse settings.

Jim

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get \$5 free gold/silver https://www.onegold.com/join/713...

Yeah I noticed that error rate and was like Sheesh!, It seems like going to 2Mhz would lower the error rate considerably. By stable clock source I assume you are saying that the Internal Osc is not very good? Because I was going to ask for testing could I just change the clock pre-scale (I guess the fuses?) from /8 to /4 (so it'd run at 2MHz and have a less-bad error rate)

Also did my code look...ok? Like is that all that's needed?

also Kartman: I guess im thinking that the UART is what basically contains a shift register (from my understanding). So all the max232 does is basically adjust the voltage levels and send them out?

Can anyone comment on this part, the >> 4 feels wrong....but it seems right in my head:

```UBRR0L = UBRRN // 00000110
UBRR0H = UBRRN >> 4 //Says it needs upper most 4 bits? and the rest zero? (I feel like im wrong here somehow)```

Just do:

`UBRR0 = UBRRN;`

the compiler knows how to split the value and which  reg to write to first.

Also since the default mode for the usart is 8N1, no need to mess with UCSR0C unless you need something different.

Jim

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get \$5 free gold/silver https://www.onegold.com/join/713...

Set the U2X bit and the error drops to near-zero:

Always set U2X if you can and the error will never be worse than

without it.  And you can't set it only when using extremely low

baud rates.

--Mike

EDIT: typo

Last Edited: Thu. Nov 8, 2018 - 06:31 PM

Since there is some uncertainty about the whole process, lets review:

1. The MCU has a UART or USART that may be implemented in hardware or software. We like to use hardware ones, where possible, as that involve much less pain and very little code.

2. The U(S)ART connects through he MCU I/O pin structure. So, its signals, in and out are logic levels that are close to ground and close to the MCU's VCC. The Rx pin is the INPUT pin and the Tx is the OUTPUT pin. These signal/logic levels are referred to as "TTL" even though they may be far from traditional TTL logic levels because of convention and because of the arrangement of the logic levels. These signals are also inverted with respect to the normal signals on an RS232 cable.

3. RS232 level converter (MAX232 and cousins) converts between the standard RS232 logic levels (typically +12V and -12V, though it can be smaller) and TTL levels appropriate for the input and output of a U(S)ART. The level converter also inverts. Note that the converter Tx pin is the CONVERTER'S output and must be connected to the U(S)ART's Rx pin. Likewise, for the converter's Rx pin and the U(S)ART's Tx pin. A converter requires a source of power and usually has a built-n charge pump power supply (usually needs several external caps) to get the +12V/-12V needed for the RS232 signals. There is also a ground connection REQUIRED between the MCU/U(S)ART and the level converter.

4, The same, or equivalent is needed at the other end of the RS232 cable. RS232 devices with a DB9 or DB25 connector can be assumed to have standard RS232 logic levels. You DO have to pay attention to the receive and transmit at each end of the cable. Typically, the receive of one end become transmit at the other. There must also be a common or ground wire in the cable, connecting at both ends. That signal MUST be connected to the level converter's ground.

5. The RS232 standard says nothing about the format of the data on the cable or even that it is asynchronous serial (and certainly not details like baud rates). Technically, the RS232 spec only addresses on-cable logic levels, secondary signalling (e.g. RTS, DTS, and such) and connectors, including pin-out.

Hope this helps.

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

Last Edited: Thu. Nov 8, 2018 - 09:16 PM

Nicely done Jim,  maybe this needs to be a sticky!

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get \$5 free gold/silver https://www.onegold.com/join/713...