// --- РУЧНЫЕ ОПРЕДЕЛЕНИЯ РЕГИСТРОВ (ATmega328P) ---
#define PORTB (*(volatile unsigned char*)0x25)
#define DDRB (*(volatile unsigned char*)0x24)
#define UCSR0A (*(volatile unsigned char*)0xC0)
#define UCSR0B (*(volatile unsigned char*)0xC1)
#define UCSR0C (*(volatile unsigned char*)0xC2)
#define UBRR0L (*(volatile unsigned char*)0xC4)
#define UBRR0H (*(volatile unsigned char*)0xC5)
#define UDR0 (*(volatile unsigned char*)0xC6)
#define TXEN0 3
#define RXEN0 4
#define UCSZ00 1
#define UCSZ01 2
#define UDRE0 5
#define RXC0 7
#define LED_PIN 5 // PB5
void uart_init(void) {
UBRR0H = 0;
UBRR0L = 51;
UCSR0B = (1 << TXEN0) | (1 << RXEN0);
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
}
void uart_putc(char c) {
while (!(UCSR0A & (1 << UDRE0)));
UDR0 = c;
}
void uart_puts(const char *s) {
while (*s) {
uart_putc(*s);
s++;
}
}
char uart_getc(void) {
while (!(UCSR0A & (1 << RXC0)));
return UDR0;
}
int main(void) {
// Настроить PB5 как выход
DDRB |= (1 << LED_PIN);
PORTB &= ~(1 << LED_PIN); // выключить
uart_init();
uart_puts("Ready. Press any key...\r\n");
while (1) {
char c = uart_getc(); // ждём любой символ
uart_puts("Kostenko Pleshkov\r\n"); // выводим фамилию
// мигаем светодиодом
PORTB |= (1 << LED_PIN);
for (volatile unsigned long i = 0; i < 30000; i++);
PORTB &= ~(1 << LED_PIN);
}
}