Страница 1 из 2
UART на 2313, да и не только на ней
Добавлено: Вт мар 06, 2007 15:19:24
Dmitro
Народ помогите вот надо подключить UART на МК, так я чето запутался как это сделать. Коротко: если настроить прерывание по опустошению регистра данных, то при обьявлении общего разрешения прерываний, у меня сразу же начинается выполнение п/п обработки этого самого прерывания

, а дело в том, что флаг прерывания изначально стоит в "1", так как регистр данных пуст (еще ничего не записывали), и это является причиной отработки прерывания. Какая последовательность при инициализации нужна, чтобы прерывание прошл корректно.
Помогите разобратся, плз.

Добавлено: Вт мар 06, 2007 17:06:54
Aheir
http://www.radiokot.ru/forum/viewtopic.php?t=343 можно попробовать прочитать..
А если вручную изменить флаг перед разрешением прерываний?
Добавлено: Вт мар 06, 2007 20:36:56
Dmitro
Ну в общем с этим вопросом я вроде бы решил, сразу хотел задейстовать прерывани по окончании передачи, но потом после опытов сделал так:
out UDR,tmp
sbi UCR,UDRIE
sei
сначала передаю данные в регистр данных UART, потом разрешаю прерывание "регистр данных пуст", и только теперь глобальное прерывание.
теперь у меня проблема, как принять данные через UART, я даже не могу понять можно этот процесс симулировать в АВР Студии или нет.
И еще когда передаю данные, тут все понятно беру массив и тулю его по очереди, а как с приемом, ну получил я символ, че с ним дальше делать если мне надо получить слово и сравнить его с заданным словом, куда сохранять входящие данные и как с ними потом работать???
Да и еще ссылка вроде что-то но я больше в асме, а там библиотек нет все прямым текстом писать надо...
Добавлено: Вт мар 06, 2007 20:54:01
Aheir
Строить другой массив из принятых данных, видимо...
Добавлено: Вт мар 06, 2007 21:12:38
Dmitro
Aheir писал(а):Строить другой массив из принятых данных, видимо...
Я не имею понятия как создавать массив из полученных данных,(по идее все это надо в ОЗУ пихать) и из ОЗУ на передачу, а как через LPM можно это провернуть или есть варианты???
Добавлено: Вт мар 06, 2007 23:05:28
Aheir
Честно говоря, это просто мои мысли на уровне здравого смысла. Ты жке можешь сохранять полученнай байты в отпределенные переменные? Потом можешь их в массив организовать, или еще как-то обработать. Если ждешь определенное слово, количество байт тебе известно
Добавлено: Ср мар 07, 2007 02:22:50
Abaktyсh
Dmitro писал(а):как принять данные через UART, я даже не могу понять можно этот процесс симулировать в АВР Студии или нет.
Посмотрите пример в курсе - там и передача и прием с буфером и анализ символов. Можно листинги АСМ посмотреть.
Симуляция передачи данных работает прекрасно.
Добавлено: Чт мар 08, 2007 01:05:34
Dmitro
Спасибо, но я знаю эту ссылку, но там инфа вся по С++ есть желание разобраться, но пока я в асме, и не нашел там примеров на нем, с симуляцией, пожалуйста внимательней, я интересовался приемом, с передачей нет проблем, прерывания работают, а вот на приеме получается надо самому ставить галку прерывания а потом записывать данные в UDR, пробовал наоборот, но пока заносишь данные галка спрыгивает. Так что пока я в поисках, всех прет С++, а мне все таки надо с асмом закончить, не могу я на пол пути перепрыгивать, ато ни там ни там ничего и не сделаю.
Добавлено: Чт мар 08, 2007 11:02:25
Abaktyсh
Там Си без ++
АСМ - получается при клмпиляции в файле листинга - там код Си закомментированый и соответствующий ему АСМ - все ясно и понятно.
Прием и передачу советую симулировать в "настоящих" симуляторах VMLAB и PROTEUS предварительно выбрав МК который они поддерживают.
Добавлено: Вт мар 20, 2007 00:00:42
Dmitro
Вроде все нормально поначалу, передача идет без проблем комп и телефон все видят нормальн , телефон выполняет команды, а вот прием данных в контроллер чето не хочет отрабатывать, не могу понять на каком этапе искать ошибку, то ли приема нет, то ли, несовпадает посылка с данными ОЗУ, наверное прийдется для начало отработать, индикацию на светодиод наличия прерывания, только вот по какому прерыванию лучше работать, прием окончен или опустел регист UDR? И как должен опустеть UDR, после того как я его прочитаю или он может сам сброситься (в студии он сам сбрасывается на следующем шаге после установки)
Добавлено: Вт мар 20, 2007 07:52:47
SfS
По теме:
1. Инициализация UART в AVR должна делаться при запрещённых прерываниях.
2. Перед разрешением прерыаний необходимо вручную сбросить флаги, записью соответствующих бит в регист USR.
3. Для передачи и приёма данных лучше всего использовать программно организованные циклические буфера. Это позволит разделить процессы приёма-передачи данных и их обработки-формирования.
Циклический буфер - это массив в памяти, и два указателя на него. Один указатель показывает начало массива, второй - конец. Если указатели равно - буффер пуст, иначе в нём есть необработанные данные.
Пример организации такого массива на C:
#define LEN 0x10 /* Длина буфера */
unsigned char cycl_buf[LEN]; /* Задаём массив длинной LEN байт */
unsigned int bbuf=0; /* Начало массива */
unsigned int ebuf=0; /* Конец массива */
/* Начало и конец равны, поскольку буфер пуст */
/* Функция, помещающая данные в массив
Возвращает 0, если данные успешно помещены в буфер или
-1, если буфер переполнен.
*/
int put_data(char c)
{unsigned int t =ebuf+1;
/* Если достигнут конец буффера, переходим на начало */
if(t>=LEN){t=0;}
/* Если буфер полон, то возвращаем ошибку (-1) */
if(t==bbuf){return(-1);}
/* Помещаем данные в массив */
cycl_buf[ebuf] = c;
ebuf = t;
return(0);
}
/* Функция, извлекающая данные из буфера.
возвращает полученны байт (0-255) или
-1, если буфер пуст
*/
int get_data()
{unsigned int t =bbuf+1;
unsigned char c;
/* Если буфер пуст, то возвращаем ошибку (-1) */
if(ebuf==bbuf){return(-1);}
/* Если достигнут конец буффера, переходим на начало */
if(t>=LEN){t=0;}
/* Помещаем данные в массив */
c=cycl_buf[bbuf] ;
bbuf = t;
return(c);
}
Добавлено: Вт мар 20, 2007 11:48:39
Abaktyсh
SfS писал(а):циклические буфера.

