Модераторы: PILOT, ManiaK, Mazzi
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Прерывание, время выполнения кода 
:(
    Опции темы
supercelt
Дата 11.8.2015, 19:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 658
Регистрация: 25.8.2005

Репутация: нет
Всего: 1



Привет. 

Код

#define F_CPU 16000000 //Частота камня
#include <avr/io.h>
#include <stdio.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <string.h>
#include <util/delay.h>

volatile unsigned char begin_recieve = 0;
volatile unsigned char cycle_counter = 0;
volatile unsigned char buffer[64];
volatile unsigned char cmp1[64] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};

int memcmp (const void * buf1, const void * buf2, size_t count){
    if (!count)
    return(0);
    while ( --count && *(char *)buf1 == *(char *)buf2 ) {
        buf1 = (char *)buf1 + 1;
        buf2 = (char *)buf2 + 1;
    }
    return( *((unsigned char *)buf1) - *((unsigned char *)buf2) );
}

ISR(TIMER2_COMP_vect){ //Входим в прерывание 2 раза за 1 период clk
    if(PIND & (1 << 7)){ //А теперь делаем 1 раз за период
        
        if(!(PIND & (1 << 6)) && begin_recieve == 0){ //Если на приёмном порте обнаружен ноль, значит начался приём первого бита
            begin_recieve = 1; //Ставим флаг что бы не заходить в это условие, т.к. Оно для распознования первого бита и факта начала приёма
            buffer[cycle_counter] = 1;
            cycle_counter++;
        } else if(begin_recieve == 1){
            if(!(PIND & (1 << 6))){
                buffer[cycle_counter] = 1;
            } else if(PIND & (1 << 6)){
                buffer[cycle_counter] = 0;
            }
            cycle_counter++;
        }
        
        if(cycle_counter == 64){
                    if(memcmp(buffer, cmp1, 64) == 0){
                PORTA |= (1 << 0);
                    }
            cycle_counter = 0;
            begin_recieve = 0;
        }
        
    }
        
}


int main(void)
{
    DDRA |= (1 << 0) | (1 << 1);
    PORTA &= ~(1 << 0) | (1 << 1);
    DDRD |= (1 << 7);
    PORTD &= ~(1 << 7);
    DDRD &= ~(1 << 6);
    PORTD &= ~(1 << 6);
    OCR2 = 63; //Задаём частоту счётчика. При предделителе 1/1 и OCR = 31 Частота будет 125 kHz
    TCCR2 |= (0 << WGM20)|(1 << WGM21); //Режим работы таймера-счётчика0 - сброс при совпадении (СТС)
    TCCR2 |= (0 << CS22)|(0 << CS21)|(1 << CS20); //предделитель частоты 1\1
    TCCR2 |= (0 << COM21)|(1 << COM20); //Смена сигнала на PB3 - Toggle
    TIMSK |= (1 << OCIE2); //Разрешаем уходить в прерывание при совпадении TCNT0 и OCR*/

    asm("sei"); //Разрешаем прерывания глобально

    while(1){
    asm ("nop");
        }
}


Вопрос. При заходе в прерывание (через одно) считывается состояние порта д6
Как только таких считываний будет 64, то идёт проверка массива[64] в которые помещались состояния порта 
Во время проверки этого массива в отладчике видно, что пока работает функция, счётчик сравнения уже подходит к тому что бы сделать следующее прерывание. А ещё проверка массива не закончилась. А следующее прерывание это новые 64 бита информации. Отладчик вообще правильно всё показывает? 
Частота камня 16 мгц, прерывание по совпадению - 63 ocr2.
PM   Вверх
ФедосеевПавел
Дата 11.8.2015, 19:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 7.2.2009

Репутация: 1
Всего: 10



Я не спец, но попробовал бы для ускорения следующее:
1. побитовый приём сдвигом бы записывал в битовый массив, при этом объём сравнений уменьшился бы в 8 раз.
2. если 64 сравнения долго, то пакет можно разбить на порции по 8, 16 или 32 бита и по окончании приема порции сравнивать, и за время приёма пакета будет 8, 4 или 2 более коротких сравнения.

