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

 
 
 
Reply to this topicStart new topic
> STM32L051K8T6 + SysTick + ADC
Борис 1984
сообщение Sep 23 2014, 05:32
Сообщение #1





Группа: Новичок
Сообщений: 5
Регистрация: 23-09-14
Пользователь №: 82 902



Добрый день, товарищи!

У меня такая проблема: настраиваю системный таймер с периодом 10мкс и АЦП с периодом преобразования 50 мкс, по отдельности все работает нормально. Когда вместе, при одинаковых приоритетах прерываний на осциллографе вижу только работу таймера, если у АЦП выше приоритет, то есть пропуски прерываний от таймера, т.е. между входами t = 20мкс. Тактирую от HSI. Проверяю это с помощью светодиода и сигнала на лапах.
CODE
void Init()
{

//------ System clock HSI = 16 MHz ----------------------------------------

// FLASH->ACR = 0x00000001;

RCC->CFGR = RCC_CFGR_SW_HSI;// | RCC_CFGR_PPRE2_DIV16;
RCC->CR = RCC_CR_HSION | RCC_CR_HSIDIVEN; // Âíóòðåííèé ãåíåðàòîð ñ äåëèòåëåì íà 4

while(!(RCC->CR & RCC_CR_HSIRDY)) ; // Îæèäàíèå ñòàáèëèçàöèè ÷àñòîòû âíóòðåííåãî ãåíåðàòîðà

while(!(RCC->CR & RCC_CR_HSIDIVF)) ;


RCC->IOPENR = RCC_IOPENR_GPIOAEN | RCC_IOPENR_GPIOBEN; // Òàêòèðîâàíèå ïîðòîâ À è Â
RCC->APB2ENR = RCC_APB2ENR_ADC1EN; // Òàêòèðîâàíèå ÀÖÏ

GPIOA->MODER = 0xE85EFDDF;
GPIOA->PUPDR = 0x25000000;

GPIOB->MODER = 0xFFFFDFFF;

ADC1->CR |= ADC_CR_ADCAL;
while(ADC1->CR & ADC_CR_ADCAL) ; // Îæèäàíèå îêîí÷àíèÿ êàëèáðîâêè

ADC1->IER |= ADC_IER_EOCIE; // Ðàçðåøåíèå ïðåðûâàíèÿ ïî çàâåðøåíèè ïðåîáðàçîâàíèÿ
ADC1->CFGR1 |= ADC_CFGR1_WAIT | ADC_CFGR1_CONT;
ADC1->CFGR2 |= ADC_CFGR2_OVSR_0 | ADC_CFGR2_OVSR_1;
ADC1->CHSELR |= ADC_CHSELR_CHSEL3; // 3 êàíàë - ïðèåìíèê
ADC1->SMPR = ADC_SMPR_SMPR;
ADC->CCR |= ADC_CCR_LFMEN; // Low Frequency Mode
ADC1->CR = ADC_CR_ADSTART | ADC_CR_ADEN;


//----------------------SysTick Timer--------------------------------
SysTick->LOAD = 5;
// NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */
SysTick->VAL = 0;
SysTick->CTRL |= 0x07;

// NVIC_SetPriority(ADC1_COMP_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
NVIC_EnableIRQ(ADC1_COMP_IRQn);
}
//-------------------------------------------
void SysTick_Handler(void) // 10 ìêñ
{
f_blink ^= 0x01;
if(f_blink)
GREEN_LED_ON;
else
GREEN_LED_OFF;
}
//-------------------------------------------
void ADC1_COMP_IRQHandler()
{
uint16_t resADC = ADC1->DR;

f_blink1 ^= 0x01;
if(f_blink1)
RED_LED_ON;
else
RED_LED_OFF;
}

Подскажите, пожалуйста в чем проблема.

Сообщение отредактировал IgorKossak - Sep 24 2014, 08:45
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
adnega
сообщение Sep 23 2014, 06:32
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата
SysTick->LOAD = 5;


16M / 8 / 5 -> 2.5 мкс

Другими словами прерывание происходит каждые 40 тактов проца. Ну что за такое время можно успеть?


Проверил по документации
Цитата
SysTick->CTRL |= 0x07;


Вообще 5 тактов, т.к. предделитель для SysTick отключается.
Go to the top of the page
 
+Quote Post
Борис 1984
сообщение Sep 23 2014, 06:50
Сообщение #3





Группа: Новичок
Сообщений: 5
Регистрация: 23-09-14
Пользователь №: 82 902



Цитата(adnega @ Sep 23 2014, 10:17) *
16M / 8 / 5 -> 2.5 мкс

Другими словами прерывание происходит каждые 40 тактов проца. Ну что за такое время можно успеть?


Не совсем понял?
Как я понимаю частота тактирования таймера HCLK/8 с предделителем /4 - T=500 кГц или 2мкс на счет. При загрузке значени 5 в LOAD - срабатывание будет через 10мкс - я это вижу на осциллографе, когда АЦП отключено

Цитата(adnega @ Sep 23 2014, 10:32) *
Проверил по документации


Вообще 5 тактов, т.к. предделитель для SysTick отключается.



Для серии L0 всегда HCLK/8 я проверил и CubeMX в Clock Configuration так показывает! Делитель нельзя отключить!!!
Go to the top of the page
 
+Quote Post
adnega
сообщение Sep 23 2014, 10:16
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(Борис 1984 @ Sep 23 2014, 10:50) *
Для серии L0 всегда HCLK/8 я проверил и CubeMX в Clock Configuration так показывает! Делитель нельзя отключить!!!

В документе "PM0223 STM32L0 Series Cortex®-M0+ programming manual"
STK_CSR:
Цитата
Bit 2 CLKSOURCE Selects the SysTick timer clock source:
0 = External reference clock.
1 = Processor clock.


Попробуйте увеличить LOAD до 200-1 и посмотреть за периодом. Должен быть 100 мкс.

16M(HSI) / 4(HSIDIV4) / 200(LOAD) / 2(BLINK on-off) = 100 мкс.
Go to the top of the page
 
+Quote Post
scifi
сообщение Sep 23 2014, 10:23
Сообщение #5


Гуру
******

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



Цитата(Борис 1984 @ Sep 23 2014, 09:32) *
настраиваю системный таймер с периодом 10мкс

Какой ужас. Зачем 10 мкс? Обычно бывает 10 мс. А если 10 мкс, то велик риск "что-нибудь не успеть", как справедливо замечено выше.
Go to the top of the page
 
+Quote Post
Борис 1984
сообщение Sep 23 2014, 10:30
Сообщение #6





Группа: Новичок
Сообщений: 5
Регистрация: 23-09-14
Пользователь №: 82 902



Спасибо!
Похоже все дело в том что МК не успевает обрабатывать прерывания на таких частотах, появляются пропуски, сейчас попробую поднять частоту через PLL.

Цитата(scifi @ Sep 23 2014, 14:23) *
Какой ужас. Зачем 10 мкс? Обычно бывает 10 мс. А если 10 мкс, то велик риск "что-нибудь не успеть", как справедливо замечено выше.


Нужна программная реализация высокоскоростного протокола обмена.
Go to the top of the page
 
+Quote Post
scifi
сообщение Sep 23 2014, 10:33
Сообщение #7


Гуру
******

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



Цитата(Борис 1984 @ Sep 23 2014, 14:30) *
Нужна программная реализация высокоскоростного протокола обмена.

Ну тогда нужно внимательно следить, чтобы всё действительно успевало выполняться. Иначе могут полезть загадочные глюки.
Go to the top of the page
 
+Quote Post
adnega
сообщение Sep 23 2014, 10:38
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(Борис 1984 @ Sep 23 2014, 14:30) *
Нужна программная реализация высокоскоростного протокола обмена.

А что за протокол?
А почему бы не приспособить для этого периферийные блоки?
А какой кайф от L-серии в такой "программной реализации"?
Go to the top of the page
 
+Quote Post
Борис 1984
сообщение Sep 23 2014, 11:52
Сообщение #9





Группа: Новичок
Сообщений: 5
Регистрация: 23-09-14
Пользователь №: 82 902



Цитата(adnega @ Sep 23 2014, 14:38) *
А что за протокол?
А почему бы не приспособить для этого периферийные блоки?
А какой кайф от L-серии в такой "программной реализации"?


Протокол собственной разработки, передача последовательностей 8-10 бит, длительность бита 250мкс.
Серия L выбрана, как низко потребляющая.
Можете подробнее рассказать, какие периферийные блоки можно использовать?
Go to the top of the page
 
+Quote Post
scifi
сообщение Sep 23 2014, 12:02
Сообщение #10


Гуру
******

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



Цитата(Борис 1984 @ Sep 23 2014, 15:52) *
Можете подробнее рассказать, какие периферийные блоки можно использовать?

SPI+DMA, к примеру.
Go to the top of the page
 
+Quote Post
adnega
сообщение Sep 23 2014, 12:05
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(Борис 1984 @ Sep 23 2014, 15:52) *
Протокол собственной разработки, передача последовательностей 8-10 бит, длительность бита 250мкс.
Серия L выбрана, как низко потребляющая.
Можете подробнее рассказать, какие периферийные блоки можно использовать?

А какой именно протокол? Можно в UART или SPI превратить? Если нет, то "плохой"))
В крайнем случае можно завести на таймер и генерить одно прерывание на бит аппаратно (делал для ИК-приемника, 1-wire, wiegand т.п.).
Чтобы проц мало потреблял, софт должен отвечать нескольким требованиям. Самое главное, он все время должен спать.
А софтовая обработка с дискретизацией 10 мкс спать процу не даст.
Go to the top of the page
 
+Quote Post
Mihey_K
сообщение Sep 23 2014, 12:28
Сообщение #12


Частый гость
**

Группа: Участник
Сообщений: 156
Регистрация: 27-09-06
Из: Irkutsk
Пользователь №: 20 747



Интересно, что за задачу решаете с таким мизерными квантами времени. И сильно сомневаюсь, что с подобными временными окнами удастся на Cortex-M все реализовать без гонки событий, тут больше ПЛИС напрашивается.


--------------------
Блог о разработке на CC430, SIM900, GPS, ARM и не только...
Go to the top of the page
 
+Quote Post
scifi
сообщение Sep 23 2014, 12:45
Сообщение #13


Гуру
******

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



Цитата(Mihey_K @ Sep 23 2014, 16:28) *
Интересно, что за задачу решаете с таким мизерными квантами времени. И сильно сомневаюсь, что с подобными временными окнами удастся на Cortex-M все реализовать без гонки событий, тут больше ПЛИС напрашивается.

Не нужно пугать раньше времени. 10 мкс - это 320 тактов. Вполне можно сделать что-то осмысленное, если не сильно тупить.
Go to the top of the page
 
+Quote Post
adnega
сообщение Sep 23 2014, 12:52
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(scifi @ Sep 23 2014, 16:45) *
Не нужно пугать раньше времени. 10 мкс - это 320 тактов. Вполне можно сделать что-то осмысленное, если не сильно тупить.

А если учесть, что бит 250 мкс. А пачки 8-10 бит, то хитровывернутая настройка аппаратных блоков вообще может свести этот показатель до рубежа 40 000 тактов @ 16МГц. Причем 40 000 тактов во сне)
Go to the top of the page
 
+Quote Post
Борис 1984
сообщение Sep 24 2014, 07:03
Сообщение #15





Группа: Новичок
Сообщений: 5
Регистрация: 23-09-14
Пользователь №: 82 902



Цитата(adnega @ Sep 23 2014, 16:05) *
А какой именно протокол? Можно в UART или SPI превратить? Если нет, то "плохой"))
В крайнем случае можно завести на таймер и генерить одно прерывание на бит аппаратно (делал для ИК-приемника, 1-wire, wiegand т.п.).
Чтобы проц мало потреблял, софт должен отвечать нескольким требованиям. Самое главное, он все время должен спать.
А софтовая обработка с дискретизацией 10 мкс спать процу не даст.


Протокол - аналог SystemSensors.
Попробовал поднять частоту с помощью PLL до 32МГц - помогло, но пока не знаю что с потреблением в итоге получится.
Все спасибо за помощь, среди постов есть интересные мысли.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 18th July 2025 - 16:36
Рейтинг@Mail.ru


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