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

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

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

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



! Исследование USART !

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

1

Исследование USART

0

2

Связь Atmega328P и Atmega32 по UART

Данные с АЦП Atmega328P передаются на Atmega32 и отображаются на LCD

http://s5.uploads.ru/t/17HSB.jpg http://s0.uploads.ru/t/CuryY.jpg

Симуляция в Протеус 7.10 sr0 + исходники Bascom 2.0.7.1  -  скачать

+1

3

Передача с компьютера в МК через переходник COM ==> USB по USART

Симуляция в Протеус 7.10 sr0 + исходники Bascom 2.0.7.1 + программа терминал для OS Windows -  скачать

Снимок экрана

http://s4.uploads.ru/t/dk75I.jpg

+1

4

Доброго здоровья!

В качестве эксперимента делал обмен по USART между двумя Atmega328.

В качастве помехи, включал шимы (12 шт.) с максимальной частотой, использовал аппаратный USART на прерываниях.

Всё отлично работает в обе стороны.

http://s6.uploads.ru/t/m815b.jpg http://s6.uploads.ru/t/yu6MI.jpg

http://s5.uploads.ru/t/GyhRe.jpg

Симуляция в Протеус 7.10 sr0 + исходники Bascom 2.0.7.1  -  скачать

+1

5

Приём по USART в прерывании.

Исходник

'===============================================================================

'          А П П А Р А Т Н Ы Й     П Р И Ё М     П О     U S A R T

'===============================================================================

  $map              ' Получаем карту распределения памяти компилятором Bascom
  $regfile = "m328pdef.dat"       ' Используемый контроллер
  $crystal = 1000000       ' 1 МГц
  $framesize = 32   'размер области используемой и необходимой для преобразований
  $hwstack = 40     ' Размер аппаратного стека
  $swstack = 16     ' Размер программного стека

'--------------------------  Настройка USART  ----------------------------------

  $baud = 4800      '4800     '19200     '38400     '57600     '76800     '115200    '230400
  Ucsr0a.1 = 1      ' Двойная скорость работы USART, скорость трансляции = $baud * 2

  On Urxc Принятые_данные_usart       ' Переход на подпрограмму обработки прерывания после окончания приёма данных по USART

'--------------------  Используемые переменные  --------------------------------

  Dim Счетчик_принятых_символов As Byte
  Dim Принятый_код_символа_usart As Byte
  Dim Буфер_приема_usart_str As String * 20
  Dim Флаг_есть_принятое_сообщ_usart As Byte

'--------------  Разрешаем работу необходимых прерываний  ----------------------
  Enable Urxc
'------------  Разрешаем работу всех включенных прерываний  --------------------
  Enable Interrupts ' Разрешаем работу прерываний
'===============================================================================
'                   Г Л А В Н Ы Й         Ц И К Л
'===============================================================================
  Главный_цикл:
    nop

     If Флаг_есть_принятое_сообщ_usart = 1 Then
         Флаг_есть_принятое_сообщ_usart = 0       ' Сбрасываем флаг
         Print "Принято - " ; Буфер_приема_usart_str       ' Передаём то, что приняли
         Буфер_приема_usart_str = ""       ' Чистим буфер приёма
         Enable Urxc       ' Включаем приём
     End If

    nop
   Idle             ' Спим, по приходу данных в USART, просыпаемся и галопируем на обработку принятого
  Goto Главный_цикл
End
'===============================================================================
'                        П О Д П Р О Г Р А М М Ы
'===============================================================================

'===============================================================================
  Принятые_данные_usart:
'-------------------------------------------------------------------------------

    Принятый_код_символа_usart = Udr0       ' Забираем содержимое аппаратного буфера USART

    If Принятый_код_символа_usart <> 13 Then       ' Проверяем, не является ли этот символ "Enter"
        Буфер_приема_usart_str = Буфер_приема_usart_str + Chr(принятый_код_символа_usart)       ' Если нет, то добавляем его в буфер принятого по USART сообщения
        Incr Счетчик_принятых_символов       ' Считаем количество принятых символов
      Else          ' Иначе выключаем приём и ставим метку, что приём закончен (принято всё сообщение), можно что-то делать с принятым
        Disable Urxc       ' Выключаем приём, пока не обработаем принятое сообщение
        Счетчик_принятых_символов = 0       ' Сбрасываем счётчик символов, готовим к следующему приёму
        Флаг_есть_принятое_сообщ_usart = 1       ' Если символ оказался "Enter", тогда флаг устанавливаем в 1. "Enter"- конец сообщения
    End If

'-------------------------------------------------------------------------------
  Return
'===============================================================================


http://s8.uploads.ru/t/MYrPq.jpg

+1

6

Алексей bird написал(а):

Выкладываю сей код, в него добавлена строка и для передачи по УАРТ.

Фрагмент кода

$regfile = "m8def.dat"
$crystal = 8000000
$hwstack = 40
$swstack = 16
$framesize = 32
'--------------------------  Настройка USART  ----------------------------------
$baud = 4800                                               '4800     '19200     '38400     '57600     '76800     '115200    '230400
  Ucsra.1 = 1                                               ' Двойная скорость работы USART, скорость трансляции = $baud * 2

  On Urxc Принятые_данные_usart                             ' Переход на подпрограмму обработки прерывания после окончания приёма данных по USART
