Страница 1 из 1
Программный UART в микроконтроллерах ATmega
Добавлено: Вт янв 27, 2009 00:13:15
trans
Никто не пытался сделать программный UART? а то одного не хватает.
Есть Учебно-отладочный стенд на базе ATmega16, к нему даделали модуль с передатчиком Xbee. С самим модулем мне работать пока не надо, однако стоит задача связи передатчика с ПК через стенд (стенд - обязательное звено). Проблема в том, что в МК UART один.
Его решено завязать на Xbee, а вот несчет компа - то ему остается фигура из трех пальцев, до тех пор, пока не написан программный UART. Полопатил инет, не нашел. может кто подкинет хотя бы идею...
заранее благодарен
Добавлено: Вт янв 27, 2009 10:12:08
asteroid7
Нужна идея как сделать, или где готовое взять?
Если первое, то я использовал таймерные временные метки в режиме совпадения. Два прерывания: совпадение, переполнение. Заранее составляется массив значений, зависит от скорости. В совпадении считывается/записывается бит, и заносится новое значение OCR. По переполнению байт передан или принят.
Код: Выделить всё
//ФОРМАТ 1-го байта
// ____ _____________________
// \ St / 0 \/ 1 \/ 2 \/ 3 \/ 4 \/ 5 \/ 6 \/ 7 / Stop Stop \ St /
// \__/\___/\___/\___/\___/\___/\___/\___/\___/ \___/
// Rx * | | | | | | | |
// Tx * | | | | | | | | | |owf
Скорости, которые работали у меня. Полудуплекс. AVR на 100% занят только этим процессом.
Код: Выделить всё
* "ПОДДЕРЖИВАЕМЫЕ СКОРОСТИ ОБМЕНА от тактируемой частоты устройства"
* +-----------+------+------+------+------+-------+-------+-------+--------+
* | | 1200 | 2400 | 4800 | 9600 | 19200 | 38400 | 57600 | 115200 |
* +-----------+------+------+------+------+-------+-------+-------+--------+
* | 1 Mhz | + | + | + | + | + | * | - | - |
* +-----------+------+------+------+------+-------+-------+-------+--------+
* | 2 Mhz | + | + | + | + | + | + | * | - |
* +-----------+------+------+------+------+-------+-------+-------+--------+
* | 4 Mhz | + | + | + | + | + | + | + | * |
* +-----------+------+------+------+------+-------+-------+-------+--------+
* | 8 Mhz | + | + | + | + | + | + | + | + |
* +-----------+------+------+------+------+-------+-------+-------+--------+
* | 12 Mhz | + | + | + | + | + | + | + | + |
* +-----------+------+------+------+------+-------+-------+-------+--------+
* | 16 Mhz | + | + | + | + | + | + | + | + |
* +-----------+------+------+------+------+-------+-------+-------+--------+
* "+" - поддерживается
* "-" - не поддерживается
* "*" - нестабильно (использовать не желательно)
// таблица тактов таймера затраченных на один бит
// +-----------+------+------+------+------+-------+-------+--------+
// | | 1200 | 2400 | 4800 | 9600 | 19200 | 57600 | 115200 |
// +-----------+------+------+------+------+-------+-------+--------+
// | 1 Mhz | 833 | 417 | 209 | 104 | 52 | 17 | 8-9 |
// +-----------+------+------+------+------+-------+-------+--------+
// | 2 Mhz | 1667 | 833 | 417 | 209 | 105 | 35 | 17 |
// +-----------+------+------+------+------+-------+-------+--------+
// | 4 Mhz | 3333 | 1667 | 833 | 417 | 209 | 70 | 35 |
// +-----------+------+------+------+------+-------+-------+--------+
// | 8 Mhz | 6667 | 3333 | 1667 | 833 | 417 | 139 | 70 |
// +-----------+------+------+------+------+-------+-------+--------+
// | 12 Mhz |10000 | 5000 | 2500 | 1250 | 625 | 208 | 104 |
// +-----------+------+------+------+------+-------+-------+--------+
// | 16 Mhz |13333 | 6667 | 3333 | 1667 | 833 | 278 | 139 |
// +-----------+------+------+------+------+-------+-------+--------+
Приём/передача бита/байта/строки и прерывания лучше на ASMе писать.
Добавлено: Вт янв 27, 2009 21:58:44
trans
Есть следующий код. По идее, он должен передавать значение 0xC2 раз в секунду на скорости 9600 бод с двумя стоп-битами. Однако в терминале ловлю сплошные нули, и то только при включении/сбросе или смене параметров соединения со стороны компа. подскажите, где я налажал? (код написан в WinAVR):
Код: Выделить всё
#include avr/io.h>//определяет имена регистров
#include util/delay.h> // дает функцию _delay_ms();
#include avr/interrupt.h>// определяет названия прерываний
unsigned char a[11]={0,2,2,0,0,0,0,2,0,2,2};
//в разряде tx "0 11000010 11"
unsigned char i=0; //счетчик бит
int main(void)
{
DDRB=255; //порт B на выход
TCCR0=10; //CTC mode, 8x prescaler
TIMSK=1<<OCIE0; //разрешить прерывание т./сч.0 по сравнению
OCR0=52;//выставить модуль счета (416 тактов/8x prescaler=52)
sei(); // разрешить прерывания глобально
return 0;
}
ISR(TIMER0_COMP_vect)
//обработчик прерывания "Т./Сч.0 -> сравнение"
{
PORTB=a[i]; // вывести в порт i-й символ массива
if(i<10) // Если не закончилась последовательность
reti(); // то завершить обработку прерывания и быть
//готовым обрабатывать следующий бит
//иначе
cli(); //запретить прерывания
_delay_ms(1000); //подождать секунду
i=0; //обнулить счетчик бит
sei(); // разрешить прерывания взад
reti(); // выйти из обработчика
}
Добавлено: Вт янв 27, 2009 22:58:07
smac
trans писал(а):.... подскажите, где я налажал? (код написан в WinAVR):
Код: Выделить всё
...
ISR(TIMER0_COMP_vect)
//обработчик прерывания "Т./Сч.0 -> сравнение"
{
PORTB=a[i]; // вывести в порт i-й символ массива
if(i<10) // Если не закончилась последовательность
reti(); // то завершить обработку прерывания и быть
//готовым обрабатывать следующий бит
//иначе
cli(); //запретить прерывания
_delay_ms(1000); //подождать секунду
i=0; //обнулить счетчик бит
sei(); // разрешить прерывания взад
reti(); // выйти из обработчика
}
задержка на секунду в прерываниях - это не есть гуд, за это время таймер успевает "нащелкать" множество тактов, а вы пропустите прерывания, во вторых - где увеличивается i ?
Вообще видимо неоптимальный код, но я не могу дать рекоммендаций к написанию "хорошего" кода на С. На асм элементарно решается
Добавлено: Вт янв 27, 2009 23:31:04
trans
А..... Шайтан-арба!!!!! (спасибо проглядел)
Правда не помогло. Взглянул на схему - max232 вроде бы с инвертором... В общем, инвертировал поток - стал получать посылки ежесекундно, хотя не то, что посылал:
1) Сначала сразу два байта 0xFE, 0xFF
2) затем один 0xFF
3) наконец, 0x00
и сначала. Может кто подскажет в чем косяк?
Добавлено: Вт янв 27, 2009 23:34:02
Секретный кот
Тем временем баском без проблем поддерживает программные УАРТы, которые причём можно повесить практически на любые ноги МК.
Добавлено: Ср янв 28, 2009 00:37:37
trans
Однако нужно родить код или на Си, или на Асме. С Асмом у меня пока туговато.
Добавлено: Вт фев 03, 2009 02:02:03
EternalEngine
Присоединяюсь к теме! тоже нужен доп. УАПП для получения MIDI сигнала. Есть ли пример в CodeVision?