Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Тайны баяна Uart в бубен храме Bascom


Тайны баяна Uart в бубен храме Bascom

Сообщений 1 страница 14 из 14

1

Уважаемые коллеги, залез в дебри, не могу понять аппаратную часть Uart, но выкладываю вам маленькую наработку, может чего подскажете, а так используйте для колдовства, ибо работают некоторые регистры:

Код:
'====================================================================================================================
'UCSRA - 7-RXC 6-TXC 5-UDRE 4-FE 3-DDR 2-PE 1-U2X 0-MPCM
'====================================================================================================================
'(
RXC - Флаг завершения приема. Флаг устанавливается в «1» при наличии непрочитанных данных в буфере приемника (регистр данных UDR). Сбрасывается флаг аппаратно после опустошения буфера.
TXC - Флаг завершения передачи. Флаг устанавливается в «1» после передачи всех разрядов посылки из сдвигового регистра передатчика, при условии, что в регистр данных UDR не было загружено нового значения. Флаг сбрасывается аппаратно при выполнении подпрограммы обработки прерывания или программно, записью в него лог. 1.
UDRE - Флаг опустошения регистра данных. Данный флаг устанавливается в «1» при пустом буфере передатчика (после пересылки байта из регистра данных UDR в сдвиговый регистр передатчика). Установленный флаг означает, что в регистр данных можно загружать новое значение. Если разряд UDRIE регистра UCR (UCSRB) установлен, генерируется запрос на прерывание «регистр данных пуст». Флаг сбрасывается аппаратно, при записи в регистр данных
FE - Флаг ошибки кадрирования. Флаг устанавливается в «1» при обнаружении ошибки кадрирования, т. е. если первый стопбит принятой посылки равен «0». Флаг сбрасывается при приеме стоп бита, равного «1».
DOR -  Флаг переполнения. В USART флаг устанавливается в «1», если в момент обнаружения нового стартбита в сдвиговом регистре приемника находится последнее принятое слово, а буфер приемника полон (два значения). В UART флаг устанавливается в «1», если новый кадр будет помещен в сдвиговый регистр приемника до того, как из регистра данных будет считано предыдущее слово. Флаг сбрасывается при пересылке принятых данных из сдвигового регистра приемника в буфер.
PE - Флаг ошибки контроля четности. Флаг устанавливается в «1», если в данных, находящихся в буфере приемника, выявлена ошибка контроля четности. При отключенном контроле четности этот разряд постоянно читается как «0»
U2X - Удвоение скорости обмена. Если этот разряд установлен в «1», коэффициент деления предделителя контроллера скорости передачи уменьшается с 16 до 8, удваивая тем самым скорость асинхронного обмена по последовательному каналу. В USART разряд U2X используется только при асинхронном режиме работы. В синхронном режиме он должен быть сброшен.
MPCM - Режим мультипроцессорного обмена. Разряд MPCM используется в режиме мультипроцессорного обмена. Если он установлен в «1», ведомый микроконтроллер ожидает приема кадра, содержащего адрес. Кадры, не содержащие адреса устройства, игнорируются.
')



'====================================================================================================================
'UCSRB - 7-RXCIE 6-TXCIE 5-UDRIE 4-RXEN 3-TXEN 2-UCSZ2 1-RXB8
'====================================================================================================================
'(
RXCIE - Разрешение прерывания по завершению приема. Если данный разряд установлен в «1», то при установке флага RXC регистра UCSRA генерируется прерывание.
TXCIE - Разрешение прерывания по завершению передачи. Если данный разряд установлен в «1», то при установке флага TXC регистра UCSRA генерируется прерывание.
UDRIE - Разрешение прерывания при очистке регистра данных UART. Если данный разряд установлен в «1», то при установке флага UDRE в регистра UCSRA  генерируется прерывание.
RXEN - Разрешение приема. При установке этого разряда в «1» разрешается работа приемника USART/UART и переопределяется функционирование вывода RXD.
TXEN - Разрешение передачи. При установке этого разряда в «1» разрешается работа передатчика UART и переопределяется функционирование вывода TXD. 4
UCSZ2 - Формат посылок. Этот разряд используется для задания размера слов данных, передаваемых по последовательному каналу. В модулях USART он используется совместно с разрядами UCSZ1 и UCSZ0 регистра UCSRC.
RXB8 - 8 й разряд принимаемых данных. При использовании 9 разрядных слов данных этот разряд содержит значение старшего разряда принятого слова. В случае USART содержимое этого разряда должно быть считано до прочтения регистра данных UDR.
TXB8 - 8 й разряд передаваемых данных. При использовании 9 разрядных слов данных, содержимое этого разряда является старшим разрядом передаваемого слова. Требуемое значение должно быть занесено в этот разряд до загрузки байта данных в регистр UDR.
')


'====================================================================================================================
'UCSRC - 7-URSEL 6-UMSEL 5-UPM1 4-UPM0 3-USBS 2-UCSZ1 1-UCSZ0 0-UCPOL
'====================================================================================================================
'(
URSEL - Выбор регистра. Этот разряд определяет, в какой из регистров модуля производится запись. Если разряд установлен в «1», обращение производится к регистру UCSRC. Если же разряд сброшен в «0», обращение производится к регистру UBRRH.
UMSEL - Режим работы USART. Если разряд сброшен в «0», модуль USART работает в асинхронном режиме. Если разряд установлен в «1», то модуль USART работает в синхронном режиме.
Upm1 И Upm0 - Режим Работы Схемы Контроля И Формирования Четности. Эти Разряды Определяют Функционирование Схем Контроля И Формирования Четности.
--------------------------------
Bits Settings:
-------------------
UPM1 UPM0
 0     0    Disabled
 0     1    Reserved
 1     0    Enabled, Even Parity
 1     1    Enabled, Odd Parity
-------------------------------
')
Ucsrc.4 = 0                                                 'UPM0
Ucsrc.5 = 1                                                 'UPM1

'(
USBS - Количество стопбитов. Этот разряд определяет количество стоп битов, посылаемых передатчиком. Если разряд сброшен в «0», передатчик посылает 1 стоп бит, если установлен в «1», то 2 стоп бита. Для приемника содержимое этого разряда безразлично.
UCSZ1 и UCSZ0 - Формат посылок. Совместно с разрядом UCSZ2 эти разряды определяют количество разрядов данных в посылках (размер слова).
-------------------------------
UCSZ2 UCSZ1 UCSZ0
  0     0     0     5-bit
  0     0     1     6-bit
  0     1     0     7-bit
  0     1     1     8-bit
  1     0     0     Reserved
  1     0     1     Reserved
  1     1     0     Reserved
  1     1     1     9-bit
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
')
Ucsrc.1 = 0                                                 'UCSZ0
Ucsrc.2 = 1                                                 'UCSZ1

'(
UCPOL - Полярность тактового сигнала. Значение этого разряда определяет момент выдачи и считывания данных на выводах модуля. Разряд используется только при работе в синхронном режиме. При работе в асинхронном режиме он должен быть сброшен в «0».
')

'====================================================================================================================
'Регистр скорости и передачи UBRRL и UBRRH 15-URSEL 14-13-12-NONE 11-10-9-8-UBRR
'====================================================================================================================

Это я набрал по мануалу.
Делаю устройство, нужно 7 бит, 1 бит чётности и 1 бит чего-то там Even.
Мануала вообще не нашел, только на Си, неужели в Bascom Avr нельзя этим управлять более гуманно и культурно?
К примеру вот так вот включил 7бит:

Код:
Ucsrc.1 = 0                                                 'UCSZ0
Ucsrc.2 = 1                                                 'UCSZ1

А вот так включил аппаратную Even Parity

Код:
Ucsrc.4 = 0                                                 'UPM0
Ucsrc.5 = 1                                                 'UPM1

И вроде как не нужно было делать программно бит чётности  :flirt:

Отредактировано Ev3658 (2016-03-27 21:46:02)

0

2

Я чот не догоняю, зачем извращаться, когда есть "CONFIG COMx"?  o.O

+1

3

RDW написал(а):

когда есть "CONFIG COMx"?

:confused:  А он с аппаратным UART работает?

0

4

Так попробуй, расскажешь, почитай: http://avrhelp.mcselec.com/index.html?config_com1.htm (там много вариаций).
Да и кристаллов масса...

0

5

Работает:

Код:
Config Com1 = 300 , Synchrone = 0 , Parity = Even , Stopbits = 2 , Databits = 7 , Clockpol = 0

Видимо натыкался на примеры, где Config Com использовали под программный Uart, COM1 - и есть аппаратный. Биты все дают реакцию, правда Stopbits =1 и =2 не выявило отклонений.

А есть буфер Uart, куда можно отослать и пока отсылается, программа, чтоб дальше работала?

0

6

Да, всё есть: http://avrhelp.mcselec.com/index.html?c … ialout.htm (и на приём тоже).
Только сильно палку не перегибай, асинхронные процессы, могут легко приводить к казусам (начиная от переполнения буфера и заканчивая реакцией (это всё учитывать надо).

0

7

Странно, но вот это сразу стопорит всю передачу:

Config Serialout = Buffered , Size = 8

Видимо какие-то регистры не совместимы с этим:

Код:
Config Com1 = 300 , Synchrone = 0 , Parity = Even , Stopbits = 2 , Databits = 7 , Clockpol = 0

0

8

Не знаю, в этом направлении тесты не проводил. Могу только предположить, что: у тебя старая версия Баскома или всё-таки баг.)
У меня всё работало при стандартных настройках.
В описании вроде нет никакой информации на предмет костамизации при использовании буфера.

+1

9

Ev3658 написал(а):

вот это сразу стопорит всю передачу

Прерывания разрешены?

0

10

Сдаюсь  :flag:

Решил тоже самое переместить с Atmega328p на Atmega128. Так, как на Uart0 у меня уже сидит UsbAsp программатор, решил перевести всё на Uart1 (второй UART).
Данные принимаю отлично, с прерываниями и всё такое, но вот отправка не получается  :insane:
На компьютер отравляется без проблем, всё полностью то-же самое, за исключением контроллера, уже шаманить начал, логики не подаётся  :canthearyou:

Код:
$regfile = "m128def.dat"
  $crystal = 14745600
  $framesize = 120
  $hwstack = 120
  $swstack = 120
  $baud1 = 300

On Urxc1 Getchar

Dim File As String * 16
Dim B As Byte
Dim Rx1 As String * 1
'Echo Off
Config Com2 = Dummy , Synchrone = 0 , Parity = Even , Stopbits = 1 , Databits = 7 , Clockpol = 0
'Config Serialout1 = Buffered , Size = 8
Open "COM2:" For Binary As #1
Enable Serial
Config Portd.3 = Output
Config Portd.2 = Input

Отправляю:

Код:
Do
 If Cts1 = 0 Then
   Lineinput #2 , Tx  'читаю из файла целую строку до 70 символов
   Dlinaf = Dlinaf - 1 ' это для отображение, сколько строк осталось
   Locate 3 , 10 : Lcd Dlinaf ; " "
   L = Len(tx) ' запоминаем кол-во символов
   P = 0
   'переходим к отправке строки, если станок хочет кушать, он ставит CTS1=0 если насытился (или не захотел принимать), то CTS1=1
   If L > 0 Then
    Do 'цикл, чтоб отослать строку и если надо, останавливаем после каждого отправленного байта
      If Cts1 = 0 Then
         Incr P 'для отображения
         Rx1 = Mid(tx , P , 1) 'берём один символ
         Rx1 = Ucase(rx1) 'переводим всё в верхний регистр
         B = Asc(rx1) 'переводим в десятичный код
         B.7 = 0 'убираем всякую шляпу
        If B > 31 Then 'отправляем только нужное
         Printbin #1 , B 'отправка 1 байта
        End If
        'выводим на экран отправленное:
        If P > 0 And P < 20 Then
            Locate 2 , P
            Lcd Mid(tx , P , 1) ; Chr(255)
            Waitms 1
        End If

         'ему нужно обозначать конец строки так, оно работало:
         If P = L Then
            Printbin #1 , 13
            Printbin #1. 10
            Printbin #1 , 13
            Printbin #1 , 13
         End If
     End If
    Loop Until P = L
      End If
   Else
   Gosub Fraza_start ' надпись "нажмите старт"
   End If

Loop Until Eof(2) <> 0

Close #2
Locate 4 , 1
Lcd "OK"

