jeka7 0 19 августа, 2009 Опубликовано 19 августа, 2009 · Жалоба AVR_asm_Pad.rar Текстовый блокнот для написания программ для AVR на ассемблере с подсветкой синтаксиса и завершение автодополнения. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
injener 3 10 ноября, 2009 Опубликовано 10 ноября, 2009 · Жалоба Доброго всем! Прошу помощи. Поставлена задача написания программы для СИФУ управляемого выпрямителя (3 фазы, мостовая схема, стабилизация тока, синхронизация). Выбор элементной базы не критичен. Опыт программирования только АВР, но совсем на начальном уровне. Где можно прочесть по поводу построения СИФУ? Может кто-то поделится алгоритмом? Заранее спасибо Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Caruso 0 16 декабря, 2009 Опубликовано 16 декабря, 2009 (изменено) · Жалоба Всем привет. Начал осваивать МК ATmega16. Написал первую программу в AVR studio. После подачи питания на МК запускается счетчик Т1 После того случается совпадение В, генерируется прерывание. Оно запускает АЦП. Когда АЦП закончило преобразование, оно тоже генерирует прерывание. Далее сохраняем результат и пытаемся его выдать по SPI. После того как последний байт передан все повторяется сначала. Но где - то что - то не работает. Вот сам код программы .INCLUDE "m16def.inc" ;*********Определяем макрос********* .MACRO OUTI LDI R25,@1 OUT @0,R25 .ENDMACRO ;*********Определяем константы********* .equ SettingsADC_1 = 0x8A .equ SettingsADC_2 = 0x60 .equ SettingsADC_3 = 0xB0 .equ SetPortCOut = 0xFF .equ SetFirstStatePortC = 0xFF .equ SetPortBOut = 0xFF .equ SetFirstStatePortB = 0x00 .equ SettingsTimT1_1 = 0x00 .equ SettingsTimT1_2 = 0x0D .equ SettingsTimT1_3 = 0x0C .equ SettingsSPI_1 = 0x10 .equ SettingsSPI_2 = 0x00 .equ SetTimeWaitT1_H = 0xFF; Сравнение в Т1 по этому значению .equ SetTimeWaitT1_L = 0xFF; Сравнение в Т1 по этому значению ;*********Назначим новые имена для регистров********* .def acc_1 = r16;Назначаем аккумулятор 1 .def acc_2 = r17;Назначаем аккумулятор 2 ;*********Начальный адрес********* .CSEG .org $0000;Начальный адрес jmp RESET;Перепрыгиваем таблицу векторов ;*********Описание векторов прерываний********* .ORG INT0addr ; External Interrupt Request 0 RETI .ORG INT1addr ; External Interrupt Request 1 RETI .ORG OC2addr ; Timer/Counter2 Compare Match RETI .ORG OVF2addr ; Timer/Counter2 Overflow RETI .ORG ICP1addr ; Timer/Counter1 Capture Event RETI .ORG OC1Aaddr ; Timer/Counter1 Compare Match A RETI .ORG OC1Baddr ; Timer/Counter1 Compare Match B rjmp START_ADC .ORG OVF1addr ; Timer/Counter1 Overflow RETI .ORG OVF0addr ; Timer/Counter0 Overflow RETI .ORG SPIaddr ; Serial Transfer Complete RETI .ORG URXCaddr ; USART, Rx Complete RETI .ORG UDREaddr ; USART Data Register Empty RETI .ORG UTXCaddr ; USART, Tx Complete RETI .ORG ADCCaddr ; ADC Conversion Complete rjmp OUTDATA .ORG ERDYaddr ; EEPROM Ready RETI .ORG ACIaddr ; Analog Comparator RETI .ORG TWIaddr ; 2-wire Serial Interface RETI .ORG INT2addr ; External Interrupt Request 2 RETI .ORG OC0addr ; Timer/Counter0 Compare Match RETI .ORG SPMRaddr ; Store Program Memory Ready RETI ;*********Начало основной программы********* .ORG INT_VECTORS_SIZE; отсюда пошла сама программа RESET: OUTI SPL,low(RAMEND) ; Это мы загружаем в двубайтный регистр указателя OUTI SPH,High(RAMEND); стека SPH:SPL адрес конца оперативной памяти ;*********Инициализация АЦП********* OUTI ADCSRA,SettingsADC_1 OUTI ADMUX,SettingsADC_2 OUTI SFIOR,SettingsADC_3 ;*********Инициализация портов********* OUTI DDRC,SetPortCOut ;Конфигурируем порт C как выход OUTI PORTC,SetFirstStatePortC;Начальное состояние порта 0 OUTI DDRB,SetPortBOut ;Конфигурируем порт B OUTI PORTB,SetFirstStatePortB;Начальное состояние порта 0 ;*********Инициализация таймера/счетчика Т1********* OUTI TCCR1A,SettingsTimT1_1 OUTI TCCR1B,SettingsTimT1_2 OUTI TIMSK,SettingsTimT1_3 OUTI OCR1AH,SetTimeWaitT1_H; С этим надо разобраться, без этих строк счетчик несчитает OUTI OCR1AL,SetTimeWaitT1_L OUTI OCR1BH,SetTimeWaitT1_H OUTI OCR1BL,SetTimeWaitT1_L ;*********Инициализация SPI********* ;OUTI SPCR,SettingsSPI_1; MAIN: sei ; Общее разрешение прерываний nop rjmp MAIN START_ADC: sei ; Общее разрешение прерываний sbi ADCSRA,ADSC WAIT: nop rjmp WAIT OUTDATA: in acc_1,ADCH in acc_2,ADCL sbi SPCR,SPE sbi SPCR,MSTR out SPDR, acc_1 WAIT_TR_DATA_1: SBIS SPSR,SPIF rjmp WAIT_TR_DATA_1 out SPDR, acc_2 WAIT_TR_DATA_2: SBIS SPSR,SPIF rjmp WAIT_TR_DATA_2 rjmp MAIN Если не трудно покритикуйте Изменено 16 декабря, 2009 пользователем rezident Нарушение п.3.4 Правил форума. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 10 16 декабря, 2009 Опубликовано 16 декабря, 2009 · Жалоба Но где - то что - то не работает. Вот сам код программы Может быть - оно и будет работать... Но, недолго! Так, как это делаете Вы, работать с прерываниями - нельзя. Обработчик прерывания должен заканчиваться командой reti, иначе стек быстро переполниться: по каждому прерыванию в него заносится адрес возврата из прерывания! OUTI OCR1AH,SetTimeWaitT1_H; С этим надо разобраться, без этих строк счетчик несчитает OUTI OCR1AL,SetTimeWaitT1_L Выбран режим счетчика 4. В этом режиме счетчик считает до значения OCR1A, сбрасывается в ноль и взводится флаг переполнения. Поэтому занести в регистр OCR1A что-то обязательно нужно. Воспользоваться лучше прерыванием по переполнению, а не по сравнению. Ещё совет. Посмотрите как в примерах записывают в регистры значения при инициализации устройств МК и придерживайтесь такого же стиля: вместо Вашего OUTI TCCR1B,SettingsTimT1_2 гораздо удобнее запись OUTI TCCR1B, (1<<WGM12)|(1<<CS12)|(1<<CS10) во всяком случае - удобнее для тех, кто захочет Вам помочь и посмотреть Вашу программу: не надо прыгать по программе вверх-вниз и заглядывать в документацию на МК. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Caruso 0 22 декабря, 2009 Опубликовано 22 декабря, 2009 · Жалоба Палыч, спасибо за ответ!!! Сам пишу программу первый раз, много не знаю. Вот второй вариант той же программы. Вроде как работает. Но мне не понятно, как формировать сигнал SS (SPI), или сигнал SS должен сам формироваться т. е. аппаратно. И как в этом режиме (SPI) передать сразу несколько байт, т. е. передать за одну посылку, или аппаратно контроллер такого сделать не может? .INCLUDE "m16def.inc" ;*********Определяем макрос********* .MACRO OUTI LDI R25,@1 OUT @0,R25 .ENDMACRO .MACRO SETBIT IN R25,@0 SBR R25,(1<<@1) OUT @0,R25 .ENDMACRO ;*********Определяем константы********* .equ TimeWait_H = 0x00 .equ TimeWait_L = 0x00 .equ SettingsSPI_1 = 0x10 .equ SettingsSPI_2 = 0x00 ;*********Назначим новые имена для регистров********* .def acc_1 = r16 ;Назначаем аккумулятор 1 .def acc_2 = r17 ;Назначаем аккумулятор 2 ;*********Начальный адрес********* .CSEG .org $0000 ;Начальный адрес JMP RESET ;Перепрыгиваем таблицу векторов ;*********Описание векторов прерываний********* .ORG INT0addr ; External Interrupt Request 0 RETI .ORG INT1addr ; External Interrupt Request 1 RETI .ORG OC2addr ; Timer/Counter2 Compare Match RETI .ORG OVF2addr ; Timer/Counter2 Overflow RETI .ORG ICP1addr ; Timer/Counter1 Capture Event RETI .ORG OC1Aaddr ; Timer/Counter1 Compare Match A RETI .ORG OC1Baddr ; Timer/Counter1 Compare Match B RETI .ORG OVF1addr ; Timer/Counter1 Overflow RJMP STARTADC .ORG OVF0addr ; Timer/Counter0 Overflow RETI .ORG SPIaddr ; Serial Transfer Complete RJMP TRANSMISSIONSPI2BYTE .ORG URXCaddr ; USART, Rx Complete RETI .ORG UDREaddr ; USART Data Register Empty RETI .ORG UTXCaddr ; USART, Tx Complete RETI .ORG ADCCaddr ; ADC Conversion Complete RJMP TRANSMISSIONSPI1BYTE .ORG ERDYaddr ; EEPROM Ready RETI .ORG ACIaddr ; Analog Comparator RETI .ORG TWIaddr ; 2-wire Serial Interface RETI .ORG INT2addr ; External Interrupt Request 2 RETI .ORG OC0addr ; Timer/Counter0 Compare Match RETI .ORG SPMRaddr ; Store Program Memory Ready RETI ;*********Начало основной программы********* .ORG INT_VECTORS_SIZE ; отсюда пошла сама программа RESET: OUTI SPL,low(RAMEND) ; Это мы загружаем в двубайтный регистр указателя OUTI SPH,High(RAMEND) ; стека SPH:SPL адрес конца оперативной памяти ;*********Инициализация АЦП********* OUTI ADCSRA, (1<<ADEN)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0) ;АЦП разрешен, прерывание от него тоже, ;коэффициент делитедя 128 OUTI ADMUX, (1<<REFS0)|(1<<ADLAR) ;AVcc - источник опорного напряжения, ;результат преобразования выравниваем влево OUTI SFIOR, (1<<ADHSM) ;Увеличиваем скорость АЦП ;*********Инициализация портов********* OUTI PORTC, (1<<PORTC0)|(1<<PORTC1)|(1<<PORTC2)|(1<<PORTC3)|(1<<PORTC4)|(1<<PORTC5)|(1<<PORTC6)|(1<<PORTC7) ;Начальное состояние порта C 1 OUTI DDRC, (1<<DDC0)|(1<<DDC1)|(1<<DDC2)|(1<<DDC3)|(1<<DDC4)|(1<<DDC5)|(1<<DDC6)|(1<<DDC7) ;Конфигурируем порт C как выход OUTI PORTB, (1<<PORTB0)|(1<<PORTB1)|(1<<PORTB2)|(1<<PORTB3)|(1<<PORTB4)|(1<<PORTB5)|(1<<PORTB6)|(1<<PORTB7) ;Начальное состояние порта B 1 OUTI DDRB, (1<<DDB0)|(1<<DDB1)|(1<<DDB2)|(1<<DDB3)|(1<<DDB4)|(1<<DDB5)|(1<<DDB6)|(1<<DDB7) ;Конфигурируем порт B как выход ;*********Инициализация таймера/счетчика Т1********* OUTI TCCR1B, (1<<CS11) ;Режим работы 0 (Normal), частоту делим на 8 OUTI TIMSK, (1<<TOIE1) ;Разрешение прерывания таймера Т1 по переполнению OUTI TCNT1H, TimeWait_H ;задаем начальное значение счетчика (старший байт) OUTI TCNT1L, TimeWait_L ;задаем начальное значение счетчика (младший байт) ;*********Инициализация SPI********* OUTI SPCR, (1<<SPIE)|(1<<MSTR)|(1<<SPI2X)|(1<<SPR1)|(1<<SPR0) ;Разрешаем прерывание SPI, выбран режим мастера, скорость передачи делим на 64 ;*********Сама программа********* SEI MAIN: NOP RJMP MAIN STARTADC: SETBIT ADCSRA,ADSC ;Старт АЦП OUTI TCNT1H, TimeWait_H ;повторно задаем начальное значение счетчика (старший байт) для синхронизации OUTI TCNT1L, TimeWait_L ;повторно задаем начальное значение счетчика (младший байт) SEI ;разрешаем прерывания RETI TRANSMISSIONSPI1BYTE: IN acc_1,ADCH ;Сохраняем значение АЦП (старший байт) IN acc_2,ADCL ;Сохраняем значение АЦП (младший байт) SETBIT SPCR,SPE ;Включение SPI OUT SPDR,acc_1 ;Заносим в регистр данных старший байт АЦП OUTI TCNT1H, TimeWait_H ;повторно задаем начальное значение счетчика (старший байт) для синхронизации OUTI TCNT1L, TimeWait_L ;повторно задаем начальное значение счетчика (младший байт) SEI RETI TRANSMISSIONSPI2BYTE: SETBIT SPCR,SPE ;Включение SPI OUT SPDR,acc_2 ;Заносим в регистр данных младщий байт АЦП OUTI TCNT1H, TimeWait_H ;повторно задаем начальное значение счетчика (старший байт) для синхронизации OUTI TCNT1L, TimeWait_L ;повторно задаем начальное значение счетчика (младший байт) SEI RETI Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 22 декабря, 2009 Опубликовано 22 декабря, 2009 · Жалоба 1. sei перед reti - не нужно 2. в обработчиках прерываний принято сохранять в стеке регистры, используемые в этом обработчике. ведь ваша фоновая программ не будет пустой как сейчас, а ваши макросы используют r25, поэтому как минимум надо было писать так ISR_XXX: push r25 .... pop r25 reti Вроде как работает. Но мне не понятно, как формировать сигнал SS (SPI), или сигнал SS должен сам формироваться т. е. аппаратно. И как в этом режиме (SPI) передать сразу несколько байт, т. е. передать за одну посылку, или аппаратно контроллер такого сделать не может?SS формирует мастер. Настройте эту ножку на ввод от греха подальше (я не шучу). Аппаратный интерфейс SPI у AVR может работать только с байтами. Поэтому для передачи других данных, больших чем байт, программист должен немного подумать над тем, как их передать побайтно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 10 23 декабря, 2009 Опубликовано 23 декабря, 2009 · Жалоба Но мне не понятно, как формировать сигнал SS (SPI), или сигнал SS должен сам формироваться т. е. аппаратно.Сигнал SS в МК используется при работе SPI в режиме Slave. Поскольку у Вас SPI - в режиме Master, то эту ножку Вы можете использовать по своему усмотрению как Вам нужно/удобно. Если, соединённое с МК по SPI устройство требует определённого состояния сигнала на своей ноге SS, то необходимо подключить её к свободной ноге МК (не обязательно к SS МК), настроить её (ногу МК) на вывод и программно формировать на ней необходимый сигнал. И как в этом режиме (SPI) передать сразу несколько байт, т. е. передать за одну посылку, или аппаратно контроллер такого сделать не может?В SPI: одна посылка - один байт. Для передачи нескольких байт, обычно, организуют буфер, в который складывают байты готовые для передачи, и, по мере их передачи - последовательно выбирают их из буфера. Можно считать, что у Вас такой буфер из двух байт уже есть: acc_1 и acc_2. Необходимо завести некие указатели/флаги, по состоянию которых можно было бы судить в прерывании от SPI о том, что уже сделано и что нужно сделать (например, флаги: "передавался первый байт из двух", "вывод байтов закончен" или что-то подобное; или реализавать очередь типа FIFO с указателями на начало и конец очереди). 2. в обработчиках прерываний принято сохранять в стеке регистры, используемые в этом обработчике.Добавлю, что помимо General Purpose Working Registers принято также сохранять регистр SREG... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 23 декабря, 2009 Опубликовано 23 декабря, 2009 · Жалоба Добавлю, что помимо General Purpose Working Registers принято также сохранять регистр SREG...Ой, как же я забыл об этом упомянуть. Нет мне прощения:) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Prevan 0 13 июня, 2010 Опубликовано 13 июня, 2010 (изменено) · Жалоба Зравствуйте! Подскажите как присвоить значение отдельным битам порта содержимое какой-нибудь переменной? например: out PORTD,temp ;будет просто установлено значение переменной temp в порт D а мне надо в порт С на 3ю ножку установить значение такое же как на 6м бите перменной temp и таким же образом раскидать другие переменные. И наоборот. Как можно сделать обратную операцию, т.е. из разных битов портов составить содержимое переменной temp? например: in temp,PINC ;будет просто скопировано значение состояния порта С переменную temp Дело в том, что мне необходимо "мягко" изменить код программы, не прибегаю к полному переписанию кода программы. Переменные, указанные в программе работают со старым подключением проводов к ножкам МК. т.е. мне надо будет изменить следующий код: out PORTD,scancod clc ldi rots,4 in temp,PINC где: PD0 <->PD4 PD1 <->PD5 PD4 <->PC0 PD5 <->PC1 PD6 <->PC2 PD7 <->PC3 Изменено 13 июня, 2010 пользователем Prevan Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
PDA 0 27 июля, 2010 Опубликовано 27 июля, 2010 · Жалоба Есть плата, похожая на программатор - на плате есть FT232BM и установлен Attiny2313. При установке драйверов FT232BM появляется USB Serial Converter и виртуальный COM-порт. Микросхема FT232BM по линиям от контактов #25 TXD и #24 RXD связана с Attiny2313 к контактам #2 PD0(RXD) и #3 PD1(TDX), через которые и собственно организован обмен данными. Вопрос: можно ли прошить МК через FT232BM, используя эти линии (похоже на UART?) - то есть ли возможность перепрошивать МК без подключения программатора (к SPI выводам МК), а только программными средствами по имеющимся линиям UART? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
skb_tantal 0 27 июля, 2010 Опубликовано 27 июля, 2010 (изменено) · Жалоба Вопрос: можно ли прошить МК через FT232BM, используя эти линии (похоже на UART?) - то есть ли возможность перепрошивать МК без подключения программатора (к SPI выводам МК), а только программными средствами по имеющимся линиям UART? в обычном режиме невозможно перепрошивать МК через TXD/RXD, теоретически для этого необходимо написать для Attiny2313 загрузчик flash через UART, т.е. Вы посылаете через FT232BM байты , МК их получает и сам себя перепрошивает Изменено 27 июля, 2010 пользователем rezident Излишнее цитирование. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
PDA 0 27 июля, 2010 Опубликовано 27 июля, 2010 (изменено) · Жалоба Я правильно понимаю, что обещание, что устройство будет программироваться только через USB, не выполнимо, то есть при производстве устройства всё равно придется хоть раз программировать МК по SPI каналу, а потом скреплять корпус? update: в обычном режиме невозможно перепрошивать МК через TXD/RXD, теоретически для этого необходимо написать для Attiny2313 загрузчик flash через UART, т.е. Вы посылаете через FT232BM байты , МК их получает и сам себя перепрошивает разве у Attiny2313 есть возможность создания лодера? всего 2К памяти, насколько я понял описание Изменено 27 июля, 2010 пользователем PDA Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
skb_tantal 0 27 июля, 2010 Опубликовано 27 июля, 2010 · Жалоба Я правильно понимаю, что обещание, что устройство будет программироваться только через USB, не выполнимо, то есть при производстве устройства всё равно придется хоть раз программировать МК по SPI каналу, а потом скреплять корпус? первый раз конечно по SPI update:разве у Attiny2313 есть возможность создания лодера? всего 2К памяти, насколько я понял описание "The device provides a Self-Programming mechanism for downloading and uploading program code by the MCU itself." 2k мало, но вроде возможно Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
PDA 0 27 июля, 2010 Опубликовано 27 июля, 2010 · Жалоба первый раз конечно по SPIТогда подскажите, возможно ли такая ситуация, что микросхема уже имеет какой-либо загрузчик? В моем случае, например, что микросхема уже имеет в себе загрузчик по UART? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Savrik 0 27 июля, 2010 Опубликовано 27 июля, 2010 · Жалоба Attiny2313 флеша маловато.. Есть ли на плате какие-либо кнопки? Если есть, можно попробовать зажать ее, перезапустить МК, и смотреть в терминал(или записать туда что-то), возможно, увидите бутлоадер. Как вариант можно создать свой. Я использую(правда, для Mega AVR)AVR911, загружаю через Avr-Osp II. Очень удобно, код для меги16 занимает около 1кб. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться