Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Простой вопрос по USART на attiny2313
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
Alt.F4
Для проектирования будущей печатки, очень нужно знать.
После инициализации USART на выходах RXD и TXD появятся какие-либо уровни или будет все чисто до загрузки в UDR?
Спасибо.
chief_olimp
вопрос задан не в той ветке.
После инициализации на TxD будет высокий уровень
ILYAUL
Цитата(Alt.F4 @ Aug 12 2010, 23:50) *
Для проектирования будущей печатки, очень нужно знать.
После инициализации USART на выходах RXD и TXD появятся какие-либо уровни или будет все чисто до загрузки в UDR?
Спасибо.

Какие установите , такие и будут. USART он ведь сам по себе. Дадите команду работать , подключится и наплюёт на все установки порта , отключится вернутся установки порта. Установите порт как Вам нужно.
Alt.F4
Ветка же AVR unsure.gif
Цитата
После инициализации на TxD будет высокий уровень
Спасибо большое!
Цитата
Какие установите , такие и будут. USART он ведь сам по себе. Дадите команду работать , подключится и наплюёт на все установки порта , отключится вернутся установки порта. Установите порт как Вам нужно.
А, то есть по тексту программы можно будет инициализовать?
Или просто в подпрограмму запихнуть установку TXEN RXEN, затем передачу, и снятие флагов TXEN RXEN?
ILYAUL
Цитата(Alt.F4 @ Aug 13 2010, 00:26) *
Ветка же AVR unsure.gif
Спасибо большое!
А, то есть по тексту программы можно будет инициализовать?
Или просто в подпрограмму запихнуть установку TXEN RXEN, затем передачу, и снятие флагов TXEN RXEN?

Конечно, если Вы не включите USART - TXEN RXEN , то работаете с портом , как Вам угодно. Включили - два высоких. Единственно , подтягивающие не отключаются. Если подтянули к питанию , то всегда высокие . Кстати для входа - это полезно
Alt.F4
ILYAUL, огромное спасибо!
Еще хотел уточнить, 1 бод/с = 8 бит/с или 10 бит/с?
Передаю 8бит данных, битов четности нет, один стоповый бит, в асинхронном режиме.
ILYAUL
Цитата(Alt.F4 @ Aug 13 2010, 08:42) *
ILYAUL, огромное спасибо!
Еще хотел уточнить, 1 бод/с = 8 бит/с или 10 бит/с?
Передаю 8бит данных, битов четности нет, один стоповый бит, в асинхронном режиме.

На эту тему можно долго дискутировать . Прнято считать (с азбуки Морзе) что он равен 1бит/cek.Но в модемных сетях , он может равнятся и 4 бит и 8 и 9 бит/сек.
Вообщем-то самое простое пояснение - это передача одного символа полезной информации . Т.е , если например кодируете букву А 4 битами , то 1 бод = 4бит /сек 8-ю = 8 бит /сек
Alt.F4
В общем долго мудрив со скоростями, пришел к выводу, что 1 бод/с = 1 бит/с
Но проблема стала в другом. Написал прогу по которой tiny2313 должен слать по порядку весь алфавит по ACSII, в HyperTerminal'е же он слал только символ "А", хотя AVR Studio эмулировал все верно. Решил перепроверить отправляя обратно, что получил. И опять, tiny2313 либо отвечает символом "А", либо вообще молчит (в зависимости, что слать). Куда копать?
Цитата
; Подпрограммы
USART_transmit:
sbis UCSRA,UDRE ;ждем пока UDR освободится
rjmp USART_transmit ;
out UDR,temp ;отправляем
ret ;возврат из процедуры отправки

USART_receive:
sbis USR,RXC ;ждем приема символа
rjmp USART_receive ;
in temp,UDR ;читаем
ret ;возврат из процедуры приема

