Respons Atmega16 yang tidak terduga atas UART
Ringkasan masalah singkat
Saya telah menginstal Atmega16 dengan kode yang akan menghasilkan Atmega16 mengirim kembali karakter apa pun yang saya kirim kepadanya melalui terminal. Saya mendapat respons, tetapi jarang karakter yang saya kirim. Saya dapat melihat output yang benar dengan mengubah baud rate tetapi saya tidak mengerti mengapa baud rate yang benar bekerja.
Lebih detail
Saya mencoba mempelajari lebih lanjut tentang pemrograman firmware pada waktu saya sendiri karena saya sangat menikmatinya. Sejauh ini dalam pemrograman firmware yang telah saya lakukan di uni, kami telah diberi file kode kerangka yang melakukan banyak antarmuka periferal dan mengatur untuk kami, tetapi saya ingin belajar ini sendiri. Saya punya beberapa pertanyaan tentang apa yang saya lakukan di sini yang ditaburi di seluruh posting tapi saya akan memerinci mereka di akhir. Jika Anda memahami kesalahpahaman atau potensi kesenjangan dalam pengetahuan saya, saya akan sangat menghargai setiap masukan yang mungkin Anda miliki.
Kode
Kode yang saya telah flash ke Atmega16 saya diambil garis hampir untuk baris dari tutorial 'Menggunakan USART dalam AVR-GCC' yang ditemukan di halaman ini . Yang saya tambahkan adalah #define untuk F_CPU. Kode asli tidak memiliki #define untuk F_CPU sehingga kode saya tidak dapat dikompilasi di AtmelStudio 7. Adakah yang bisa menjelaskan mengapa penulis tidak mendefinisikan F_CPU dalam file asli mereka? Saya menduga mereka mungkin telah menggunakan beberapa alat atau kompiler selain Atmel Studio 7 tapi saya tidak bisa mengatakannya dengan pasti.
#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
}
}
Pengaturan perangkat keras
- MCU: Atmega16;
- Toolchain: Atmel Studio 7, berkedip dengan AVR dragon;
- Catu daya: 5V rel diambil dari papan pengembangan yang disediakan universitas (yang diambil dari komputer USB). Kapasitor cakram keramik 100nF digunakan untuk memotong kabel listrik papan tempat memotong roti
- Konverter USB ke serial: Yang ini . TXD pada USB ke serial converter yang terhubung ke RXD Atmega (Pin 15). RXD pada konverter terhubung ke RXD pada Atmega (Pin 14).
Perangkat lunak terminal: Putty (dengan baudrate 9600).
Bukti tanggapan yang salah
Untuk mengulangi, Atmega harus mengembalikan apa yang dikirim kepadanya yaitu OUTPUT harus sama persis dengan INPUT.
Keluaran Putty
Tangkapan Osiloskop
Saya telah menggunakan Picoscope saya dengan decoding serial untuk memeriksa apakah Atmega menerima input yang benar, yang tampaknya memang demikian. Misalnya, ketika saya menekan tombol 'f', itu diterima dengan benar. Output masih '6' (atau ampersand '&' pada kesempatan).
Perbaikan saya menemukan bahwa saya tidak mengerti
Jika saya mengubah baudrate ke 2500in Putty, semuanya ditampilkan dengan benar. Saya memilih nilai ini secara acak dan saya tidak tahu mengapa itu bekerja (itu membuat saya percaya bahwa saya telah membuat kesalahan di suatu tempat dengan baudrate tapi saya tidak melihat di mana mengingat saya menyalin tutorial hampir persis ... saya pikir).
Pertanyaan
- Apa yang telah saya lakukan salah / apa yang terjadi di sini?
- Mengapa tutorial asli tidak menentukan # F_CPU?
- Mengapa pengaturan baud rate ke 2500 memperbaiki masalah? (Saya menduga ini akan dijawab jika pertanyaan 1 dijawab)