0
\$\begingroup\$

I implemented the following program to send data to a serial monitor.When I run it, I expect to see abcd but I always see ⸮bcd:

#include <string.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#define BAUD 9600
#define CLKPS 8
#define F_CPU 16000000UL
#define TCNT0_VALUE (0xFF - F_CPU / CLKPS / BAUD)
static volatile uint8_t bit = 0;
static volatile uint16_t data = 0;
static volatile int tx_in_progress = 0;
static void swuart_init(uint8_t tx_pin)
{
 // initialize timer
 TCNT0 = TCNT0_VALUE;
 TCCR0A = 0x00;
 TCCR0B = 1 << CS01;
 TIMSK0 = 1 << TOIE0;
 // enable tx pin
 DDRD |= (1 << tx_pin);
}
/* set up payload: 1 start bit, 0 parity bits, 1 stop bit */
static void swuart_send_byte(uint8_t byte)
{
 tx_in_progress = 1;
 data = (1 << 10) | ((uint16_t) byte << 1);
 while (tx_in_progress)
 ;
}
int main(void)
{
 swuart_init(PD7);
 sei();
 swuart_send_byte('a');
 swuart_send_byte('b');
 swuart_send_byte('c');
 swuart_send_byte('d');
 for (;;)
 ;
 return 0;
}
ISR(TIMER0_OVF_vect)
{
 TCNT0 = TCNT0_VALUE;
 if (!tx_in_progress)
 return;
 if (data & (1 << bit))
 PORTD |= (1 << PD7);
 else
 PORTD &= ~(1 << PD7);
 if (bit < 10)
 bit++;
 else {
 bit = 0;
 tx_in_progress = 0;
 }
}
asked Apr 7, 2023 at 4:50
\$\endgroup\$
2
  • 1
    \$\begingroup\$ What if you add a short delay between calling the setup and starting output? You could be causing some glitching that looks like a start bit. \$\endgroup\$ Commented Apr 7, 2023 at 5:05
  • \$\begingroup\$ @hobbs It is causing a glitch that looks like a start bit. \$\endgroup\$ Commented Apr 7, 2023 at 5:10

1 Answer 1

2
\$\begingroup\$

The problem is that the pin is uninitialized, and you send a byte immediately after pin is initialized.

And the pin is incorrectly initialized to logic low, which is a start bit.

Initialize the pin as a high output, not as a low output. You might want to delay at least 10 bits worth of time to make sure that situation after boot and reset has stabilized before start bit of first byte can be sent.

It is also a hazard to set the transmit flag first and then set the data what to transmit. The interrupt might trigger between setting the flag and setting what data to send.

answered Apr 7, 2023 at 5:02
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.