БуферА это у девушек

в программе буферЫ.
Весна однако

Добавлено: Вт мар 20, 2007 12:37:32
SfS
Abaktyсh писал(а): 
БуферА это у девушек

в программе буферЫ.
Весна однако

Всё надо уметь применять

и Буфера и буферы.
Добавлено: Вт мар 20, 2007 14:29:29
Abaktyсh
Я не много по другому пишу комментарии для начинающих.
Вот это место:
Код: Выделить всё
/* Если буфер полон, то возвращаем ошибку (-1) */
if(t==bbuf){return(-1);}
/* Помещаем данные в массив */
cycl_buf[ebuf] = c;
ИМХО понятней так:
Код: Выделить всё
/* Если буфер полон, то завершаем выполнение
функции и возвращаем ошибку (-1) */
if (t == bbuf) {
return(-1);
}
/* Сюда попадем если буфер не полон */
/* Помещаем данные в массив */
cycl_buf[ebuf] = c;
Добавлено: Вс мар 25, 2007 14:29:16
Dmitro
я не совсем понимаю, зачем нужен циклический буфер, ведь я в программе указываю, что как прийдет такой символ "0d", то его принять и уйти на побайтное сравнение принятых данных с массивом из памяти программ, а там по обстаятельствам...
Объясните зачем он нужен, чтобы я велосипед не изобретал
Добавлено: Пн апр 02, 2007 07:58:38
SfS
Dmitro писал(а):я не совсем понимаю, зачем нужен циклический буфер, ведь я в программе указываю, что как прийдет такой символ "0d", то его принять и уйти на побайтное сравнение принятых данных с массивом из памяти программ, а там по обстаятельствам...
Объясните зачем он нужен, чтобы я велосипед не изобретал
Он не всегда нужен. Но если приход данных и их обработка асинхронны - то нужен.
То есть если программа организована так - по прерыванию данные складываются в буфер и всё. А анализируются данные в другом месте программы, когда это удобно программисту.
И наоборот - данные пишутся в буфер в любом месте, а реально выводятся в порт по прерыванию. Это позволяет программе не ждать, пока освободится порт для вывода. Кинул сколько надо байт в буфер - и выполняешь программу дальше. УАРТ устройство ведь относительно медленное.
И снова непонятки...
Добавлено: Пн апр 16, 2007 18:04:31
Dmitro
При приеме данных через UART, как срабатывают прерывания: есть прерывание по окончании приема и прерывание по опустошении регистра данных UDR, так вот вопрос, если я попытаюсь считать регистр данных по прерыванию "прием окончен", будет ли это означать, что в регистре UDR, уже находятся данные, или они еще в пути от сдвигового регистра, и я в итоге загружаю неизвестно что. Так по какому прерыванию работать ...
Поделитесь опытом, ПЛЗ.
Re: И снова непонятки...
Добавлено: Пн апр 16, 2007 18:20:27
tych
Dmitro писал(а):если я попытаюсь считать регистр данных по прерыванию "прием окончен", будет ли это означать, что в регистре UDR, уже находятся данные
Да.
В даташите по-моему есть диаграмма где нарисовано в какой момент возникает флаг и прерывание "прием окончен".
Добавлено: Вт июл 22, 2008 09:59:15
сергей111
Извините, смотрел поиском, но все равно не работает...
Контроллер AtMega64, есть 2 платы: приемник и передатчик
листинг приемника:
...;инициализация
;передача и прием по USART0(PE0,PE1,PE2)
ldi temp,0
out ucsr0a,temp
ldi temp,$33
out ubrr0l,temp
ldi temp,0
sts ubrr0h,temp
ldi temp,$f9
out ucsr0b,temp
main:
;прием по usart
in temp,ucsr0a
sbrs temp,rxc0
rjmp (pc-2)
out portc,temp ;здесь отображается на индикаторе принимаемое значение
rjmp main
листинг передатчика:
...;инициализация
ldi temp,0 ;все флаги usart сброшены
sts ucsr1a,temp
ldi temp,0 ;speed=9600 bod
sts ubrr1l,temp
ldi temp,$33
sts ubrr1h,temp
ldi temp,0b00000110 ;формат посылки/передачи (8разрядов 1стоп-бит)
sts ucsr1c,temp
ldi temp,$f9 ;режим работы
sts ucsr1b,temp
main:
sts udr1,temp
lds temp,ucsr1a ;(lds)ожидание конца передачи
sbrs temp,udre1 ;пропустить если бит в регистре установлен
rjmp (pc-2)
rjmp main
В чем проблема? Вроде и литературы по данной тематике много прочел, может в коде что-то неправильно или еще что-то не учел. Заранее благодарен за помощь.
Посмотрите листинг пожалуйста, вдруг проблема не коде, а на аппаратном уровне (в схеме).
Добавлено: Вт июл 22, 2008 21:27:03
smac
сергей111 писал(а):Извините, смотрел поиском, но все равно не работает...
main:
;прием по usart
in temp,ucsr0a
sbrs temp,rxc0
rjmp (pc-2)
out portc,temp ;здесь отображается на индикаторе принимаемое значение
rjmp main
Посмотрите листинг пожалуйста, вдруг проблема не коде, а на аппаратном уровне (в схеме).
Скорее всего - в коде.
Конкретно по теме - где в приведенном куске у вас собственно прием?
Я имею ввиду то, что нет считывания данных из регистра UDR0, по идее после того как вы проверили бит rxc0, то перед тем как выводить в порт регистр temp нужно сначала считать в него содержание регистра UDR0. Например
или