STM32 новичку в ARM что к чему

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Мучитель микросхем
Сообщения: 443
Зарегистрирован: Ср окт 19, 2011 08:48:27
Откуда: Мать городов русских

Сообщение Frogfot »

[uquote="VladislavS",url="/forum/viewtopic.php?p=3797023#p3797023"]20 тактов на цикл. Многовато.[/uquote]
Спасибо. Еще вопрос - какую max частоту можно получить с ШИМа на STM32F103C8T6 при 72 Мгц тактовой? У меня получилось 36 МГц.

Код: Выделить всё

TIM1->PSC = 0;
TIM1->ARR = 1;
Или как-то можно вывести 72 МГц?
Хорошему коту и в декабре - март :)
Реклама
Опытный кот
Аватара пользователя
Сообщения: 819
Зарегистрирован: Вт окт 23, 2012 13:17:25
Откуда: Прокопьевск

Сообщение Oxford »

ARR определяет частоту. Поэтому никак.
Инженер R@D

Telegram чат: https://t.me/radiowolf или в поиске приложения @radiowolf. Личка:@cncoxford
Контактная информация:
Реклама
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Сообщение COKPOWEHEU »

[uquote="Frogfot",url="/forum/viewtopic.php?p=3797063#p3797063"]Или как-то можно вывести 72 МГц?[/uquote]
Нельзя. Сами подумайте: на один бит надо дернуть SCK сначала к 1, потом к 0. А за один такт вы успеете сделать либо то, либо другое.
Мучитель микросхем
Сообщения: 443
Зарегистрирован: Ср окт 19, 2011 08:48:27
Откуда: Мать городов русских

Сообщение Frogfot »

2 Oxford, COKPOWEHEU: спасибо, значит, я думал правильно.

Добавлено after 16 minutes 28 seconds:
Народ, ещё вопрос - как для STM32 для Keil разместить подпрограмму из FLASH в RAM?

Добавлено after 5 hours 49 minutes 52 seconds:
[uquote="VladislavS",url="/forum/viewtopic.php?p=3797023#p3797023"]20 тактов на цикл. Многовато.[/uquote]
Попробовал через пинать порт через DMA - завёл в памяти массив 256 байт, заполнил его значениями от 0 до 0xFF и вывожу в порт - в самом младшем разряде порта частота примерно 3.4 МГц - т.е. при 2-х пинках на период DMA гонит данные примерно 6.8 МГц - т.е. около 10-11 тактов на на 1 пинок. В самом старшем (8-м) - 26.8 кГц. Осцила нет, меряю анализатором Selao.
Хорошему коту и в декабре - март :)
Реклама
Эиком - электронные компоненты и радиодетали
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Ваш пример. 8 тактов на цикл - 4.5 МГц.

Код: Выделить всё

  for(uint32_t i;;)
  {
    GPIOA->ODR=i++;
  }

Код: Выделить всё

        LDR.N    R1,??main_0      ;; 0x4001080c