; Основное тело программы
Start:
rcall USART_receive ; принимаем символ
rcall USART_transmit ; отправляем этот символ
rjmp Start
Alt.F4
Немного покапавшись, вышел на скорость 4800бит/с. Все символы возвращаются. Почему 4800???
Загрузил первую прогу, терминал подвисает на этой скорости, на 9600-абракадабра, на 57600 - символ "А"
Значит дело в скорости. Чему равен 1 бод/с?
vvs157
Цитата(Alt.F4 @ Aug 14 2010, 01:05) *
Чему равен 1 бод/с?
В случае RS232 всегда 1 бод/сек = 1 бит/сек. Ваша проблема в том, что вы выставили несколько неверную скорость порта. Чем выше скорость, тем меньше диапазон допустимых отклонений от номинала
Alt.F4
Почему же он не работает на 57600 а только на 4800? sad.gif
Нажмите для просмотра прикрепленного файла
@Ark
Цитата
Цитата(Alt.F4 @ Aug 13 2010, 08:42)
Еще хотел уточнить, 1 бод/с = 8 бит/с или 10 бит/с?
Передаю 8 бит данных, битов четности нет, один стоповый бит, в асинхронном режиме

Здесь есть некоторая неточность. Ошибка - в обозначении бод/сек.
Бод - это скорость передачи информации, измеряемая в символах в секунду.
Если 1 символ = 1 бит, то 1 бод = 1 бит/сек.. В случае же какой-либо "хитрой"
модуляции, 1 символ может передавать несколько бит. Тогда 1 бод больше 1 бит/сек.
В случае RS232 всегда 1 бод = 1 бит/сек. 9600 бод = 9600 бит/сек .
Но это скорость, с учетом всех бит, передаваемых по каналу: старт, стоп, четность.
Например, если на скорости обмена 9600, используется формат передачи:
длина слова - 8 бит; 1 старт-бит; 1 стоп-бит; четность не используется;
то для передачи одного байта полезной информации (8 бит), потребуется
передача 10 бит по каналу связи. "Полезная скорость", в этом случае,
составит 960 байт в секунду или 7680 бит/сек (максимальная без учета пауз).
Если будете использовать другой формат, например, с двумя стоп-битами
и битом четности. То на скорости 9600, передача одного байта потребует уже
передачи 12-ти бит по каналу. Скорость передачи "полезной" информации
в этом случае упадет до 800 байт в секунду или 6400 бит в секунду.
Alt.F4
@Ark, спасибо, понятно. Не понятно почему на заданной скорости не работает.
Скоро сойду с ума wacko.gif
@Ark
Цитата
Почему же он не работает на 57600 а только на 4800?

Какая тактовая частота процессора? Аппаратный модуль UART обычно получает рабочую
частоту для обмена ее делением. Допустимая ошибка по частоте для RS232 - не более 1-2%
(примерно). Нужно для каждой конкретной скорости вычислять ошибку. Иногда бывает,
что на большей скорости ошибка меньше... Смотрите документацию на ваш МК - там обычно
указываются допустимые скорости для UART, в зависимости от тактовой частоты процессора.
...
Еще, конечно, зависит от самого тактового генератора. Его возможная ошибка по частоте
будет влиять обязательно. На одной и той же частоте - от кварца может все работать,
а от внутреннего RC - может и не работать. Все нужно считать. Или смотреть готовые таблицы
в документации, если они там, конечно, есть...
Alt.F4
Кварц 4,608Мгц, в даташите по tiny2313 такого варианта нет, но нашел таблицы, где такой есть. Да и по формуле все сходится.
Перепаивал кварц, думал, может он частоту плохо держит - не помогло.
Фьюзы установлены на внешний кварц (CKSEL3..0 - 1101, SUT1..0 - 10, SKDIV8 - 0).
з.ы. заметил глюк в avr_studio, как только происходит запись 0х06 в регистр UCSRC, сразу же это число записывается в UBBRH. Пробовал оставлять как есть, пробовал UBRR прописывать в самом конце - связь не удалось наладить.
@Ark
Цитата
в даташите по tiny2313 такого варианта нет

Так может ваша тинька не поддерживает такую скорость? И Вы зря мучеетесь?
Проверьте все другие стандартные скорости по порядку, начиная медленных.
Alt.F4
Скорости до 1Мбит/с поддерживает. Просто в таблицах даташита кварца 4,608 нет.
Попробую сейчас скорости поменять начиная с самой низкой.
@Ark
Цитата
Скорости до 1Мбит/с поддерживает.

Да это все абстракция. Все зависит от конкретной частоты, и точности тактового генератора. И делителя в UART...
В некоторых случаях на 115200 работает, а на 57600 - нет...
ILYAUL
Цитата(Alt.F4 @ Aug 14 2010, 10:29) *
Почему же он не работает на 57600 а только на 4800? sad.gif
Нажмите для просмотра прикрепленного файла

Так. Передатчик USART работает с буфферизацией , поэтому первый посланный ему байт - пролетает мимо буфера , сразу в сдвиговый регистр и ждать освобождение UDR смысла нет он и так свободен. "Застрянет" в буфере только 2 байт.

Ваша программа сначала принимает символ - затем его отправляет , затем принимает и снова отправляет - по прикидкам UDR вообще проверять не нужно. Посланный Вами байт давно ушёл он даже в буфере не "застрял".
В чём проверяете программу и откуда получаете байт?

Специально скачал DS для 2313 для 4мгц запросто выставляется скорость UUSART 57600 правда ошибка -3,5 и сделайте в программе так
ldi temp,(SYSCLK)/((16*USARTSPEED)-1)
sts UBRR0L,temp
У Вас естественно out
где ,SYSCLK = 4608000 USARTSPEED=57600 в def их
Alt.F4
Проверяю в HyperTerminal.
Все заработало на скорости 2400бит/с! Мне в принципе достаточно.
Огромное спасибо всем откликнувшимся!
з.ы. в текст программы обязательно добавлять строки
Цитата
ldi temp,0x80 ;
out CLKPR,temp ;
ldi temp,0x00 ;
out CLKPR,temp ;
Не знаю зачем, но без них не работает.

Цитата
Специально скачал DS для 2313 для 4мгц
Огромное спасибо за помощь! Но у меня же кварц 4,608Мгц.
rx3apf
Цитата(Alt.F4 @ Aug 14 2010, 12:24) *
Кварц 4,608Мгц,
Фьюзы установлены на внешний кварц (CKSEL3..0 - 1101, SUT1..0 - 10, SKDIV8 - 0).

А вот на кой черт SKDIV8=0 (вообще-то он CKDIV8, ну да ладно) ? Если 0, то делитель на 8 ВКЛЮЧЕН. Т.о. Частота опорника не 4.608 MHz, а в 8 раз меньше, и настроить UART на 57600 никак не получится...

Цитата(Alt.F4 @ Aug 14 2010, 13:30) *
Не знаю зачем, но без них не работает.

А это отключение прескалера. Если сделать CKDIV8=1, то и эти строки не нужны.
Alt.F4
Цитата
Если 0, то делитель на 8 ВКЛЮЧЕН
Если сделать CKDIV8=1, то и эти строки не нужны.
Спасибо! А все голову ломаю. Просто шью uniprof, а там галочка соответствует 1, а в даташите tiny2313 на русском не сказано нулем или единицей устанавливается CKDIV8

Еще хотел узнать, возможно ли как-то передавать символы ACSII просто написав допустим
ldi temp,'ABCDE' ;
out UDR,temp ;

Или надо на каждый символ создать таблицу в 16-ричном виде и просто адресовать используя Z?
ILYAUL
Цитата(Alt.F4 @ Aug 14 2010, 13:49) *
Спасибо! А все голову ломаю. Просто шью uniprof, а там галочка соответствует 1, а в даташите tiny2313 на русском не сказано нулем или единицей устанавливается CKDIV8

Еще хотел узнать, возможно ли как-то передавать символы ACSII просто написав допустим
ldi temp,'ABCDE' ;
out UDR,temp ;

Или надо на каждый символ создать таблицу в 16-ричном виде и просто адресовать используя Z?

ldi temp,'A' ;
out UDR,temp
ldi temp,'B' ;
out UDR,temp
..............................................

Или через таблицу
rx3apf
Цитата(Alt.F4 @ Aug 14 2010, 13:49) *
Или надо на каждый символ создать таблицу в 16-ричном виде и просто адресовать используя Z?