'--------------------  Используемые переменные USART ---------------------------

  Dim Счетчик_принятых_символов As Byte
  Dim Принятый_код_символа_usart As Byte
  Dim Буфер_приема_usart_str As String * 8
  Dim Флаг_есть_принятое_сообщ_usart As Bit
'--------------  Разрешаем работу необходимых прерываний USART -----------------
  Enable Urxc

'--------- Конфигурируем ЖКИ ------------------------------
Config Lcd = 16 * 2
Config Lcdpin = Pin , Rs = Portc.4 , E = Portc.5 , Db4 = Portc.0 , Db5 = Portc.1 , Db6 = Portc.2 , Db7 = Portc.3
Cursor Off
Config Portc = Output
Config Portb = Output
Config Portd.0 = Input
Config Portd.1 = Output
Cls

'-----------  Настройка таймеров  --------------------------------------
Config Timer1 = Timer , Prescale = 64
On Timer1 Pulse0

Enable Timer1
Start Timer1

'---------Переменные-------------------------------------
Dim A As Integer
A = 0

'------------  Разрешаем работу всех включенных прерываний  --------------------
  Enable Interrupts                                         ' Разрешаем работу прерываний
'===============================================================================
'                   Г Л А В Н Ы Й         Ц И К Л
'===============================================================================
  Главный_цикл:
    Locate 2 , 1 : Lcd A
    Locate 1 , 1 : Lcd Буфер_приема_usart_str

     If Флаг_есть_принятое_сообщ_usart = 1 Then
         Флаг_есть_принятое_сообщ_usart = 0                 ' Сбрасываем флаг
         'Print "Принято - " ; Буфер_приема_usart_str       ' Передаём то, что приняли
         Буфер_приема_usart_str = ""                        ' Чистим буфер приёма
         Enable Urxc                                        ' Включаем приём
     End If

  Goto Главный_цикл
End
'===============================================================================
'                        П О Д П Р О Г Р А М М Ы
'===============================================================================

  Принятые_данные_usart:
    Принятый_код_символа_usart = Udr                        ' Забираем содержимое аппаратного буфера USART

    If Принятый_код_символа_usart <> 13 Then                ' Проверяем, не является ли этот символ "Enter"
         Буфер_приема_usart_str = Буфер_приема_usart_str + Chr(принятый_код_символа_usart)       ' Если нет, то добавляем его в буфер принятого по USART сообщения
        Incr Счетчик_принятых_символов                      ' Считаем количество принятых символов
      Else                                                  ' Иначе выключаем приём и ставим метку, что приём закончен (принято всё сообщение), можно что-то делать с принятым
        Disable Urxc                                        ' Выключаем приём, пока не обработаем принятое сообщение
   
        Счетчик_принятых_символов = 0                       ' Сбрасываем счётчик символов, готовим к следующему приёму
        Флаг_есть_принятое_сообщ_usart = 1                  ' Если символ оказался "Enter", тогда флаг устанавливаем в 1. "Enter"- конец сообщения
    End If

'-------------------------------------------------------------------------------
  Return

Pulse0:
A = A + 1

Print A ;                                               'тут главное поставить точку с запятой
Printbin 13                                           'а это самое главное, т.к. предыдущее отключает спецсимволы, то добавляем нужные(CR) в ручном режиме
Return

Помогла вот эта статья
В итоге индикация и счёт идёт нормально, ничего не заезжает и нет лишних символов.

0

7

Прием и передача по USART на прерываниях - скачать

Исходник, реализовано 2 варианта: ASM AVR и Bascom, вариант выбирается константой "Const Realizaciya_preryvaniya"

'===============================================================================

  $map              ' Получаем карту распределения памяти компилятором Bascom
  $regfile = "m8def.dat"       ' Используемый контроллер
  $crystal = 1000000       ' 1 МГц
'  $crystal = 7372800       ' 7,3728 МГц, кварц для стабильной работы USART во всём диапазоне скоростей передачи и приёма
  $framesize = 32   'размер области используемой и необходимой для преобразований
  $hwstack = 40     ' Размер аппаратного стека
  $swstack = 16     ' Размер программного стека

  Const Realizaciya_preryvaniya = 0       ' Если "0", то обработка производится с помощью ASM AVR, если "1", то силами компилятора Bascom

'----------  Настройка режима пониженного энергопотребления  -------------------

  Mcucr.7 = 1       ' Разрешён спящий режим Idle

'------------------------  Настройка USART  ------------------------------------

  $baud = 4800      '4800     '19200     '38400     '57600     '76800     '115200    '230400
  Ucsra.1 = 1       ' Двойная скорость работы USART, скорость трансляции = $baud * 2

  #if Realizaciya_preryvaniya = 0
      On Urxc Прием_данных_usart_asm Nosave       ' Переход на подпрограмму обработки прерывания после окончания приёма данных по USART
      On Udre Передача_данных_usart_asm Nosave       ' Переход на подпрограмму обработки прерывания после опустошения буфера передачи данных по UART
  #endif

  #if Realizaciya_preryvaniya = 1
      On Urxc Прием_данных_usart       ' Переход на подпрограмму обработки прерывания после окончания приёма данных по USART
      On Udre Передача_данных_usart       ' Переход на подпрограмму обработки прерывания после опустошения буфера передачи данных по UART
  #endif

'------------------- Конфигурация LCD на базе HD44780 --------------------------

  Config Lcd = 16 * 2       ' Используемый LCD
  Config Lcdpin = Pin , Rs = Portc.4 , E = Portc.5 , Db4 = Portc.0 , Db5 = Portc.1 , Db6 = Portc.2 , Db7 = Portc.3

  Initlcd           ' Инициализируем LCD
  Waitms 50         ' Ждем пока все запустится
  Cursor Off Noblink       ' Выключаем неморгающий курсор
  Cls               ' Чистим экран, на всякий случай

'-----------------------  Настройка TIMER1  ------------------------------------

  Config Timer1 = Timer , Prescale = 1

  #if Realizaciya_preryvaniya = 0
      On Timer1 Обработка_прерывания_timer1_asm Nosave       ' Переход на подпрограмму обработки прерывания после переполнения счётчика TIMER1
  #endif

  #if Realizaciya_preryvaniya = 1
      On Timer1 Обработка_прерывания_timer1       ' Переход на подпрограмму обработки прерывания после переполнения счётчика TIMER1
  #endif

  Stop Timer1
  Timer1 = 0
  Dim Флаг_было_прерывание_timer1 As Byte

'--------------------  Используемые переменные  --------------------------------

  Dim Цикл As Byte

  Dim Переменная_word As Word

  Dim Флаг_буфер_uart_пуст As Byte
  Dim Флаг_есть_принятое_сообщ_usart As Byte

  Dim Буфер_lcd_str As String * 20

  Dim Номер_символа As Byte
  Dim Счетчик_принятых_символов As Byte
  Dim Принятый_код_символа_usart As Byte

  Dim Буфер_приема_usart_byte(20) As Byte
  Dim Буфер_приема_usart_str As String * 20 At Буфер_приема_usart_byte(1) Overlay

  Dim Буфер_передачи_usart_byte(20) As Byte
  Dim Буфер_передачи_usart As String * 20 At Буфер_передачи_usart_byte(1) Overlay

'--------------  Разрешаем работу необходимых прерываний USART -----------------
  Enable Urxc
  Enable Timer1 : Start Timer1
'------------  Разрешаем работу всех включенных прерываний  --------------------
  Enable Interrupts ' Разрешаем работу прерываний
'===============================================================================
'                   Г Л А В Н Ы Й         Ц И К Л
'===============================================================================
  Главный_цикл:

    If Флаг_было_прерывание_timer1 = 1 Then
        Буфер_lcd_str = Str(переменная_word)       ' Получаем строковую переменную для вывода на LCD
        Буфер_передачи_usart = Буфер_lcd_str       ' Получаем строковую переменную для вывода по USART
        Буфер_lcd_str = Format(буфер_lcd_str , "    0")       ' Форматируем переменную, для корректного вывода на LCD

        Enable Udre ' Включаем прерывание, тем самым начиная передачу

        Locate 1 , 1       ' Определяем номер строки и знакоместа
        Lcd Буфер_lcd_str       ' Выводим переменную на LCD

        Флаг_было_прерывание_timer1 = 0       ' Скидываем флаг
        Goto Главный_цикл       ' Проверяем, может ещё что-нибудь надо сделать
    End If

    If Флаг_есть_принятое_сообщ_usart = 1 And Флаг_буфер_uart_пуст = 1 Then
        Флаг_есть_принятое_сообщ_usart = 0       ' Сбрасываем флаг

        Locate 2 , 1       ' Определяем номер строки и знакоместа
        Lcd Spc(20) ' Чистим строку

        Locate 2 , 1       ' Определяем номер строки и знакоместа
        Lcd Буфер_приема_usart_str       ' Выводим на LCD

'        Буфер_приема_usart_str = ""       ' Чистим буфер приёма

        For Цикл = 1 To 20
            Буфер_приема_usart_byte(цикл) = 0
        Next Цикл

        Enable Urxc ' Включаем прерывание, тем самым начиная приём
        Goto Главный_цикл       ' Проверяем, может ещё что-нибудь надо сделать
     End If

   sleep
  jmp Главный_цикл
End
'===============================================================================
'                        П О Д П Р О Г Р А М М Ы
'===============================================================================

'===============================================================================
  Прием_данных_usart_asm:       ' Время выполнения прерывания 54 такта
'-------------------------------------------------------------------------------
' Сохраняем регистры, которые используем в обработке прерывания
'---------- Стек ------------
    !Push R25       ' Время выполнения инструкции, 2 такта
    !In R25 , Sreg  ' Время выполнения инструкции, 2 такта
    !Push R25       ' Время выполнения инструкции, 2 такта
'--------- Регистры ------------
    !push R10       ' Время выполнения инструкции, 2 такта
    !push R11       ' Время выполнения инструкции, 2 такта
    !push R26       ' Время выполнения инструкции, 2 такта
    !push R27       ' Время выполнения инструкции, 2 такта

' Обработка в прерывании Прием_данных_usart

' Забираем содержимое аппаратного буфера USART
    !IN R25 , UDR

' Если не перевод строки, собираем сообщение в кучку
    !cpi R25 , 13
    !BRNE Прием_символа       ' Перейти если не равно, время выполнения инструкции, 1 или 2 такта

' Запрещаем прерывание после приёма
    !cbi Ucsrb , 7  ' Время выполнения инструкции, 2 такта

' Сбрасываем счётчик символов, готовим к следующему приёму
    !ldi R26 , 0    ' Время выполнения инструкции, 1 такт
    !sts {Счетчик_принятых_символов} , R26       ' Время выполнения инструкции, 2 такта

' Если символ оказался "Enter", тогда флаг устанавливаем в 1. "Enter"- конец сообщения
    !ldi R26 , 1    ' Время выполнения инструкции, 1 такт
    !sts {Флаг_есть_принятое_сообщ_usart} , R26       ' Время выполнения инструкции, 2 такта
    !rjmp Выход_прием_данных_usart       ' Время выполнения инструкции, 2 такта

   Прием_символа:
    !lds R26 , {Счетчик_принятых_символов}       ' Время выполнения инструкции, 2 такта
    !inc R26        ' Время выполнения инструкции, 1 такт
    !sts {Счетчик_принятых_символов} , R26       ' Время выполнения инструкции, 2 такта

' Получаем адрес переменной
    Loadadr Буфер_приема_usart_byte(счетчик_принятых_символов) , X     ' Время выполнения инструкции, 9 тактов

' Забираем значение
    !ST X , R25     ' Время выполнения инструкции, 2 такта

   Выход_прием_данных_usart:

' Восстанавливаем регистры
'--------- Регистры ------------
    !pop R27        ' Время выполнения инструкции, 2 такта
    !pop R26        ' Время выполнения инструкции, 2 такта
    !pop R11        ' Время выполнения инструкции, 2 такта
    !pop R10        ' Время выполнения инструкции, 2 такта
'---------- Стек ------------
    !pop R25        ' Время выполнения инструкции, 2 такта
    !Out Sreg , R25 ' Восстанавливаем содержимое указателя, время выполнения инструкции, 2 такта
    !Pop R25        ' Время выполнения инструкции, 2 такта
'---- Вертаемся туда, откуда пришли ------
    !reti           ' Время выполнения инструкции, 4 такта
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Передача_данных_usart_asm:       ' Время выполнения прерывания 55 или 66 тактов, зависит от того, что передаём (символ или перевод строки)
'-------------------------------------------------------------------------------
' Сохраняем регистры, которые используем в обработке прерывания
'---------- Стек ------------

    !Push R25       ' Время выполнения инструкции, 2 такта
    !In R25 , Sreg  ' Время выполнения инструкции, 2 такта
    !Push R25       ' Время выполнения инструкции, 2 такта

'--------- Регистры ------------

    !push R10       ' Время выполнения инструкции, 2 такта
    !push R11       ' Время выполнения инструкции, 2 такта
    !push R26       ' Время выполнения инструкции, 2 такта
    !push R27       ' Время выполнения инструкции, 2 такта

' Обработка в прерывании Передача_данных_usart

' Считаем символы
    !lds R25 , {Номер_символа}       ' Время выполнения инструкции, 2 такта
    !inc R25        ' Время выполнения инструкции, 1 такт
    !sts {Номер_символа} , R25       ' Время выполнения инструкции, 2 такта

' Получаем адрес переменной
    Loadadr Буфер_передачи_usart_byte(номер_символа) , X       ' Время выполнения инструкции, 9 тактов

' Забираем значение
    !ld R25 , X     ' Время выполнения инструкции, 2 такта

' Если не "0", передаём значение в USART
    !cpi R25 , 0    ' Время выполнения инструкции, 2 такта
    !BRNE Передача_символа       ' Перейти если не равно, время выполнения инструкции, 1 или 2 такта

' Передаем "Enter" (перевод строки)
    !ldi R25 , 13   ' Время выполнения инструкции, 1 такт
    !Out Udr , R25  ' Время выполнения инструкции, 1 такт

' Запрещаем прерывание после опустошения буфера UART
    !cbi Ucsrb , 5  ' Время выполнения инструкции, 2 такта

'Чистим Буфер_передачи_usart
    !ldi R25 , 0    ' Время выполнения инструкции, 1 такт
    !sts {Буфер_передачи_usart} , R25       ' Время выполнения инструкции, 2 такта

'Обнуляем счетчик символов
    !sts {Номер_символа} , R25       ' Время выполнения инструкции, 2 такта

' Поднимаем флаг, говорящий о том, что аппаратный буфер USART пуст и можно что-нибудь принять или отправить
    !ldi R25 , 1    ' Время выполнения инструкции, 1 такт
    !sts {Флаг_буфер_uart_пуст} , R25       ' Время выполнения инструкции, 2 такта
    !rjmp Выход_передача_данных_usart       ' Время выполнения инструкции, 2 такта

   Передача_символа:
    !sts udr , R25  ' Время выполнения инструкции, 2 такта

   Выход_передача_данных_usart:

' Восстанавливаем регистры
'--------- Регистры ------------

    !pop R27        ' Время выполнения инструкции, 2 такта
    !pop R26        ' Время выполнения инструкции, 2 такта
    !pop R11        ' Время выполнения инструкции, 2 такта
    !pop R10        ' Время выполнения инструкции, 2 такта

'---------- Стек ------------

    !pop R25        ' Время выполнения инструкции, 2 такта
    !Out Sreg , R25 ' Восстанавливаем содержимое указателя, время выполнения инструкции, 2 такта
    !Pop R25        ' Время выполнения инструкции, 2 такта

'---- Вертаемся туда, откуда пришли ------

    !reti           ' Время выполнения инструкции, 4 такта

'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Обработка_прерывания_timer1_asm:       ' Время выполнения прерывания 45 тактов
'-------------------------------------------------------------------------------
' Сохраняем регистры, которые используем в обработке прерывания
'---------- Стек ------------

    !Push R26       ' Время выполнения инструкции, 2 такта
    !In R26 , Sreg  ' Время выполнения инструкции, 2 такта
    !Push R26       ' Время выполнения инструкции, 2 такта

'--------- Регистры ------------

    !push R27       ' Время выполнения инструкции, 2 такта
    !push R30       ' Время выполнения инструкции, 2 такта
    !push R31       ' Время выполнения инструкции, 2 такт

'-----  Обработка в прерывании TIMER1  -------------

'----  Увеличиваем переменную, аналог Incr Переменная_word  ------

    !ldi R26 , {Переменная_word}
    !ldi R27 , 0    ' Смотрим вторую часть адреса в отчёте компиляции Bascom

    !ld R30 , X+
    !ld R31 , X
    !subi R30 , &HFF
    !sbci R31 , &HFF
    !st X , R31
    !st -X , R30

'----  Ставим флаг, аналог Флаг_было_прерывание_timer1 = 1  -----

    !ldi R30 , 1
    !sts {Флаг_было_прерывание_timer1} , R30

' Восстанавливаем регистры
'--------- Регистры ------------

    !pop R31        ' Время выполнения инструкции, 2 такта
    !pop R30        ' Время выполнения инструкции, 2 такта
    !pop R27        ' Время выполнения инструкции, 2 такта

'---------- Стек ------------

    !pop R26        ' Время выполнения инструкции, 2 такта
    !Out Sreg , R26 ' Восстанавливаем содержимое указателя, время выполнения инструкции, 2 такта
    !Pop R26        ' Время выполнения инструкции, 2 такта

'---- Вертаемся туда, откуда пришли ------

    !reti           ' Время выполнения инструкции, 4 такта

'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Передача_данных_usart:       ' Время выполнения прерывания 148-152 такта
'-------------------------------------------------------------------------------
    Incr Номер_символа       ' Готовим переменную, что-бы взять следующий символ   = 7 мкс
    If Буфер_передачи_usart_byte(номер_символа) = 0 Then       ' Если все передали, запрещаем прерывание и готовим переменные для следующей передачи        = 6 мкс
        Udr = 13    ' Передаем "Enter" (перевод строки)
        Disable Udre       ' Запрещаем прерывание после опустошения буфера UART
        Буфер_передачи_usart = ""
        Номер_символа = 0       ' Какой символ будем читать при следующей передаче по USART
        Флаг_буфер_uart_пуст = 1       ' Поднимаем флаг, говорящий о том, что аппаратный буфер USART пуст и можно что-нибудь принять или отправить
      Else
        Udr = Буфер_передачи_usart_byte(номер_символа)       ' Поочерёдно заносим байтовые значения в аппартный буфер МК, для передачи
    End If
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Прием_данных_usart:       ' Время выполнения прерывания 153-238 тактов
'-------------------------------------------------------------------------------

    Принятый_код_символа_usart = Udr       ' Забираем содержимое аппаратного буфера USART

    If Принятый_код_символа_usart <> 13 Then       ' Проверяем, не является ли этот символ "Enter"
        Буфер_приема_usart_str = Буфер_приема_usart_str + Chr(принятый_код_символа_usart)       ' Если нет, то добавляем его в буфер принятого по USART сообщения
        Incr Счетчик_принятых_символов       ' Считаем количество принятых символов
      Else          ' Иначе выключаем приём и ставим метку, что приём закончен (принято всё сообщение), можно что-то делать с принятым
        Disable Urxc       ' Выключаем приём, пока не обработаем принятое сообщение
        Счетчик_принятых_символов = 0       ' Сбрасываем счётчик символов, готовим к следующему приёму
        Флаг_есть_принятое_сообщ_usart = 1       ' Если символ оказался "Enter", тогда флаг устанавливаем в 1. "Enter"- конец сообщения
    End If

'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Обработка_прерывания_timer1:       ' Время выполнения прерывания 138 тактов
'-------------------------------------------------------------------------------

    Incr Переменная_word       ' Увеличиваем переменную
    Флаг_было_прерывание_timer1 = 1       ' Ставим флаг

