Я тестирую свою первую печатную плату, основанную на ATMega328, и столкнулся с нежелательным поведением UART:
Когда у меня есть UART, подключенный к моему компьютеру через USB-кабель FTDI, он работает отлично, но если я отсоединю кабель от печатной платы, я могу отправить ввод на линию Rx печатной платы, просто коснувшись Rx и заземления одним пальцем на в то же время.
На самом деле у меня раньше была проблема с пальцами, вызывающими плохой ввод, и ответом на это было то, что у меня были плавающие напряжения.
Конечно, линии Rx/Tx, когда они ни к чему не подключены, тоже будут плавающими, что, я думаю, вызывает здесь ту же проблему.
Мне действительно нужно, чтобы это было надежно - в частности, я хотел бы, чтобы на UART не было ввода, когда на самом деле ничего не отправляет ввод.
Тогда два вопроса:
Что может быть причиной этого?
Что мне делать, чтобы это исправить? Подтягивание на линии Rx?
Дополнительная информация: так я тестировал.
#include <avr/io.h>
#define USART_BAUDRATE 9600
#define F_CPU 16000000UL
#define UBRR_VALUE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
#define pin (PC3)
void initUART(void)
{
// Set baud rate
UBRR0H = (uint8_t)(UBRR_VALUE >> 8);
UBRR0L = (uint8_t)UBRR_VALUE;
// Set frame format to 8 data bits, no parity, 1 stop bit
UCSR0C |= (1 << UCSZ01) | (1 << UCSZ00);
//enable transmission and reception
UCSR0B |= (1 << RXEN0) | (1 << TXEN0);
}
void sendUARTByte(uint8_t data)
{
// Wait for byte to be transmitted
while (!(UCSR0A & (1<<UDRE0))) { }
// Transmit data
UDR0 = data;
}
uint8_t receiveUARTByte()
{
// Wait for byte to be received
while (!(UCSR0A & (1<<RXC0))) { }
// Receive data
return UDR0;
}
int main(void)
{
uint8_t input = '!';
DDRC = _BV(pin);
PORTC = 0;
initUART();
while(1)
{
PORTC |= _BV(pin);
sendUARTByte(input);
input = receiveUARTByte();
PORTC &= ~_BV(pin);
sendUARTByte(input);
input = receiveUARTByte();
}
}
По сути, все, что он делает, это переключается PC3
(= pin
) всякий раз, когда есть какой-либо вход на UART, и просто отражает вход обратно на выход.
Он отлично работает при подключении к моему компьютеру, но затем, если я отсоединяю линию Rx и перемещаю линию заземления на другую площадку (чтобы я мог легко одновременно касаться контактов Rx и заземления), я все еще получаю переключение контактов. на высокой частоте, но я не получаю никакого вывода на компьютер (хотя линии Tx и заземления все еще подключены).
Вот соответствующая часть схемы:
UART находится в центре слева.
Довольно часто, по крайней мере, активируют внутреннее подтягивание и, возможно, обеспечивают более сильное внешнее. Плавающие входы не просто вызывают ложные сигналы; входное напряжение, близкое к напряжению кроссовера логического уровня, может привести к тому, что микросхема будет потреблять чрезмерный ток, поскольку как верхний, так и нижний полевые транзисторы могут быть частично включены, вызывая путь проводимости от источника питания к земле.
Например, на ATmega вы можете установить внутреннюю подтяжку основного последовательного вывода следующим образом.
/* Idea copied from arduino bootloader - Enable internal pull-up
resistor on pin D0 (RX), in order to supress line noise */
DDRD &= ~_BV(PIND0);
PORTD |= _BV(PIND0);
Я столкнулся с той же проблемой, когда разрабатывал свою печатную плату ATmega64.
Он работал нормально, когда TX / RX подключался к компьютеру через USB-кабель FTDI, и если я отключал FTDI от компьютера или от платы ATmega64, то выходные контакты контроллера переключались без какого-либо ввода.
Решение: у меня на плате был установлен LM317 на 3,7 В. Я подключил к нему TX/RX, и проблема была решена.
Решение: я разработал вторую печатную плату с более прочным заземлением и плоскостью 3,7 В, и тогда TX/RX не показал никаких проблем. Таким образом, вы можете улучшить плоскость GND и V CC в проектировании печатных плат.
Яшасун
Крис Стрэттон
Яшасун
Яшасун