Добрый вечер всем товарищи возникла нужда управлять нагрузками с ПК взял Atmega16 и начал прикошачивать е к ПК почитал про UART написал некую ерись на асме просьба сильно не издеваться асм сложный язык а я учусь В общем нуждаюсь в помощи с программой для МК прокомментируйте мой код где и что нужно сделать по другому и как это сделать всем откликнувшимся буду благодарен за помощь и конструктивную критику ниже привожу код на асме
Код:
;################################ ;## USART блок для связи мк ATmega16 ## ;## с PC кварцевый генератор 8 мгц ## ;## alexval2006. г.Валуйки 30/05/2010г ## ;###############################
;---------- Псевдокоманды управления ---------- .include "m16def.inc" ; Присоединение файла описаний .list ; Включение листинга .def temp = R16 .def byte_res = R17 .def byte_count = R18 .def t0 = R19 .def temp1 = R20 ;---------- Определение констант ---------- ;.equ adres = 0x01 ;---------- Определение констант UART ---------- .equ XTAL = 8000000 .equ baudrate = 9600 .equ bauddivider = XTAL/(16*baudrate)-1 ;---------- Макрос для передачи текста в ПК ---------- .MACRO putc ldi temp,@0 rcall uart_snt ; вызываем подпрограмму передачи данных по UART. .ENDMACRO .cseg ;---------- Прерывания ---------- rjmp init ; сброс reti ;EXT_INT0 ; IRQ0 Handler reti ;EXT_INT1 ; IRQ1 Handler reti ;TIM2_COMP ; Timer2 Compare Handler reti ;TIM2_OVF ; Timer2 Overflow Handler reti ;TIM1_CAPT ; Timer1 Capture Handler reti ;TIM1_COMPA ; Timer1 CompareA Handler reti ;TIM1_COMPB ; Timer1 CompareB Handler reti ;TIM1_OVF ; Timer1 Overflow Handler reti ;TIM0_OVF ; Timer0 Overflow Handler reti ;SPI_STC ; SPI Transfer Complete Handler rjmp UART_RXC ; Прерывание по приёму байта по UART reti ;USART_UDRE ; UDR Empty Handler прерывание по опустошению регистра UDR reti ;USART_TXC ; USART TX Отправлен байт по USART reti ;ADC ; ADC Conversion Complete Handler reti ;EE_RDY ; EEPROM Ready Handler reti ;ANA_COMP ; Analog Comparator Handler reti ;TWSI ; Two-wire Serial Interface Handler reti ;EXT_INT2 ; IRQ2 Handler reti ;TIM0_COMP ; Timer0 Compare Handler reti ;SPM_RDY ; Store Program Memory Ready Handler
;---------- Цикл ожиданя прерывания по приёму байта на UART ---------- MAIN: rjmp MAIN ;---------- Обработка прерывания по событию “ПРИЕМ БАЙТА” через UART ---------- UART_RXC: ;IN R21,SREG ;Достали SREG в R21 M02: sbis UCSRA, RXC ;Проверяем бит RXC в регистре UCSRA rjmp M02 ;Если установлен переходим на метку M02 in temp, UDR ;Сохраняем полученный символ (Чтение порта) ;sbis UCSRA,FE ;Проверяем на наличие ошибки кадра ;rjmp Exit ;---------- Адрес приёмника ---------- cpi temp, 0x01 ;Сравниваем с кодом 0x14 breq PC_cmd0 rjmp M01 ;---------- Определяю тип команды и выполняю соответствующее действие ---------- PC_cmd0: cpi temp,0xff brne PC_cmd1 rjmp M0 ;---------- PC_cmd1: cpi temp,0x01 brne PC_cmd2 rjmp M1 PC_cmd2: cpi temp,0x02 brne PC_cmd3 rjmp M2 PC_cmd3: cpi temp,0x03 brne PC_cmd4 rjmp M3 PC_cmd4: cpi temp,0x04 brne PC_cmd5 rjmp M4 PC_cmd5: cpi temp,0x05 brne PC_cmd6 rjmp M5 PC_cmd6: cpi temp,0x06 brne PC_cmd7 rjmp M6 PC_cmd7: cpi temp,0x07 brne PC_cmd8 rjmp M7 PC_cmd8: cpi temp,0x08 brne PC_cmd9 rjmp M8 PC_cmd9: cpi temp,0x09 brne PC_cmd10 rjmp M9 PC_cmd10: cpi temp,0x0A brne PC_cmd11 rjmp M10 PC_cmd11: cpi temp,0x0B brne PC_cmd12 rjmp M11 PC_cmd12: cpi temp,0x0C brne PC_cmd13 rjmp M12 PC_cmd13: cpi temp,0x0D brne PC_cmd14 rjmp M13 PC_cmd14: cpi temp,0x0E brne PC_cmd15 rjmp M14 PC_cmd15: cpi temp,0x0F brne PC_cmd16 rjmp M15 PC_cmd16: cpi temp,0x10 brne PC_cmd17 rjmp M16 PC_cmd17: cpi temp,0x11 brne PC_cmd18 rjmp M17 PC_cmd18: cpi temp,0x12 brne PC_cmd19 rjmp M18 PC_cmd19: cpi temp,0x13 brne PC_cmd20 rjmp M19 PC_cmd20: cpi temp,0x14 brne M01 rjmp M20 ;---------- M0: clr temp1 out PORTA, temp1 ;Тушим все светодиоды по приходу кода FF out PORTB, temp1 ;Тушим все светодиоды по приходу кода FF out PORTC, temp1 ;Тушим все светодиоды по приходу кода FF rjmp M01 ;---------- M1: sbi PORTA, 0 ;Зажигаем светодиод по приходу данных rjmp M01 M2: sbi PORTA, 1 ;Зажигаем светодиод по приходу данных rjmp M01 M3: sbi PORTA, 2 ;Зажигаем светодиод по приходу данных rjmp M01 M4: sbi PORTA, 3 ;Зажигаем светодиод по приходу данных rjmp M01 M5: sbi PORTA, 4 ;Зажигаем светодиод по приходу данных rjmp M01 M6: sbi PORTA, 5 ;Зажигаем светодиод по приходу данных rjmp M01 M7: sbi PORTA, 6 ;Зажигаем светодиод по приходу данных rjmp M01 M8: sbi PORTA, 7 ;Зажигаем светодиод по приходу данных rjmp M01 ;---------- M9: sbi PORTB, 0 ;Зажигаем светодиод по приходу данных rjmp M01 M10: sbi PORTB, 1 ;Зажигаем светодиод по приходу данных rjmp M01 M11: sbi PORTB, 2 ;Зажигаем светодиод по приходу данных rjmp M01 M12: sbi PORTB, 3 ;Зажигаем светодиод по приходу данных rjmp M01 M13: sbi PORTB, 4 ;Зажигаем светодиод по приходу данных rjmp M01 M14: sbi PORTB, 5 ;Зажигаем светодиод по приходу данных rjmp M01 M15: sbi PORTB, 6 ;Зажигаем светодиод по приходу данных rjmp M01 M16: sbi PORTB, 7 ;Зажигаем светодиод по приходу данных rjmp M01 ;---------- M17: sbi PORTC, 0 ;Зажигаем светодиод по приходу данных rjmp M01 M18: sbi PORTC, 1 ;Зажигаем светодиод по приходу данных rjmp M01 M19: sbi PORTC, 2 ;Зажигаем светодиод по приходу данных rjmp M01 M20: sbi PORTC, 3 ;Зажигаем светодиод по приходу данных rjmp M01 ;---------- ;А на выходе вернем все как было. ;Достаем в обратном порядке Exit: ;OUT SREG, r21 RETi ;Спокойно выходим. Регистры вернул как было. ;---------- M03: M01: sei ;Разрешение прерываний rjmp main ;---------- Инициализация ---------- init: cli ;Общий запрет прерываний ;---------- Инициализация стека ---------- ldi temp,high(RAMEND) out SPH,temp ldi temp,low(RAMEND) out SPL,temp ;Запрет прерываний ;---------- Инициализация портов В.В. ---------- ldi temp, 0xFF ;Настраиваем порт A out DDRA, temp ldi temp, 0x00 out PORTA, temp
ldi temp, 0xFF ;Настраиваем порт B out DDRB, temp ldi temp, 0x00 out PORTB, temp
ldi temp, 0xFF ;Настраиваем порт С out DDRC, temp ldi temp, 0x00 out PORTC, temp ;---------- Инициализация UART ---------- uart_init: LDI R16, low(bauddivider) OUT UBRRL, temp LDI R16, high(bauddivider) OUT UBRRH, temp LDI R16,0 OUT UCSRA, temp LDI temp, (1<<RXEN)|(1<<TXEN)|(1<<RXCIE)|(0<<TXCIE) ;Прерывания запрещены, прием-передача разрешен. OUT UCSRB, temp LDI temp, (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1) ;Формат кадра - 8 бит, пишем в регистр UCSRC, за это отвечает бит селектор OUT UCSRC, temp ;---------- clr temp ;Очищяем регистр temp putc 'H' ;Приветствие, мол коннект успешен и усарт работает putc 'e' putc 'l' putc 'l' putc 'o' putc ',' putc ' ' putc 'm' putc 'y' putc ' ' putc 'n' putc 'a' putc 'm' putc 'e' putc ' ' putc 'i' putc 's' putc ' ' putc 'A' putc 'l' putc 'e' putc 'x' putc 0x0D ;putc 0x0A rjmp m01 ;***************************************************************************************************************************** ;---------- Передача символа на ПК ---------- UART_TXC : LDI temp, 'A' ;Загоняем в регистр код буквы RCALL uart_snt LDI temp, 'l' ;Загоняем в регистр код буквы RCALL uart_snt LDI temp, 'e' ;Загоняем в регистр код буквы RCALL uart_snt LDI temp, 'x' ;Загоняем в регистр код буквы RCALL uart_snt LDI temp, 0x0D ;Загоняем в регистр код 0x0D RCALL uart_snt rjmp M01 ;---------- Процедура отправки байта ---------- uart_snt: SBIS UCSRA,UDRE ;Пропуск если нет флага готовности RJMP uart_snt ;Ждем готовности - флага UDRE OUT UDR, temp ;Шлем байт! RET ;*****************************************************************************************************************************
Не претендую на абсолют и уж тем более внимательное разбирательство. Зачем такая запутанность? Ведь гораздо приятнее смотреть на файл в последовательности. Например заполнили кусок с векторами прерываний, поставили метку "старт" или "ресет" и начали инициировать стек, настраивать порты, периферию... Закончили это муторное дело, даем команду разрешения прерываний и пошла метка основного цикла "майн". В майне при необходимости вызываем подпрограммы, что то ворочаем. За майном описали эти подпрограммы (если есть они). За подпрограммами делаем кусок для обработки прерываний. (Я во всяком случае делаю так). Тогда программа хоть читабельна. Тут честно говоря задолбался скакать сверху-вниз и поперек. PS. Могу кинуть в кусок программы на асме для меги16. Если надо - пишите в личку
_________________ Загружая на вход компьютера "мусор", на выходе получим "мусор^32". PS. Не работаю с: Proteus, Multisim, EWB, Micro-Cap... не спрашивайте даже
А может стоит на чем нибудь попроще писать, на Си например...
я просил помощи по программе на ассемблере а не совета на чем легче программировать я поставил себе цель освоить асм и не намерен отступать от неё с си я общялся некоторое время но асм это более оптимальная вешь Meteor признаю корявости много, буду признателен за примеры на асме как это всё лучше реализовать
Заголовок сообщения: Re: Atmega16+UART+PC помощь с программой для МК
Добавлено: Пн май 31, 2010 17:51:12
Первый раз сказал Мяу!
Зарегистрирован: Пт мар 19, 2010 18:07:16 Сообщений: 33
Рейтинг сообщения:0
alexval2006 , для начала составьте алгоритм работы Вашей проги. Так Вы не запутаетесь в написании проги и у Вас будет меньше ошибок. Затем прогоняйте прогу в протеусе. Также советую ити от простого к сложному:сначала отладьте прием байтов по UART, затем приделайте одну нагрузку и попробуйте ней поуправлять. А потом можно будет подключать столько нагрузок, сколько Вам нужно. Не стремитесь сделать все сразу. Кстати, софт на ПК удобно писать в HiAsm. Если будут вопросы, пишите мне в личку.
С протеусом дружу давно и отлажую в нём прежде чем перейти к конечной отладке в железе это не первая моя программа для мк просто с UART в первые подружился. С UART я добился успеха в приеме передаче байта но одного кода сразу шлю два байта последовательно прога не успевает походу не знаю как лучше сделать наверно надо или буфер какой то городить или даже не знаю. На щет алгоритма подумаю но я и так в этой проге не путаюсь она ничтожно мала и приметивна до безобразия, просто у меня проблемы с оптимизацией кода работает но коряво хотелось бы лучше да и не все задуманное получилось С HiAsm знаком но остановился на Pure basic мне он больше по душе для написания разного мелкого софта для пк.
Заголовок сообщения: Re: Atmega16+UART+PC помощь с программой для МК
Добавлено: Пн май 31, 2010 18:40:27
Первый раз сказал Мяу!
Зарегистрирован: Пт мар 19, 2010 18:07:16 Сообщений: 33
Рейтинг сообщения:0
Цитата:
С UART я добился успеха в приеме передаче байта но одного кода сразу шлю два байта последовательно прога не успевает походу не знаю как лучше сделать наверно надо или буфер какой то городить или даже не знаю.
Не надо никакого буфера. У меня тоже такое было. При передаче символов нужно вставить паузу.
Кстати, какая структуза сообщения? Может, Вы много времени тратите на обработку первого байта. Или прога пропускает первый байт и потом все время глючит. Пришлите мне, что Вы шлете на МК, и я помогу сделать Вам алгоритм.
Цитата:
На щет алгоритма подумаю но я и так в этой проге не путаюсь она ничтожно мала и приметивна до безобразия
А алгоритмом не пренебрегайте. Даже если прога простая, Вы можете неправильно написать код со всеми вытекающими последствиями(проверено на личном опыте).
Отсылаю три байта последовательно ничего особенного со скоростью 9600 ну к примеру 0x01, 0x02, 0x03 каждый зажигает назначенный ему светодиод Я тут вспомнил делал как то в одном устройстве прием инфы с компа по UART писал на Си ставил задержку межу принимаемыми байтами 25ms пахало нормально надо наверно и здесь сварганить нечто похожее
Заголовок сообщения: Re: Atmega16+UART+PC помощь с программой для МК
Добавлено: Пн май 31, 2010 23:06:03
Мучитель микросхем
Зарегистрирован: Вс янв 07, 2007 01:45:48 Сообщений: 491 Откуда: Российская Федерация, будь она неладна...
Рейтинг сообщения:0
Если адреса у устройства нет, и ни каково контроля целостности тоже (что не есть гуд), то самое простое сделать примерно так:
Код:
UA_RX: in r16, UDR ;Читаем байт in r17, PORTx ;Читаем порт sbrc r16, 7 ;Если бит 7 принятого байта установлен, переход на ON, если нет - OFF rjmp ON OFF: com r16 ;Инвертируем принятый байт and r17, r16 ;Лог. И out PORTx, r17 ;Вывод в порт reti ;Выход ON: or r17, r16 ;Лог. ИЛИ out PORTx, r17 ;Вывод в порт reti ;Выход
Работает так: Принимаем байт, если бит 7 установлен - то выбранную линию надо вкл., если сброшен - то выкл. Линия выбирается путём установки соответствующего бита. На пример: отсылаем 0b10000001 - Вкл. линию 0; 0b10000010 - Вкл. линию 1;
0b00000001 - Выкл. линию 0; 0b00000010 - Выкл. линию 1;
Код писал на ходу, не проверял, но вроде так.
_________________ Научить нельзя, можно научиться. Пифагор. Вставь недостающие буквы в слово *у*ня. Если у тебя получилось слово кухня, значит ты интеллигентный человек.
Да работать должно я делал похожую конструкцию в сду, адресацию я делал неполучилось походу все дело в задержках. По идее надо добавить щетчик принятых байт в посылке их 3 и задержки между байтами около 25-50ms 1байт адрес устройства второй номер канала а третий пока проигнорировать (резерв) CRC позже без нее мороки много
Заголовок сообщения: Re: Atmega16+UART+PC помощь с программой для МК
Добавлено: Вт июн 01, 2010 08:20:39
Мучитель микросхем
Зарегистрирован: Вс янв 07, 2007 01:45:48 Сообщений: 491 Откуда: Российская Федерация, будь она неладна...
Рейтинг сообщения:0
И без задержек работать должно. (у меня работало).
_________________ Научить нельзя, можно научиться. Пифагор. Вставь недостающие буквы в слово *у*ня. Если у тебя получилось слово кухня, значит ты интеллигентный человек.
Заголовок сообщения: Re: Atmega16+UART+PC помощь с программой для МК
Добавлено: Вт июн 01, 2010 09:15:57
Поставщик валерьянки для Кота
Карма: 2
Рейтинг сообщений: 11
Зарегистрирован: Пт май 23, 2008 19:32:22 Сообщений: 2401 Откуда: Россия, Волгоград
Рейтинг сообщения:0 Медали: 1
Пожалуй я тоже отмечусь в теме, т.к. являюсь приверженцем asm'а. 1. оно же самое главное - посмотри на свою таблицу векторов прерываний у м16 вектора 2-х словные, и при таком задании ты никогда не попадешь на UART_RXC, по всей видимости таблица сгенерирована VMLab, поэтому очень рекомендую для задания векторов прерываний использовать конструкцию:
Код:
.org <Имя прерывания> (из файла m16def.inc) jmp <метка обработчик> (ну или reti)
и жизнь станет намного проще....
пы сы Ну и напоследок - стиль написания это просто жесть Послушай Meteor'а, дядька дело говорит
_________________ Чем дальше, тем больше становлюсь занудой...
Мяу, GP1! Состарил ты меня , хорошо хоть на пенсию не списал
Цитата:
за прерывания спасибо а то в нете нашол а хрен знает откуда они
А если открыть даташит и скопировать? В разделе Interrupts они хорошо приведены.
_________________ Загружая на вход компьютера "мусор", на выходе получим "мусор^32". PS. Не работаю с: Proteus, Multisim, EWB, Micro-Cap... не спрашивайте даже
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения