Привет всем хаброюзерам. Совсем недавно, товарищ Himura опубликовал свою статью UART в ATtiny13 или Как вывести данные из МК за 52р, и тут я вспомнил, что имею кроме предыдущих наработок по этой теме, а именно Трёхканальный UART АЦП на ATtiny13, есть ещё кое-что, часть которой я вырезал из довольно таки любопытного проекта Happy Christmas and Happy New Year wishes from Attiny13, там есть и программный UART, как чтение так и отправка, и ещё кое что по SPI, вообщем рекомендую заглянуть всем кто заинтересовался, правда ресурс англоязычный.
Вот видео работы:
Урезав всё, что для меня лишнее из кода товарища Vinod.S, получилось:
#define F_CPU 9600000
#include <avr/io.h>
#include <util/delay.h>
#define SOFT_TX_PIN (1<<PB1) // PB1 будет работать как TXD
#define SOFT_TX_PORT PORTB
#define SOFT_TX_DDR DDRB
int helloHabr = 0;
int main (void) {
uart_tx_init (); // инициализация прог. UARTа
while (1) {
helloHabr++;
uart_print("Hello Hаbr, I'm ATtiny 13 "); // превед
num_to_str(helloHabr, 4); // 0..9999 т.к. только 4 числа можно вывести
uart_print(" counds");
uart_print("rn"); // переход на новую строчку
_delay_ms(1000);
}
return 0;
}
void uart_tx_init ()
{
TCCR0A = 1 << WGM01; // compare mode
TCCR0B = 1 << CS00; // prescaler 1
SOFT_TX_PORT |= SOFT_TX_PIN;
SOFT_TX_DDR |= SOFT_TX_PIN;
OCR0A = 75; //115200 baudrate at prescaler 1
}
// Функция вывода содержимого переменной
void num_to_str(unsigned int value, unsigned char nDigit)
{
switch (nDigit)
{
case 4:
uart_send_byte((value / 1000) + '0');
case 3:
uart_send_byte(((value / 100) % 10) + '0');
case 2:
uart_send_byte(((value / 10) % 10) + '0');
case 1:
uart_send_byte((value % 10) + '0');
}
}
void uart_print(char *str)
{
byte i = 0;
while (str[i]) {
uart_send_byte(str[i++]);
}
}
//bitbanged UART transmit byte
void uart_send_byte (unsigned char data)
{
unsigned char i;
TCCR0B = 0;
TCNT0 = 0;
TIFR0 |= 1 << OCF0A;
TCCR0B |= (1 << CS00);
TIFR0 |= 1 << OCF0A;
SOFT_TX_PORT &= ~SOFT_TX_PIN;
while (!(TIFR0 & (1 << OCF0A)));
TIFR0 |= 1 << OCF0A;
for (i = 0; i < 8; i++)
{
if (data & 1)
SOFT_TX_PORT |= SOFT_TX_PIN;
else
SOFT_TX_PORT &= ~SOFT_TX_PIN;
data >>= 1;
while (!(TIFR0 & (1 << OCF0A)));
TIFR0 |= 1 << OCF0A;
}
SOFT_TX_PORT |= SOFT_TX_PIN;
while (!(TIFR0 & (1 << OCF0A)));
TIFR0 |= 1 << OCF0A;
}
Arduino IDE без проблем проглотила его:
Всё это занимает 470 байт, то есть меньше половины памяти ATtiny13, можно ещё немало напрограммировать, если умело использовать ресурсы микроконтроллера.
Как видите набор символов Hello Hаbr, I'm ATtiny 13 выводиться при помощи функции uart_print("..."); а значение переменных, к примеру, пускай переменная будет называться value, тогда вывод в строчку содержимого будет осуществляться при помощи функции num_to_str(value, 4); где 4 — количество цифр, в данном случае можно вывести значение от 0 до 9999. Строчки uart_print("rn"); заканчивают строчку при выводе в UART и осуществляется переход на новую, по аналогии кнопка Enter на клавиатуре. Порт который будет работать как TXD задаётся в строчках #define SOFT_TX_PIN (1<<PB1). На карте портов это выглядит вот так:
Ну и напоследок — ATtiny13 тактируется от внутренней RC цепочки, настроенной на частоту в 9.6 МГц, делитель на 8 отключён, это задаётся фьюз-битом lf 0x7A.
Скорость UART'а 115200 бод(англ. baud).
Чтобы фотки не пропадали.
Ссылки:
UART в ATtiny13 или Как вывести данные из МК за 52р;
Трёхканальный UART АЦП на ATtiny13;
Happy Christmas and Happy New Year wishes from Attiny13;
Прошивка и программирование ATtiny13 при помощи Arduino(обновлено);
P.S. Если нагреть микроконтроллер до ~60 градусов, то начнёт приходить мусор, проверил лично, но это простимо учитывая цену ATtiny13.
Автор: HWman