фазовый здвиг

gena321
Offline
Зарегистрирован: 19.01.2019
Приветствую!
Наткнулся здесь на такую программу 
HardwareTimer pwmtimer3(3);
HardwareTimer pwmtimer2(2);

void setup() {
  pinMode(PA7, PWM);
  pwmtimer3.pause();
  pwmtimer3.setPrescaleFactor(1);       
  pwmtimer3.setOverflow(5760 - 1);         
  pwmtimer3.setCompare(TIMER_CH2, 2880);  
  pwmtimer3.refresh();
  pwmtimer3.resume();
  delay(50); //регулировка фазового сдвига
  pinMode(PA3, PWM);
  pwmtimer2.pause();
  pwmtimer2.setPrescaleFactor(1);       
  pwmtimer2.setOverflow(5760- 1);          
  pwmtimer2.setCompare(TIMER_CH4, 2880);  
  pwmtimer2.refresh();
  pwmtimer2.resume();
}

void loop() {
}

 

но величина delay не вносить никакого сдвига фазы.
Подскажите пожалйста как сделать фазовый здвиг.
b707
Offline
Зарегистрирован: 26.05.2017

gena321 пишет:

но величина delay не вносить никакого сдвига фазы.

интересно, как вы это проверяли? :)

И кстати, у  вас величина задержки в десятки раз больше периода таймера, о каком "сдвиге" вы говорите? Фазовый сдвиг по определению меньше периода

 

gena321
Offline
Зарегистрирован: 19.01.2019

проверял на осциллоскопе, вставлял разные значения в delay

b707
Offline
Зарегистрирован: 26.05.2017

gena321 пишет:

проверял на осциллоскопе, вставлял разные значения в delay

Вы какую частоту таймера пытаетесь задать? а фазовый сдвиг ккой?

gena321
Offline
Зарегистрирован: 19.01.2019

здесь 12,5 кГц

gena321
Offline
Зарегистрирован: 19.01.2019

сдвиг любой, например 30 градусов 

b707
Offline
Зарегистрирован: 26.05.2017

gena321 пишет:

частота 12.5 КГц

сдвиг любой, например 30 градусов 

Если у вас частота 12 КГц - то есть период порядка 80 микросекунд, так какой же сдвиг вы пытаетесь всести задержкой в 50 миллисекунд - в сотни раз больше периода?

Фазовый сдвиг проще всего делать задавая начальное значение счетчика на одном таймере 0, а на другом - сдвигом на нужную часть периода. Для значния переполнения 5760 и сдвига на 30 градусов это будет 5760*30/360 = 480

 

gena321
Offline
Зарегистрирован: 19.01.2019
поставил
delayMicroseconds(41);

 

кажется работает, загрузил один раз, за втором получил ошибку "core is locked", проверяю 
gena321
Offline
Зарегистрирован: 19.01.2019

Спасибо 707, все как надо

b707
Offline
Зарегистрирован: 26.05.2017

gena321 пишет:

кажется работает

Я вам написал как надо делать - если не поняли, лучше переспрашивайте. Ваш код в первом сообщении в принципе неверный,  задержками точный сдвиг никогда не сделать.

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

Хотя повторяю, то как вы делаете - удаление гланд через Ж

gena321
Offline
Зарегистрирован: 19.01.2019

Это не проблема, с чего то начинать надо

b707
Offline
Зарегистрирован: 26.05.2017

gena321 пишет:

Это не проблема, с чего то начинать надо

перевожу - "разбираться лень, сойдет и так".

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

gena321
Offline
Зарегистрирован: 19.01.2019
707
Это только начало, добавлю кнопки и посмотрю как это работает, возможно возникнут вопросы 
ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

gena321 пишет:

707
Это только начало, добавлю кнопки и посмотрю как это работает, возможно возникнут вопросы 

хреново заработает, попросите лучше b707 в коде показать

gena321
Offline
Зарегистрирован: 19.01.2019

Вот сделал так, сдвиг фазы регулируется проблема = импульсы не стабильные, дрожат.

HardwareTimer pwmtimer1(1);
HardwareTimer pwmtimer4(4);
#include <LiquidCrystal.h>
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);
int i;
int ovfi;

void setup() {
  pinMode(PA8, PWM); //Rx
  pinMode(PB7, PWM); //Tx
  pinMode(PB6, INPUT_PULLDOWN);
  pinMode(PB9, INPUT_PULLDOWN);
  lcd.begin(16, 2);
}

void loop() {
  ovfi = 10000 - i;
  pwmtimer1.pause();
  pwmtimer1.setPrescaleFactor(1);       
  pwmtimer1.setOverflow(5760 - 1);         
  pwmtimer1.setCompare(TIMER_CH1, 2880);  
  pwmtimer1.refresh();
  pwmtimer1.resume();

  delayMicroseconds(60); // 16 us shift
  // delayMicroseconds(30);// 6us
  delayMicroseconds(i);

  pwmtimer4.pause();
  pwmtimer4.setPrescaleFactor(1);       
  pwmtimer4.setOverflow(5760 - 1);            
  pwmtimer4.setCompare(TIMER_CH2, 2880); 
  pwmtimer4.refresh();
  pwmtimer4.resume();

  if (digitalRead(PB9) == HIGH)
  {
    if (i < 6000)
      // if (i < 25)
    {
      i++;
      analogWrite(PB0, i);  
      delay(50);
    }
  }
  if (digitalRead(PB6) == HIGH)
  {
    if (i > 0)
    {
      i--;
      analogWrite(PB0, i); 
      delay(50);
    }
  }
  lcd.setCursor(0, 1);
  lcd.println(i);

}

 

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Я бы тоже дрожал если бы меня все время пинали. Зачем вы постоянно таймеры останавливаете/запускаете?

b707
Offline
Зарегистрирован: 26.05.2017

gena321 пишет:

Вот сделал так, сдвиг фазы регулируется проблема = импульсы не стабильные, дрожат.

 

полную фигню сделали - вот и дрожат.

Во-первых, как Вам уже сказали - настройкам таймеров нечего делать в loop() - так работать не будет. Во-вторых - что за фигня у вас в строчках 38-42?  Вы в курсе, в каких пределах должен лежать параметр функции analogWrite()?

По-моему, вы пытаетесь настроить таймерыЮ подбрасывая монетку. Орел - пишем одну строчку, решка - другую. Пока вы не прочитаете раздел даташита СТМ про таймеры - или хотя бы какую-нибудь хорошу статью в инете - и главное - НЕ РАЗБЕРЕТЕСЬ В СУТИ - нифига у вас не выйдет

И еще - если вы не слушаете ответов - зачем спрашивать? Пробуйте сами, не отнимайте у людей время.

gena321
Offline
Зарегистрирован: 19.01.2019
Теперь не дрожат, их вообще нет

void loop() {
  ovfi = 10000 - i;
  pwmtimer1.pause();
  pwmtimer1.setPrescaleFactor(1);       
  pwmtimer1.setOverflow(5760 - 1);         
  pwmtimer1.setCompare(TIMER_CH1, 2880);  
 // pwmtimer1.refresh();
  //pwmtimer1.resume();

  delayMicroseconds(60); // 16 us shift
  // delayMicroseconds(30);// 6us
  delayMicroseconds(i);

  pwmtimer4.pause();
  pwmtimer4.setPrescaleFactor(1);       
  pwmtimer4.setOverflow(5760 - 1);            
  pwmtimer4.setCompare(TIMER_CH2, 2880); 
 // pwmtimer4.refresh();
 // pwmtimer4.resume();

  if (digitalRead(PB9) == HIGH)

 

gena321
Offline
Зарегистрирован: 19.01.2019

Как сказал, встретил простую программу, проверяю будет ли она работать

b707
Offline
Зарегистрирован: 26.05.2017

gena321 пишет:
Теперь не дрожат, их вообще нет

Неудивительно - ответы не читаем.

Разбирайтесь. Начните с методички - что такое таймеры вообще и как работают. Потом переходите к таймерам СТМ32.

А тут с таким подходом писать не надо. Вам никто не поможет.

RG22EM
Offline
Зарегистрирован: 27.08.2016

gena321 пишет:

Как сказал, встретил простую программу, проверяю будет ли она работать

Все ли грибы съедобные? Съедобны все, только некоторые один раз )))
Так и с вашей программой!

Вам же сказали как надо делать, на таймерах, да и то не идеально (Джиттер), так как кварцевые резонаторы разного качества, а сейчас в ардуино нано вообще стараются поставить керамический, а на китайском клоне WAVGAT тоже керамика и по умолчанию от синтезатора PLL тактируется...
Таймеры - это тот минимум на чём надо реализовать, читайте

