AVR studio в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
B@R5uk
Собутыльник Кота
Сообщения: 2896
Зарегистрирован: Сб ноя 13, 2010 12:53:25
Откуда: приходит весна?

Re: AVR studio 4 в вопросах и ответах

Сообщение B@R5uk »

Подскажите, пожалуйста, имеется ли в АВР-студии возможность эмулировать работу МК при заданных осцилограммах напряжений на его входах? То есть я программирую МК так, чтобы он вёл себя определённым образом при подаче на вход определённых сигналов, и хочу это проверить перед прошивкой. Я знаю, что в АВР-студии можно во время дебагинга выставлять мышкой значения логических входов МК. Но, поскольку входные сигналы имеют длину в тысячи тактов МК, проделать такую проверку пологаясь только на брэйкпоинты и мышку не представляется возможным. Кроме того, желательно, чтобы эмулировалась работа переферийных устройств, в частности компаратора (поскольку именно на него будет подаваться аналоговый сигнал). Подскажите, чем можно воспользоваться, если в AVR Studio нет такой возможности.

Заранее спасибо.
Реклама
zyhelman
Родился
Сообщения: 11
Зарегистрирован: Вс дек 29, 2013 02:26:35
Откуда: Украина, Киев

Re: AVR studio 4 в вопросах и ответах

Сообщение zyhelman »

Доброго всем дня! Пишу один простенький код под тиньку13 но он почему то не хочет работать не в протеусе не в железке, симулятор студии работает нормально...
Код следующий:
Спойлер

Код: Выделить всё

#define F_CPU 128000L
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdbool.h>
#include <avr/sfr_defs.h>

#define AMP bit_is_set(PINB,0)
#define POW bit_is_set(PINB,1)
#define TIMER bit_is_set(PINB,2)
#define TIMERSTOP (POW && TIMER)
#define LED_ON PORTB |= _BV(PB5)
#define LED_OFF PORTB &= ~_BV(PB5)
#define POW_ON PORTB = 0x10 
#define POW_OFF PORTB = 0x20
#define AMP_ON PORTB |= _BV(PB3) 
#define AMP_OFF PORTB &= ~_BV(PB3)
#define AMP_S(state) if(state){AMP_ON;}else{AMP_OFF;}


volatile unsigned int countdown = 0;
volatile bool isTIMER = false;
volatile bool isAMP = false;
volatile bool isON = false;




void timer_enable(void)
{	
	TCCR0B |= (1<<CS02) | (1<<CS00); //clock/1024
	TCNT0 = 7;//Timer value;
	isTIMER = true;
}
void timer_disable(void)
{
	TCCR0B |= (0<<CS02) | (0<<CS00); //timer stopped
	isTIMER = false;
}

void power_off(void)
{
	timer_disable();
	isAMP = false;
	isON = false;
}

ISR(TIM0_OVF_vect)
{
	if(PORTB&0x20) 
	{	
		LED_OFF;
	}
	else 
	{
		LED_ON;
	}
	countdown -= 2;
	if(countdown == 0) 
	{
		power_off();
	}
	TCNT0 = 7;//Timer value;
}

void config(void)
{
	DDRB = 0x38;
	PORTB = 0x20;
	TIMSK0 = 0x02;
}

int main(void)
{
	config();
	asm("sei");	
    while(1)
    {
        if(TIMERSTOP && isON) 
		{      
			_delay_ms(20);
			if(TIMERSTOP)
			{
				timer_disable();
				countdown = 0;				
			}  
		}
		else if(TIMER && isON) 
		{      
			_delay_ms(20);
			if(TIMER)
			{
			   if(!isTIMER)
			   {
					timer_enable();
			   }
			   countdown += 30;
			}  
		}
		else if(AMP && isON) 
		{      
			_delay_ms(50);
			if(AMP)
			{
				isAMP = !isAMP;
				AMP_S(isAMP);
			}  
		}       
		else if(POW) 
		{         
			_delay_ms(20);
			if(POW)
			{
				if(isON)
				{
					power_off();
				}
				else
				{
					isON = true;
					POW_ON;
					
				}
			}
		}   
		_delay_ms(100);
    }
}
Понимаю что код ужасный но очень нужна помощь, месяц убил на него а он не работает толком. Ошибки выбиваются при работе с кнопками, а именно при вызове макроса POW_ON.
протеус говорит на это:
СпойлерИзображение
железка просто молчит
Заранее благодарен
Реклама
Alexeyslav
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич
Контактная информация:

Re: AVR studio 4 в вопросах и ответах

Сообщение Alexeyslav »