Можно вот так:
CODE
;----------------------------------------------------------------------
; Программа выдачи сообщений
; Текст сообщения описывается директивами .db непосредственно после
; команды rcall Msg, признаком конца текста является байт 00.
; После выполнения программы управление возвращается на следующую за
; байтом 00 команду. Программа не портит регистры. Для выдачи текста
; используется команда rcall Print.
; Эта версия программы может использоваться только для микроконтроллеров
; с 16-разрядным счетчиком PC !!!
;----------------------------------------------------------------------

Msg:
push temp
in temp,SREG
push temp
push YH ; сохраним
push YL ; рабочие
push ZH ; регистры
push ZL
in YH,SPH ; адрес текущей
in YL,SPL ; позиции стека
ldd ZH,Y+7
ldd ZL,Y+8 ; адрес операнда в памяти
lsl ZL ; адрес для команды lpm
rol ZH
Msg1:
lpm temp,Z+ ; очередной байт
tst temp ; контроль на терминатор
breq Msg2 ; текст закончился
rcall Print ; вывод байта
rjmp Msg1
Msg2:
adiw ZL,1 ; коррекция для нечетного адреса
lsr ZH ; новый адрес возврата
ror ZL
std Y+7,ZH
std Y+8,ZL ; меняем адрес в стеке
pop ZL
pop ZH
pop YL
pop YH
pop temp
out SREG,temp
pop temp
ret


И вызов:
rcall Msg
.db "Hello, World !",13,10,0

А уж "Print" - это хоть напрямую вывод в UDR с превентивным контролем готовности, хоть в программный FIFO, хоть на LCD-индикатор или еще куда...
vvs157
Цитата(Alt.F4 @ Aug 14 2010, 13:49) *
Еще хотел узнать, возможно ли как-то передавать символы ACSII просто написав допустим
ldi temp,'ABCDE' ;
out UDR,temp ;

Или надо на каждый символ создать таблицу в 16-ричном виде и просто адресовать используя Z?
Это же ассемблер AVR, а не x86 или z80. Посмотрите повнимательнее на описание ассемблерных инструкций.
Alt.F4
А каким образом можно полученные символы сохранять в таблицу описанную директивой .db?
И затем сравнивать. Допустим если получили "hello", то сделать одно, если "bye", то другое?
ILYAUL
Цитата(Alt.F4 @ Aug 15 2010, 14:10) *
А каким образом можно полученные символы сохранять в таблицу описанную директивой .db?
И затем сравнивать. Допустим если получили "hello", то сделать одно, если "bye", то другое?

Сдедайте массив в SRAM и сохраняйте
BUFDS: .byte 16
Вытаскиваете значения из Sram и сравниваете
Alt.F4
Вытаскивать получается командой ld (ldd).
А вот записывать какой?
На
Код
st  reg,Z;

avr_studio ругается invalid register
ILYAUL
Цитата(Alt.F4 @ Aug 15 2010, 17:08) *
Вытаскивать получается командой ld (ldd).
А вот записывать какой?
На
Код
st  reg,Z;

avr_studio ругается invalid register

Можно так :
ldwi Z,StartRAM085 где ldwi - макрос , раскрывается в ldi ZH,high(StartRAM085) и ldi ZL,low(StartRAM085)
sts (StartRAM085+ValPressH),temp прямая адресация к ячейке SRAM
a можно и так
ldi temp,high(408)
st Z+,temp
ldi temp,low(408)
st Z+,temp