gena321
Offline
Зарегистрирован: 19.01.2019

Что на тимерах можна это сделать это не новость.

gena321
Offline
Зарегистрирован: 19.01.2019

Добавил noInterrupts() ;, стало намного лучше но в место  480 шагов (сообщение # 6) для 30 градусов  этот сдиг происходит после 9 шагов .

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

gena321 пишет:

Что на тимерах можна это сделать это не новость.

Посмотреть бы в кодах как это выглядит для arduino nano

gena321
Offline
Зарегистрирован: 19.01.2019

Со сдвигом фазы не встретил

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

gena321, я давал отличный рабочий  пример  сдвига фаз прямоугольника для STM32, даже с картинкой.

gena321
Offline
Зарегистрирован: 19.01.2019

Спасибо, читаю.

Вот и там наткнулся на эту программу, о чом  говорил в самом начале, но про регулировку фазы там пока ничего не нашол.

Когда перенести эти генератора в сетап прямоугольники стабильные но фазу можнно менять только вручную.

Можно ли сделать обновление сетап при нажатии кнопки ? 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

gena321, там всего два настраиваемых парамера:  ARR = (36E6/нужную_частоту_Гц)-1 ;  CCR2 -отставание фазы второго сигнала в тактах мк  -1

gena321
Offline
Зарегистрирован: 19.01.2019
 
Нашел, сообщение #70, здесь тоже менять сдвиг можно только вручную.
пригодилась бы функция  - refresh setup "while" or" if" button is high
gena321
Offline
Зарегистрирован: 19.01.2019

Но у Вас один тимэр = замечательно 

gena321
Offline
Зарегистрирован: 19.01.2019
Получилось, Спасибо dimax

///////////////////////////////
#include <LiquidCrystal.h>
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);
int i;
int ovfi;
//////////////////////////////
void setup() {
  // put your setup code here, to run once:
pinMode(PA8,PWM); 
pinMode(PA9,PWM); 
////////////////////////////////////
 pinMode(PB6, INPUT_PULLDOWN);
  pinMode(PB9, INPUT_PULLDOWN);
  lcd.begin(16, 2);
////////////////////////////////////
}

void loop() {
  ovfi = 10000 - i;

TIMER1_BASE->CCER=(1<<4)|(1<<0);//cc1e/cc2e enable 
TIMER1_BASE->CCMR1=(1<<13)|(1<<12)|(1<<5)|(1<<4);//toogle mode 
TIMER1_BASE->PSC=0;
TIMER1_BASE->ARR=2879; //frequency
TIMER1_BASE->CCR1=0 ;
//TIMER1_BASE->CCR2=1439 ;//phase
TIMER1_BASE->CCR2= i ;//phase
TIMER1_BASE->CR1=1;
////////////////////////////////////
if (digitalRead(PB9) == HIGH)
  {
    if (i < 6000)
      // if (i < 25)
    {
      i++;//if pin PB3 is pressed and the duty ratio value is less than 255
      analogWrite(PB0, i);  // analogWrite values from 0 to 255
    
      //delay(100);
    }
       
  }
  if (digitalRead(PB6) == HIGH)
  {
    if (i > 0)
    
    {
      i--;// if pin PB5 is pressed and the duty ratio value is greater than 0
      analogWrite(PB0, i);  // analogWrite values from 0 to 255
      
      //delay(100);
    }
   
  }
  lcd.setCursor(0, 1);
  lcd.println(i);
///////////////////////////////////
}


////////////////////////////////////
/*
 *  gena321, там всего два настраиваемых парамера:
ARR = (36E6/нужную_частоту_Гц)-1 ;  
CCR2 -отставание фазы второго сигнала в тактах мк  -1
 */

/////////////////////////////////

 

gena321
Offline
Зарегистрирован: 19.01.2019

А как менять ширину  импульса?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

gena321, в данном режиме никак. Нужно перенастраивать таймер в PWM режим.

gena321
Offline
Зарегистрирован: 19.01.2019

 

Вот этот и есть в PWM, как их соединить ?

 pwmtimer1.pause();
  pwmtimer1.setPrescaleFactor(1);          //частота     
  pwmtimer1.setOverflow(5760 - 1);         //частота       
  pwmtimer1.setCompare(TIMER_CH1, 2880);   //ширина 
  pwmtimer1.refresh();
  pwmtimer1.resume();

 

 

 

 

b707
Offline
Зарегистрирован: 26.05.2017