??main_1:
        STR      R0,[R1, #+0]
        ADDS     R0,R0,#+1
        B.N      ??main_1
СпойлерИзображение
DS2_2020227231019.png
(34.77 КБ) 147 скачиваний
Если пожертвовать скважностью, 10 тактов на цикл - 7.2 МГц

Код: Выделить всё

  for(GPIO::PA_1 pin;;)
  {
    pin=1;
    pin=0;
  }

Код: Выделить всё

        MOV      R0,#+131072
        LDR.N    R1,??main_0      ;; 0x40010810
        MOV      R2,#+131074
??main_1:
        STR      R2,[R1, #+0]
        STR      R0,[R1, #+0]
        B.N      ??main_1
СпойлерИзображение
DS2_2020227225737.png
(37.48 КБ) 139 скачиваний
Если подравнять скважность, то 12 тактов на цикл - 6 МГц.

Код: Выделить всё

  for(GPIO::PA_0 pin;;)
  {
    pin=1;
    __NOP(); __NOP();
    pin=0;
  }
СпойлерИзображение
DS2_2020227232426.png
(36.28 КБ) 136 скачиваний
Добавлено after 18 minutes 52 seconds:
На короткой последовательности можно ещё чуть выжать. Но это неспортивно.
Спойлер

Код: Выделить всё

void Dryg()
{
  GPIO::PA_0::set();
  __NOP();
  GPIO::PA_0::clear();
  __NOP();
}


int main()
{  
  for(;;)
  {
    Repeat<Dryg,50>();
  }
}
Изображение

Код: Выделить всё

main:
        MOV      R0,#+65536
        LDR.N    R1,??DataTable1  ;; 0x40010810
        MOVS     R2,#+1
??main_0:
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        STR      R2,[R1, #+0]
        Nop      
        STR      R0,[R1, #+0]
        Nop      
        B.N      ??main_0
DS2_2020227233846.png
(25.63 КБ) 169 скачиваний
Реклама
Мучитель микросхем
Сообщения: 443
Зарегистрирован: Ср окт 19, 2011 08:48:27
Откуда: Мать городов русских

Сообщение Frogfot »

[uquote="VladislavS",url="/forum/viewtopic.php?p=3798142#p3798142"]Ваш пример. 8 тактов на цикл - 4.5 МГц.[/uquote]
Благодарствую, вот оказывается, как много всего я ещё не знал :)

В перспективе присматриваюсь к формированию VGA с МК - типа чтобы грузонуть МК по самые помидоры. Ну, может не на этом - STM32F103C8T6, а на 103-м, только с 64 кБ ОЗУ, или же на более шустром - "Black Pils" - STM32F401/411, или другом М4/М7.
Хорошему коту и в декабре - март :)
Реклама
Открыл глаза
Аватара пользователя
Сообщения: 42
Зарегистрирован: Сб янв 05, 2013 21:03:05

Сообщение passer_by »

[uquote="Frogfot",url="/forum/viewtopic.php?p=3797063#p3797063"]Или как-то можно вывести 72 МГц?[/uquote]
На вывод PA8

Код: Выделить всё

void MCO_out (void){
	RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;                       	   // enable clock for port A
	GPIOA->CRH &= ~GPIO_CRH_CNF8_0;		         		   // setting out alternative push-pull for PA8
	GPIOA->CRH |= GPIO_CRH_CNF8_1;
	GPIOA->CRH |= (GPIO_CRH_MODE8_0 | GPIO_CRH_MODE8_1);     // gpio speed 50 MHz
	RCC->CFGR |= RCC_CFGR_MCO_SYSCLK ;//  HSE; PLL; SYSCLK;   // select source clokc SYSCLK
}
Или можно вывести частоту кварца HSE, после PLL, ну и саму системную частоту SYSCLK.
Если птичка уже в одном прыжке от тебя, всё-таки побереги свой нос, может она за оконным стеклом???
Мудрый кот
Аватара пользователя
Сообщения: 1795
Зарегистрирован: Ср апр 04, 2012 09:55:53
Откуда: Северодонецк

Сообщение RoboC »

Подскажите новичку, почему не опускается ножка от прерывания по сравнению.
Инициализация stm32f0 tim3:

Код: Выделить всё

 Brightness = 100;
 NVIC_EnableIRQ(TIM3_IRQn);   
 
 TIM3->PSC = 153; 
 TIM3->ARR = 255; 
 TIM3->DIER   |= TIM_DIER_UIE    //*!<Update interrupt enable */
              | TIM_DIER_CC1IE;  //*!<Capture/Compare 1 interrupt enable */
 
 TIM3->CCR1 = Brightness; //*!< TIM capture/compare register 1,  */
 TIM3->CR1 |= TIM_CR1_CEN; 
Обработчик прерывания:

Код: Выделить всё

void TIM3_IRQHandler (void)
{  
  if(TIM3->SR & TIM_SR_UIF == TIM_SR_UIF){
   TIM3->SR = 0;  
   GPIOA->BSRR |= BS(10);         // поднимим ножку
  }
  
  if(TIM3->SR & TIM_SR_CC1IF == TIM_SR_CC1IF){        
       TIM3->SR =0;
       GPIOA->BSRR |= BR(10);       //опустим ножку          
  }
}
У того, кто делает — получается редко. У того, кто не делает — не получается никогда.
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Для начала убрать чтение из BSRR. Дальше будем посмотреть.
Мудрый кот
Аватара пользователя
Сообщения: 1795
Зарегистрирован: Ср апр 04, 2012 09:55:53
Откуда: Северодонецк

Сообщение RoboC »

Чтение BSRR влияет на настройку таймера или на поднятие флага TIM_SR_CC1IF?
У того, кто делает — получается редко. У того, кто не делает — не получается никогда.
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 7361
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

Сообщение uldemir »

И еще, сбрасывайте тот флаг, который обрабатываете, а не все. это по поводу строчки: TIM3->SR =0; лучше TIM3->SR &= ~TIM_SR_UIF;
А вообще, можно этот вывод сделать аппаратно и не нужно будет никаких прерываний.
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Мудрый кот
Аватара пользователя
Сообщения: 1795
Зарегистрирован: Ср апр 04, 2012 09:55:53
Откуда: Северодонецк

Сообщение RoboC »

И еще, сбрасывайте тот флаг, который обрабатываете..
Там всего ~1220 прерываний в секунду и CCR1 установлен на середину счета таймера, друг другу они мешать не должны.

TIM3->SR =0; сбросит все флаги(и TIM_SR_UIF), причем каждый сброс прописан в обработчике для своего флага.
А вообще, можно этот вывод сделать аппаратно и не нужно будет никаких прерываний
Естественно, но я настраивал таймер для работы через прерывания.
TIM_SR_UIF по переполнению поднимается
TIM_SR_CC1IF по сравнению не поднимается

Вопрос у гуру: почему? :oops:
У того, кто делает — получается редко. У того, кто не делает — не получается никогда.
Контактная информация:
Опытный кот
Аватара пользователя
Сообщения: 819
Зарегистрирован: Вт окт 23, 2012 13:17:25
Откуда: Прокопьевск

Сообщение Oxford »

[uquote="passer_by",url="/forum/viewtopic.php?p=3800102#p3800102"]Или можно вывести частоту кварца HSE, после PLL, ну и саму системную частоту SYSCLK.[/uquote]

кварц 4-16mhz, Pll/2 выводиться, SYSCLK должен быть меньше или равно 50 mhz
Инженер R@D

Telegram чат: https://t.me/radiowolf или в поиске приложения @radiowolf. Личка:@cncoxford
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

[uquote="RoboC",url="/forum/viewtopic.php?p=3800264#p3800264"]Чтение BSRR влияет на настройку таймера или на поднятие флага TIM_SR_CC1IF?[/uquote]
На таймер оно не влияет.

Но Вас не смущает то, что:

1) код "поднятия" и "опускания" ножки у Вас в обработчике абсолютно одинаковый, т.е., уже только одно это означает ошибку;

2) читать BSRR вообще нельзя, а Вы это в обоих случаях делаете?
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="RoboC",url="/forum/viewtopic.php?p=3800264#p3800264"]Чтение BSRR влияет на настройку таймера или на поднятие флага TIM_SR_CC1IF?[/uquote]Нет, но это как грязной лапой потрогать :) Такой код и читать дальше не хочется.

