Точный подсчет тактов контроллера

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Аватара пользователя
Radist228
Родился
Сообщения: 15
Зарегистрирован: Ср ноя 25, 2015 18:05:40

Точный подсчет тактов контроллера

Сообщение Radist228 »

Здравствуйте, пишу код в Keil uvision и использую отладочную плату STM32F4DISCOVERY и возникла необходимость точного расчета тактов выполнения куска кода. Нашел в интернетах код с помощью которого можно подсчитать количество тактов, но в режиме отладки счетчик выполняет разное количество тактов. Может есть какие либо другие способы подсчета количества тактов?

Код программы:


#include "main.h"
#include "math.h"



uint16_t delay_count=0;
uint16_t data_adc=0;
uint16_t flag=0,i_1,i_2,i_3,i_4;

uint32_t count_tic=0;
uint32_t mod_1=0,m_1,m_2,mo_p;
uint32_t mod_2=0,mod_3=0;
uint32_t N=16,N1=4;
uint32_t sq,X,i=0,sum;
int32_t y1[40][20],y2[40][20];
int32_t a_1,a_2,m;
uint32_t k,s;



void SysTick_Handler(void) //1ms
{
if(delay_count>0){delay_count--;}
}

/*-*/
uint32_t usr_sqrt(uint32_t value)
{
uint32_t d, a;

__asm {
CLZ a, value
RSB a, a, #0x1F
};

d = 1 << ((a >> 1)+1);
a = (d + ( value >> a )) >> 1;
d = (a + value / a)>>1;
a = (d + value / d)>>1;
d = (a + value / a)>>1;
a = (d + value / d)>>1;
return a;
}

/*-*/
uint16_t get_adc_value()
{
ADC_SoftwareStartConv(ADC1);
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
return ADC_GetConversionValue(ADC1);
}

/*-*/
void delay_ms(uint16_t delay_temp)
{
delay_count = delay_temp;
while(delay_count){}
}

/*-*/

int main(void)
{
SystemCoreClockUpdate();
SysTick_Config(SystemCoreClock/1000);
LED_ini();
DAC_ini();
ADC_R_ini();


#define DWT_CYCCNT *(volatile unsigned long *)0xE0001004
#define DWT_CONTROL *(volatile unsigned long *)0xE0001000
#define SCB_DEMCR *(volatile unsigned long *)0xE000EDFC




while(1)
{



if(flag==0){i_1=get_adc_value();flag=1;}
if(flag==1){i_2=get_adc_value();flag=2;}
if(flag==2){i_3=get_adc_value();flag=3;}
if(flag==3){i_4=get_adc_value();flag=0;}

SCB_DEMCR |= 0x01000000;
DWT_CONTROL|= 1; //включение счетчика
DWT_CYCCNT = 0;


i++;
mod_1=i%2;
y1[mod_1][0]=i_1-i_3;
y2[mod_1][0]=i_2-i_4;
mo_p=1;


for(k=1;k<=N1-1;k++)
{
m=mo_p;
m_1=(i)%(m+1);
m_2=(i)%(2*m+1);
mod_2=(m_1+1)%(m+1);
y1[m_2][k]=y1[m_1][k-1]+y1[mod_2][k-1];
y2[m_2][k]=y2[m_1][k-1]+y2[mod_2][k-1];
mo_p=2*mo_p;
}
mod_3=(m_2+1)&(2*m+1);
a_1=y1[m_2][N1-1]+y1[mod_3][N1-1];
a_2=y2[m_2][N1-1]+y2[mod_3][N1-1];
a_1*=a_1;
a_2*=a_2;
sum=a_1+a_2;
sq=usr_sqrt(sum);
X=sq/(2*N);
DAC_SetChannel1Data(DAC_Align_12b_R,X*1.365);
count_tic = DWT_CYCCNT; //результат
}
}




Вот картинки иллюстрирующие разное количество тактов
Рисунок_1.png
(139.7 КБ) 436 скачиваний
Рисунок_2.png
(139.52 КБ) 631 скачивание
Реклама
Аватара пользователя
scorpi_0n
Вымогатель припоя
Сообщения: 616
Зарегистрирован: Вс ноя 01, 2015 13:13:49

Re: Точный подсчет тактов контроллера

Сообщение scorpi_0n »

Radist228 писал(а):возникла необходимость точного расчета тактов выполнения куска кода.
Вот то что вы получили и есть самый точный расчёт. Даже если он в каждом случае разный.
Нашел в интернетах код с помощью которого можно подсчитать количество тактов, но в режиме отладки счетчик выполняет разное количество тактов.
Потому что АРМ не является ядром с детерминированным временем выполнения кода. Изначально. Даже в свободном полёте. А в режиме отладки и подавно. Плюс ещё может накладываться куча других факторов типа прерываний запросов ДМА и пр.
Может есть какие либо другие способы подсчета количества тактов?
Есть. На любом таймере например. Но результат будет такой же.
Реклама
Аватара пользователя
Radist228
Родился
Сообщения: 15
Зарегистрирован: Ср ноя 25, 2015 18:05:40

Re: Точный подсчет тактов контроллера

Сообщение Radist228 »

А можно ли как-нибудь сделать чтобы определенный кусок кода выполнялся определенное количество тактов. к примеру. часть кода выполняется за 100-200 тактов, но надо чтобы он выполнялся, к примеру, за 202 такта. можно ли сделать какое нибудь ожидание, что-то вроде задержки, которая ждала бы оставшееся число тактов до 202?
Аватара пользователя
Radist228
Родился
Сообщения: 15
Зарегистрирован: Ср ноя 25, 2015 18:05:40

Re: Точный подсчет тактов контроллера

Сообщение Radist228 »

И еще кое что забыл сказать, разное количество тактов выполняется именно этот кусок, что может быть причиной этому?


for(k=1;k<=N1-1;k++)
{
m=mo_p;
m_1=(i)%(m+1);
m_2=(i)%(2*m+1);
mod_2=(m_1+1)%(m+1);
y1[m_2][k]=y1[m_1][k-1]+y1[mod_2][k-1];
y2[m_2][k]=y2[m_1][k-1]+y2[mod_2][k-1];
mo_p=2*mo_p;
}
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
scorpi_0n
Вымогатель припоя
Сообщения: 616
Зарегистрирован: Вс ноя 01, 2015 13:13:49

Re: Точный подсчет тактов контроллера

Сообщение scorpi_0n »

Буфер данных буфер кода конвейер команд прерывания SysTick.
Вообще подсчёт тактов плохая примета. Приводит к потере времени и неработоспособному коду.
Реклама
Аватара пользователя
Radist228
Родился
Сообщения: 15
Зарегистрирован: Ср ноя 25, 2015 18:05:40

Re: Точный подсчет тактов контроллера

Сообщение Radist228 »

В этой задаче подсчет тактов необходим на этапе отладки. чтобы подстроиться под работу АЦП. время работы АЦП и выполнения кода должны быть одинаковыми, но этого, как я понял, достичь трудно(((
Ведь должны же быть какие нибудь способы решить данную проблему
Реклама
arkhnchul
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

Re: Точный подсчет тактов контроллера

Сообщение arkhnchul »

способы - не привязываться к тактам вообще.
вам зачем "время работы АЦП и выполнения кода должны быть одинаковыми"?
Аватара пользователя
Radist228
Родился
Сообщения: 15
Зарегистрирован: Ср ноя 25, 2015 18:05:40

Re: Точный подсчет тактов контроллера

Сообщение Radist228 »

ну там весь метод на этом построен, подается непрерывный сигнал и мы его обрабатываем. один период мы квантуем ацп, после проводим расчет этого периода и так через период производятся вычисления, сперва ацп, потом расчет. но там еще есть накопление нескольких периодов , поэтому все должно быть точно. если появляются рассинхроны то демодулированный сигнал получается не четкий
arkhnchul
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

Re: Точный подсчет тактов контроллера

Сообщение arkhnchul »

и как часто надо опрашивать АЦП?
если я правильно представляю себе описанную задачу, то путь примерно такой: настраиваем АЦП на старт преобразования по событию таймера, в прерывании по окончанию преобразования запускаем расчет. Поскольку интервалы таймера весьма точны, то периоды между преобразованиями будут известны и фиксированы (если вычисления будут успевать пройти между событиями таймера)
Аватара пользователя
Radist228
Родился
Сообщения: 15
Зарегистрирован: Ср ноя 25, 2015 18:05:40

Re: Точный подсчет тактов контроллера

Сообщение Radist228 »

ну, система какая, нужно на одном периоде выполнить 4 отсчета ацп. после чего произвести расчет
Аватара пользователя
Radist228
Родился
Сообщения: 15
Зарегистрирован: Ср ноя 25, 2015 18:05:40

Re: Точный подсчет тактов контроллера

Сообщение Radist228 »

ну а сама частота опроса зависит от времени расчета, там вычисления довольно долгие по тактам
arkhnchul
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

Re: Точный подсчет тактов контроллера

Сообщение arkhnchul »

Radist228 писал(а): нужно на одном периоде выполнить 4 отсчета ацп. после чего произвести расчет
период какой?
Radist228 писал(а):частота опроса зависит от времени расчета
так не бывает :dont_know: если вам нужно довести частоту опроса до такой степени, чтобы она ограничивалась только производительностью вычислений - какой период максимально допустим?
Аватара пользователя
Radist228
Родился
Сообщения: 15
Зарегистрирован: Ср ноя 25, 2015 18:05:40

Re: Точный подсчет тактов контроллера

Сообщение Radist228 »

Ну смотрите. Суть данного метода в чем заключается.У нас есть синус с определенной частотой , мы берем 4 отсчета на периоде. После чего вычитаем и суммируем их и производим расчет буферных значений. Число тактов работы АЦП должно ровняться числу тактов вычислений. Как будто у нас непрерывные преобразования. Частота самого синуса напрямую зависит от количества тактов вычислений. К примеру, у меня количество тактов на вычисления где-то 1000, а число тактов на работу АЦП тоже примерно 1000. Частота несущей около 168 кГц.
arkhnchul
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

Re: Точный подсчет тактов контроллера

Сообщение arkhnchul »

Radist228 писал(а):У нас есть синус с определенной частотой , мы берем 4 отсчета на периоде.
на периоде синуса?
Radist228 писал(а):Частота самого синуса напрямую зависит от количества тактов вычислений.
:shock: вот этого не понял. Вы про входной или тот, который ЦАП-оп выводите?

если по-другому: вам нужны четыре последовательных отсчета АЦП, с фиксированными временными промежутками между ними. По этим отсчетам вы производите расчет и пихаете результат в ЦАП. Так?
если да, то, собственно, в описанной схеме с таймерами вообще не вижу проблемы. Если у вас допустимо отставание по времени ЦАП-а от отсчетов АЦП на два периода (==время восьми отсчетов), а не один с четвертью (==четырех плюс вычисления), то все еще вкуснее - обсчет предыдущей пачки можно делать в то время, пока формируется новая пачка целиком, а не ее четверть.
Аватара пользователя
Radist228
Родился
Сообщения: 15
Зарегистрирован: Ср ноя 25, 2015 18:05:40

Re: Точный подсчет тактов контроллера

Сообщение Radist228 »

Попробую еще раз обьяснить. А то и я начинаю путаться. В общем есть синус из вне, он подается на АЦП. Сам АЦП делает 4 отсчета(к примеру 500 тактов). После чего эти отсчеты отправляются считаться в коде. После чего надо рассчитанное значение подать на ЦАП. И все это надо сделать ровно за 500 тактов. Чтобы АЦП начал преобразование синуса в той же фазе как и в прошлый раз. Но проблема у меня возникла с тем, что блок расчетов делал разное количество тактов, в результате чего на выходе ЦАП сигнал был не четкий и были отклонения от нужного значения. Я как думал сделать, если я знаю число тактов на преобразование АЦП, то могу сделать так. Взять таймер, настроить его на прерывание каждые 2*(число тактов преобразования АЦП) и при том условии что число тактов на расчетную часть и вывод через ЦАП будет меньше числа тактов работы АЦП.
arkhnchul
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

Re: Точный подсчет тактов контроллера

Сообщение arkhnchul »

вот самая проблема - "все нужно сделать за 500 тактов". Забудьте пока о том, что в природе существуют такты. За какое время должна выполняться выдача значения в ЦАП от начала первого преобразования АЦП? Какая задержка допустима?

проблема в том, что ваша задача - что вы конкретно хотите сделать на выходе из (какого?) входящего сигнала - совершенно непонятна.

например, как вижу сейчас:
объявляем 8 переменных для отсчетов - 4 текущих, 4 рабочих
объявляем счетчик отсчетов
объявляем флаг готовности к расчету
объявляем переменную под результат расчета

АЦП настраиваем на запуск от события таймера
в прерывании по окончании преобразования АЦП пишем в "текущую" переменную согласно счетчика, инкрементируем счетчик. Если счетчик досчитал до четвертого преобразования (т.е. текущее завершенное - четвертое), то пишем отсчеты из текущих в рабочие, сбрасываем счетчик, поднимаем флаг готовности к расчету

в основном цикле:
ждем флага готовности. Как он появился:
производим расчет
пишем результат в переменную
сбрасываем флаг готовности
** пишем результат в ЦАП

или, если нам нужны точные промежутки между выдачей в ЦАП:
заводим таймер на нужный период
в основном цикле не делаем **
в прерывании по данному таймеру пишем в ЦАП значение переменной результата
Аватара пользователя
Radist228
Родился
Сообщения: 15
Зарегистрирован: Ср ноя 25, 2015 18:05:40

Re: Точный подсчет тактов контроллера

Сообщение Radist228 »

Ну, я примерно понял систему. Спасибо за подсказку))
Аватара пользователя
moLCHec
Мявтор!
Сообщения: 825
Зарегистрирован: Вс дек 18, 2005 20:04:42
Откуда: Свердловская обл.
Контактная информация:

Re: Точный подсчет тактов контроллера

Сообщение moLCHec »

А чего таймеры использовать то никак ?!
В СТМ с ними чудеса творить можно даже каскадом при желании запустить.
Да и ДМА никто не отменял, настроил запуск АЦП по таймеру, настроил ДМА на 8 преобразований и по прерыванию ДМА в середине и в конце выполняешь расчет и пр.
Настоящий кот всегда либо голоден,
либо невыспался ...
Ответить

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