Исследование USART
! Исследование USART !
Сообщений 1 страница 14 из 14
Поделиться22014-01-18 05:57:03
Связь Atmega328P и Atmega32 по UART
Данные с АЦП Atmega328P передаются на Atmega32 и отображаются на LCD
Симуляция в Протеус 7.10 sr0 + исходники Bascom 2.0.7.1 - скачать
Поделиться32014-01-20 17:50:22
Передача с компьютера в МК через переходник COM ==> USB по USART
Симуляция в Протеус 7.10 sr0 + исходники Bascom 2.0.7.1 + программа терминал для OS Windows - скачать
Снимок экрана
Поделиться42014-02-06 23:07:34
Доброго здоровья!
В качестве эксперимента делал обмен по USART между двумя Atmega328.
В качастве помехи, включал шимы (12 шт.) с максимальной частотой, использовал аппаратный USART на прерываниях.
Всё отлично работает в обе стороны.
Симуляция в Протеус 7.10 sr0 + исходники Bascom 2.0.7.1 - скачать
Поделиться52014-02-16 10:10:03
Приём по 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 * 2On Urxc Принятые_данные_usart ' Переход на подпрограмму обработки прерывания после окончания приёма данных по USART
'-------------------- Используемые переменные --------------------------------
Dim Счетчик_принятых_символов As Byte
Dim Принятый_код_символа_usart As Byte
Dim Буфер_приема_usart_str As String * 20
Dim Флаг_есть_принятое_сообщ_usart As Byte'-------------- Разрешаем работу необходимых прерываний ----------------------
Enable Urxc
'------------ Разрешаем работу всех включенных прерываний --------------------
Enable Interrupts ' Разрешаем работу прерываний
'===============================================================================
' Г Л А В Н Ы Й Ц И К Л
'===============================================================================
Главный_цикл:
nopIf Флаг_есть_принятое_сообщ_usart = 1 Then
Флаг_есть_принятое_сообщ_usart = 0 ' Сбрасываем флаг
Print "Принято - " ; Буфер_приема_usart_str ' Передаём то, что приняли
Буфер_приема_usart_str = "" ' Чистим буфер приёма
Enable Urxc ' Включаем приём
End Ifnop
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
'===============================================================================
Поделиться62014-02-26 10:53:07
Выкладываю сей код, в него добавлена строка и для передачи по УАРТ.
$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 * 2On 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 Pulse0Enable Timer1
Start Timer1'---------Переменные-------------------------------------
Dim A As Integer
A = 0'------------ Разрешаем работу всех включенных прерываний --------------------
Enable Interrupts ' Разрешаем работу прерываний
'===============================================================================
' Г Л А В Н Ы Й Ц И К Л
'===============================================================================
Главный_цикл:
Locate 2 , 1 : Lcd A
Locate 1 , 1 : Lcd Буфер_приема_usart_strIf Флаг_есть_принятое_сообщ_usart = 1 Then
Флаг_есть_принятое_сообщ_usart = 0 ' Сбрасываем флаг
'Print "Принято - " ; Буфер_приема_usart_str ' Передаём то, что приняли
Буфер_приема_usart_str = "" ' Чистим буфер приёма
Enable Urxc ' Включаем приём
End IfGoto Главный_цикл
End
'===============================================================================
' П О Д П Р О Г Р А М М Ы
'===============================================================================Принятые_данные_usart:
Принятый_код_символа_usart = Udr ' Забираем содержимое аппаратного буфера USARTIf Принятый_код_символа_usart <> 13 Then ' Проверяем, не является ли этот символ "Enter"
Буфер_приема_usart_str = Буфер_приема_usart_str + Chr(принятый_код_символа_usart) ' Если нет, то добавляем его в буфер принятого по USART сообщения
Incr Счетчик_принятых_символов ' Считаем количество принятых символов
Else ' Иначе выключаем приём и ставим метку, что приём закончен (принято всё сообщение), можно что-то делать с принятым
Disable Urxc ' Выключаем приём, пока не обработаем принятое сообщение
Счетчик_принятых_символов = 0 ' Сбрасываем счётчик символов, готовим к следующему приёму
Флаг_есть_принятое_сообщ_usart = 1 ' Если символ оказался "Enter", тогда флаг устанавливаем в 1. "Enter"- конец сообщения
End If'-------------------------------------------------------------------------------
ReturnPulse0:
A = A + 1Print A ; 'тут главное поставить точку с запятой
Printbin 13 'а это самое главное, т.к. предыдущее отключает спецсимволы, то добавляем нужные(CR) в ручном режиме
Return
Помогла вот эта статья
В итоге индикация и счёт идёт нормально, ничего не заезжает и нет лишних символов.
Поделиться72014-03-02 06:42:58
Прием и передача по USART на прерываниях - скачать
'===============================================================================
$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.3Initlcd ' Инициализируем 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
#endifStop Timer1
Timer1 = 0
Dim Флаг_было_прерывание_timer1 As Byte'-------------------- Используемые переменные --------------------------------
Dim Цикл As Byte
Dim Переменная_word As Word
Dim Флаг_буфер_uart_пуст As Byte
Dim Флаг_есть_принятое_сообщ_usart As ByteDim Буфер_lcd_str As String * 20
Dim Номер_символа As Byte
Dim Счетчик_принятых_символов As Byte
Dim Принятый_код_символа_usart As ByteDim Буфер_приема_usart_byte(20) As Byte
Dim Буфер_приема_usart_str As String * 20 At Буфер_приема_usart_byte(1) OverlayDim Буфер_передачи_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") ' Форматируем переменную, для корректного вывода на LCDEnable Udre ' Включаем прерывание, тем самым начиная передачу
Locate 1 , 1 ' Определяем номер строки и знакоместа
Lcd Буфер_lcd_str ' Выводим переменную на LCDФлаг_было_прерывание_timer1 = 0 ' Скидываем флаг
Goto Главный_цикл ' Проверяем, может ещё что-нибудь надо сделать
End IfIf Флаг_есть_принятое_сообщ_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 Ifsleep
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
'===============================================================================
Поделиться82014-08-09 07:24:39
Мультипроцессорный USART, 9-ти битный, адресный - скачать
Поделиться102016-09-25 21:01:15
Связь по USART Atmega328P - скачать
Поделиться112016-09-25 21:11:56
Связь по USART Atmega8 - скачать
Поделиться122016-09-26 12:06:02
Обновление 30.01.2022
Связь по USART 4 х Atmega2560 - Скачать с google disk