Ошибка в приоритете операций & и ==. Правильно будет

Код: Выделить всё

if((TIM3->SR & TIM_SR_UIF) == TIM_SR_UIF)
или вообще

Код: Выделить всё

if(TIM3->SR & TIM_SR_UIF)

[uquote="WiseLord",url="/forum/viewtopic.php?p=3800329#p3800329"]2) читать BSRR вообще нельзя, а Вы это в обоих случаях делаете?[/uquote]Да можно. Только зачем и что он оттуда прочтёт.

[uquote="WiseLord",url="/forum/viewtopic.php?p=3800329#p3800329"]1) код "поднятия" и "опускания" ножки у Вас в обработчике абсолютно одинаковый,[/uquote]И всё таки он разный.
Открыл глаза
Аватара пользователя
Сообщения: 42
Зарегистрирован: Сб янв 05, 2013 21:03:05

Сообщение passer_by »

[uquote="Oxford",url="/forum/viewtopic.php?p=3800305#p3800305"]кварц 4-16mhz, Pll/2 выводиться, SYSCLK должен быть меньше или равно 50 mhz[/uquote]
Не понял.
RCC->CFGR |= RCC_CFGR_MCO_SYSCLK - Выводит установленную вами системную частоту. Не больше не меньше, а именно ту, что вы установили после всех делителей/множетелей, после System Clock Mux на AHB Prescaler.
к примеру параметры RCC->CFGR из stm32f10x.h

