Phản ứng bất ngờ của Atmega16 trên UART
Tóm tắt vấn đề
Tôi đã flash một Atmega16 với mã sẽ dẫn đến Atmega16 gửi lại bất kỳ ký tự nào tôi gửi cho nó thông qua một thiết bị đầu cuối. Tôi nhận được phản hồi, nhưng hiếm khi nhân vật tôi gửi. Tôi có thể thấy đầu ra chính xác bằng cách thay đổi tốc độ baud nhưng tôi không hiểu tại sao tốc độ baud chính xác hoạt động.
Thêm chi tiết
Tôi đang cố gắng tìm hiểu thêm về lập trình phần mềm trong thời gian riêng của mình vì tôi khá thích nó. Cho đến nay trong chương trình phần sụn tôi đã thực hiện tại uni, chúng tôi đã được cung cấp các tệp mã bộ xương thực hiện nhiều giao diện ngoại vi và thiết lập cho chúng tôi, nhưng tôi muốn tự mình tìm hiểu điều này. Tôi đã có một vài câu hỏi về những gì tôi đang làm ở đây rắc khắp bài viết nhưng cuối cùng tôi sẽ phân loại chúng. Nếu bạn nhận ra bất kỳ sự hiểu lầm hoặc lỗ hổng tiềm năng nào trong kiến thức của tôi, tôi sẽ đánh giá rất cao bất kỳ đầu vào nào bạn có thể có.
Mật mã
Mã tôi đã flash vào Atmega16 của tôi được lấy gần như dòng cho hướng dẫn 'Sử dụng USART trong AVR-GCC' được tìm thấy trên trang này . Tất cả những gì tôi đã thêm là #define cho F_CPU. Mã ban đầu không có #define cho F_CPU vì vậy mã của tôi sẽ không được biên dịch trong AtmelStudio 7. Có ai có thể giải thích lý do tại sao tác giả sẽ không xác định F_CPU trong tệp gốc của họ không? Tôi đoán họ có thể đã sử dụng một số công cụ hoặc trình biên dịch khác ngoài Atmel Studio 7 nhưng tôi không thể nói chắc chắn được.
#include <avr/io.h>
#define F_CPU 7372800 //this was chosen because the tutorial states this is the frequency we want to operate at
#define USART_BAUDRATE 9600
#define BAUD_PRESCALE (((( F_CPU / 16) + ( USART_BAUDRATE / 2)) / ( USART_BAUDRATE )) - 1)
int main ( void )
{
char ReceivedByte ;
UCSRB = (1 << RXEN ) | (1 << TXEN ); // Turn on the transmission and reception circuitry
UCSRC = (1 << URSEL ) | (1 << UCSZ0 ) | (1 << UCSZ1 ); // Use 8- bit character sizes
UBRRH = ( BAUD_PRESCALE >> 8); // Load upper 8- bits of the baud rate value into the high byte of the UBRR register
UBRRL = BAUD_PRESCALE ; // Load lower 8- bits of the baud rate value into the low byte of theUBRR register
for (;;) // Loop forever
{
while (( UCSRA & (1 << RXC )) == 0) {}; // Do nothing until data have been received and is ready to be read from UDR
ReceivedByte = UDR ; // Fetch the received byte value into the variable " ByteReceived "
while (( UCSRA & (1 << UDRE )) == 0) {}; // Do nothing until UDR is ready for more data to be written to it
UDR = ReceivedByte ; // Echo back the received byte back to the computer
}
}
Thiết lập phần cứng
- MCU: Atmega16;
- Toolchain: Atmel Studio 7, nhấp nháy với rồng AVR;
- Nguồn cung cấp: Đường ray 5V được lấy từ một trường phát triển do trường đại học cung cấp (được lấy từ USB máy tính). Tụ điện đĩa gốm 100nF được sử dụng để bỏ qua trên đường dây điện bánh mì
- Bộ chuyển đổi USB sang nối tiếp: Cái này . TXD trên bộ chuyển đổi USB sang nối tiếp được kết nối với RXD Atmega (Chân 15). RXD trên bộ chuyển đổi được kết nối với RXD trên Atmega (Chân 14).
Phần mềm đầu cuối: PuTTY (với tốc độ baudrate là 9600).
Bằng chứng của các phản ứng không chính xác
Để nhắc lại, Atmega nên trả lại những gì đã được gửi tới nó, tức là OUTPUT phải chính xác như INPUT.
Đầu ra PuTTY
Chụp dao động
Tôi đã sử dụng Máy chụp ảnh của mình với giải mã nối tiếp để kiểm tra xem Atmega có nhận được đầu vào chính xác hay không. Chẳng hạn, khi tôi nhấn phím 'f', nó được nhận chính xác. Đầu ra vẫn là '6' (hoặc ký hiệu '&' đôi khi).
Một sửa chữa tôi vấp phải mà tôi không hiểu
Nếu tôi thay đổi baudrate thành 2500in PuTTY, mọi thứ sẽ được hiển thị chính xác. Tôi đã chọn giá trị này một cách ngẫu nhiên và tôi không biết tại sao nó hoạt động (điều đó khiến tôi tin rằng tôi đã mắc lỗi ở đâu đó với baudrate nhưng tôi không thấy nơi nào tôi đã sao chép hướng dẫn gần như chính xác ... Tôi nghĩ).
Câu hỏi
- Tôi đã làm gì sai / chuyện gì đang xảy ra ở đây?
- Tại sao hướng dẫn ban đầu không #define F_CPU?
- Tại sao cài đặt tốc độ baud thành 2500 khắc phục sự cố? (Tôi nghi ngờ điều này sẽ được trả lời nếu câu hỏi 1 được trả lời)