Какая же это работа с кнопками? Такое происходит когда в схеме происходят очень быстрые процессы, тогда модель математически распадается(появляются такие ситуации как деление на ноль, бесконечные величины и т.д.) и невозможно что-либо далее рассчитать. В данном случае, не пытайтесь в симулятор ввести ВСЮ схему - только те части которые необходимо симулировать, остальную часть схемы заменить математическим эквивалентом или просто выбросить.
У вас там наверняка есть и силовые ключи и трансформатор... эти элементы не нужны для отладки программы, именно они и приводят к таким последствиям.
zyhelman
Родился
Сообщения: 11
Зарегистрирован: Вс дек 29, 2013 02:26:35
Откуда: Украина, Киев

Re: AVR studio 4 в вопросах и ответах

Сообщение zyhelman »

Да, вы правы, есть полевики и реле, но почему тогда в железе не работает?
Реклама
Эиком - электронные компоненты и радиодетали
Alexeyslav
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич
Контактная информация:

Re: AVR studio 4 в вопросах и ответах

Сообщение Alexeyslav »

На этот вопрос существует миллион ответов. искать их непродуктивно. Проще ответить на вопрос почему оно ДОЛЖНО работать, обычно на этот вопрос ответов не так уж много. Попробуйте подойти к решению проблемы именно с этой стороны.
Реклама
zyhelman
Родился
Сообщения: 11
Зарегистрирован: Вс дек 29, 2013 02:26:35
Откуда: Украина, Киев

Re: AVR studio 4 в вопросах и ответах

Сообщение zyhelman »

В протеусе заработало после упрощения схемы, нашлось пару мелких недочетов, проверю на железе теперь) Спасибо Вам огромное :))
Реклама
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: AVR studio 4 в вопросах и ответах

Сообщение Gudd-Head »

B@R5uk писал(а):Подскажите, пожалуйста, имеется ли в АВР-студии возможность эмулировать работу МК при заданных осцилограммах напряжений на его входах?
Можно, но только лог. "1" и "0".
Симулятор опшионс — стимули энд логгинг — стимули: подгружаете файл, который будет воздействовать на соотв. порт.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
B@R5uk
Собутыльник Кота
Сообщения: 2896
Зарегистрирован: Сб ноя 13, 2010 12:53:25
Откуда: приходит весна?

Re: AVR studio 4 в вопросах и ответах

Сообщение B@R5uk »

Gudd-Head, огромное СПАСИБИЩЕ! Будем пробовать.
Alexeyslav
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич
Контактная информация:

Re: AVR studio 4 в вопросах и ответах

Сообщение Alexeyslav »

Но бывает полезней к студии подключить протеус в качестве удаленного отладчика(вообще поидее наоборот, это студия подключается к протеусу в качестве удаленного отладчика, но загружает его в своё окно). Правда, протеус тогда может помещаться только в пределах главного окна студии, что не всегда удобно...
Аватара пользователя
B@R5uk
Собутыльник Кота
Сообщения: 2896
Зарегистрирован: Сб ноя 13, 2010 12:53:25
Откуда: приходит весна?

Re: AVR studio 4 в вопросах и ответах

Сообщение B@R5uk »

Gudd-Head, подскажите, пожалуйста, где можно прочитать про формат файлов *.sti или про то, какой программой их можно создать?
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: AVR studio 4 в вопросах и ответах

Сообщение ARV »

B@R5uk писал(а):где можно прочитать про формат файлов *.sti или про то, какой программой их можно создать?
вот здесь можно прочитать: http://www.simple-devices.ru/attachment ... 8-2010.pdf
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
B@R5uk
Собутыльник Кота
Сообщения: 2896
Зарегистрирован: Сб ноя 13, 2010 12:53:25
Откуда: приходит весна?

Re: AVR studio 4 в вопросах и ответах

Сообщение B@R5uk »

ARV, Gudd-Head, спасибо вам преогромнейшее, вы не представляете, как мне помогли. Отладил таки свою подпрограмму приёма сигнала. Оно даже в железе заработало. Замутил тут хитрую систему, позволяющую передавать данные из программы на ноутбуке в микроконтроллер через звуковой выход путём модуляции по типу спектрумовского сохранения на кассету. Если кто в курсе, тот поймёт. Программа -- жесть, жёсткие тайминги, привязка к скорости выполнения каждой комманды МК, длительность каждого цикла и каждого пути по всем ветвлениям процедуры пришлось рассчитать.
Alexeyslav
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич
Контактная информация:

Re: AVR studio 4 в вопросах и ответах

Сообщение Alexeyslav »

Это, вероятно, просто признак неправильного подхода к задаче. "спектрум" будучи более медлительным и тот справлялся замечательно с этой задачей, а у вас пришлось все жестко рассчитывать. Или скорости огромные? да вроде же звуковой тракт...
Аватара пользователя
B@R5uk
Собутыльник Кота
Сообщения: 2896
Зарегистрирован: Сб ноя 13, 2010 12:53:25
Откуда: приходит весна?

Re: AVR studio 4 в вопросах и ответах

Сообщение B@R5uk »

Alexeyslav писал(а):Это, вероятно, просто признак неправильного подхода к задаче. "спектрум" будучи более медлительным и тот справлялся замечательно с этой задачей, а у вас пришлось все жестко рассчитывать. Или скорости огромные? да вроде же звуковой тракт...
Я в своё время разбирался с его программой. Там во-первых у процессора набор инструкций более удобный, во-вторых, спектрум работает на частоте 3,5 МГц, а мой МК сейчас от встроенного 1 МГц-вого генератора, в третьих, если мне не изменяет память, то там тоже много рабочих констант, то есть всё жёстко рассчитано.

Впрочем, вот моя программа, может посоветуете, что можно улучшить (только не советуйте всё переделать через прерывания -- я пока всех тонкостей не знаю):
Спойлер

Код: Выделить всё

.include "tn26def.inc"

                cli                     ;   Отмена прерываний
                ldi     r16,    0x7F    ;   Порт А -- выход, кроме
                out     DDRA,   r16     ;       самого старшего бита
                ldi     r16,    0x40    ;   Порт Б -- вход, кроме
                out     DDRB,   r16     ;       бита 6
                ldi     r16,    1<<ACBG ;   Положительный вход комаратора
                out     ACSR,   r16     ;       подключить к внутренним 1.18В
                ldi     r16,    0xDF    ;   Инициализация
                out     SP,     r16     ;       стека
loop:           ldi     r26,    0x60    ;   Инициализация
                ldi     r27,    0x00    ;       указателя X
                ld      r16,    X       ;   Загрузка прочитанного байта из памяти
                bst     r16,    7       ;   Сохранение старшего бита
                andi    r16,    0x7F    ;   Маска выхода
                out     PORTA,  r16     ;   Вывод младших 7-и битов в прот А
                ser     r16             ;   Подтяжка неиспользуемых выходов
                bld     r16,    6       ;   Подготовка вывода
                out     PORTB,  r16     ;   Вывод старшего 8-го бита
                ldi     r16,    0x01    ;   Количество принимаемых байт
                rcall   rsvr_begin      ;   Вызов процедуры приёма данных
                rjmp    loop            ;   Рабочий цикл

;==============
;                           Процедура принятия данных
;==============

.def    btcnt   =   r16
.def    lstat   =   r17
.def    temp    =   r18
.def    lpcnt   =   r19
.def    plcnt   =   r20
.def    flcnt   =   r21
.def    rslt    =   r21

;.equ   INPRT   =   PINB
.equ    INPRT   =   ACSR

;   Регистры, используемые на этапе синхронизации:
;       -   lstat
;       -   lpcnt
;       -   plcnt
;       -   temp
;       -   flcnt
;   Регистры, используемые в процессе считывания:
;       -   btcnt           (передаётся в процедуру из программы)
;       -   X (R27:R26)     (передаётся в процедуру из программы)
;       -   lstat           (инициализируется на этапе синхронизации)
;       -   lpcnt
;       -   plcnt
;       -   temp
;       -   rslt


;   Инициализация
rsvr_begin:     ldi     flcnt,  0x10    ;   Допустимое число ошибок синхронизации
                in      lstat,  INPRT   ;   Чтение линии
rsvr_afrsh:     ldi     plcnt,  0x08    ;   Минимальное число синхроимпульсов
;   Ожидание переключения с таймаутом
                ldi     lpcnt,  0x28    ;   Допустимое время ожидания смены сигнала
rsvr_wait_1:    in      temp,   INPRT   ;   Чтение линии
                eor     temp,   lstat   ;   Сравнение
                andi    temp,   1<<ACO  ;       с запомненным значением
                brne    rsvr_chng_1     ;   Если значение изменилось переход к задержке
                dec     lpcnt           ;   Уменьшить допустимое время ожидания
                brne    rsvr_wait_1     ;   Если время не вышло, продолжить ожидание
;   Обработка таймаута
rsvr_timeout:   dec     flcnt           ;   Уменьшить допустимое число ошибок
                brne    rsvr_afrsh      ;   Если лимит ошибок не достигнут, продолжить
                rjmp    rsvr_end        ;   Иначе, закончить процедуру
;   Мёртвое время после переключения
rsvr_chng_1:    ldi     lpcnt,  0x05    ;   Инициализация задержки
rsvr_revsl:     com     lstat           ;   Инвертировать запомненное состояние линии
rsvr_dtm_1:     dec     lpcnt           ;   Уменьшить время задержки
                brne    rsvr_dtm_1      ;   Повторить, если время не вышло
;   Ожидание переключения с таймаутом
                ldi     lpcnt,  0x25    ;   Допустимое время ожидания смены сигнала
rsvr_wait_2:    in      temp,   INPRT   ;   Чтение линии
                eor     temp,   lstat   ;   Сравнение
                andi    temp,   1<<ACO  ;       с запомненным значением
                brne    rsvr_chck_1     ;   Если уровень изменился, переход к проверкам
                dec     lpcnt           ;   Уменьшить допустимое время ожидания
                brne    rsvr_wait_2     ;   Если время не вышло, продолжить ожидание
                rjmp    rsvr_timeout    ;   Иначе, переход к обработке таймаута
;   Проверка длительности импульса
rsvr_chck_1:    cpi     lpcnt,  0x0D    ;   Сравнить оставшееся время с порогом
                brcc    rsvr_chck_2     ;   Если не синхроимпульс, ко второй проверке
                subi    plcnt,  0x01    ;   Уменьшить необходимое число синхроимпульсов
                brcc    rsvr_skip_1     ;   Если заёма нет, то пропуск
                clr     plcnt           ;       отмены вычитания
rsvr_skip_1:    ldi     lpcnt,  0x03    ;   Инициализация задержки
                rjmp    rsvr_revsl      ;   Переход к задержке
;   Проверка возможности перехода к считыванию
rsvr_chck_2:    tst     plcnt           ;   Проверка необходимого числа синхроимпульсов
                breq    rsvr_rdng       ;   Если достаточно, то к процедуре считывания
                dec     flcnt           ;   Уменьшить допустимое число ошибок
                breq    rsvr_end        ;   Если лимит попыток достигнут, закончить
                ldi     plcnt,  0x08    ;   Минимальное число синхроимпульсов
                ldi     lpcnt,  0x03    ;   Инициализация задержки
                rjmp    rsvr_revsl      ;   Переход к задержке
;   Процедура считывания данных
rsvr_rdng:      ldi     lpcnt,  0x05    ;   Инициализация задержки
                com     lstat
rsvr_btinit:    ldi     rslt,   0x80    ;   Инициализация принимаемого байта
;   Мёртвое время после последней операции
rsvr_dtm_2:     dec     lpcnt           ;   Уменьшить время задержки
                brne    rsvr_dtm_2      ;   Повторить, если время не вышло
;   Ожидание переключения с таймаутом
                ldi     lpcnt,  0x0B    ;   Допустимое время ожидания смены сигнала
rsvr_wait_3:    in      temp,   INPRT   ;   Чтение линии
                eor     temp,   lstat   ;   Сравнение
                andi    temp,   1<<ACO  ;       с запомненным значением
                brne    rsvr_chng_2     ;   Если значение изменилось переход к задержке
                dec     lpcnt           ;   Уменьшить допустимое время ожидания
                brne    rsvr_wait_3     ;   Если время не вышло, продолжить ожидание
                rjmp    rsvr_end        ;   Иначе, закончить процедуру
;   Задержка перед считыванием
rsvr_chng_2:    ldi     lpcnt,  0x11    ;   Инициализация задержки перед считыванием
rsvr_dtm_3:     dec     lpcnt           ;   Уменьшить время задержки
                brne    rsvr_dtm_3      ;   Повторить, если время не вышло
;   Процедура считывания
                ldi     plcnt,  0x00    ;   Инициализация числа чтений нулевго бита
;   Счёт по низкому уровню
                ldi     lpcnt,  0x08    ;   Инициализация числа чтений низкого уровня
rsvr_read_1:    in      temp,   INPRT   ;   Чтение линии
                eor     temp,   lstat   ;   Сравнение
                andi    temp,   1<<ACO  ;       с запомненным значением
                breq    rsvr_skip_2     ;   Если прочитана единица, то пропустить
                inc     plcnt           ;       инремент числа чтений нулевого бита
rsvr_skip_2:    dec     lpcnt           ;   Уменьшить необходимое число чтений
                brne    rsvr_read_1     ;   Если чтения не исчерпаны, повторить
;   Счёт по высокому уровню
                ldi     lpcnt,  0x08    ;   Инициализация числа чтений высокого уровня
