Hello everyone!
Im having a very strange issue with an ATMega328P and I cant seem to solve it.
The issue is that the processor is sending 7 data bits instead of 8 data bits even though its configured to send 8-data bits.
I wrote this code a while back and prototyped it on the Arduino UNO but programmed it using Atmel Studio 7 and Atmel ICE, used the fuse settings for internal 8MHz clock with no "clock div 8". The code worked fine on this platform.
I recently received the final hardware after a very long delay due to Covid/semiconductor shortage. The strange thing is that the same code for the same processor is no longer working and I'm not sure why, ive never tested the code on this hardware but ive tested older unrelated code and everything seems to work except the UART. The RS485 enable pin goes low way before the UART transmission is completed, its about 1000 times faster than the baud rate and only shows up as a dot when zoomed to fit the transmission data on screen.
All the registers seem to be correctly configured according to the datasheet, maybe ive stared at the same code for too long and am going crazy, no idea. I do get frame errors (from the UCSR0A status register) whenever I try to send data larger than 7-bits so it seems that it understands that it is configured for 7-bits but according to the register debug overview it configured correctly.
Ive added the stripped UART code and output, captured on the scope below. The datasheet is attached and registers info I'm using can be found on page 159.
https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdfHave a nice weekend!
PS:
Sorry for the comment indentation, it doesn't want to indent correctly when posting it here.
#define F_CPU 7372800UL
#define BAUD 9600
#define UBRR F_CPU/16/BAUD-1 // 47
#include <avr/io.h>
#include <util/delay.h>
int main(void){
UBRR0H = ((uint8_t)(UBRR >> 8)); // Set baud rate, 8Mhz UBRR -> 47
UBRR0L = ((uint8_t)(UBRR)); // Baud rate Low
UCSR0B = (1<< RXEN0) | (1 << TXEN0); // Enable RX/TX
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); // 8-data bits and 1 stop bit, no parity.
DDRD = (1 << PORTD4); // Set PD4 as output, PD4 = RS485 control pin
while (1){
PORTD = (1 << PORTD4); //Transmit enable for RS485
while(!(UCSR0A & (1<<UDRE0))); // While data register is empty.
UDR0 = 0xAA;
_delay_us(850); //Should not need this for the EN-pin. did not need it before...
PORTD = (0 << PORTD4); // Disable transmit
_delay_ms(1000);
}
}