Search code examples
cavratmega

PuTTY not sending data to AVR serial


in an exercise for my embedded programming course we have to program an Atmega328p AVR chip to receive data through the serial port. We have to do this by calling a function that waits until it receives a char. Next it should display the ascii value of that char in led lights, but I am having trouble even receiving it. I've done a lot of debugging and I think I narrowed it down to PuTTY not even sending the data, or the AVR not receiving it properly. I will put my code in below:

/*
From the PC should come a char, sent via the serial port to the USART data register. 
It will arrive in the RXB, which receives data sent to the USART data register. 
While running the loop, the program should encounter a function that is called and waits for the RXB to be filled. 
Then it will read the RXB and return it to the main loop.
The result will be stored and processed accordingly.
*/

#define F_CPU 15974400
#include <util/delay.h>
#include <avr/io.h>
#include <stdlib.h>
#include <avr/interrupt.h>

void writeChar(char x);
void initSerial();
char readChar();

int main(void)
{
    initSerial();
    while (1) 
    {
        char c = readChar(); //reads char, puts it in c
        _delay_ms(250); //waits

        writeChar(c); // spits that char back into the terminal
    }
}

void initSerial(){
UCSR0A = 0;
//UCSR0B = (1 << TXEN0); // Enable de USART Transmitter
UCSR0B = 0b00011000; //transmit and receive enable
//UCSR0C = (1 << UCSZ01) | (0 << UCSZ00); /* 8 data bits, 1 stop bit */
UCSR0C = 0b00100110; // Even parity, 8 data bits, 1 stop bit
UBRR0H=00;
UBRR0L=103; //baudrade 9600 bij
}

void writeChar(char x){
    while(!(UCSR0A & (1 << UDRE0))); // waits until it can send data
    UDR0 = x; // Puts x into the UDR0, outputting it
}

char readChar(){
    while (!(UCSR0A & (1 << RXC0))); //waits until it can send data
    return UDR0; // returns the contents of the UDR0 (the receiving part of course
}

The problem is that when I enter anything in PuTTY (that I assume I set up correctly. https://prnt.sc/rc7f0f and https://prnt.sc/rc7fbj seem to be the important screens.

Thanks in advance, I am completely out of ideas.


Solution

  • I fixed it myself. I figured it out while taking it downstairs to test it on another laptop. I still had LEDs put in all pins of PORTD, all on input mode (that's the default mode). I quick look at the Atmega328p user guide (section 2.5.3) revealed that the pin D0 was actually the RxD in for the USART. By putting an LED on it and effectively grounding it, it was always pulled low, and would never be put high by the CPU, which would stop the while loop check while (!(UCSR0A & (1 << RXC0))); //waits until it can send data in readChar();

    So by simply removing that led it would work again. Obviously that would mean it was floating, so I set the DDRD to all be output, as nothing needed to be input anyway.

    That ended up fixing it.