AVR studio в вопросах и ответах
- B@R5uk
- Собутыльник Кота
- Сообщения: 2896
- Зарегистрирован: Сб ноя 13, 2010 12:53:25
- Откуда: приходит весна?
Re: AVR studio 4 в вопросах и ответах
Подскажите, пожалуйста, имеется ли в АВР-студии возможность эмулировать работу МК при заданных осцилограммах напряжений на его входах? То есть я программирую МК так, чтобы он вёл себя определённым образом при подаче на вход определённых сигналов, и хочу это проверить перед прошивкой. Я знаю, что в АВР-студии можно во время дебагинга выставлять мышкой значения логических входов МК. Но, поскольку входные сигналы имеют длину в тысячи тактов МК, проделать такую проверку пологаясь только на брэйкпоинты и мышку не представляется возможным. Кроме того, желательно, чтобы эмулировалась работа переферийных устройств, в частности компаратора (поскольку именно на него будет подаваться аналоговый сигнал). Подскажите, чем можно воспользоваться, если в AVR Studio нет такой возможности.
Заранее спасибо.
Заранее спасибо.
- Реклама
Re: AVR studio 4 в вопросах и ответах
Доброго всем дня! Пишу один простенький код под тиньку13 но он почему то не хочет работать не в протеусе не в железке, симулятор студии работает нормально...
Код следующий:
Понимаю что код ужасный но очень нужна помощь, месяц убил на него а он не работает толком. Ошибки выбиваются при работе с кнопками, а именно при вызове макроса POW_ON.
протеус говорит на это:
железка просто молчит
Заранее благодарен
Код следующий:
Спойлер
Код: Выделить всё
#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);
}
}
протеус говорит на это:
Спойлер
Заранее благодарен
-
Alexeyslav
- Друг Кота
- Сообщения: 4550
- Зарегистрирован: Чт май 05, 2011 21:26:34
- Откуда: Украина, Славутич
- Контактная информация:
Re: AVR studio 4 в вопросах и ответах
Какая же это работа с кнопками? Такое происходит когда в схеме происходят очень быстрые процессы, тогда модель математически распадается(появляются такие ситуации как деление на ноль, бесконечные величины и т.д.) и невозможно что-либо далее рассчитать. В данном случае, не пытайтесь в симулятор ввести ВСЮ схему - только те части которые необходимо симулировать, остальную часть схемы заменить математическим эквивалентом или просто выбросить.
У вас там наверняка есть и силовые ключи и трансформатор... эти элементы не нужны для отладки программы, именно они и приводят к таким последствиям.
У вас там наверняка есть и силовые ключи и трансформатор... эти элементы не нужны для отладки программы, именно они и приводят к таким последствиям.
Re: AVR studio 4 в вопросах и ответах
Да, вы правы, есть полевики и реле, но почему тогда в железе не работает?
-
Alexeyslav
- Друг Кота
- Сообщения: 4550
- Зарегистрирован: Чт май 05, 2011 21:26:34
- Откуда: Украина, Славутич
- Контактная информация:
Re: AVR studio 4 в вопросах и ответах
На этот вопрос существует миллион ответов. искать их непродуктивно. Проще ответить на вопрос почему оно ДОЛЖНО работать, обычно на этот вопрос ответов не так уж много. Попробуйте подойти к решению проблемы именно с этой стороны.
- Реклама
Re: AVR studio 4 в вопросах и ответах
В протеусе заработало после упрощения схемы, нашлось пару мелких недочетов, проверю на железе теперь) Спасибо Вам огромное 
- Gudd-Head
- Друг Кота
- Сообщения: 20092
- Зарегистрирован: Чт сен 18, 2008 12:27:21
- Откуда: Столица Мира Санкт-Петербург
Re: AVR studio 4 в вопросах и ответах
Можно, но только лог. "1" и "0".B@R5uk писал(а):Подскажите, пожалуйста, имеется ли в АВР-студии возможность эмулировать работу МК при заданных осцилограммах напряжений на его входах?
Симулятор опшионс — стимули энд логгинг — стимули: подгружаете файл, который будет воздействовать на соотв. порт.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
- B@R5uk
- Собутыльник Кота
- Сообщения: 2896
- Зарегистрирован: Сб ноя 13, 2010 12:53:25
- Откуда: приходит весна?
Re: AVR studio 4 в вопросах и ответах
Gudd-Head, огромное СПАСИБИЩЕ! Будем пробовать.
-
Alexeyslav
- Друг Кота
- Сообщения: 4550
- Зарегистрирован: Чт май 05, 2011 21:26:34
- Откуда: Украина, Славутич
- Контактная информация:
Re: AVR studio 4 в вопросах и ответах
Но бывает полезней к студии подключить протеус в качестве удаленного отладчика(вообще поидее наоборот, это студия подключается к протеусу в качестве удаленного отладчика, но загружает его в своё окно). Правда, протеус тогда может помещаться только в пределах главного окна студии, что не всегда удобно...
- B@R5uk
- Собутыльник Кота
- Сообщения: 2896
- Зарегистрирован: Сб ноя 13, 2010 12:53:25
- Откуда: приходит весна?
Re: AVR studio 4 в вопросах и ответах
Gudd-Head, подскажите, пожалуйста, где можно прочитать про формат файлов *.sti или про то, какой программой их можно создать?
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: AVR studio 4 в вопросах и ответах
вот здесь можно прочитать: http://www.simple-devices.ru/attachment ... 8-2010.pdfB@R5uk писал(а):где можно прочитать про формат файлов *.sti или про то, какой программой их можно создать?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- B@R5uk
- Собутыльник Кота
- Сообщения: 2896
- Зарегистрирован: Сб ноя 13, 2010 12:53:25
- Откуда: приходит весна?
Re: AVR studio 4 в вопросах и ответах
ARV, Gudd-Head, спасибо вам преогромнейшее, вы не представляете, как мне помогли. Отладил таки свою подпрограмму приёма сигнала. Оно даже в железе заработало. Замутил тут хитрую систему, позволяющую передавать данные из программы на ноутбуке в микроконтроллер через звуковой выход путём модуляции по типу спектрумовского сохранения на кассету. Если кто в курсе, тот поймёт. Программа -- жесть, жёсткие тайминги, привязка к скорости выполнения каждой комманды МК, длительность каждого цикла и каждого пути по всем ветвлениям процедуры пришлось рассчитать.
-
Alexeyslav
- Друг Кота
- Сообщения: 4550
- Зарегистрирован: Чт май 05, 2011 21:26:34
- Откуда: Украина, Славутич
- Контактная информация:
Re: AVR studio 4 в вопросах и ответах
Это, вероятно, просто признак неправильного подхода к задаче. "спектрум" будучи более медлительным и тот справлялся замечательно с этой задачей, а у вас пришлось все жестко рассчитывать. Или скорости огромные? да вроде же звуковой тракт...
- B@R5uk
- Собутыльник Кота
- Сообщения: 2896
- Зарегистрирован: Сб ноя 13, 2010 12:53:25
- Откуда: приходит весна?
Re: AVR studio 4 в вопросах и ответах
Я в своё время разбирался с его программой. Там во-первых у процессора набор инструкций более удобный, во-вторых, спектрум работает на частоте 3,5 МГц, а мой МК сейчас от встроенного 1 МГц-вого генератора, в третьих, если мне не изменяет память, то там тоже много рабочих констант, то есть всё жёстко рассчитано.Alexeyslav писал(а):Это, вероятно, просто признак неправильного подхода к задаче. "спектрум" будучи более медлительным и тот справлялся замечательно с этой задачей, а у вас пришлось все жестко рассчитывать. Или скорости огромные? да вроде же звуковой тракт...
Впрочем, вот моя программа, может посоветуете, что можно улучшить (только не советуйте всё переделать через прерывания -- я пока всех тонкостей не знаю):
Спойлер
Код: Выделить всё
.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
-
Alexeyslav
- Друг Кота
- Сообщения: 4550
- Зарегистрирован: Чт май 05, 2011 21:26:34
- Откуда: Украина, Славутич
- Контактная информация:
Re: AVR studio 4 в вопросах и ответах
Частота процессора не показатель, на том процессоре который использовался в спектруме одна самая простая команда выполнялась 4 такта, а длинная - 12 тактов и более. Так что ресурс по скорости исполнения инструкций и того ниже.
Привязка к длительности импульса конечно очень проста, но такой способ передачи данных очень чувствителен к помехам, любой лишний импульс и все насмарку т.к. теряется синхронизация.
Проще было бы посмотреть в сторону передачи данных как это делается в UART, только появляется специфика - нестабильная скорость передачи/приема, которую я решил очень просто - передается всего 4 информационных бита в одной посылке, это дает нам нечувствительность к разнице скорости приема/передачи в 10%, перед началом передачи даётся импульс повышенной длительности по которому приемник определяет необходимую скорость передачи, подразумевая что во время передачи всего пакета частота тактирования существенно не изменится(более 10%).
У меня получилось таким способом выиграть еще 16% (+-8% отклонения скорсоти в обе стороны) на нестабильность скорости приема/передачи. У вас может получится и того больше.
Всё это я делал на фиксированной скорости 48Кбод = 4.8Мгц/100 контроллер после получения синхронизирующего импульса и коррекции скорости приема по нему просто считывал состояние порта каждые 100 тактов при помощи таймера - в остальное время контроллер не делал ничего критичного. Единственные узкие места - обеспечить минимальное время между концом первого импульса синхронизации и вычислением скорости приема по результатам измерения длительности импульса и алгоритм ожидания начала следующего импульса синхронизации перед каждой посылкой из 4-х бит, чтобы ликвидировать накапливающуюся ошибку скорости приема.
В данном случае, в случае помех может быть повреждены отдельные биты, но пакеты будут приняты несмотря ни на что. И эта проблема уже решается применением помехоустойчивых кодов на уровне выше. Но судя по тому что у вас сейчас все работает на наличие помех не жалуетесь.
Привязка к длительности импульса конечно очень проста, но такой способ передачи данных очень чувствителен к помехам, любой лишний импульс и все насмарку т.к. теряется синхронизация.
Проще было бы посмотреть в сторону передачи данных как это делается в UART, только появляется специфика - нестабильная скорость передачи/приема, которую я решил очень просто - передается всего 4 информационных бита в одной посылке, это дает нам нечувствительность к разнице скорости приема/передачи в 10%, перед началом передачи даётся импульс повышенной длительности по которому приемник определяет необходимую скорость передачи, подразумевая что во время передачи всего пакета частота тактирования существенно не изменится(более 10%).
У меня получилось таким способом выиграть еще 16% (+-8% отклонения скорсоти в обе стороны) на нестабильность скорости приема/передачи. У вас может получится и того больше.
Всё это я делал на фиксированной скорости 48Кбод = 4.8Мгц/100 контроллер после получения синхронизирующего импульса и коррекции скорости приема по нему просто считывал состояние порта каждые 100 тактов при помощи таймера - в остальное время контроллер не делал ничего критичного. Единственные узкие места - обеспечить минимальное время между концом первого импульса синхронизации и вычислением скорости приема по результатам измерения длительности импульса и алгоритм ожидания начала следующего импульса синхронизации перед каждой посылкой из 4-х бит, чтобы ликвидировать накапливающуюся ошибку скорости приема.
В данном случае, в случае помех может быть повреждены отдельные биты, но пакеты будут приняты несмотря ни на что. И эта проблема уже решается применением помехоустойчивых кодов на уровне выше. Но судя по тому что у вас сейчас все работает на наличие помех не жалуетесь.
- B@R5uk
- Собутыльник Кота
- Сообщения: 2896
- Зарегистрирован: Сб ноя 13, 2010 12:53:25
- Откуда: приходит весна?
Re: AVR studio 4 в вопросах и ответах
3,5 МГц — это частота исполнения команд процессора Z80. А так то частота тактовых импульсов 14 МГц. Да, там есть команды, которые исполняются долго, но даже инкремент, декремент сдвоенного регистра по длительности равен команде NOP. Так что частота, всё-таки показатель.
На счёт стабильности приёма я в своей программе не задумывался вообще. Для меня тут было главное — простота кода и чтобы хоть как-то заработало. (Кстати, полноценные тесты ещё впереди). Тем, не менее, у меня в процессе приёма синхронизация происходит для каждого бита по спаду сигнала от предыдущего бита. В те моменты времени, когда в сигнале передаётся информация, процедура производит 16 чтений порта, результаты усредняются, и в конце подсчитывается итоговый результат. (Код перед вами — легко убедиться самому -- код с метки rsvr_read_1) Так что стабильность, думаю, достигается высокая (необходима ошибка синхронизации на 1/8 рабочего периода, (который равен 250 мкс), либо 50% сигнала в информационной области должно быть испорчено, чтобы результат получился неправильный).
На счёт таймера мысль была, но поскольку это моё первое знакомство с AVR вообще, я пока ещё не в курсе как, да чего. Изучение ещё только предстоит. Возможно, используя прерывания и таймер удастся сделать процедуру приёма сигнала в фоновом режиме, а не загружая весь МК работой. При моёй текущей частоте несущего сигнала, бит передаётся в течении 250 циклов МК, этого времени более чем достаточно для обсчёта. А если подключить кварц на 12 МГц, то расходовать 3000 операций на один бит данных — это уже будет перебор.
Ещё раз код, а то уехал.
На счёт стабильности приёма я в своей программе не задумывался вообще. Для меня тут было главное — простота кода и чтобы хоть как-то заработало. (Кстати, полноценные тесты ещё впереди). Тем, не менее, у меня в процессе приёма синхронизация происходит для каждого бита по спаду сигнала от предыдущего бита. В те моменты времени, когда в сигнале передаётся информация, процедура производит 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 в вопросах и ответах
Что-то вы в оффтоп свалились, товарищи.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
- B@R5uk
- Собутыльник Кота
- Сообщения: 2896
- Зарегистрирован: Сб ноя 13, 2010 12:53:25
- Откуда: приходит весна?
Re: AVR studio 4 в вопросах и ответах
Gudd-Head, прошу прощения.
А AVR Studio только к протеусу можно подключить? С Микрокапом она не дружит? А то не охото новую программу осваивать, а моделировать работу МК в виртуальном железе очень хотелось бы.
А AVR Studio только к протеусу можно подключить? С Микрокапом она не дружит? А то не охото новую программу осваивать, а моделировать работу МК в виртуальном железе очень хотелось бы.
-
Alexeyslav
- Друг Кота
- Сообщения: 4550
- Зарегистрирован: Чт май 05, 2011 21:26:34
- Откуда: Украина, Славутич
- Контактная информация:
Re: AVR studio 4 в вопросах и ответах
Где это вы такой Z80 нашли? В те времена он работал на максимальной частоте 2.5Мгц, потом появились его высокоскоростные аналоги на Z80A 4Мгц, 6Мгц, 8Мгц и даже Z80H на 12Мгц.
14Мгц это вероятно была системная частота которая делилась формируя необходимые частоты в схеме и в том числе нужные для процессора 3.5мгц, потом эти 3.5Мгц тактируют внутренний конвеер в процессоре, и каждая команда выполняется минимум за 4 таких такта, даже NOP.
3000 тактов на бит это не перебор, их можно потратить на помехоустойчивый алгоритм.
14Мгц это вероятно была системная частота которая делилась формируя необходимые частоты в схеме и в том числе нужные для процессора 3.5мгц, потом эти 3.5Мгц тактируют внутренний конвеер в процессоре, и каждая команда выполняется минимум за 4 таких такта, даже NOP.
3000 тактов на бит это не перебор, их можно потратить на помехоустойчивый алгоритм.
- WishMasterMax
- Потрогал лапой паяльник
- Сообщения: 389
- Зарегистрирован: Пн июл 09, 2012 11:07:59
- Откуда: Ukraine
- Контактная информация:
Re: AVR studio 4 в вопросах и ответах
Доброго времени суток! Подскажите а как в студии писать в еепром собственные структуры? С байтами то все понятно, а вот по аналогии со структурами не получается работать. Структура имеет следующий вид
Необходимо записать в еепром массив из 10 таких структур. Ткните мордой пожалуйста
Заранее благодарен 
Спойлер
Код: Выделить всё
typedef struct {
unsigned char R;
unsigned char G;
unsigned char B;
} TColor;