'-------------------------------------------------------------------------------
  Return
'===============================================================================

http://s8.uploads.ru/t/Qjow9.jpg

0

8

Мультипроцессорный USART, 9-ти битный, адресный  -  скачать

http://se.uploads.ru/t/u0Sx3.jpg

0

9

Atmega64 + USART0 (на прерываниях) + USART1 (на прерываниях)

Симуляция (Протеус 7.10) + исходник (Bascom 2.0.7.1) + Документация, реализация силами Bascom  -  скачать

http://sa.uploads.ru/t/FNEdG.jpg

Симуляция (Протеус 7.10) + исходник (Bascom 2.0.7.1) + Документация, реализация на ASM AVR  -  скачать

http://sa.uploads.ru/t/FNEdG.jpg

0

10

Связь по USART Atmega328P  -  скачать

http://sf.uploads.ru/t/HWt59.jpg

+1

11

Связь по USART Atmega8  -  скачать

+1

12

Обновление 30.01.2022

Связь по USART 4 х Atmega2560  -  Скачать с google disk
http://s1.uploads.ru/t/ivXzF.jpg http://s4.uploads.ru/t/uIA49.jpg

+3

13

Приём данных с ПК + Авто BootLoader

Исходник

$map
  $regfile = "m328pdef.dat"
  $crystal = 8000000
  $framesize = 128
  $hwstack = 128
  $swstack = 128

'===============================================================================
'                     Н А С Т Р О Й К А     USART_0
'===============================================================================
  Const Const_baud_usart_0 = 38400       ' Скорость трансляции USART_0

  Const Usart_0_const_size_buffer = 100       ' Размер буферов приёма и передачи, USART_0

  Config Com1 = Const_baud_usart_0 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0

'---------------  Обработчики прерываний USART_0  ------------------------------
  On Urxc Usart_0_input_data Nosave       ' Переход на подпрограмму обработки прерывания после окончания приёма данных по USART
  On Udre Usart_0_output_data Nosave       ' Переход на подпрограмму обработки прерывания после опустошения буфера передачи данных по USART
  On Utxc Usart_0_finish_output Nosave       ' Переход на подпрограмму обработки прерывания после окончания передачи данных по USART

'-----------------  Используемые переменные USART_0  ---------------------------
  Dim Usart_0_flag_resived_usart As Byte       ' Флаг сигнализирующий о том, что идёт приём по USART_0
  Dim Usart_0_flag_data_input As Byte       ' Флаг сигнализирующий о том, что приняты ноые данные по USART_0
  Dim Usart_0_flag_transmitted As Byte       ' Флаг сигнализирующий о том, что идёт передача по USART_0
  Dim Usart_0_count_transmitter As Byte       ' Считаем количество переданных символов по USART_0
  Dim Usart_0_count_received_symbols As Byte       ' Считаем количество принятых символов

  Dim Temp_usart_0_count_rxd_symbols As Byte       ' Временно считаем количество принятых символов

  Dim Usart_0_input_buffer_str As String * Usart_0_const_size_buffer
  Dim Usart_0_input_buffer_byte(usart_0_const_size_buffer) As Byte At Usart_0_input_buffer_str Overlay

  Dim Usart_0_output_buffer_str As String * Usart_0_const_size_buffer       ' Строковый буфер приёма USART_0

  Dim Usart_0_temp_rxd_str As String * Usart_0_const_size_buffer

'===============================================================================
'    И С П О Л Ь З У Е М Ы Е     С Л У Ж Е Б Н Ы Е     С И М В О Л Ы
'===============================================================================
  Dim Sumbol_set_str As String * 1 : Sumbol_set_str = "s"
  Dim Sumbol_get_str As String * 1 : Sumbol_get_str = "g"
  Dim Sumbol_boot_str As String * 1 : Sumbol_boot_str = "b"

  Dim Sumbol_set_byte As Byte At Sumbol_set_str Overlay
  Dim Sumbol_get_byte As Byte At Sumbol_get_str Overlay
  Dim Sumbol_boot_byte As Byte At Sumbol_boot_str Overlay : Sumbol_boot_byte = 123       'Стандартное значение BootLoader Bascom

  Dim Rxd_val_byte As Byte
  Dim Rxd_val_int As Integer
  Dim Rxd_val_word As Word
  Dim Rxd_val_long As Long

  Dim Rxd_val_byte_str As String * 3
  Dim Rxd_val_int_str As String * 6
  Dim Rxd_val_word_str As String * 5
  Dim Rxd_val_long_str As String * 10
  Dim Rxd_val_str As String * 50

'===============================================================================
'           И С П О Л Ь З У Е М Ы Е     П О Д П Р О Г Р А М М Ы
'===============================================================================
'            Подпрограмма   если 1 - ждём окончания передачи, иначе идём дальше, передача закончится автоматически
'                |    |             |   |    |                         |   |     |
  Declare Sub Print_usart_0(byval Copy_str_usart_0 As String * Usart_0_const_size_buffer , Byval Copy_byte_usart_0 As Byte)

'===============================================================================
          '  Разрешаем работу необходимых прерываний
'===============================================================================
  Enable Urxc       ' Разрешаем прерывания по приёму USART
'===============================================================================
          ' Разрешаем работу всех включенных прерываний
'===============================================================================
  Enable Interrupts
'===============================================================================
  Print_usart_0 "Start Program Atmega328P" , 1

'                   Г Л А В Н Ы Й         Ц И К Л
  Prime_cycle:
'===============================================================================

     If Usart_0_flag_data_input > 0 Then

         Gosub Processing_usart_0_input_buffer

         Goto Prime_cycle
     End If       'If Usart_0_flag_data_input > 0 Then



   Idle
'===============================================================================
  Goto Prime_cycle
End
'
'===============================================================================

'===============================================================================
  Processing_usart_0_input_buffer:
'-------------------------------------------------------------------------------
    If Usart_0_input_buffer_byte(1) = Sumbol_set_byte Then
        Gosub Set_parameter
        Goto Exit_proces_usart_0_input_buffer
    End If

    If Usart_0_input_buffer_byte(1) = Sumbol_get_byte Then
        Gosub Get_parameter
        Goto Exit_proces_usart_0_input_buffer
    End If

    If Usart_0_input_buffer_byte(1) = Sumbol_boot_byte Then
        Gosub Apply_bootloader
        Goto Exit_proces_usart_0_input_buffer
    End If

    If Mid(usart_0_input_buffer_str , 1 , 4) = "test" Then
        Print_usart_0 "Пакет принят" , 1
        Goto Exit_proces_usart_0_input_buffer
    End If

   Exit_proces_usart_0_input_buffer:
    Gosub Usart_0_clearing_buffer_receive
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Set_parameter:
'-------------------------------------------------------------------------------
    Rxd_val_byte_str = Mid(usart_0_input_buffer_str , 3 , 3)       'Забираем 3 символа начиная с 3 символа принятой строки
    Rxd_val_byte = Val(rxd_val_byte_str)

    'Rxd_val_int_str = Mid(usart_0_input_buffer_str , 3 , 6)       'Забираем 6 символов (знак+5-ти значное значение) начиная с 3 символа принятой строки
    'Rxd_val_int = Val(rxd_val_int_str)

    'Rxd_val_word_str = Mid(usart_0_input_buffer_str , 3 , 5)  'Забираем 5 символов (5-ти значное значение) начиная с 3 символа принятой строки
    'Rxd_val_word = Val(Rxd_val_word_str)

    'Rxd_val_long_str = Mid(usart_0_input_buffer_str , 3 , 8)  'Забираем 8 символов (знак+7-ми значное значение) начиная с 3 символа принятой строки
    'Rxd_val_long = Val(Rxd_val_long_str)

    'Rxd_val_int_str = Mid(usart_0_input_buffer_str , 3 , 50)  'Забираем 50 символов начиная с 3 символа принятой строки

'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Get_parameter:
'-------------------------------------------------------------------------------

'-------------------------------------------------------------------------------
  Return
'===============================================================================



'===============================================================================
  Usart_0_clearing_buffer_receive:
'-------------------------------------------------------------------------------
'    For Temp_usart_0_count_rxd_symbols = 1 To Usart_0_count_received_symbols
'        Usart_0_input_buffer_byte(Temp_usart_0_count_rxd_symbols) = 0
'    Next Temp_usart_0_count_rxd_symbols       'For Temp_usart_0_count_rxd_symbols = 1 To Usart_0_count_received_symbols

'    Usart_0_temp_rxd_str = ""
'    Usart_0_input_buffer_str = ""
'    Usart_0_count_received_symbols = 0       'Сбрасываем счётчик принятых символов USART_0
'    Usart_0_flag_data_input = 0

  '-------------------------------------------------------------------
  ' Аналог закомментированого фрагмента, работает значительно быстрее
  '-------------------------------------------------------------------
    !ldi R16 , 0
    !lds R17 , {Usart_0_count_received_symbols}
    Loadadr Usart_0_input_buffer_byte(1) , X

   Repeat_clear_buffer_rxd:
    !st X+ , R16
    !dec R17
    !brne Repeat_clear_buffer_rxd

    !sts {Usart_0_count_received_symbols} , R16
    !sts {Usart_0_flag_data_input} , R16

    Enable Urxc
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Sub Print_usart_0(byval Copy_str_usart_0 As String , Byval Copy_byte_usart_0 As Byte)
'-------------------------------------------------------------------------------
    Disable Urxc       'Запрещаем прерывания по прёму в USART_0

    Usart_0_flag_transmitted = 1       'Флаг сигнализирует о том, что идёт передача по USART_0
    Usart_0_output_buffer_str = Copy_str_usart_0 + Chr(13) + Chr(10)       'Добавляем к содержимому буфера команды конца строки и перевода каретки                      ' Забираем передаваемые данные в буфер передачи по USART_0

    Loadadr Usart_0_output_buffer_str , X
    !ld R16 , X

    !sts Udr0 , R16       'Закидываем в аппаратный буфер МК первый байт из буфера передачи

    Enable Udre       'Разрешаем прерывания, если UDR0 пуст, тем самым начиная передачу по USART_0
    Enable Utxc       'Разрешаем прерывания, по окончании передачи по USART_0

   'Если надо, ожидаем окончания трансляции, иначе выходим
    If Copy_byte_usart_0 > 0 Then
       Expect_end_of_transmission_0:
        If Usart_0_flag_transmitted > 0 Then
            nop
            Goto Expect_end_of_transmission_0
        End If       'If Usart_0_flag_transmitted > 0 Then
    End If       'If Copy_byte_usart_0 > 0 Then
'-------------------------------------------------------------------------------
  End Sub
'===============================================================================

'===============================================================================
  Usart_0_input_data:
'-------------------------------------------------------------------------------
    !Push R16
    !In R16 , Sreg
    !Push R16

    #if _romsize > 128000
        !in R16 , RAMPZ
        !Push R16
    #endif

    !push R17
    !push R26
    !push R27

    !IN R17 , UDR0

   'Проверка на BootLoader
    !cpi R17 , 123
    !BREQ Apply_bootloader       'Перейти если равно

   'Если не BootLoader принимаем все символы
    !ldi R16 , 1
    !sts {Usart_0_flag_resived_usart} , R16

    !cpi R17 , 13
    !BREQ Exit_input_data_usart

    !cpi R17 , 10
    !BRNE Input_sumbol

    !lds R16 , Ucsr0b
    !andi R16 , &B_0111_1111
    !sts Ucsr0b , R16

    !ldi R16 , 0
    !sts {Usart_0_flag_resived_usart} , R16
    !ldi R16 , 1
    !sts {Usart_0_flag_data_input} , R16
    !rjmp Exit_input_data_usart

   Input_sumbol:
    Loadadr Usart_0_input_buffer_str , X
    !lds R16 , {usart_0_count_received_symbols}
    !add R26 , R16
    !clr R16
    !adc R27 , R16

    !ST X , R17

    !lds R16 , {Usart_0_count_received_symbols}
    !inc R16
    !sts {Usart_0_count_received_symbols} , R16

   Exit_input_data_usart:

    !pop R27
    !pop R26
    !pop R17

    #if _romsize > 128000
        !pop R16
        !out RAMPZ  , R16
    #endif

    !pop R16
    !Out Sreg , R16
    !Pop R16

    !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================
  Apply_bootloader:
'-------------------------------------------------------------------------------
    Config Watchdog = 16
    Reset Watchdog
    Start Watchdog

    Wait 1
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Usart_0_output_data:
'-------------------------------------------------------------------------------
    !Push R16
    !In R16 , Sreg
    !Push R16

    #if _romsize > 128000
        !in R16 , RAMPZ
        !Push R16
    #endif

    !push R26
    !push R27

    !lds R16 , {Usart_0_count_transmitter}
    !inc R16
    !sts {Usart_0_count_transmitter} , R16

    Loadadr Usart_0_output_buffer_str , X
    !add R26 , R16
    !clr R16
    !adc R27 , R16

    !ld R16 , X
    !cpi R16 , 0
    !BRNE Transmitter_sumbol

    !lds R16 , Ucsr0b
    !andi R16 , &B_1101_1111
    !sts Ucsr0b , R16

    !rjmp Exit_transmitter_data_usart

   Transmitter_sumbol:
    !sts udr0 , R16

   Exit_transmitter_data_usart:
    !pop R27
    !pop R26

    #if _romsize > 128000
        !pop R16
        !out RAMPZ  , R16
    #endif

    !pop R16
    !Out Sreg , R16
    !Pop R16

    !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Usart_0_finish_output:
'-------------------------------------------------------------------------------
    !Push R16
    !In R16 , Sreg
    !Push R16

    !Push R17
    !Push R26
    !Push R27

    #if _romsize > 128000
        !in R16 , RAMPZ
        !Push R16
    #endif

    !lds R16 , Ucsr0b
    !andi R16 , &B_1011_1111
    !sts Ucsr0b , R16

    !lds R16 , Ucsr0b
    !ori R16 , &B_1000_0000
    !sts Ucsr0b , R16

    !ldi R16 , 0
    !lds R17 , {Usart_0_count_transmitter}
    Loadadr Usart_0_output_buffer_str , X

   Usart_0_finish_output_1:
    !st X , R16
    !dec R17
    !brne Usart_0_finish_output_1

    !sts {Usart_0_count_transmitter} , R16
    !sts {Usart_0_flag_transmitted} , R16

   Exit_usart_0_finish_output:

    #if _romsize > 128000
        !pop R16
        !out RAMPZ  , R16
    #endif

    !pop R27
    !pop R26
    !pop R17

    !pop R16
    !Out Sreg , R16
    !Pop R16

    !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================

+3

14

Atbanned28 + USART0 + USART1 + Авто BootLoader ( при условии использования стандартного BootLoadera Bascom, проверка в приёмнике USART0 на значение "123")

Гоняют друг другу данные

Симуляция + исходники  -  скачать

http://s7.uploads.ru/t/YHZ0s.jpg

+3