rsvr_read_2:    in      temp,   INPRT   ;   Чтение линии
                eor     temp,   lstat   ;   Сравнение
                andi    temp,   1<<ACO  ;       с запомненным значением
                brne    rsvr_skip_3     ;   Если прочитан ноль, то пропустить
                inc     plcnt           ;       инремент числа чтений нулевого бита
rsvr_skip_3:    dec     lpcnt           ;   Уменьшить необходимое число чтений
                brne    rsvr_read_2     ;   Если чтения не исчерпаны, повторить
;   Расшифровка принятого бита в читаемый байт
                subi    plcnt,  0x08    ;   Сравнение числа нулевых чтений с порогом
                ror     rslt            ;   Сохранение бита в принимаемый байт
                brcs    rsvr_save       ;   Если байт готов, то сохранить его
                ldi     lpcnt,  0x06    ;   Инициализация задержки
                rjmp    rsvr_dtm_2      ;   Переход к задержке
;   Сохранение байта
rsvr_save:      st      x+,     rslt    ;   Запись байта в регистры/память
                cpi     r26,    0x10    ;   Проверка выхода указателя за регистр R15
                brne    rsvr_skip_4     ;   Если выхода нет, то пропустить
                ldi     r26,    0x60    ;       перестановку указателя на память
rsvr_skip_4:    cpi     r26,    0xD8    ;   Проверить наличие свободного места
                breq    rsvr_end        ;   Если место закончилось, закончить процедуру
                dec     btcnt           ;   Иначе, уменьшить количество читаемых байт
                breq    rsvr_end        ;   Если все байты приняты, закончить процедуру
                ldi     lpcnt,  0x02    ;   Иначе, инициализация задержки
                rjmp    rsvr_dtm_2      ;   Переход к задержке
;   Конец
rsvr_end:       ret
Отличие моего формата данных от спектрумовского заключается в том, что единица передаётся не одним в двое коротким по сравненю с нулём импульсом, а двумя. Пилот тон имеет частоту 2 кГц, длительность передачи одного бита 250 мкс, то есть скорость данных 4000 бит/с. Стоповый импульс пилот-тона, после которого начинается считывание информации -- половина единичного бита (то есть импульс, в двое короткий по сравнению с нулевым битом и в четверо более короткий по сравнению с пилот-тоном). Моя звуковая поддерживает максимальную частоту дискретизации 48 кГц, так что каждый бит -- это 6 звуковых семплов.
Alexeyslav
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич
Контактная информация:

Re: AVR studio 4 в вопросах и ответах

Сообщение Alexeyslav »

Частота процессора не показатель, на том процессоре который использовался в спектруме одна самая простая команда выполнялась 4 такта, а длинная - 12 тактов и более. Так что ресурс по скорости исполнения инструкций и того ниже.

Привязка к длительности импульса конечно очень проста, но такой способ передачи данных очень чувствителен к помехам, любой лишний импульс и все насмарку т.к. теряется синхронизация.
Проще было бы посмотреть в сторону передачи данных как это делается в UART, только появляется специфика - нестабильная скорость передачи/приема, которую я решил очень просто - передается всего 4 информационных бита в одной посылке, это дает нам нечувствительность к разнице скорости приема/передачи в 10%, перед началом передачи даётся импульс повышенной длительности по которому приемник определяет необходимую скорость передачи, подразумевая что во время передачи всего пакета частота тактирования существенно не изменится(более 10%).
У меня получилось таким способом выиграть еще 16% (+-8% отклонения скорсоти в обе стороны) на нестабильность скорости приема/передачи. У вас может получится и того больше.
Всё это я делал на фиксированной скорости 48Кбод = 4.8Мгц/100 контроллер после получения синхронизирующего импульса и коррекции скорости приема по нему просто считывал состояние порта каждые 100 тактов при помощи таймера - в остальное время контроллер не делал ничего критичного. Единственные узкие места - обеспечить минимальное время между концом первого импульса синхронизации и вычислением скорости приема по результатам измерения длительности импульса и алгоритм ожидания начала следующего импульса синхронизации перед каждой посылкой из 4-х бит, чтобы ликвидировать накапливающуюся ошибку скорости приема.

В данном случае, в случае помех может быть повреждены отдельные биты, но пакеты будут приняты несмотря ни на что. И эта проблема уже решается применением помехоустойчивых кодов на уровне выше. Но судя по тому что у вас сейчас все работает на наличие помех не жалуетесь.
Аватара пользователя
B@R5uk
Собутыльник Кота
Сообщения: 2896
Зарегистрирован: Сб ноя 13, 2010 12:53:25
Откуда: приходит весна?

Re: AVR studio 4 в вопросах и ответах

Сообщение B@R5uk »

3,5 МГц — это частота исполнения команд процессора Z80. А так то частота тактовых импульсов 14 МГц. Да, там есть команды, которые исполняются долго, но даже инкремент, декремент сдвоенного регистра по длительности равен команде NOP. Так что частота, всё-таки показатель.

На счёт стабильности приёма я в своей программе не задумывался вообще. Для меня тут было главное — простота кода и чтобы хоть как-то заработало. (Кстати, полноценные тесты ещё впереди). Тем, не менее, у меня в процессе приёма синхронизация происходит для каждого бита по спаду сигнала от предыдущего бита. В те моменты времени, когда в сигнале передаётся информация, процедура производит 16 чтений порта, результаты усредняются, и в конце подсчитывается итоговый результат. (Код перед вами — легко убедиться самому -- код с метки rsvr_read_1) Так что стабильность, думаю, достигается высокая (необходима ошибка синхронизации на 1/8 рабочего периода, (который равен 250 мкс), либо 50% сигнала в информационной области должно быть испорчено, чтобы результат получился неправильный).

На счёт таймера мысль была, но поскольку это моё первое знакомство с AVR вообще, я пока ещё не в курсе как, да чего. Изучение ещё только предстоит. Возможно, используя прерывания и таймер удастся сделать процедуру приёма сигнала в фоновом режиме, а не загружая весь МК работой. При моёй текущей частоте несущего сигнала, бит передаётся в течении 250 циклов МК, этого времени более чем достаточно для обсчёта. А если подключить кварц на 12 МГц, то расходовать 3000 операций на один бит данных — это уже будет перебор.

Ещё раз код, а то уехал.
Спойлер

Код: Выделить всё

.include "tn26def.inc"

                cli                     ;   Отмена прерываний
                ldi     r16,    0x7F    ;   Порт А -- выход, кроме
                out     DDRA,   r16     ;       самого старшего бита
                ldi     r16,    0x40    ;   Порт Б -- вход, кроме
                out     DDRB,   r16     ;       бита 6
                ldi     r16,    1<<ACBG ;   Положительный вход комаратора
                out     ACSR,   r16     ;       подключить к внутренним 1.18В
                ldi     r16,    0xDF    ;   Инициализация
                out     SP,     r16     ;       стека
loop:           ldi     r26,    0x60    ;   Инициализация
                ldi     r27,    0x00    ;       указателя X
                ld      r16,    X       ;   Загрузка прочитанного байта из памяти
                bst     r16,    7       ;   Сохранение старшего бита
                andi    r16,    0x7F    ;   Маска выхода
                out     PORTA,  r16     ;   Вывод младших 7-и битов в прот А
                ser     r16             ;   Подтяжка неиспользуемых выходов
                bld     r16,    6       ;   Подготовка вывода
                out     PORTB,  r16     ;   Вывод старшего 8-го бита
                ldi     r16,    0x01    ;   Количество принимаемых байт
                rcall   rsvr_begin      ;   Вызов процедуры приёма данных
                rjmp    loop            ;   Рабочий цикл

;==============
;                           Процедура принятия данных
;==============

.def    btcnt   =   r16
.def    lstat   =   r17
.def    temp    =   r18
.def    lpcnt   =   r19
.def    plcnt   =   r20
.def    flcnt   =   r21
.def    rslt    =   r21

;.equ   INPRT   =   PINB
.equ    INPRT   =   ACSR

;   Регистры, используемые на этапе синхронизации:
;       -   lstat
;       -   lpcnt
;       -   plcnt
;       -   temp
;       -   flcnt
;   Регистры, используемые в процессе считывания:
;       -   btcnt           (передаётся в процедуру из программы)
;       -   X (R27:R26)     (передаётся в процедуру из программы)
;       -   lstat           (инициализируется на этапе синхронизации)
;       -   lpcnt
;       -   plcnt
;       -   temp
;       -   rslt


;   Инициализация
rsvr_begin:     ldi     flcnt,  0x10    ;   Допустимое число ошибок синхронизации
                in      lstat,  INPRT   ;   Чтение линии
rsvr_afrsh:     ldi     plcnt,  0x08    ;   Минимальное число синхроимпульсов
;   Ожидание переключения с таймаутом
                ldi     lpcnt,  0x28    ;   Допустимое время ожидания смены сигнала
