реклама на сайте
подробности

 
 
5 страниц V  < 1 2 3 4 5 >  
Reply to this topicStart new topic
> SAM4S, Ничего не выходит
RabidRabbit
сообщение Aug 5 2015, 13:14
Сообщение #31


Местный
***

Группа: Свой
Сообщений: 397
Регистрация: 3-12-09
Из: Россия, Москва
Пользователь №: 54 040



А прерывания от АЦП с какой частотой следуют?
Не то у Вас там double арифметика, по-моему... Все всё успевают?
Не лучше ли будет dout = ((dacc_in * 9) + 6000) / 10;
Ведь по-любому там всё к инту приводится...
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Aug 5 2015, 13:28
Сообщение #32


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



возникло прерывание, а дальше? флаг наличия прерывания надо снять или он снимается чтением регистра?
у вас там точно нет вечного прерывания?

когда код в прерывании понятно дело что все работает, он же крутиться постоянно... и сам время прерывания фиксирует...
Go to the top of the page
 
+Quote Post
scifi
сообщение Aug 5 2015, 13:30
Сообщение #33


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Грендайзер @ Aug 5 2015, 16:14) *
И ещё пробовал отключать оптимизацию, код выполнялся правильно, но работал оооочень медленно.

Это не оттого ли, что мигаете лампочкой? Лампочка мигает, а программа стоит и ждёт, оттого всё оооочень медленно. Включили оптимизацию - циклы ожидания мигалки пропали - всё стало летать.
Я не понял, что это за фильтр и как он работает или не работает, так что о причинах сбоев гадать не берусь.
Go to the top of the page
 
+Quote Post
DmitryM
сообщение Aug 5 2015, 13:43
Сообщение #34


Знающий
****

Группа: Свой
Сообщений: 583
Регистрация: 7-06-06
Из: Таганрог
Пользователь №: 17 840



Цитата(Грендайзер @ Aug 5 2015, 16:40) *
прошу прощения за ошибки допущенные при копировании. вот поправленный вариант


А где NVIC_SetPriority (ADC_IRQn, ?);
Ладно, работает на приоритете по умолчанию.
Где проверка на готовность DACC к преобразованию?

P.S. volatile для локальной переменной функции это конечно ...
Go to the top of the page
 
+Quote Post
Грендайзер
сообщение Aug 5 2015, 14:46
Сообщение #35


Местный
***

Группа: Участник
Сообщений: 368
Регистрация: 18-04-11
Из: Город-герой Москва
Пользователь №: 64 451



RabidRabbit, а не всё ли равно, с какой частотой следуют прерывания. Логика кода такая: сначала запускается ЦАП (как только выбран и включён канал, цап начинает работать автоматом, выдавая раз в 25 циклов прерывание о завершении преобразования). Затем запускается автокалибровка АЦП. Когда она завершится процессор уйдёт в прерывание и далее я считав регистр строчками

Код
volatile int IRQ_sense = 0;
IRQ_sense = ADC -> ADC_ISR & (ADC_IER_EOCAL | ADC_IER_EOC5);

сбрасываю флаги прерывания (сбрасываются при чтении) и определяю от чего прерывание - конец калибровки или конец преобразования. Затем строчкой
Код
ADC -> ADC_CR = ADC_CR_START;

запускаю АЦП на преобразование. Даже если где то прерывания и пересекутся, то у ЦАП приоритет ниже чем у АЦП и он подождёт, пока тот отработает.

Цитата
возникло прерывание, а дальше? флаг наличия прерывания надо снять или он снимается чтением регистра?

Да, строчками
Код
IRQ_sense = ADC -> ADC_ISR & (ADC_IER_EOCAL | ADC_IER_EOC5);
IRQ_sense = DACC -> DACC_ISR;

Флаг сбрасывается при чтении регистров.

Цитата
Я не понял, что это за фильтр и как он работает или не работает, так что о причинах сбоев гадать не берусь.

Лампочки сдесь не причём. С сужу по наличию/отсутствию сигнала, который наблюдаю осциллографом. При правильной работе и лампочки должны мигать и сигнал быть... А там что то одно sad.gif

Цитата
А где NVIC_SetPriority (ADC_IRQn, ?);

Да, я не повышаю приоритет АЦП, я понижаю приоритет ЦАП.
Цитата
Где проверка на готовность DACC к преобразованию?

Когда выдаётся прерывание о завершении преобразования ЦАП готов. Если бы он не был готов, то строчки кода фильтра помещённые в подпрограмму обработки прерывания с АЦП так же не отрабатывались бы.

Сообщение отредактировал Грендайзер - Aug 5 2015, 14:53
Go to the top of the page
 
+Quote Post
scifi
сообщение Aug 5 2015, 15:57
Сообщение #36


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Грендайзер @ Aug 5 2015, 17:46) *
Лампочки сдесь не причём. С сужу по наличию/отсутствию сигнала, который наблюдаю осциллографом. При правильной работе и лампочки должны мигать и сигнал быть... А там что то одно sad.gif

И как это может работать? Наводящий вопрос: сколько времени занимает выполнение вот этого участка кода?
Код
{PIOA -> PIO_CODR = PIO_CODR_P19 | PIO_CODR_P20;}
for (int i = 0; i < 1000000; i ++){}
{PIOA -> PIO_SODR = PIO_SODR_P19 | PIO_SODR_P20;}
for (int i = 0; i < 1000000; i ++){}

И ещё один вопрос: при этом у процессора вообще останется время на обсчёт фильтра?
Go to the top of the page
 
+Quote Post
Грендайзер
сообщение Aug 5 2015, 17:08
Сообщение #37


Местный
***

Группа: Участник
Сообщений: 368
Регистрация: 18-04-11
Из: Город-герой Москва
Пользователь №: 64 451



Цитата
И ещё один вопрос: при этом у процессора вообще останется время на обсчёт фильтра?

Сколько угодно. Фильтр расчитывается лишь в том случае, если переменная flag == 1. Она устанавливается в 1 в функции обработки прерывания от АЦП, и сбрасывается в 0, как только завершился код фильтра для данного отсчёта поступившего с АЦП. После этого фильтр не считается, а моргают лампочки....
Цитата
И как это может работать? Наводящий вопрос: сколько времени занимает выполнение вот этого участка кода?

Не всё ли равно сколько времени занимает этот кусок кода? Его выполнение стопорнётся, как только придёт прерывание с переферии (ЦАП/АЦП). Впрочем я в ф-ции int main(void) я коментил лампочки и писал строчку типа
Код
dout = din;

без всякого фильтра. Всё равно никакого эффекта. Как будто компилятор хочет всё выполнять в функциях прерывания, а на основную ему наср наплевать smile3046.gif
При том самое интересное, что в основной ф-ции переменную flag процессор обнуляет, а вот фильтр банит...

Сообщение отредактировал Грендайзер - Aug 5 2015, 17:13
Go to the top of the page
 
+Quote Post
scifi
сообщение Aug 5 2015, 17:32
Сообщение #38


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Грендайзер @ Aug 5 2015, 20:08) *
Сколько угодно. Фильтр расчитывается лишь в том случае, если переменная flag == 1. Она устанавливается в 1 в функции обработки прерывания от АЦП, и сбрасывается в 0, как только завершился код фильтра для данного отсчёта поступившего с АЦП. После этого фильтр не считается, а моргают лампочки....

Представьте, что одна итерация "мигания" длится 1 секунду. Это значит, что фильтр может обновляться не чаще, чем 1 раз в секунду.

Цитата(Грендайзер @ Aug 5 2015, 20:08) *
Впрочем я в ф-ции int main(void) я коментил лампочки и писал строчку типа
Код
dout = din;

без всякого фильтра. Всё равно никакого эффекта. Как будто компилятор хочет всё выполнять в функциях прерывания, а на основную ему наср наплевать smile3046.gif
При том самое интересное, что в основной ф-ции переменную flag процессор обнуляет, а вот фильтр банит...

Довольно бессмысленно вносить случайные изменения в неработающую программу в надежде, что она заработает.
И выкиньте из головы мысль о том, что компилятор виноват. Это ошибки в вашей программе. Да, для оптимизации компилятору разрешено многое такое, что новичка может поставить в тупик, но есть чёткие правила. Если хотите понимать, что он нагенерил, смотрите в справочник инструкций процессора. Начинайте с низких уровней оптимизации, потому что на высших уровнях код корёжится до неузнаваемости, без поллитры не разберёшься, но при этом правильные программы не ломаются. Ну и вообще сомневаюсь, что у вас всё упёрлось в оптимизацию. Выглядит так, будто вы просто не понимаете, как работает программа, и надеетесь включением оптимизации волшебным образом решить все проблемы.
Можно было бы попробовать поразбираться, но вы привели неполный код, а полный, наверное, слишком большой, то есть разбираться будет лень. Ну и я не знаю, как там в SAMах всё работает, может быть, хитрые нюансы есть.
Go to the top of the page
 
+Quote Post
Грендайзер
сообщение Aug 5 2015, 18:01
Сообщение #39


Местный
***

Группа: Участник
Сообщений: 368
Регистрация: 18-04-11
Из: Город-герой Москва
Пользователь №: 64 451



Цитата
Представьте, что одна итерация "мигания" длится 1 секунду

Не могу представить. Процессору пришло прерывание, он на эту итерацию плюнул и пошёл отрабатывать прерывание.
Цитата
Довольно бессмысленно вносить случайные изменения в неработающую программу в надежде, что она заработает.

Изменения не случайные, они показывают, что в целом ход программы идёт так как задумано... не монятно куда пропадают отдельные куски... вот тут да...
Впрочем что ещё может быть, если даже из ассемблерного кода этот самый кусок пропал?
P.S.
Впрочем, может Вы в чём то и правы... Попробую ещё раз всё с самого насала написать.

Сообщение отредактировал Грендайзер - Aug 5 2015, 18:03
Go to the top of the page
 
+Quote Post
scifi
сообщение Aug 5 2015, 18:04
Сообщение #40


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Грендайзер @ Aug 5 2015, 21:01) *
Не могу представить. Процессору пришло прерывание, он на эту итерацию плюнул и пошёл отрабатывать прерывание.

Дык фильтр-то обсчитывается не в обработчике прерывания. Потому он и ждёт, пока мигалка не промигается.
Go to the top of the page
 
+Quote Post
Грендайзер
сообщение Aug 5 2015, 19:01
Сообщение #41


Местный
***

Группа: Участник
Сообщений: 368
Регистрация: 18-04-11
Из: Город-герой Москва
Пользователь №: 64 451



да... это до меня дошло... завтра попробую ещё раз проэксперементировать. В прочем как я уже говорил, моргалку я коментил, и на работе это не сказывалось (во всяком случае в лучшую сторону).
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Aug 5 2015, 19:06
Сообщение #42


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



вам не кейз надо делать, потому что попав в одно состояние вы в нем висите до окончания, а просто цикл мигания а под циклом if состояния флага. тогда вы оперативно получите отклик
Go to the top of the page
 
+Quote Post
Грендайзер
сообщение Aug 7 2015, 12:13
Сообщение #43


Местный
***

Группа: Участник
Сообщений: 368
Регистрация: 18-04-11
Из: Город-герой Москва
Пользователь №: 64 451



Снова здравствуйте. Вообщем промучился ещё день но так и не пришёл к решению. Вопрос к гуру ARMов, правильно ли в моём коде происходит уход в прерывание. Написал простейшую программулину, которая генерит пилу на выходе ЦАП. Заметил интересную особенность когда просматривал дизасемблированный код. В одном из регистров (r3), действительно появляются значения пилы в процессе работы цикла в программе main. Однако при уходе в подпрограмму прерывания в него записывается какая то ерунда. В ЦАП же записывается содержимое регистра r2 в котором, в процессе основного цикла хранится значение размаха пилы, т.е. 3000, а при входе в подпрограмму прерывания в него записывается значением которым я инициировал переменную dout, т.е. 300. После же выхода из прерывания в регистр r3 возвращается значение dout на момент когда пришло прерывание, а в r2 3000, т.е. размах пилы. Приведу весь код и рисунки с дизассемблера.
CODE
#include "sam.h"

int dout = 300;

void DACC_Handler( void );

int main(void)
{

/* Initialize the SAM system */
SystemInit();

__enable_irq ();

// --------------- Enable Interrupts in NVIC ----------------------------
NVIC_EnableIRQ(DACC_IRQn);

//------------------- Disable Watchdog Timer ---------------------------
WDT -> WDT_MR = WDT_MR_WDDIS; // disable Watchdog Timer
//----------------------------------------------------------------------

//----------------- Switch to fast RC oscillator ----------------------
// Enable Fast RC oscillator but DO NOT switch to RC now
PMC-> CKGR_MOR |= (CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCRCEN);

// Wait the Fast RC to stabilize
while (!(PMC -> PMC_SR & PMC_SR_MOSCRCS)){};

// Change Fast RC oscillator frequency
PMC-> CKGR_MOR = (PMC-> CKGR_MOR & ~CKGR_MOR_MOSCRCF_Msk) | CKGR_MOR_KEY_PASSWD |
CKGR_MOR_MOSCRCF_4_MHz;

// Wait the Fast RC to stabilize
while (!(PMC-> PMC_SR & PMC_SR_MOSCRCS)){};

// Switch to Fast RC
PMC-> CKGR_MOR = (PMC -> CKGR_MOR & ~CKGR_MOR_MOSCSEL) | CKGR_MOR_KEY_PASSWD;
//---------------------------------------------------------------------------------------------------------------

//-------------------------- Switch to Main Clock ---------------------------------------------------------------
// Switch to Main Clock
PMC -> PMC_MCKR |= PMC_MCKR_CSS_MAIN_CLK;

// Wait the Fast RC to stabilize
while (!(PMC-> PMC_SR & PMC_SR_MOSCRCS)){};
//---------------------------------------------------------------------------------------------------------------

//-------------------------- PLLA enable ------------------------------------------------------------------------

// Number Wait States Required to Access the Embedded Flash Memory (page 366 and 1183 datasheet)
EFC0 -> EEFC_FMR = (EFC0 -> EEFC_FMR & ~EEFC_FMR_FWS_Msk) | EEFC_FMR_FWS(6);

// Always stop PLL first!
PMC-> CKGR_PLLAR = CKGR_PLLAR_ONE | CKGR_PLLAR_MULA(0);

// Adjustment of the Multiplier and Divider
PMC-> CKGR_PLLAR = CKGR_PLLAR_ONE | CKGR_PLLAR_MULA(24) | CKGR_PLLAR_DIVA(1) |
CKGR_PLLAR_PLLACOUNT(100) | PMC_MCKR_PLLADIV2;

// Wait the PLL Lock
while (!(PMC-> PMC_SR & PMC_SR_LOCKA)){};

// Switch to PLLA Clock
PMC -> PMC_MCKR = (PMC -> PMC_MCKR & ~PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_PLLA_CLK;

// Wait Master Clock is Ready
while(!(PMC -> PMC_SR & PMC_SR_MCKRDY)){};

// --------- Enables the corresponding peripheral clock ----------------
// ------------------------ Enable PIOA --------------------------------
PMC -> PMC_PCER0 = (1 << ID_PIOA);

// ---------------------- Enable DACC clock ----------------------------
PMC -> PMC_PCER0 = (1 << ID_DACC);
PMC -> PMC_PCER0 = (1 << ID_ADC);

// --------- Enable corresponding pins ---------------------------------
PIOA -> PIO_PER = PIO_PER_P19 | PIO_PER_P20;

// ---- Enable output corresponding pins in PORTA-----------------------
PIOA -> PIO_OER = PIO_OER_P19|PIO_OER_P20;


// -- DAC SET
// --------------------- DACC Software Reset ---------------------------
DACC -> DACC_CR = DACC_CR_SWRST;

// ----------------------- DACC Mode Register --------------------------
DACC -> DACC_MR = DACC_MR_WORD_HALF | DACC_MR_USER_SEL_CHANNEL1;

// ----------------------- Channel 1 Enable ----------------------------
DACC -> DACC_CHER = DACC_CHER_CH1;

// ------------------- End of conversion interrupt ---------------------
DACC -> DACC_IER = DACC_IER_TXRDY;

// ---------------------- Start of conversion --------------------------
//DACC -> DACC_CDR = DACC_CDR_DATA(dout);

while (1)
{
if (dout == 3000)
{dout = 0;}
else
{dout = dout + 100;}
}
return 0;
}

void DACC_Handler( void )
{
volatile int IRQ_sense = 0;
IRQ_sense = DACC -> DACC_ISR;
DACC -> DACC_CDR = DACC_CDR_DATA(dout);
return;
}


Сообщение отредактировал IgorKossak - Aug 7 2015, 16:09
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!

Эскизы прикрепленных изображений
Прикрепленное изображение
Прикрепленное изображение
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 7 2015, 12:35
Сообщение #44


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Это не проблема ARM, а проблема того, что сие никак не есть "генератор пилы". Вы имеете произвольный счетчик никак не завязанный на время, значение которого переодически выбрасывается в DAC. Займитесь алгоритмом. И языком 'C' - тоже, а то как у "Джамшута" по-русски получается sad.gif


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
scifi
сообщение Aug 7 2015, 12:43
Сообщение #45


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



+100500, пила там точно не получится.
Для начала надо бы просто постараться понять, как работает процессор с прерываниями (вообще любой, не обязательно ARM). Потому что написать этот код и заявить, что это "генератор пилы" может только человек с какими-то нереальными фантазиями.
Go to the top of the page
 
+Quote Post

5 страниц V  < 1 2 3 4 5 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 04:29
Рейтинг@Mail.ru


Страница сгенерированна за 0.01504 секунд с 7
ELECTRONIX ©2004-2016