Гена, сколько Вам нужно повторить, что таймер НЕ НАДО НАСТРАИВАТЬ в основном цикле loop ? Вы понимаете, что loop у вас запускается сотни раз в секунду - и значит вы сотни раз в секунду заново настраиваете и перезапускаете таймер? - никакой устойчивой генерации сигнала в таком случае в принципе быть не может. В этой ветке вам уже три или четыре раза это сказали - и опять в скетче сообщения #31 у вас настройка в loop

gena321
Offline
Зарегистрирован: 19.01.2019
У dimax работа стабильна потому что там один тимер. Сообщение #34 это воапрос.
Другой вариант это что то такое - 
(1) The configuration signal PB6 (TIM4-CH1) is a floating input, and the signal enters here through the comparator to obtain a rising edge. 

(2) Configure TIM4 time base, configure TIM4-CH1 input capture, select TIM_TS_TI1FP1 input trigger, other configuration according to the routine, enable TIM4, open interrupt TIM_IT_CC1. 

(3) Start the TIM2 sampling interval timing in the TIM4 interrupt routine. 

(4) In the interrupt program of TIM2, sampling is started. 
копаюсь 
gena321
Offline
Зарегистрирован: 19.01.2019

Вот этой строкой можна менять ширину импульсов, как ее добавить в dimax программу ?

 pwmtimer1.setCompare(TIMER_CH2, 2880);

 

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Посмотреть, как это делается в исходнике библиотеки.

b707
Offline
Зарегистрирован: 26.05.2017

gena321 пишет:

У dimax работа стабильна потому что там один тимер.

Нет, не поэтому. У dimax стабильно потому в его программе таймер настраивается ДО ИСПОЛЬЗОВАНИЯ.

Это не обязательно должно быть в сетапе - можно написать отдельную функцию или часть кода. Но этого нельзя вставлять в основной loop - как вы этого не поймете? Так работать не будет.

У меня такое чувство. что не только таймеры - вы и программировать-то начали с месяц назад. Не понимаете элементарных вещей. Может для начала с полгодика какие-нибудь проекты по проще освоить? Таймеры - не самое простое дело для новичка.

 

b707
Offline
Зарегистрирован: 26.05.2017

Гена - вы там выше спрашиваете "Как вызывать setup по кнопке?"

А нафига системный setup() вызывать? Создайте свою функцию setup_gena() , поместите в нее настройку таймера даи вызывайте по кнопке...

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

b707 пишет:

Гена - вы там выше спрашиваете "Как вызывать setup по кнопке?"

А нафига системный setup() вызывать? Создайте свою функцию setup_gena() , поместите в нее настройку таймера даи вызывайте по кнопке...

Примерно так?:
 

void setup_gena(psc,arr,ccr1,ccr2,cr1) {
unsigned int psc;
unsigned int arr;
unsigned int ccr1;
unsigned int ccr2;
unsigned int cr1;

pinMode(PA8,PWM); 
pinMode(PA9,PWM); 
TIMER1_BASE->CCER=(1<<4)|(1<<0);//cc1e/cc2e enable 
TIMER1_BASE->CCMR1=(1<<13)|(1<<12)|(1<<5)|(1<<4);//toogle mode 
TIMER1_BASE->PSC=psc;
TIMER1_BASE->ARR=arr;
TIMER1_BASE->CCR1=ccr1;
TIMER1_BASE->CCR2=ccr2;
TIMER1_BASE->CR1=cr1;

}

 

b707
Offline
Зарегистрирован: 26.05.2017

Я, честно, на память вот так вот не могу все эти параметры выставить, а искать в Гугле - это вы и сами можете :)

таймер перед настройкой надо остановить, тут этого нет

pinMode тут явно лишние, их в основной setup() надо.

и с параметрами функции вы что-то намудрили

gena321
Offline
Зарегистрирован: 19.01.2019

Спасибо Всем за советы, пригодилось бы больше примеров как в сообщении #41

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

ua6em пишет:

b707 пишет:

Гена - вы там выше спрашиваете "Как вызывать setup по кнопке?"

А нафига системный setup() вызывать? Создайте свою функцию setup_gena() , поместите в нее настройку таймера даи вызывайте по кнопке...

Примерно так?:
 