.dseg
StartRAM085: byte 50
это для обоих случаев
Alt.F4
Спасибо огромное! Буду разбираться.
Alt.F4
Извиняюсь за глупый вопрос. Я удалил сообщение.
Все дело оказалось в командах, вместо rcall, писал rjmp в подпрограмме. =(
Вот, что бывает, если с утра до вечера без перекура насиловать мозг программированием...
Alt.F4
Из-за нехватки памяти программ, приобрел ATmega48.
Запустил в симуляторе программу и наткнулся на ошибку:
error: Operand 1 out of range: 0xc0
в функции USART_transmit. Причем она скопирована с даташита. Поиск ни к чему не привел...
Код
USART_transmit:
    sbis    UCSR0A,UDRE0  ;  <--error: Operand 1 out of range: 0xc0
    rjmp    USART_transmit;
    out    UDR0,temp      ;  <--error: Operand 1 out of range: 0xc6
    ret                   ;
В чем может быть дело?
Спасибо.
rx3apf
Цитата(Alt.F4 @ Sep 5 2010, 21:01) *
В чем может быть дело?

Ну да, регистры USART в этом семействе недоступны для in/out, используйте lds/sts.
Alt.F4
Код
USART_transmit:
    lds    temp,UCSR0A;
    sbrs    temp,5    ;ждем пока содержимое из UDR0 перегрузится в сдвиговый регистр
    rjmp    USART_transmit;
    sts    UDR0,temp    ;отправляем
    ret                ;возврат из процедуры отправки
Правильно написал?
з.ы. в даташите приведены неверные примеры wacko.gif
rx3apf
Цитата(Alt.F4 @ Sep 5 2010, 21:41) *
Правильно написал?

Вроде да, хотя правильнее использовать не номер бита, а символическое имя.
Пардон, а сохранять temp перед поллингом статуса кто будет ? А то так и будет передавать вместо требуемых данных содержимое UCSR0A...
Цитата
з.ы. в даташите приведены неверные примеры wacko.gif

Да, но там есть и сноска, что при обращении к портам в расширенном пространстве i/o надо заменить in/out на lds/sts.
Alt.F4
rx3apf, спасибо огромное cheers.gif .
з.ы. но даташит ИМХО составлен неверно.
Alt.F4
Код
USART_receive:
    lds        temp2,UCSR0A    ;
    sbrs    temp2,(RXC0)    ;ждем приема символа (установка RXC)
    rjmp    USART_receive    ;
    lds        temp,UDR0        ;читаем
    ret                        ;возврат из процедуры приема
Прогоняю в avr_studio и данные из UDR0 не копируются в temp. После lds temp,UDR0; temp и UDR0 сбрасываются в 0х00.
В чем может быть проблема?
Спасибо.
ILYAUL
Цитата(Alt.F4 @ Sep 6 2010, 11:18) *
В чем может быть проблема?
Спасибо.


Не мучайтесь - в симмуляторе.
Alt.F4
Снова косяк c USART: cимволы из одной таблицы памяти программ МК почему-то передает неверно, причем только половину. Другие же таблицы передаются без ошибок.
Может это в адресации? Т.к. если таблица написана так:
Код
.db 'R','e','z','h','i','m',0x20,'"','O','h','r','a';
.db 'n','a','"',0x20,'a','k','t','i','r','o','v','a';
.db 'n','.'                                ;
то в HyperTerminal'е наблюдаю: Rezhim "OhАEЫ›ААP0ч*™*˜
А если так:
Код
.db 'R','e','z','h','i','m',0x20,'"','O','h';
.db 'r','a','n','a','"',0x20,'a','k','t','i';
.db 'v','i','r','o','v','a','n','.'    ;
то уже почему-то RezhАEЫ›ААP0ч*™*˜B™B˜

з.ы. и еще понять не могу, почему когда загружаю прошивку в UniProf, он в окне EEPROM грузит какие-то данные и шьет их в МК. Ведь эта же память по программе пуста!
Спасибо.
Alt.F4
Странно, но проблема оказалось в том, что между названием таблицы и предыдущей строкой не было пустой строки!!!
Правда вопрос про EEPROM все еще не раскрыт cranky.gif
Alt.F4
Код
Start:
    ldi        temp,0b00011000; установка TXEN RXEN
    sts        UCSR0B,temp; USART вкл    
    rcall    123; там мы отправляем по USART 123
..........
тут мы принимаем по USART и передаем, все работает.
затем нажали на кнопку и выключаемся
..........
end:
    clr        temp; снятие TXEN RXEN
    sts        UCSR0B,temp; USART выкл    
rjmp  Start
Проблема: символы 123 отправляются не с первого раза! Необходимо сначала посетить "end" и только со второго "Start" символы 123 передаются. Хотя и с первого раза в середине программы USART работает. В чем может быть проблема?
Еще прикол с таблицами из поста 39 остался.
Может это avr_studio зажигает?
Спасибо.

Нашел причину: необходимо сначала принять хотя бы один символ, только после этого МК будет осуществлять передачу. Почему так? ph34r.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.