А если совместить оба совета...

Но повторюсь, я лишь размышляю.
PM   Вверх
supercelt
Дата 11.8.2015, 20:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 658
Регистрация: 25.8.2005

Репутация: нет
Всего: 1



Тут фишка ещё вот в чём. Этот код это Rfid считка меток 125кгц. И может быть у меня сама логика неправильная. Я всегда стараюсь полностью принять быстро данные, а потом уже этот массив ковырять. НО, посылка кода сметки  это 64 бита информации. И каждый 1 бит - это 64 такта несущей частоты 125 кгц. А приём у меня идёт 1 раз за период несущей. Получается я принимаю первые 64 такта - это один бит. Потом проверяю что бы все 64 были либо 1 либо 0. И если допустим все 64 элемента - 1, то значит мы приняли полноценный 1 бит. И таких битов 64. 
Так вот если принимать разом то это массив из 4096 элементов. Мне кажется памяти не хватит в мк. Либо читать состояние порта только 1 раз за 64 такта. А если потери пакетов или амплитудные помехи?
PM   Вверх
Romikgy
Дата 11.8.2015, 20:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 3
Всего: 146



Цитата(supercelt @  11.8.2015,  18:26 Найти цитируемый пост)
счётчик сравнения уже подходит к тому что бы сделать следующее прерывание. А ещё проверка массива не закончилась. А следующее прерывание это новые 64 бита информации.

это говорит о неправильном подходе к реализации!
прерывание должно выполнятся максимально быстро ! никаких долгих расчетов в них быть не должно !
надо менять логику программы... и всегда помнить что МК это не интел на 2-3 гигагерца!


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
ФедосеевПавел
Дата 11.8.2015, 20:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 7.2.2009

Репутация: 1
Всего: 10



Почитайте в стандарте RFID, как обрабатывать ошибки и синхронизироваться, но после синхронизации, я бы 64 раза принимал бит и инкрементировал некие счётчики количества 1 и 0. После приёма 64 бит по этим счётчикам принимал решение о том, что пришло 0 или 1, с учётом возможных ошибок (count0=10, count1=54). Теперь ясно, что пришло, и этот результирующий бит записал бы в массив.
Не знаю как записал - или из ISR или выставил бы флаг готовности, по которому из основной программы производилась бы запись.
PM   Вверх
supercelt
Дата 11.8.2015, 21:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 658
Регистрация: 25.8.2005

Репутация: нет
Всего: 1



ФедосеевПавел, Всё правильно пишите. Я так уже пробовал. Слишком долгая обработка идёт тоже. Я вот почему-то думаю что в считках сделано так что никто не принимает все 64 части одного бита. Ибо это накладно. Может берут 1 значение между 0 и 64 тактом и всё. Как-то так
PM   Вверх
ФедосеевПавел
Дата 11.8.2015, 21:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 7.2.2009

Репутация: 1
Всего: 10



Не знаю. Есть стандарт и для чего-то же каждый бит дублируется 64 раза.


Цитата(supercelt @  11.8.2015,  21:02 Найти цитируемый пост)
Слишком долгая обработка идёт тоже.

Но во многие разы быстрее.
А что мешает после обработки 64 принятых разрядов в ISR выставить флаг готовности и неспешно за время приёма следующих 64 разрядов записать этот бит в массив принятых бит. Времени - вагон 64/(125кГц)=(1/2)мс, что на 16МГц составит примерно 4000 команд. Это на запись 1 бита в массив. Тут даже можно умножение применить, не только указатели.
PM   Вверх
supercelt
Дата 11.8.2015, 22:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 658
Регистрация: 25.8.2005

Репутация: нет
Всего: 1



так вот потом, когда этот 64 массив надо перебрать, нужно уже принимать и записывать в буфер следующие 64. Есть пример кода считывателя. Так там автор и принимает и обрабатывает биты во вложенных циклах. И непонятно как это у него всё работает, ведь дциклы у него в основной ф-ии программы и не привязаны ни к времени ни к прерываниям. Получается он как бы уверен что один проход цикла фор у него занимает как раз 1 бит. Угадал штоль?
PM   Вверх
ФедосеевПавел
Дата 11.8.2015, 22:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 7.2.2009

Репутация: 1
Всего: 10



Два чередующихся буфера по 8 байт.
Один используется для приема, второй для обработки. После приёма в буфер №1 ставится признак завершения приёма и приём следующего массива идёт в буфер №2. А буфер №1 обрабатывается. По завершению обработки буфер №1 помечается, как готовый к приёму и по завершению приёма в буфер №2, снова будет приём в буфер №1.

Пробуй реализовывать и проверять. А то получается игра в хрустальные шары.

Я более чем уверен, что предложенные мною сейчас и ранее меры достаточны для увеличения быстродействия. Они алгоритмически сложнее for, но эффективны.

Пожалуй, мне больше нечего добавить в теме. Совсем нечего.
PM   Вверх
supercelt
Дата 11.8.2015, 22:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 658
Регистрация: 25.8.2005

Репутация: нет
Всего: 1



Спасибо, буду пробовать
PM   Вверх
xvr
Дата 12.8.2015, 13:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



Цитата(supercelt @  11.8.2015,  21:02 Найти цитируемый пост)
 Я так уже пробовал. Слишком долгая обработка идёт тоже.

Т.е. складывание в массив 64х битов и последующая memcmp над ним быстрее, чем простой инкремент одной переменной? Не верю! ( (с) Станиславский)  smile 


PM MAIL   Вверх
bass
Дата 19.8.2015, 14:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 315
Регистрация: 5.8.2007

Репутация: нет
Всего: 2



Не понимаю по какому протоколу осуществляеться прием.
Но сравнение нужно проводить не в прерывании. Так и МК можно подвесить, вернее сам то он не сломаеться а выполнять свои функции откажеться. Надеюсь в данной схеме не предусмотрено управление Кран-балкой. ТО на производстве будет ЧП.


Код

#define F_CPU 16000000 //Частота камня
#include <avr/io.h>
#include <stdio.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <string.h>
#include <util/delay.h>

volatile unsigned char begin_cmp = 0;



ISR(TIMER2_COMP_vect)
{ 
begin_cmp = 1;//говорим что приняли
}
        
}
int main(void)
{
//Настраиваем таемер

    while(1)
{
             if( begin_cmp == 1)//нужно выполнить сравнение
             {
             begin_cmp = 0;
              // Производим  операцию
              }
}

Правда не понл по какому  протоколу осуществляеться прием. Но по комментариям видно что старт осуществляеться по низкому уровню на линии. Не легче ли исользовать INT (Внешние прерывание).
На СТМ е могут возникнуть проблемы 
 begin_cmp = 0; в данном месте. Нужно отключать прерывание в момент выполнения данной операции. Особенно если инициаторов задачи несколько. (Не атомарная операция) 

Это сообщение отредактировал(а) bass - 19.8.2015, 14:31
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Микроконтроллеры (MCU) и микропроцессоры (MPU)"
PILOT ManiaK
UniBomb Mazzi

На данный раздел помимо Правил форума распространяются текже следующие правила:


  • Прежде чем создать тему воспользуйтесь поиском или посмотрите в faq. Возможно на форуме уже есть ответ на ваш или близкий к вашему вопрос.
  • В заголовке темы в квадратных скобках обозначьте используемое семейство микроконтроллера: [avr],[pic],[arm].
  • При создании темы с вопросом указывайте участок кода с ошибкой, версию компилятора, схемы подключения, fuse биты и прочие данные, которые помогут найти правильный ответ. Для форматирования текста программ используйте кнопку код.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Для флуда, просьб выполнить задание, поиска партнёров или исполнителей существуют свои разделы.
  • Если вы заметили несовместимое с правилами сообщение, то можете уведомить об этом модератора раздела нажав кнопку Репорт у соответствующего сообщения.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, PILOT, ManiaK, UniBomb, Mazzi.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Микроконтроллеры (MCU) и микропроцессоры (MPU) | Следующая тема »


 




[ Время генерации скрипта: 0.0532 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.