|
STM32F10x, не перестаёт удивлять |
|
|
|
Feb 6 2011, 20:02
|
Частый гость
 
Группа: Участник
Сообщений: 183
Регистрация: 22-06-05
Из: Таганрог
Пользователь №: 6 233

|
Полдня чесал репу и разлохматил бубен на казалоь бы ровном месте... А именно: имеем некий код в основном цикле, с временем исполнения, определяемым периодом таймера. Таймер запускается перед контролируемым кодом, тот в цикле делает свои дела, а выходит по флагу, к-й устанавливается в обработчике прерывания (Update Event) этого таймера. Таймер запускается перед этим блоком. По так и невыясненным причинам, всё работало после ресета до того момента, пока не происходило некое внешнее прерывание (с приоритетом ниже таймера), делающее быстро другие примитивные дела, не относящиеся к интересующему участку кода. После этого начинались чудеса - на очередном внешнем цикле после запуска таймера код лихо проскакивал проверку while(!bStopDSS), даже не заглянув внутрь, и происходило 2! прерывания от таймера, одно из которых видимо и устанавливало bStopDSS=1 до входа во внутренний цикл. Вылечил проверкой флага прерывания перед включением таймера. Перекорячивается конвейер команд? При включении таймера (строка TIM3->CR1 |= TIM_CR1_CEN) ещё не сброшен бит прерывания? Код volatile uint8_t bStopDSS; while(1) // внешний цикл { bStopDSS = 0; TIM3->CNT = 0; TIM3->SR = ~TIM_IT_Update; while(TIM3->SR & TIM_IT_Update); // без этой проверки - чудеса TIM3->CR1 |= TIM_CR1_CEN;
while(bStopDSS == 0) { // Внутренний цикл, выходим по таймеру. } // ...готовимся к следующему циклу // }
void TIM3_IRQHandler (void) { // Сбрасываем флаг прерывания TIM3->SR = ~TIM_IT_Update; // Останавливаем таймер TIM3->CR1 &= ~TIM_CR1_CEN; // Флаг окончания внутреннего цикла bStopDSS = 1; } Такие дела. В голове смятение.
Сообщение отредактировал pr0m - Feb 6 2011, 20:05
--------------------
Правильно поставленный вопрос - половина ответа...
|
|
|
|
|
 |
Ответов
|
Feb 8 2011, 22:00
|
Участник

Группа: Участник
Сообщений: 72
Регистрация: 7-01-11
Пользователь №: 62 073

|
Цитата Вы наверное имеете ввиду доступ к bit-banding региону Нет, bit-banding тут не при чем. Просто если посмотреть код, генерируемый компилятором, то видно, что маску он не делает. Делается либо сдвиг + проверка <0, либо используется команда TST, которая как раз и делает AND. А что надо получить в конечном итоге, прямоугольник заданной частоты? Может быть как-то на таймерах это сделать, неужели синус + компаратор лучше (не спорю, просто не сталкивался). На счет цапов я бы предложил попробовать реализовать используя возможности стм32, а именно дма + синхр. по таймеру.
|
|
|
|
|
Feb 9 2011, 16:48
|
Частый гость
 
Группа: Участник
Сообщений: 183
Регистрация: 22-06-05
Из: Таганрог
Пользователь №: 6 233

|
Цитата(akimych @ Feb 9 2011, 01:00)  А что надо получить в конечном итоге, прямоугольник заданной частоты? Может быть как-то на таймерах это сделать, неужели синус + компаратор лучше (не спорю, просто не сталкивался). Мне нужны разные виды модуляции, в том числе ЛЧМ. Код typedef struct { u32 freq_start; //начальная частота, Гц u32 freq_stop; //конечная частота, Гц u32 tau_f; //время изменения от начальной до конечной, мкс u32 tau_d; //длительность радиоимпульса,мкс u32 freq_carrier;//частота гетеродина, Гц }DDS_CONFIG; Таймера в стм32, конечно, хорошие, учитывая 16-битные прескалеры и авторелоады (кстати, для гетеродина использую), позволяют с достаточной точностью получить требуемые частоты, но не годятся для получения ЛЧМ-сигнала: при частоте 400кГц и тактовой таймера 72МГц прескалер=0, ARR=180-1. Следующее возможное значение по частоте 72000/179=402,234кГц, ниже 397,790кГц, - порядок шага по частоте ясен. Сравним с разрешающей способностью DDS (аккумулятор 32-битный) dF=Fd/2^32=72000000/(кол-во тактов на выполнение кода DDS)/2^32=72000000/20/2^32=0,00083819 Гц. Это почему не таймеры, с приращением ARR в обработчике. А почему именно синусы (комплементарные), кажется пояснял выше, может нет, повторюсь: кажется очевидным простой ход - вместо таблицы синуса подсунуть DDS-у таблицу меандра (наполовину 0х000, наполовину 0хFFF), как вариант, можно выводить на пин старший бит из таблицы сигнала. На низких формируемых частотах можете не заметить, но на высоких выползает джиттер (дрожат фронты). Причина в большой величине приращения аккумулятора фазы на каждом шаге... вобщем, тут нужно прочувствовать и увидеть  А побороть это можно сделав 2 синуса, отфильтровать и подать на компаратор - так сделано у Analog Devices в некоторых DDS-чипах. Цитата(akimych @ Feb 9 2011, 01:00)  На счет цапов я бы предложил попробовать реализовать используя возможности стм32, а именно дма + синхр. по таймеру. Не знаю.... В итоге нужно в ЦАП-ы засовывать, посредством дма или софтом, значение из таблицы сигнала, причём не значения по порядку, а вычислять индекс на основании значения аккумулятора фазы, так что сдаётся мне, дма по таймеру здесь не помогут. Собсно код: Код .... register union { struct { uint32_t unused:24; uint32_t index:8; }field; uint32_t total; }acc; ...... while(bStopDSS == 0) { if( dp > freq_stop ) { // acc.total = 0; dp = freq_start; ddp = tau; // break; } DAC->DHR12RD = _sinewave[acc.field.index]; acc.total += dp; dp += ddp; }
--------------------
Правильно поставленный вопрос - половина ответа...
|
|
|
|
|
Feb 9 2011, 21:08
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(pr0m @ Feb 9 2011, 18:48)  Не знаю.... В итоге нужно в ЦАП-ы засовывать, посредством дма или софтом, значение из таблицы сигнала, причём не значения по порядку, а вычислять индекс на основании значения аккумулятора фазы, Значения из таблицы по индексу из аккумулятора фазы заталкивать в массив в памяти, из которого выбирать при помощи DMA с активацией по таймеру. Буфер FIFO, выравнивающий неодинаковость времени вычислений.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Feb 10 2011, 06:06
|
Частый гость
 
Группа: Участник
Сообщений: 183
Регистрация: 22-06-05
Из: Таганрог
Пользователь №: 6 233

|
Цитата(ReAl @ Feb 10 2011, 00:08)  Значения из таблицы по индексу из аккумулятора фазы заталкивать в массив в памяти, из которого выбирать при помощи DMA с активацией по таймеру. Буфер FIFO, выравнивающий неодинаковость времени вычислений. Спасибо, мысль понятна, только аккумулятор бегает по кругу, через переполнение (изменение аака от 0 до 2^32-1 соответсвует одному периоду сигнала - фаза от 0 до 2*PI), причём на бОльших частотах шаг приращения акка выше. Предвычисление индексов и массива некоторого конечного размера для ЦАП-а, натравливание на него дма, и так опять же по кругу? А в чём преимущество в сравнении с 3 строчками кода, делающими это в главном цикле? Алгоритм не должен никого ждать, кроме как в случае прерывания извне для приёма новой конфигурации - только в этом случае он приостанавливается.
Сообщение отредактировал pr0m - Feb 10 2011, 06:13
--------------------
Правильно поставленный вопрос - половина ответа...
|
|
|
|
Сообщений в этой теме
pr0m STM32F10x Feb 6 2011, 20:02 akimych Интересно то, что после while(TIM3->SR & TI... Feb 6 2011, 21:29 AHTOXA Цитата(pr0m @ Feb 7 2011, 01:02) Такие де... Feb 7 2011, 06:06 pr0m Цитата(AHTOXA @ Feb 7 2011, 09:06) Попроб... Feb 7 2011, 08:42  AHTOXA Цитата(pr0m @ Feb 7 2011, 13:42) Флаг UEV... Feb 7 2011, 09:16   pr0m Цитата(AHTOXA @ Feb 7 2011, 12:16) Однако... Feb 7 2011, 12:20 pr0m Победил. Не была задана группировка с вытеснением ... Feb 7 2011, 14:18 sonycman Цитата(pr0m @ Feb 7 2011, 17:18) Задал пр... Feb 7 2011, 15:21  pr0m Цитата(sonycman @ Feb 7 2011, 18:21) Так ... Feb 7 2011, 15:39   sonycman Цитата(pr0m @ Feb 7 2011, 18:39) Высший-т... Feb 7 2011, 16:04    AHTOXA Цитата(sonycman @ Feb 7 2011, 21:04) По у... Feb 7 2011, 16:17     sonycman Цитата(AHTOXA @ Feb 7 2011, 19:17) Ненене... Feb 7 2011, 16:25      pr0m Цитата(sonycman @ Feb 7 2011, 19:25) Так ... Feb 7 2011, 16:57       sonycman Цитата(pr0m @ Feb 7 2011, 19:57) Нет, одн... Feb 7 2011, 17:11        pr0m Цитата(sonycman @ Feb 7 2011, 20:11) Хм, ... Feb 7 2011, 17:17       AHTOXA Цитата(pr0m @ Feb 7 2011, 21:57) Нет, одн... Feb 7 2011, 17:15        sonycman Цитата(AHTOXA @ Feb 7 2011, 20:15) Всё же... Feb 7 2011, 17:22        pr0m Цитата(AHTOXA @ Feb 7 2011, 20:15) Всё же... Feb 7 2011, 17:31         AHTOXA Цитата(pr0m @ Feb 7 2011, 22:22) А моя пр... Feb 7 2011, 17:32         KnightIgor Цитата(pr0m @ Feb 7 2011, 18:31) А моя пр... Feb 7 2011, 17:58          pr0m Цитата(KnightIgor @ Feb 7 2011, 20:58) По... Feb 7 2011, 18:05      AHTOXA Цитата(sonycman @ Feb 7 2011, 21:04) По у... Feb 7 2011, 17:06 pr0m Разобрался. sonycman прав. 15 подгрупп после ресет... Feb 7 2011, 17:53 sonycman Цитата(pr0m @ Feb 7 2011, 20:53) И что ж ... Feb 7 2011, 18:05  pr0m Цитата(sonycman @ Feb 7 2011, 21:05) В эт... Feb 7 2011, 18:11 akimych Цитата1) Для детерминированности времени исполнени... Feb 7 2011, 19:06 pr0m Цитата(akimych @ Feb 7 2011, 22:06) Стран... Feb 7 2011, 19:31 akimych ЦитатаВ этой ветке переплелись мои вопросы по двум... Feb 7 2011, 21:24 pr0m Цитата(akimych @ Feb 8 2011, 00:24) На сч... Feb 8 2011, 07:03  ReAl Цитата(pr0m @ Feb 8 2011, 09:03) Там долж... Feb 8 2011, 23:27    vmp Цитата(pr0m @ Feb 10 2011, 09:06) Спасибо... Feb 10 2011, 07:39     pr0m Цитата(vmp @ Feb 10 2011, 10:39) Преимуще... Feb 10 2011, 12:19    ReAl Цитата(pr0m @ Feb 10 2011, 08:06) Спасибо... Feb 10 2011, 14:07     pr0m Цитата(ReAl @ Feb 10 2011, 17:07) Проблем... Feb 10 2011, 21:48 pr0m Красиво, получается, но основной недостаток - чуть... Feb 11 2011, 14:31 akimych В принципе, запись в буфер и запись в регистр ЦАП-... Feb 13 2011, 02:17 pr0m Цитата(akimych @ Feb 13 2011, 05:17) Изме... Feb 13 2011, 07:03
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|