Страница 1 из 2

UART на 2313, да и не только на ней

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

Добавлено: Вт мар 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 писал(а):циклические буфера.
:lol: БуферА это у девушек :lol: в программе буферЫ.

Весна однако :lol:

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

Добавлено: Вт мар 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. Например

Код: Выделить всё

in temp, UDR0
или

Код: Выделить всё

lds temp, UDR0