Дело в том, что он принимает информацию и осознаёт её правильность в плане чётности битов, так как если Even заменить на None или другое, то он вырубает приём, так-же не захочет принимать, если поставить 8 бит.
На компьютере всё нормально, осциллографом пощупал, всё в норме (логические уровни тоже), ну не знаю, что может быть не так? Уже и 16мГц кварц и 14хххмГц пробовал, такое ощущение, что где-то со скоростью проблемы, хотя частота передачи схожа с частотой передачи с ПК (с ПК всё ок).
Если использовать буфер на передачу, то он стоит, чувствуется его надо как-то опустошать или не знаю, чего он там примет на себя и всё

Код:
Config Serialout1 = Buffered , Size = 8

.

0

11

Используя буфер на отправку, надо точно знать, что данные успевают отправляться. Насколько я помню, в описании есть ряд переменных, читая которые, можно понять, в каком состоянии буфер. Честно, мне было проще отказаться от использования буфера на отправку (геморроя больше). А вот на приём использовал нормально (два порта перебрасывались с свистом).
Есть ещё полезный оператор: http://avrhelp.mcselec.com/index.html?bufspace.htm
Так же не надо забывать, что если данные текут нонстопом, то обязательно нужно МК ставить кратный кварц частоте передачи (иначе накапливается ошибка), если это ПК. Если это два МК, то кварцы должны быть одинаковые (из одной серии).
Ну и если использовать только буфер на приём, то этого порой достаточно, чтобы не использовать буфер на отправку, т.к. пока отправляется, полу аппаратно прерывание принимает данные.
Так же не забываем факт о том, что скорость приёма, не должна быть быстрее скорости отправки, иначе полюбасу буфер переполнится.
И внутренние процесс в МК не должны препятствовать приёму/отправки.

Отредактировано RDW (2016-04-01 18:21:43)

0

12

Работаю без буфера, на Atmega328 отправляется, на Atmega128 через второй аппаратный UART не отправляется.
Приём отличный.
Пробовал ассемблером конфигурировать, без изменений.

Код:
Ucsr1c.1 = 0                                                'UCSZ0
Ucsr1c.2 = 1                                                'UCSZ1

Пробовал делать программный бит чётности, тоже без изменений.
Тут вот именно, если не правильный бит чётности, то передача сразу прерывается, а так-то она идёт, данные отсылаются!
То-есть у меня емсть подтверждения, что данные я передаю и бит чётности совпадает, так-же 7 бит то-же совпадают, но не ясно, почему он не может понять Atmega128, но спокойно понимает Atmega328.
Есть разница между двумя кодами, в Atmega328 используется I2C для LCD, а в Atmega128 его нет, но как это может влиять на передачу данных?

Кварц уже подпаял высокой точности, разные пробовал, не в них дело.
Добавлено спустя 59 минут 30 секунд:

Дело не в МК, перепаял, всё то-же самое. Видимо придётся сажать на Uart0.

Отредактировано Ev3658 (2016-04-01 19:36:25)

0

13

Чую я колдовство!!! Оно есть!!! Я уверен!!! Получилось отправить, но логически это не объясняется.
Всё дело в какой-то задержке при передачи данных, к примеру в момент передачи данных у меня посылается по Gosub просто так (там строка осциляторА=135) и возвращается, а ещё задерживается на LCD - и если это убрать, ничего не работает  :tired: . Явно нужна какае-то пауза, пробовал эмитировать, не она, получается нужно пошевелить таймер и послать чего нибудь на LCD.
Добавлено спустя 22 часа 45 минут 56 секунд:
Есть предположения, что переменная залазит куда-то за область позволенного и в этом весь коллапс.

Отредактировано Ev3658 (2016-04-02 19:06:20)

0

14

Если у кого не получается передать информацию на устройство, на всякий случай оставлю немного данных для уверенности.
UART AVR Bascom RS232

Эта строка работает нормально:

Код:
Config Com1 = 300 , Synchrone = 0 , Parity = Even , Stopbits = 1 , Databits = 7 , Clockpol = 0

Точней не надо её копировать, я про то, что она действует исправно. То-есть толк от неё есть, по этому заранее узнавайте параметры устройтства и подстраивайте под него.
Кварц для МК лучше подбирать из следующих номиналов:

1 МГц:
0,2% отклонение: 2.400, 4.800
1,8432 Mhz: 1,8432 МГц:
безошибочный: 2.400, 4.800, 9.600, 14.400, 19.200, 28.800, 38.400, 57,600, 76,800, 115 200, 230400 бод
2 Mhz: 2 МГц:
0,2% отклонение: 2.400, 4.800, 9.600, 19.200 бод
Правильно: 250000 бод
3,6864 Mhz: 3,6864 МГц:
безошибочный: 2.400, 4.800, 9.600, 14.400, 19.200, 28.800, 38.400, 57,600, 76,800, 115 200, 230400 бод
4 Mhz: 4 МГц:
0,2% отклонение: 2.400, 4.800, 9.600, 38.400 бод
безошибочный: 250.000, 500.000 бод
7,3728 Mhz: 7,3728 МГц:
безошибочный: 2.400, 4.800, 9.600, 14.400, 19.200, 28.800, 38.400, 57,600, 76,800, 115 200, 230400 бод
8 Mhz: 8 МГц:
0,2% отклонение: 2.400, 4.800, 9.600, 19.200, 38.400, 76,800 бод
Правильно: 250000, 500000, 1000000 бит
11,0592 Mhz: 11,0592 МГц:
безошибочный: 2.400, 4.800, 9.600, 14.400, 19.200, 28.800, 38.400, 57,600, 76,800, 115 200, 230400 бод
14,7456 Mhz: 14,7456 МГц:
безошибочный: 2.400, 4.800, 9.600, 14.400, 19.200, 28.800, 38.400, 57,600, 76,800, 115 200, 230400 бод
16 Mhz: 16 МГц:
0,1% до 0,2% отклонение: 4.800, 9.600, 14.400, 19.200, 38.400, 76,800 бод
Правильно: 2400, 250000, 500000, 1000000 бит
18,432 Mhz: 18,432 МГц:
безошибочный: 2.400, 4.800, 9.600, 14.400, 19.200, 28.800, 38.400, 57,600, 76,800, 115 200, 230400 бод
20 Mhz: 20 МГц:
-0,2% До 0,2% отклонение: 9.600, 14.400, 19.200, 28.800, 38.400 бод
безошибочный: 2.400, 4.800, 250.000, 500.000 бод


Если используйте первый UART в контроллере (а их может быть больше одного), то мне показалось, лучше всего вот так:
Отправить байт:

Код:
PRINTBIN B

Принять байт:
А вот тут засада, дело в том, что у UART есть прерывание по наполнению буфера UART.

Код:
On Urxc Getchar
Enable Urxc
Enable Interrupts

Сама подпрограмма на вкус и цвет, главное, при быстром приёме опустошить быстро буфер. Вот много жрущий память код, который выполняется, как только сработало прерывание:

Код:
Getchar:
L = 0
Do
If Ischarwaiting() = 0 Then Exit Do
   L = L + 1
   B = Inkey()
   If L <60 Then Tx = Tx + Chr(b)
Loop
Return

В итоге вы получаете строку текста. Лучше много кода не пихать в подпрограмму, иначе не успеет опустошить буфер до следующего приёма и если есть возможность остановить передачу при приёме, воспользуйтесь этим.
По поводу буфера, кто как с ним работает, я решил без него, но штука бывает полезная:
буфер выходных данных

Код:
Config Serialout = Buffered , Size = 8

буфер входных данных

Код:
Config Serialin = Buffered , Size = 8

Если используйте второй UART в контроллере, то он используется не так, как первый:

Код:
Config Com2 = 300 , Synchrone = 0 , Parity = Even , Stopbits = 1 , Databits = 7 , Clockpol = 0
Open "COM2:" For Binary As #1

Отправить байт:

Код:
PRINTBIN #1,B

Принять байт:

Код:
On Urxc1 Getchar
Enable Urxc1
Enable Interrupts
Код:
Getchar:
L = 0
Do
If Ischarwaiting(#1) = 0 Then Exit Do
   L = L + 1
   B = Inkey(#1)
   If L <60 Then Tx = Tx + Chr(b)
Loop
Return

0


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Тайны баяна Uart в бубен храме Bascom