Jump to content

    

STM32F103 не пишет в TIM4->DIER

Подумав немного, пришел вот к каким заключениям: 

- конденсатор УВХ 8 пФ действительно будет заряжаться через 10к в течении 0,8мкСек. Это больше времени выборки 0,625мкСек и по истечении времени выборки конденсатор УВХ всё ещё будет не до конца заряжен. Это приведет к ошибке измерений.

- для исключения вышеописанного, как мне кажется, нужно увеличить время выборки, скажем до 13,5 циклов.

Установка же дополнительной ёмкости на вход АЦП создаст мне доп проблемы, т.к. нужно будет вводить паузу перед измерением, поскольку доп. конденсатор должен будет сначала разрядиться от 3,3В после выключения ШИМ.

Share this post


Link to post
Share on other sites
8 часов назад, MPetrovich сказал:

Установка же дополнительной ёмкости на вход АЦП создаст мне доп проблемы, т.к. нужно будет вводить паузу перед измерением, поскольку доп. конденсатор должен будет сначала разрядиться от 3,3В после выключения ШИМ.

Может вы и правы, оставьте этот вопрос на потом. Там и так емкость входа + паразитные емкости уже будут около 10pF. Плюс осциллографом будете смотреть, еще 20-50pF.

Судя по тому, что вы уже успешно измеряете постоянные напряжения, АЦП уже более-менее настроен. Если и есть ошибки измерения, они небольшие.
А то что никак не можете измерить свой целевой сигнал противо-ЭДС, это скорей всего как раз следствие неправильного момента измерения.
Выведите программный строб на свободную ножку МК в момент запуска АЦП, и смотрите осциллографом с синхронизацией по стробу, как в этот момент выглядит входное напряжение.
Скорее всего вы пытаетесь измерять сразу после выключения ШИМ (начала паузы). А это в корне не верно. Там в индуктивной цепи должен быть переходной процесс, вот вы на него и попадаете.
Смотрели осциллографом как на вашем двигателе выглядит это напряжение?

Share this post


Link to post
Share on other sites

Отпаял все ранее навешанные диоды и подпаял 10к напрямую ко входам АЦП. Установил время выборки 13,5 циклов. Проверил измерение в "крайних точках", подав на один из входов PHASE сначала +5В, потом GND. Результат соответственно: 4095 и 0. Причем измерял с частотой ШИМ 10кГц, запуская АЦП в прерывании от ШИМ.

Но это статика, а в динамике пока не очень срастается.

1 hour ago, Baser said:

Скорее всего вы пытаетесь измерять сразу после выключения ШИМ (начала паузы). А это в корне не верно. Там в индуктивной цепи должен быть переходной процесс, вот вы на него и попадаете.

Я воткнул перед запуском конверсии паузу в 5мкСек. Это довольно много, поскольку теперь и само преобразование длится 2,158мкСек. Эдак мне придётся ограничить максимальную скважность до 90%, иначе не останется времени на измерения. Но пока это не критично, запустить бы процесс)))

1 hour ago, Baser said:

Смотрели осциллографом как на вашем двигателе выглядит это напряжение?

Осциллографа дома нету, только на работе, а буду там только 6-го... возможно.

Share this post


Link to post
Share on other sites
9 часов назад, MPetrovich сказал:

Осциллографа дома нету, только на работе,

Для очень многих задач хватает логического анализатора за 5 евро от китайцев. Искать на али по ключевым словам "логический анализатор 8 каналов". Причем он в некоторых случаях куда полезнее осциллографа. Закажите, если не в этом проекте - так в следующем он вам 100% пригодится.

Share this post


Link to post
Share on other sites
1 hour ago, Сергей Борщ said:

Для очень многих задач хватает логического анализатора за 5 евро от китайцев.

Есть такой. 

Share this post


Link to post
Share on other sites

Кто подскажет какой длительности будет команда NOP при тактовой частоте контроллера 72МГц?

Share this post


Link to post
Share on other sites
3 hours ago, MPetrovich said:

Кто подскажет какой длительности будет команда NOP при тактовой частоте контроллера 72МГц?

https://developer.arm.com/docs/dui0553/a/the-cortex-m4-instruction-set/miscellaneous-instructions/nop

Share this post


Link to post
Share on other sites

"NOP ничего не делает. NOP не обязательно занимает много времени. Процессор может удалить его из конвейера до того, как он достигнет стадии выполнения.

Используйте NOP для заполнения, например, чтобы разместить следующую инструкцию на 64-битной границе."

Больше про этот оператор ничего не сказано. " не обязательно занимает много времени" - это как то расплывчато...

 

Share this post


Link to post
Share on other sites
29 minutes ago, MPetrovich said:

"NOP ничего не делает. NOP не обязательно занимает много времени. Процессор может удалить его из конвейера до того, как он достигнет стадии выполнения.

Используйте NOP для заполнения, например, чтобы разместить следующую инструкцию на 64-битной границе."

Больше про этот оператор ничего не сказано. " не обязательно занимает много времени" - это как то расплывчато...

 

NOP is not necessarily a time-consuming NOP - не обязательно занимает время.

А вообще - это команда выполняющаяся за один цикл.

Share this post


Link to post
Share on other sites
6 часов назад, MPetrovich сказал:

Кто подскажет какой длительности будет команда NOP при тактовой частоте контроллера 72МГц?

NOP = 1 такт, но как вы  прочитали, её лучше не использовать.

Задержку лучше делать таймером:
 

void DelayUs(uint16_t delay)
{
    uint16_t s = 0;
    TIM_SetCounter(TIM5, s);
    while((TIM_GetCounter(TIM5) - s) < delay);
}

или через Systick(китайцы почему-то любят):
 

void delay_init(u8 SYSCLK)
{
    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
    fac_us=SYSCLK/8;            
    fac_ms=(u16)fac_us*1000;
}                                    

void delay_us(u32 nus)
{        
    u32 temp;            
    SysTick->LOAD=nus*fac_us;
    SysTick->VAL=0x00;       
    SysTick->CTRL=0x01 ;     
    do
    {
        temp=SysTick->CTRL;
    }
    while(temp&0x01&&!(temp&(1<<16)));
    SysTick->CTRL=0x00;      
    SysTick->VAL =0X00;      
}

или тупо  считать такты сложения:

   for (volatile u32 i=0; i<0x04; i++){};

 

 

Share this post


Link to post
Share on other sites
12 minutes ago, HardEgor said:

Задержку лучше делать таймером:

ДА, уже сделал)))

 

13 minutes ago, HardEgor said:

или через Systick(китайцы почему-то любят):

Китайцы на то и китайцы - кто-то один раз показал и все стали повторять. От системного таймера задержки можно только в некритичных местах. А если такую в прерывание воткнешь, то потом неизвестно чего ждать.

 

15 minutes ago, HardEgor said:

или тупо  считать такты сложения:

   for (volatile u32 i=0; i<0x04; i++){};

А сколько один плюсик времени занимает? На вскидку - 2 такта: прибавил +сравнил. Нет?

 

Share this post


Link to post
Share on other sites
33 minutes ago, MPetrovich said:

или через Systick(китайцы почему-то любят):

Потому что это самый простой бесполезный таймер, который, к тому же, присутствует во всех МК.

 

35 minutes ago, MPetrovich said:

А сколько один плюсик времени занимает? На вскидку - 2 такта: прибавил +сравнил. Нет?

прибавил+сравнил+переход к началу цикла со сбросом конвейера, может быть, но это не точно

Share this post


Link to post
Share on other sites
1 час назад, piroman сказал:

прибавил+сравнил+переход к началу цикла со сбросом конвейера

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

Share this post


Link to post
Share on other sites
3 hours ago, MPetrovich said:

Д От системного таймера задержки можно только в некритичных местах. А если такую в прерывание воткнешь, то потом неизвестно чего ждать.

 

То есть - задержку в прерывание воткнешь?

Share this post


Link to post
Share on other sites
8 hours ago, Aleksandr Baranov said:

То есть - задержку в прерывание воткнешь?

Да, в прерывание. Например мне нужно переждать переходный процесс после отключения активного уровня ШИМ - примерно 5мкСек , чтобы потом АЦП измерил напряжение. Я понимаю, что обработчик прерывания нужно завершить побыстрее, но в моём случае задержка необхлдима.

11 hours ago, HardEgor said:

Задержку лучше делать таймером:
 


void DelayUs(uint16_t delay)
{
    uint16_t s = 0;
    TIM_SetCounter(TIM5, s);
    while((TIM_GetCounter(TIM5) - s) < delay);
}

У меня таймер считает вниз поэтому задержка выглядит так:

void DelayUs(uint16_t delay)
{
    TIM_SetCounter(TIM5, delay);
    while((TIM_GetCounter(TIM5))>0);
}

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now