Код: Выделить всё

 #define  RCC_CFGR_MCO_SYSCLK                ((uint32_t)0x04000000)        /*!< System clock selected as MCO source */
 #define  RCC_CFGR_MCO_HSI                   ((uint32_t)0x05000000)        /*!< HSI clock selected as MCO source */
 #define  RCC_CFGR_MCO_HSE                   ((uint32_t)0x06000000)        /*!< HSE clock selected as MCO source */
 #define  RCC_CFGR_MCO_PLLCLK_Div2           ((uint32_t)0x07000000)        /*!< PLL clock divided by 2 selected as MCO source */
Добавлено after 12 minutes 37 seconds:
То есть записывая бит в нужный регистр RCC->CFGR вы можете просмотреть (осциллографом или анализатором) верно ли вы настроили всю цепочку делителей/множителей.
Если птичка уже в одном прыжке от тебя, всё-таки побереги свой нос, может она за оконным стеклом???
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

VladislavS писал(а):И всё таки он разный
Чёрт, только сейчас, хорошо присмотревшись, вижу разницу BS/BR.
Тогда да, код в части GPIO потенциально рабочий, т.к. читается BSRR всегда как нули, но из-за read-modify-write обработчик будет дольше выполняться, что на высоких частотах критично.
Контактная информация:
Мудрый кот
Аватара пользователя
Сообщения: 1795
Зарегистрирован: Ср апр 04, 2012 09:55:53
Откуда: Северодонецк

Сообщение RoboC »

Ошибка в приоритете операций & и ==.
Да можно. Только зачем и что он оттуда прочтёт.
VladislavS спасибо.
У того, кто делает — получается редко. У того, кто не делает — не получается никогда.
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="passer_by",url="/forum/viewtopic.php?p=3800389#p3800389"]RCC->CFGR |= RCC_CFGR_MCO_SYSCLK - Выводит установленную вами системную частоту.[/uquote]Читаем RM, ибо он рулез!
When the System Clock is selected to output to the MCO pin, make sure that this clock
does not exceed 50 MHz (the maximum IO speed).
Открыл глаза
Аватара пользователя
Сообщения: 42
Зарегистрирован: Сб янв 05, 2013 21:03:05

Сообщение passer_by »

[uquote="VladislavS",url="/forum/viewtopic.php?p=3800423#p3800423"]Читаем RM, ибо он рулез![/uquote]
:oops: Не попадалось. Работал исключительно с мк до 50мгц.

Добавлено after 27 minutes 8 seconds:
К с тате. Не знаю в какой теме задать вопрос.
Сделал на STM32f042 ЩИМ на таймере с управляемым заполнением импульса для регулировки мощности на нагрузке. Там много еще чего, по этому тактирывал от внутреннего RC-генератора, экономил ножки. ШИМ вывел на оптрон. И с него управление на затвор мосфета. То есть полная развязка по питанию - микруха от одного источника питания, мосфет от другого. Обычную, активную нагрузку регулирует на ура. Стоит подключить коллекторный двигатель (для чего и делалось) все, хана, микруха сходит с ума, выдает какое то случайное заполнение импульса, ну и остальные блоки то же выходят из под контроля. Каких только фильтров ни делал по питанию двигателя ни чего не помогает. Пока грешу на тактовый RC-генератор микрухи, типа нестабильно работает в условиях помех....
Ни кто не сталкивался?
Если птичка уже в одном прыжке от тебя, всё-таки побереги свой нос, может она за оконным стеклом???
Ответить

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