Halo untuk semua pengguna Geektimes! Suatu hari, sebagai hasil dari layanan saya, saya perlu mengimplementasikan perangkat lunak UART pada mikrokontroler ATtiny13 yang populer. Googling, saya menemukan sejumlah besar artikel tentang topik ini, banyak dari mereka diposting di sini:Dan ada sumber daya lain:, -, ( ). , -, CodeVision AVR, , -, . C UART-. , ( 8- ). , .. , AVR.
— , , .
Jadi, mari kita mulai. Saya hanya akan memposting file header uart13.h dalam bentuk yang berisi komentar dalam kode, semuanya sederhana di sana.File header Uart13.h
#ifndef _UART13_H_
#define _UART13_H_ 1
#include <avr/io.h>
#include <avr/interrupt.h>
#define TXPORT PORTB
#define RXPORT PINB
#define TXDDR DDRB
#define RXDDR DDRB
#define TXD 0
#define RXD 1
#define T_DIV 0x02
#define BAUD_DIV 0x7D
volatile uint16_t txbyte;
volatile uint8_t rxbyte;
volatile uint8_t txbitcount;
volatile uint8_t rxbitcount;
void uart_init();
void uart_send(uint8_t tb);
int16_t uart_recieve(uint8_t* rb);
#endif
Tapi saya akan memecah deskripsi kode implementasi perpustakaan menjadi beberapa bagian agar tidak mengubah artikel menjadi satu spoiler besar dengan kode.Ganggu TIM0_COMPAISR(TIM0_COMPA_vect)
{
TXPORT = (TXPORT & ~(1 << TXD)) | ((txbyte & 0x01) << TXD);
txbyte = (txbyte >> 0x01) + 0x8000;
if(txbitcount > 0)
{
txbitcount--;
}
}
OCR0A. , , OCR0A. , TCNT0 ( CTC, TCCR0A). UART. txbyte : , , txbyte TXD , , .
, 0xFFFF , , TXD . , : 1 , 8 1 , 10 (0x0A), txbyte . . void uart_send(uint8_t tb).
TIM0_COMPBISR(TIM0_COMPB_vect)
{
if(RXPORT & (1 << RXD))
rxbyte |= 0x80;
if(--rxbitcount == 0)
{
TIMSK0 &= ~(1 << OCIE0B);
TIFR0 |= (1 << OCF0B);
GIFR |= (1 << INTF0);
GIMSK |= (1 << INT0);
}
else
{
rxbyte >>= 0x01;
}
}
OCR0B. TIM0_COMPA, , , TCNT0. , , . , RXD , , rxbyte, , , . rxbyte, .
INT0ISR(INT0_vect)
{
rxbitcount = 0x09;
rxbyte = 0x00;
if(TCNT0 < (BAUD_DIV / 2))
{
OCR0B = TCNT0 + (BAUD_DIV / 2);
}
else
{
OCR0B = TCNT0 - (BAUD_DIV / 2);
}
GIMSK &= ~(1 << INT0);
TIFR0 |= (1 << OCF0A) | (1 << OCF0B);
TIMSK0 |= (1 << OCIE0B);
}
Mengganggu INT0. Ini bekerja pada ujung pulsa di input INT0, digunakan untuk melacak awal penerimaan informasi. Atur penghitung bit ke 9, atur ulang isi variabel rxbyte. Menetapkan nilai untuk register OCR0B, yang menentukan frekuensi TIM0_COMPB interupsi, harus dalam waktu di tengah bit yang diterima. Setelah itu, interupsi TIM0_COMPB diaktifkan, dan interupsi INT0 dinonaktifkan.Berikut ini adalah fungsi pengguna untuk bekerja dengan UART.Fungsi Uart_sendvoid uart_send(uint8_t tb)
{
while(txbitcount);
txbyte = (tb + 0xFF00) << 0x01;
txbitcount = 0x0A;
}
UART. , . , , 8 txbyte , 8 0xFF, , . 10.
uart_recieveint16_t uart_recieve(uint8_t* rb)
{
if(rxbitcount < 0x09)
{
while(rxbitcount);
*rb = rxbyte;
rxbitcount = 0x09;
return (*rb);
}
else
{
return (-1);
}
}
UART. 8- , . , , , (-1). , . , , (-1).
uart_initvoid uart_init()
{
txbyte = 0xFFFF;
rxbyte = 0x00;
txbitcount = 0x00;
rxbitcount = 0x09;
TXDDR |= (1 << TXD);
RXDDR &= ~(1 << RXD);
TXPORT |= (1 << TXD);
RXPORT |= (1 << RXD);
OCR0A = BAUD_DIV;
TIMSK0 |= (1 << OCIE0A);
TCCR0A |= (1 << WGM01);
TCCR0B |= T_DIV;
MCUCR |= (1 << ISC01);
GIMSK |= (1 << INT0);
sei();
}
Fungsi inisialisasi UART. Tidak ada argumen, tidak ada nilai balik. Menginisialisasi variabel global dan register mikrokontroler. Dari komentar dalam kode semuanya harus jelas.Jadi, inilah saatnya untuk menulis beberapa main sederhana () menggunakan perpustakaan kami dan melihat apa yang terjadi dalam hal jumlah kode dan memeriksa kinerjanya.main.c#include "uart13.h"
int main(void)
{
uint8_t b = 0;
uart_init();
while (1)
{
if(uart_recieve(&b) >= 0)
uart_send(b);
}
return (0);
}
Kami mengkompilasi:Penggunaan Memori Program: 482 byte 47,1%
Data Penuh Penggunaan Memori: 5 byte 7,8% Penuh
Tidak buruk, kami memiliki lebih dari setengah memori mikrokontroler dalam persediaan!Memeriksa dalam Proteus:Intinya: implementasi ternyata cukup bermanfaat, data ditransmisikan dan diterima secara independen, perpustakaan delay.h tidak digunakan sama sekali, dan lebih dari setengah memori mikrokontroler dibiarkan sebagai cadangan.Saya lampirkan kode sumber perpustakaan, mereka dikompilasi dalam avr-gcc: Sumber di GitHub