Comments 16
Применение прерывания INT0/INT1 сильно ограничивают положение вывода под приём…
Да и сама функция UART без внешнего тактового сигнала сомнительна. Внутренний генератор обладает очень низкой точностью и даже с калибровкой уплывает от температуры и напряжения питания. Только в TYNY45/85 есть температурная стабилизация встроенного генератора.
Как-то пробовал UART аппаратный но с внутренним генератором на ATMEGA48, точности не хватает. Даже после калибровки во время работы частота уходит и на другом конце начинают лезть ошибки приёма, и не на всех переходниках USB-UART есть возможность подбирать кастомную скорость передачи с необходимым шагом.
Да и сама функция UART без внешнего тактового сигнала сомнительна. Внутренний генератор обладает очень низкой точностью и даже с калибровкой уплывает от температуры и напряжения питания. Только в TYNY45/85 есть температурная стабилизация встроенного генератора.
Как-то пробовал UART аппаратный но с внутренним генератором на ATMEGA48, точности не хватает. Даже после калибровки во время работы частота уходит и на другом конце начинают лезть ошибки приёма, и не на всех переходниках USB-UART есть возможность подбирать кастомную скорость передачи с необходимым шагом.
Да, действительно, я совершенно упустил из виду то, что INT0 жестко привязывает пин PB1 к использованию на вход. Исправлю на использование прерывания PCINT. Насчет нестабильности — лично я не проверял в температуре, но на моем тестовом образце я поставил значение OCR0A равным 0х70 — вроде бы все работает как положено, ошибок нет, осциллографом проверял длительность бита — все в порядке. Ну, а выбирать в общем-то и не приходится, статья то про ATtiny13, и если на ней необходимо сделать UART, то других вариантов нет.
PCINT не различает фронт/спад… там только одно понятие: изменение состояния.
ATTINY13 может тактироваться внешним сигналом.
По даташиту, зависимости частоты внутреннего генератора от напряжения и температуры просто жуткие. Скорей всего хорошо отрабатывает именно другая сторона подстраиваясь под скорость передачи вашего контроллера.
Погрешность скорости в 2% и последний бит уже находится не в своём фрейме, а подстройка внутреннего генератора если не ошибаюсь происходит шагами по 0.5-1% запас очень небольшой, и надо тщательно калибровать чтобы не выйти за пределы допустимого отклонения.
ATTINY13 может тактироваться внешним сигналом.
По даташиту, зависимости частоты внутреннего генератора от напряжения и температуры просто жуткие. Скорей всего хорошо отрабатывает именно другая сторона подстраиваясь под скорость передачи вашего контроллера.
Погрешность скорости в 2% и последний бит уже находится не в своём фрейме, а подстройка внутреннего генератора если не ошибаюсь происходит шагами по 0.5-1% запас очень небольшой, и надо тщательно калибровать чтобы не выйти за пределы допустимого отклонения.
Сколько использовал внутренний RC генератор никогда с уартом не было проблем вплоть до 38400. Вы часом не на али контроллеры покупаете?
Предвижу гнев, но все же чем ATtiny13 лучше STM32F030F4P6 за 0,5 доллара в китае или 55р в чипдипе(от 25штук)?
Не всё измеряется деньгами простоту, например, ни за какие деньги не купишь.
Более того, есть еще ATTINY10 в SOT-23 корпусе, вообще 6-ногий товарищ.
Цена начинает играть роль только при крупносерийном производстве а в остальном — доступность и качество документации.
Под STM32 нужно еще учится, искать документацию, разобраться в бардаке множества сред разработки — чтобы разобраться в STM-ках нужна очень сильная мотивация и направляющий импульс.
Более того, есть еще ATTINY10 в SOT-23 корпусе, вообще 6-ногий товарищ.
Цена начинает играть роль только при крупносерийном производстве а в остальном — доступность и качество документации.
Под STM32 нужно еще учится, искать документацию, разобраться в бардаке множества сред разработки — чтобы разобраться в STM-ках нужна очень сильная мотивация и направляющий импульс.
Просто потому что 8-ногий DIP значительно проще использовать чем 20-ногий TSSOP или еще хуже LQFP. Да и глупо как-то выглядит использование STM32 для принятия по UART пары байт и управления нагревательным элементом. (Для этого я использовал эту ATtiny — нагрев и датчик температуры с передачей данных по UART)
Посмотрите ATtiny441/841. Два настоящих UART, термостабилизация внутреннего генератора и всего 14 ног, правда в SOIC-корпусе. Эволюция ATtiny 24/44/84.
Стоимость? оно то конечно не так важно, но обидно использовать дорогой контроллер и сознательно не пользоваться избыточной периферией когда это можно сделать на более дешёвом.
Если не в ущерб качеству, то конечно.
Просто если в дешевом частота внутреннего генератора уплывает, а кварц или внешнее тактирование делать не хочется, или еще какие ограничения выявляются, то вот можно взять ATTiny441 с аппаратным уартом (даже с двумя).
Просто если в дешевом частота внутреннего генератора уплывает, а кварц или внешнее тактирование делать не хочется, или еще какие ограничения выявляются, то вот можно взять ATTiny441 с аппаратным уартом (даже с двумя).
Если передачу оборвать, то вот здесь:
мы и останемся, навсегда.
Может лучше, что бы функция приема возвращала байт если он принят или ничего если нет?
int16_t uart_recieve(uint8_t* rb)
...
while(rxbitcount);
...
мы и останемся, навсегда.
Может лучше, что бы функция приема возвращала байт если он принят или ничего если нет?
Был не прав, поторопился с выводами, rxbitcount обнулится таймером.
Мне не нравится, что uart_recieve() вынуждает задерживаться в ней если начат прием байта. Лучше иметь буфер хотя бы на один уже принятый байт, а принимаемый собирать отдельно (вроде в аппаратном UARTе так и сделано).
И еще, если не «повезет»:
можно получить ноль вместо реально переданного байта
Мне не нравится, что uart_recieve() вынуждает задерживаться в ней если начат прием байта. Лучше иметь буфер хотя бы на один уже принятый байт, а принимаемый собирать отдельно (вроде в аппаратном UARTе так и сделано).
И еще, если не «повезет»:
int16_t uart_recieve(uint8_t* rb)
{
if(rxbitcount < 0x09) // Если счетчик бит на прием меньше 9
{
while(rxbitcount); // Ждем пока завершится текущий прием
// !!!!!!!!!!!!!!!!!!!!!
// если в этот момент случится прерывание INT0, то в rxbyte обнулится
// !!!!!!!!!!!!!!!!!!!!!
*rb = rxbyte; // Пишем по адресу указателя принятый байт
rxbitcount = 0x09; // Восстанавливаем значение счетчика бит
return (*rb); // Возвращаемся
}
else
{
return (-1); // Иначе возвращаем -1 (принимать нечего)
}
}
можно получить ноль вместо реально переданного байта
Sign up to leave a comment.
Полнодуплексный программный UART для ATtiny13