void setup_gena(psc,arr,ccr1,ccr2,cr1) {
unsigned int psc;
unsigned int arr;
unsigned int ccr1;
unsigned int ccr2;
unsigned int cr1;

pinMode(PA8,PWM); 
pinMode(PA9,PWM); 
TIMER1_BASE->CCER=(1<<4)|(1<<0);//cc1e/cc2e enable 
TIMER1_BASE->CCMR1=(1<<13)|(1<<12)|(1<<5)|(1<<4);//toogle mode 
TIMER1_BASE->PSC=psc;
TIMER1_BASE->ARR=arr;
TIMER1_BASE->CCR1=ccr1;
TIMER1_BASE->CCR2=ccr2;
TIMER1_BASE->CR1=cr1;

}

 

Месье в детстве изучал "отрыжку Вирта" - Паскаль? ;)))))

В нормальном ЯП так не пишут. Гы!

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

wdrakula пишет:

Месье в детстве изучал "отрыжку Вирта" - Паскаль? ;)))))

В нормальном ЯП так не пишут. Гы!

Ты пальцем покажи... )))

Паскаль не знаю, от слова совсем, но примеры из книги адаптировал и применял в ЯЗЫКЕ Инфо-Бухгалтер при работе с базами данных, с Ребусом, Дибэйсом, фокспро - знаком ))) А лучшая программа всех времён и народов для работы с базами данных - "Легко и Просто"? Не согласен???? )))

gena321
Offline
Зарегистрирован: 19.01.2019

Вот нашел такую программу

#include 'stm32f303xc.h'
long cnt1 = 0;
long cnt2 = 0;
short x = 0;
void Delay(uint32_t circles);
int main(void){
RCC->AHBENR = RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOEEN; //clock for A and E ports
RCC->APB1ENR = RCC_APB1ENR_TIM3EN; //clock for timer
GPIOE->MODER |= GPIO_MODER_MODER11_0 // Green
| GPIO_MODER_MODER10_0 // Orange
| GPIO_MODER_MODER9_0 // Red LED output mode
| GPIO_MODER_MODER2_0; // PE02 - TRIGG PIN outputmode
TIM3->CCMR1 = TIM_CCMR1_CC1S_0; //CC AS INPUT, MAP TI1 (PE03)
TIM3->CCER = TIM_CCER_CC1NP_Msk | TIM_CCER_CC1P_Msk; // EVENT ON RISING AND FALLING EDGE
TIM3->CCMR1 = TIM_CCMR1_IC1PSC; // NO PSC - CAPTURE EACH EVENT
TIM3->CCER = TIM_CCER_CC1E; // ENABLE INPUT CAPTURE COMPARE MODE
TIM3->DIER = TIM_DIER_CC1IE; // ENABLE CC INTERRUPT 
TIM3->CR1 = TIM_CR1_CEN; // ENABLE TIM3
NVIC_EnableIRQ(TIM3_IRQn); // ENABLE NVIC INTERRUPT FOR TIM3
Delay(800000); // Wait some time
GPIOE->ODR |= GPIO_ODR_2; // Set PE02
Delay(8000); // Wait 10us
GPIOE->ODR &= ~(GPIO_ODR_2); // Reset PE02
 
while(1){}
}
void TIM3_IRQHandler(void)
{
if(x==0)
{
cnt1 = TIM3->CCR1; // GET VALUE
x++; // REMEMBER THAT NEXT IS FALLING EDGE
GPIOE->ODR |= GPIO_ODR_10; // SET LED TO CONFIRM
}
else if(x==1)
{
cnt2 = TIM3->CCR1; // GET VALUE
x--; // NEXT IS RISING EDGE
GPIOE->ODR |= GPIO_ODR_11; // SET LED TO CONFIRM
}
}
// SysTick clock = 8MHz so you get 1sec delay afret 8000000 circles
//
void Delay(uint32_t circles)
{
SysTick->LOAD = circles - 1;
SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_ENABLE_Msk;
while(!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)); 
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}

Там есть функция 

TIM3->CCER = TIM_CCER_CC1E; // ENABLE INPUT CAPTURE COMPARE MODE

похожая до этих двух в месте - ширина импульсов

  pwmtimer1.setOverflow(5760 - 1);
  pwmtimer1.setCompare(TIMER_CH3, 2880); //ширина импульсов

можно ли  это использовать в программе dimax ?

gena321
Offline
Зарегистрирован: 19.01.2019

помню что dimax сказал в #33, но может, все-таки можно?

Один канал сдвигать, второй менять ширину .