Поделиться132018-03-31 03:17:49
Приём данных с ПК + Авто BootLoader
$map
$regfile = "m328pdef.dat"
$crystal = 8000000
$framesize = 128
$hwstack = 128
$swstack = 128'===============================================================================
' Н А С Т Р О Й К А USART_0
'===============================================================================
Const Const_baud_usart_0 = 38400 ' Скорость трансляции USART_0Const 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 OverlayDim 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 BascomDim Rxd_val_byte As Byte
Dim Rxd_val_int As Integer
Dim Rxd_val_word As Word
Dim Rxd_val_long As LongDim 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 ThenIdle
'===============================================================================
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 IfIf Usart_0_input_buffer_byte(1) = Sumbol_get_byte Then
Gosub Get_parameter
Goto Exit_proces_usart_0_input_buffer
End IfIf Usart_0_input_buffer_byte(1) = Sumbol_boot_byte Then
Gosub Apply_bootloader
Goto Exit_proces_usart_0_input_buffer
End IfIf Mid(usart_0_input_buffer_str , 1 , 4) = "test" Then
Print_usart_0 "Пакет принят" , 1
Goto Exit_proces_usart_0_input_buffer
End IfExit_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) , XRepeat_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} , R16Enable Urxc
'-------------------------------------------------------------------------------
Return
'==============================================================================='===============================================================================
Sub Print_usart_0(byval Copy_str_usart_0 As String , Byval Copy_byte_usart_0 As Byte)
'-------------------------------------------------------------------------------
Disable Urxc 'Запрещаем прерывания по прёму в USART_0Usart_0_flag_transmitted = 1 'Флаг сигнализирует о том, что идёт передача по USART_0
Usart_0_output_buffer_str = Copy_str_usart_0 + Chr(13) + Chr(10) 'Добавляем к содержимому буфера команды конца строки и перевода каретки ' Забираем передаваемые данные в буфер передачи по USART_0Loadadr 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_usartInput_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} , R16Exit_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 WatchdogWait 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} , R16Loadadr 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 , R16Exit_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 , XUsart_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} , R16Exit_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
'===============================================================================
Поделиться142019-03-04 09:54:47
Atbanned28 + USART0 + USART1 + Авто BootLoader ( при условии использования стандартного BootLoadera Bascom, проверка в приёмнике USART0 на значение "123")
Гоняют друг другу данные
Симуляция + исходники - скачать











