Здравствуйте, уважаемые пользователи форума!
Имеется (в теории): ATxmega128A1, датчик давления в выходом на 0-5В, драйвер RS-232 (ADM202), Zigbee (AT86RF230).
Задача: Соединить это всё. Напряжение с датчика давления подаётся на АЦП в МК, с МК раздаётся на RS-232 и Zigbee.
Zigbee через SPI. RS-232 через USART и работает для прошивки МК.
Перелопатил мануалы. Вот что получилось.
.include "m128def.inc"
.org $0000
rjmp INIT ;Переход на секцию инициализации
.org $000E
rjmp ADC_Complete ;Прерывание от АЦП
.org $0030
;==================
;Обработчик прерывания:
ADC_Complete:
in r17,ADCH
reti
;==================
;Одна большая инициализация
INIT:
;Инициализация стека:
ldi r16,low(RAMEND)
out SPL,r16
ldi r16,high(RAMEND)
out SPH,r16
;Инициализация АЦП:
ldi r16,0x00
out admux,r16
ldi r16,0b10111110
out ADCSRA,r16
;Инициализация SPI как MASTER
SPI_MasterInit:
; Установка MOSI и SCK на вывод, все остальные на ввод
ldi r17,(1<<DDC5)|(1<<DDC7)
out DDRC,r17
; Разрешение SPI в режиме мастера, установка скорости связи fck/16
ldi r17,(1<<SPE)|(1<<MSTR)|(1<<SPR0)
out SPCR,r17
ret
;параметры скорости записаны в r16, r17
ldi r16, low(0x33)
ldi r17, high(0x33)
USART_Init:
; Установка скорости связи
out UBRRH, r17
out UBRRL, r16
; Разрешение работы приемника и передатчика
ldi r16, (1<<RXEN)|(1<<TXEN)
out UCSRB,r16
; Установка формата посылки: 8 бит данных, 2стоп-бита
ldi r16, (1<<USBS)|(3<<UCSZ0)
out UCSRC,r16
ret
proga:
USART_Transmit:
; Ожидание освобождения буфера передатчика
sbis UCSRA,UDRE
rjmp USART_Transmit
; Помещение данных (r17) в буфер, отправка данных
out UDR,r17
ret
USART_Receive:
; Ожидание окончания приема данных
sbis UCSRA, RXC
rjmp USART_Receive
; Загрузка принятых данных из буфера
in r16, UDR
ret
SPI_MasterTransmit:
; Запуск передачи данных (r16)
out SPDR,r17
Wait_Transmit:
; Ожидание завершения передачи данных
sbis SPSR,SPIF
rjmp Wait_Transmit
ret
rjmp proga
Будет ли правильно работать?
Заранее благодарю.
ATxmega128A1: Имеет ли право на жизнь прог-ма
- Реклама
- Engineer_Keen
- Друг Кота
- Сообщения: 3872
- Зарегистрирован: Пт янв 29, 2010 10:27:40
- Откуда: Москва
Re: ATxmega128A1: Имеет ли право на жизнь прог-ма
Не будет, без некоторых переделок.
1) Inc-файл от меги128, у вас Xmega, это совершенно разные контроллеры (честно говоря даже не знаю где взять инк от ИКС-меги)
2) По всему коду куча не нужных ret. Ret ставится в конце подпрограммы, а у вас они и в инициализации и в главном цикле. Впечатление, что куски надергали из разных примеров то ли невнимательно, то ли без понимания. Либо уберите, либо оформляйте эти блоки отдельными процедурами и вызывайте из основной программы через Rcall.
3) Прерывания (АЦП) не разрешены (нет SEI в инициализации).
4) В SPI точно не нужна линия CS? (посмотрел ДШ на RF230 - нужна, там называется SEL)
5) Исходя из логики программы (при условии, если бы она работала), получается что МК
- постоянно передает последнее значение АЦП в UART и SPI (USART_Transmit, SPI_MasterTransmit). Зачем постоянно передавать? АЦП сработало - передаем, потом ждем.
- постоянно принимает данные из UART и ничего с ними не делает(USART_Receive). Зачем? Если для будущих целей управления, то сделать по прерыванию.
6) Скорее всего ZigBee еще надо инициализировать какими-то настройками, ДШ влом подробно читать...
Главное решить с первым вопросом. В случае, если у вас все-таки просто MEGA, нужно просто обработать код напильником (кстати оформляйте вложением, раз он такой длинный). А если XMEGA, то не знаю, сам только описание мельком читал, но там и таблица прерываний другая и регистры по-другому называются.
1) Inc-файл от меги128, у вас Xmega, это совершенно разные контроллеры (честно говоря даже не знаю где взять инк от ИКС-меги)
2) По всему коду куча не нужных ret. Ret ставится в конце подпрограммы, а у вас они и в инициализации и в главном цикле. Впечатление, что куски надергали из разных примеров то ли невнимательно, то ли без понимания. Либо уберите, либо оформляйте эти блоки отдельными процедурами и вызывайте из основной программы через Rcall.
3) Прерывания (АЦП) не разрешены (нет SEI в инициализации).
4) В SPI точно не нужна линия CS? (посмотрел ДШ на RF230 - нужна, там называется SEL)
5) Исходя из логики программы (при условии, если бы она работала), получается что МК
- постоянно передает последнее значение АЦП в UART и SPI (USART_Transmit, SPI_MasterTransmit). Зачем постоянно передавать? АЦП сработало - передаем, потом ждем.
- постоянно принимает данные из UART и ничего с ними не делает(USART_Receive). Зачем? Если для будущих целей управления, то сделать по прерыванию.
6) Скорее всего ZigBee еще надо инициализировать какими-то настройками, ДШ влом подробно читать...
Главное решить с первым вопросом. В случае, если у вас все-таки просто MEGA, нужно просто обработать код напильником (кстати оформляйте вложением, раз он такой длинный). А если XMEGA, то не знаю, сам только описание мельком читал, но там и таблица прерываний другая и регистры по-другому называются.
Re: ATxmega128A1: Имеет ли право на жизнь прог-ма
Ошибки усвоил. Только вот по поводу 5ого пункта есть вопросы: "АЦП сработало - передаем, потом ждем." и "Если для будущих целей управления, то сделать по прерыванию." как это организовать? моих знаний пока на это не хватает. Вчера поставил новую AVR Studio 5, там есть для Хмега inc-файл. Вся прога вообще никак не будет работать плоть до инициализации стека...буду искать другой попроще МК...
- Engineer_Keen
- Друг Кота
- Сообщения: 3872
- Зарегистрирован: Пт янв 29, 2010 10:27:40
- Откуда: Москва
Re: ATxmega128A1: Имеет ли право на жизнь прог-ма
Мысль про МК попроще правильная, Xmega великовата для такой задачки.
Что касается 5-го пункта, там все просто. У вас уже имеется прерывание АЦП, вот в нем можно и сразу передавать полученное значение через UART и SPI. А если нужно управлять работой контроллера, то нужно написать обработчик прерывания по приходу байта по UART и блок анализа этого байта (или строки). Тогда основной цикл будет состоять из одной строчки.
Еще лучше будет, если использовать отдельный регистр с флагами, чтобы в самом обработчике не делать ничего громоздкого, только подготовительные операции и установка флага. Например:
Что касается 5-го пункта, там все просто. У вас уже имеется прерывание АЦП, вот в нем можно и сразу передавать полученное значение через UART и SPI. А если нужно управлять работой контроллера, то нужно написать обработчик прерывания по приходу байта по UART и блок анализа этого байта (или строки). Тогда основной цикл будет состоять из одной строчки.
Код: Выделить всё
proga: RJMP progaКод: Выделить всё
ADC_Complete:
in r17,ADCH ;сохранить значение АЦП
SBR Flags,0x01 ;установить флаг готовности данных к передаче
reti
...
...
...
proga:
SBRC Flags,0 ;проверить флаг готовности к передаче
RJMP proga ;переход на начало, если флаг не установлен
RCALL USART_Transmit ;передать по UART
RCALL SPI_MasterTransmit ;и по SPI
CBR Flags,0x01 ;сбросить флаг