rsvr_wait_1:    in      temp,   INPRT   ;   Чтение линии
                eor     temp,   lstat   ;   Сравнение
                andi    temp,   1<<ACO  ;       с запомненным значением
                brne    rsvr_chng_1     ;   Если значение изменилось переход к задержке
                dec     lpcnt           ;   Уменьшить допустимое время ожидания
                brne    rsvr_wait_1     ;   Если время не вышло, продолжить ожидание
;   Обработка таймаута
rsvr_timeout:   dec     flcnt           ;   Уменьшить допустимое число ошибок
                brne    rsvr_afrsh      ;   Если лимит ошибок не достигнут, продолжить
                rjmp    rsvr_end        ;   Иначе, закончить процедуру
;   Мёртвое время после переключения
rsvr_chng_1:    ldi     lpcnt,  0x05    ;   Инициализация задержки
rsvr_revsl:     com     lstat           ;   Инвертировать запомненное состояние линии
rsvr_dtm_1:     dec     lpcnt           ;   Уменьшить время задержки
                brne    rsvr_dtm_1      ;   Повторить, если время не вышло
;   Ожидание переключения с таймаутом
                ldi     lpcnt,  0x25    ;   Допустимое время ожидания смены сигнала
rsvr_wait_2:    in      temp,   INPRT   ;   Чтение линии
                eor     temp,   lstat   ;   Сравнение
                andi    temp,   1<<ACO  ;       с запомненным значением
                brne    rsvr_chck_1     ;   Если уровень изменился, переход к проверкам
                dec     lpcnt           ;   Уменьшить допустимое время ожидания
                brne    rsvr_wait_2     ;   Если время не вышло, продолжить ожидание
                rjmp    rsvr_timeout    ;   Иначе, переход к обработке таймаута
;   Проверка длительности импульса
rsvr_chck_1:    cpi     lpcnt,  0x0D    ;   Сравнить оставшееся время с порогом
                brcc    rsvr_chck_2     ;   Если не синхроимпульс, ко второй проверке
                subi    plcnt,  0x01    ;   Уменьшить необходимое число синхроимпульсов
                brcc    rsvr_skip_1     ;   Если заёма нет, то пропуск
                clr     plcnt           ;       отмены вычитания
rsvr_skip_1:    ldi     lpcnt,  0x03    ;   Инициализация задержки
                rjmp    rsvr_revsl      ;   Переход к задержке
;   Проверка возможности перехода к считыванию
rsvr_chck_2:    tst     plcnt           ;   Проверка необходимого числа синхроимпульсов
                breq    rsvr_rdng       ;   Если достаточно, то к процедуре считывания
                dec     flcnt           ;   Уменьшить допустимое число ошибок
                breq    rsvr_end        ;   Если лимит попыток достигнут, закончить
                ldi     plcnt,  0x08    ;   Минимальное число синхроимпульсов
                ldi     lpcnt,  0x03    ;   Инициализация задержки
                rjmp    rsvr_revsl      ;   Переход к задержке
;   Процедура считывания данных
rsvr_rdng:      ldi     lpcnt,  0x05    ;   Инициализация задержки
                com     lstat
rsvr_btinit:    ldi     rslt,   0x80    ;   Инициализация принимаемого байта
;   Мёртвое время после последней операции
rsvr_dtm_2:     dec     lpcnt           ;   Уменьшить время задержки
                brne    rsvr_dtm_2      ;   Повторить, если время не вышло
;   Ожидание переключения с таймаутом
                ldi     lpcnt,  0x0B    ;   Допустимое время ожидания смены сигнала
rsvr_wait_3:    in      temp,   INPRT   ;   Чтение линии
                eor     temp,   lstat   ;   Сравнение
                andi    temp,   1<<ACO  ;       с запомненным значением
                brne    rsvr_chng_2     ;   Если значение изменилось переход к задержке
                dec     lpcnt           ;   Уменьшить допустимое время ожидания
                brne    rsvr_wait_3     ;   Если время не вышло, продолжить ожидание
                rjmp    rsvr_end        ;   Иначе, закончить процедуру
;   Задержка перед считыванием
rsvr_chng_2:    ldi     lpcnt,  0x11    ;   Инициализация задержки перед считыванием
rsvr_dtm_3:     dec     lpcnt           ;   Уменьшить время задержки
                brne    rsvr_dtm_3      ;   Повторить, если время не вышло
;   Процедура считывания
                ldi     plcnt,  0x00    ;   Инициализация числа чтений нулевго бита
;   Счёт по низкому уровню
                ldi     lpcnt,  0x08    ;   Инициализация числа чтений низкого уровня
rsvr_read_1:    in      temp,   INPRT   ;   Чтение линии
                eor     temp,   lstat   ;   Сравнение
                andi    temp,   1<<ACO  ;       с запомненным значением
                breq    rsvr_skip_2     ;   Если прочитана единица, то пропустить
                inc     plcnt           ;       инремент числа чтений нулевого бита
rsvr_skip_2:    dec     lpcnt           ;   Уменьшить необходимое число чтений
                brne    rsvr_read_1     ;   Если чтения не исчерпаны, повторить
;   Счёт по высокому уровню
                ldi     lpcnt,  0x08    ;   Инициализация числа чтений высокого уровня
rsvr_read_2:    in      temp,   INPRT   ;   Чтение линии
                eor     temp,   lstat   ;   Сравнение
                andi    temp,   1<<ACO  ;       с запомненным значением
                brne    rsvr_skip_3     ;   Если прочитан ноль, то пропустить
                inc     plcnt           ;       инремент числа чтений нулевого бита
rsvr_skip_3:    dec     lpcnt           ;   Уменьшить необходимое число чтений
                brne    rsvr_read_2     ;   Если чтения не исчерпаны, повторить
;   Расшифровка принятого бита в читаемый байт
                subi    plcnt,  0x08    ;   Сравнение числа нулевых чтений с порогом
                ror     rslt            ;   Сохранение бита в принимаемый байт
                brcs    rsvr_save       ;   Если байт готов, то сохранить его
                ldi     lpcnt,  0x06    ;   Инициализация задержки
                rjmp    rsvr_dtm_2      ;   Переход к задержке
;   Сохранение байта
rsvr_save:      st      x+,     rslt    ;   Запись байта в регистры/память
                cpi     r26,    0x10    ;   Проверка выхода указателя за регистр R15
                brne    rsvr_skip_4     ;   Если выхода нет, то пропустить
                ldi     r26,    0x60    ;       перестановку указателя на память
rsvr_skip_4:    cpi     r26,    0xD8    ;   Проверить наличие свободного места
                breq    rsvr_end        ;   Если место закончилось, закончить процедуру
                dec     btcnt           ;   Иначе, уменьшить количество читаемых байт
                breq    rsvr_end        ;   Если все байты приняты, закончить процедуру
                ldi     lpcnt,  0x02    ;   Иначе, инициализация задержки
                rjmp    rsvr_dtm_2      ;   Переход к задержке
;   Конец
rsvr_end:       ret
Последний раз редактировалось B@R5uk Вт июл 15, 2014 15:45:07, всего редактировалось 1 раз.
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: AVR studio 4 в вопросах и ответах

Сообщение Gudd-Head »

Что-то вы в оффтоп свалились, товарищи.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
B@R5uk
Собутыльник Кота
Сообщения: 2896
Зарегистрирован: Сб ноя 13, 2010 12:53:25
Откуда: приходит весна?

Re: AVR studio 4 в вопросах и ответах

Сообщение B@R5uk »

Gudd-Head, прошу прощения.

А AVR Studio только к протеусу можно подключить? С Микрокапом она не дружит? А то не охото новую программу осваивать, а моделировать работу МК в виртуальном железе очень хотелось бы.
Alexeyslav
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич
Контактная информация:

Re: AVR studio 4 в вопросах и ответах

Сообщение Alexeyslav »

Где это вы такой Z80 нашли? В те времена он работал на максимальной частоте 2.5Мгц, потом появились его высокоскоростные аналоги на Z80A 4Мгц, 6Мгц, 8Мгц и даже Z80H на 12Мгц.
14Мгц это вероятно была системная частота которая делилась формируя необходимые частоты в схеме и в том числе нужные для процессора 3.5мгц, потом эти 3.5Мгц тактируют внутренний конвеер в процессоре, и каждая команда выполняется минимум за 4 таких такта, даже NOP.

3000 тактов на бит это не перебор, их можно потратить на помехоустойчивый алгоритм.
Аватара пользователя
WishMasterMax
Потрогал лапой паяльник
Сообщения: 389
Зарегистрирован: Пн июл 09, 2012 11:07:59
Откуда: Ukraine
Контактная информация:

Re: AVR studio 4 в вопросах и ответах

Сообщение WishMasterMax »

Доброго времени суток! Подскажите а как в студии писать в еепром собственные структуры? С байтами то все понятно, а вот по аналогии со структурами не получается работать. Структура имеет следующий вид
Спойлер

Код: Выделить всё

typedef struct {
	unsigned char R;     
	unsigned char G;  
	unsigned char B;   
} TColor;
Необходимо записать в еепром массив из 10 таких структур. Ткните мордой пожалуйста :)) Заранее благодарен :))
In me the WishMaster...
Изображение
Изображение
Ответить

Вернуться в «AVR»