Функция форматного вывода printf довольно мощное средство языка Си. Приминительно к микроконтроллерам, возможно, сначала не совсем понятно, что там считать за стандарный поток вывода и как здесь может работать printf(). Библиотека avr-libc содержит файл stdio.h которая включает реализацию стандарных функций ввода-вввода.
<stdio.h>: Standard IO facilities
Я взял оттуда ХеллоВорлд:
#include <stdio.h> static int uart_putchar(char c, FILE *stream); static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE); static int uart_putchar(char c, FILE *stream) { if (c == '\n') uart_putchar('\r', stream); loop_until_bit_is_set(UCSRA, UDRE); UDR = c; return 0; } int main(void) { init_uart(); stdout = &mystdout; printf("Hello, world!\n"); return 0; }
И модифицировал пример из поста ATmega8: работа на Си с USART/UART через прерывание заменив функцию writeSerial(char* str) на printf. Получилась такая штука:
/* for ATMEGA-8 echo_serial.c read string via UART with symbol ':' as End-Of-Line and write this string in UART backward site: http://countzero.weebly.com compile: avr-gcc -mmcu=atmega8 -Wall -Os -o echo_serial.elf echo_serial.c avr-objcopy -O ihex echo_serial.elf echo_serial.hex */ #define F_CPU 16000000UL #define LEN 32 #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #include <stdio.h> char buffer[LEN]; register unsigned char IT asm("r16"); volatile unsigned char done; volatile unsigned char IDX; static int uart_putchar(char c, FILE *stream) { if (c == '\n') uart_putchar('\r', stream); loop_until_bit_is_set(UCSRA, UDRE); UDR = c; return 0; } inline void clearStr(char* str) { for(IT=0;IT<LEN;IT++) str[IT]=0; } /* void writeSerial(char* str) { IT=0; while (str[IT] != 0 && IT < LEN) { while(!(UCSRA&(1<<UDRE))){}; UDR = str[IT]; IT++; } } */ ISR(USART_RXC_vect) { char bf= UDR; buffer[IDX]=bf; IDX++; if (bf == ':' || IDX >= LEN) { IDX=0; done=1; } } void blink13(uint8_t count) { PORTB |= (1<<PB5); count =(count <<1);count--; //count=(count*2)-1; for (IT=0;IT<count;IT++) { _delay_ms(500); PORTB ^= (1<<PB5); }; }; static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE); int main(void) { // USART init UBRRL=103; UCSRB=(1<<TXEN)|(1<<RXEN)|(1<<RXCIE); UCSRC=(1<<URSEL)|(3<<UCSZ0); DDRB |= (1<<PB5); // pinMode(13,OUTPUT); blink13(3); //ready indication IDX=0; done=0; sei(); stdout = &mystdout; int count=0; for (;;) { if (done) { count++; PORTB |= (1<<PB5); // writeSerial(buffer); printf("Recived string#%d: %s\n",count, buffer); clearStr(buffer); PORTB &= ~(1<<PB5); done=0; } } return 0; }
Весит такая прошивка около уже 1900 байт вместо 330, но в ряде случаев, это лучше, чем изобретение велосипеда с шахматами и поэтессами.