Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F103 - как получить на выходе пина меандр в половину тактовой частоты?
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
zheka
STM32F103 - как получить на выходе пина меандр в половину тактовой частоты?
Хочу настроить тактовый генератор на 64 МГц и получить на выходе 32 МГц.
Перерыл интернет - я наверное даже не знаю по каким ключевым словам искать
В какой режим нужно отправить таймер, чтобы получить желаемое?
ViKo
MCO смотрите.
zheka
спасибо, но мне бы с таймером. Я хочу в определенные моменты знать, сколько тактов отсчиталось, прерывания хочу.

в частности, хочу запустить таймер, вывести на пин ровно 1024 клока и остановиться. Возможно такое?
ViKo
Таймер может работать на частоте шины. Делить на 2 тоже. Но как задать количество ттактов? Другим таймером попробовать задать интервал, а с него подать сигнал разрешения. Конкретнее не скажу.
adnega
Цитата(zheka @ Mar 2 2015, 22:10) *
вывести на пин ровно 1024 клока и остановиться. Возможно такое?

А задачку целиком озвучить можете?
Сначала просто 32МГц, сейчас уже 1024 клока...
Если супер стабильность не важна, а важно лишь ограничение частоты сверху, то можно и SPI + DMA настроить.
А так, как правильно сказали, читайте про каскадное соединение таймеров. При работе на частоте FCPU/2 про прерывания можно забыть.
Только аппаратная реализация с опциональным прерыванием в конце пачки.
zheka
Вот что мне нужно было:
Код
TIM_TimeBaseStructInit(&TIM_InitStructure);
  TIM_InitStructure.TIM_Prescaler = 1000;  
  TIM_InitStructure.TIM_Period = 1000;
  TIM_TimeBaseInit(TIM4, &TIM_InitStructure);

  TIM_OCStructInit(&TIM_OCConfig);
  TIM_OCConfig.TIM_OCMode = TIM_OCMode_Toggle;
  TIM_OCConfig.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OC1Init(TIM4, &TIM_OCConfig);
  TIM_ITConfig(TIM4, TIM_DIER_UIE, ENABLE);

  TIM_Cmd(TIM4, ENABLE);


Но это пока без отсчета тактов. Делители поставил такими, чтобы наносекунды превратились в миллисекунды. Вроде работает.
Что-то не густо в сети про каскадное соединение таймеров. Этот термин означает конкретный режим или фишку контроллера? Или эже этим термином обозначается прием - включать и выключать таймер, дергающий ножкой, другим таймером, тупо отсчитывающим временные интервалы?

Цитата
А задачку целиком озвучить можете?

Да я все SDRAMом хочу рулить. Не отговаривайте. Долно и нудно объяснять почему я не хочу использовать контроллер с аппаратным SDRAM.
Хочу запустить таймер, управляющий клоком, на строго определенное число тактов.
SSerge
Цитата(zheka @ Mar 3 2015, 23:31) *
Что-то не густо в сети про каскадное соединение таймеров. Этот термин означает конкретный режим или фишку контроллера? Или эже этим термином обозначается прием - включать и выключать таймер, дергающий ножкой, другим таймером, тупо отсчитывающим временные интервалы?

Есть только один способ разобраться - читать реф.мануал, писать код и смотреть что получается.

Смотрите Figure 52, ведущий таймер надо настроить на генерацию подходящего сигнала TRGO, а ведомый получит этот сигнал на один из своих входов ITR0 .. ITR3 (см. Table 82, описание регистров TIMx_CR2, TIMx_SMCR).
zheka
И при этом ведущий же таймер будет дергать клоком, я правильно понял? А ведомый будет считать клоки?
SSerge
Подойдёт, я думаю, режим Gated Mode - The counter clock is enabled when the trigger input (TRGI) is high,
это в поле SMS регистра SMCR.
Ведущий будет своим сигналом разрешать/запрещать клок для ведомого.
zheka
Цитата(SSerge @ Mar 3 2015, 20:00) *
Подойдёт, я думаю, режим Gated Mode - The counter clock is enabled when the trigger input (TRGI) is high,
это в поле SMS регистра SMCR.
Ведущий будет своим сигналом разрешать/запрещать клок для ведомого.


Спасибо, получилось. РАзобрался с каскадами. Вывел мастер и слейв на осциллограф.
Вот код
Код
    GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_6 | GPIO_Pin_0);
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    
    
  TIM_TimeBaseStructInit(&TIM_InitStructure);
  TIM_InitStructure.TIM_Prescaler = 1000-1;  
  TIM_InitStructure.TIM_Period = 1000;
  TIM_TimeBaseInit(TIM2, &TIM_InitStructure);

  TIM_OCStructInit(&TIM_OCConfig);
  TIM_OCConfig.TIM_OCMode = TIM_OCMode_Toggle;
  TIM_OCConfig.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OC1Init(TIM2, &TIM_OCConfig);

  /* Select the Master Slave Mode */
  TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);
  /* Master Mode selection */
  TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);


  TIM_Cmd(TIM2, ENABLE);

  TIM_TimeBaseStructInit(&TIM_InitStructure);
  TIM_InitStructure.TIM_Prescaler = 1-1;  
  TIM_InitStructure.TIM_Period = 10;
  TIM_TimeBaseInit(TIM3, &TIM_InitStructure);

  TIM_OCStructInit(&TIM_OCConfig);
  TIM_OCConfig.TIM_OCMode = TIM_OCMode_Toggle;
  TIM_OCConfig.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OC1Init(TIM3, &TIM_OCConfig);

  /* Slave Mode selection: TIM3 */
    TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Gated);
    TIM_SelectInputTrigger(TIM3, TIM_TS_ITR1);

    /* Select the Master Slave Mode */
    TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);

    /* Master Mode selection: TIM3 */
    TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update);
  TIM_Cmd(TIM3, ENABLE);


Прилагаю ниже осциллограмму. Настроил на 10 клоков (красные клоки), но реакция ведомого таймера (спад синего графика) почему-то на одиннадцатый клок. Чем объяснить?
SSerge
Цитата(zheka @ Mar 4 2015, 00:40) *
Настроил на 10 клоков (красные клоки), но реакция ведомого таймера (спад синего графика) почему-то на одиннадцатый клок. Чем объяснить?

Может потому, что таймер считает от 0 до 10?

Тут вообще не очень понятно.
TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update); приведёт к тому, что TIM2 на своём выходе TRGO будет формировать импульс длительностью в 1 такт в момент апдейта, через каждые 1000*1001 тактов.

Только в этот момент на TIM3 будет поступать входной клок, по одному клоку на каждый импульс TRGO.
Поскольку в TIM3->ARR заряжено 10, то TIM3 отсчитает 11 таких клоков до своего апдейта.
zheka
Значит нужно 999 для TIM2 и 9 для TIM3 ?
Не... я понимаю, что математически это сработает, просто хочется делать правильно, а не "подравнивать ножки стула подпиливанием".
Ладно, разберусь.

Есть другой вопрос - а нельзя ли как-то, путем хитрых манипуляций с PLL заставить контроллер работать на частоте 72 МГц, а таймеры тактировать 32 МГц? 32 ведь кратно 8-ми, нельзя ли как-то отдельно эти 8 МГц умножать на 4 и от результата тактировать таймер?


ТАКИ ФИГНЯ ПОЛУЧАЕТСЯ...
Не могу один клок отсечь (то бишь один полупериод).
Ставлю Period = 1 - получаю 2 смены состояния, ставлю 0 - не получаю ничего.
SSerge
Figure 8. Clock tree в реф. мануале.
Видим что все клоки для периферии делаются из SYSCLK посредством двух прескалеров: AHB Prescaler и после него APB1 или APB2 Prescaler.
Так что 32 МГц можно получить только делением SYSCLK=64МГц на два.
zheka
Вот ведущий таймер
TIM_InitStructure.TIM_Prescaler = 1-1;
TIM_InitStructure.TIM_Period = 1;

Вот ведомый
TIM_InitStructure.TIM_Prescaler = 1000-1;
TIM_InitStructure.TIM_Period = 1;
Осциллографом получаю 9 кГц на выходе ведомого.
Хотя по идее должно быть - 72 000 000/2/1000/2 = 18 кГц.
Где ошибка закралась?


С тактироваинем все нормально, при одиночной работе таймера по стандартным настройкам секундные импульсы генерируются правильно.
Вот мой PLL на всякий случай.
Код
/* Enable HSE */
  RCC_HSEConfig(RCC_HSE_ON);

  /* Wait till HSE is ready */
  HSEStartUpStatus = RCC_WaitForHSEStartUp();

  if (HSEStartUpStatus == SUCCESS)
  {
    /* Enable Prefetch Buffer */
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

    /* Flash 2 wait state */
    FLASH_SetLatency(FLASH_Latency_2);

    /* HCLK = SYSCLK */
    RCC_HCLKConfig(RCC_SYSCLK_Div1);

    /* PCLK2 = HCLK */
    RCC_PCLK2Config(RCC_HCLK_Div1);

    /* PCLK1 = HCLK/2 */
    RCC_PCLK1Config(RCC_HCLK_Div2);

    /* PLLCLK = 8MHz * 9 = 72 MHz */
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

    /* Enable PLL */
    RCC_PLLCmd(ENABLE);

    /* Wait till PLL is ready */
    while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
    {}

    /* Select PLL as system clock source */
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

    /* Wait till PLL is used as system clock source */
    while (RCC_GetSYSCLKSource() != 0x08)
    {}
  }

  /* TIM2 and TIM3 clocks enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3 , ENABLE);

   /* Enable GPIOA, GPIOC, ADC1 , AFIO and TIM1 clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA| RCC_APB2Periph_GPIOC | RCC_APB2Periph_TIM1 | RCC_APB2Periph_AFIO, ENABLE);
SSerge
Так.
SYSCLK=72 000 000
прескалер AHB = 1
прескалер APB1 (на которой сидят TIM2 и TIM3) = 2
таким образом на TIM2 приходит клок 72e6/2

прескалер TIM2 = 1
период TIM2 =2
при этом если по-прежнему TRGO генерируется по событию апдейта, то получается что импульс на TRGO длительностью в один такт таймера формируется каждые два такта. В одном такте на TRGO 1, в другом 0, и опять 1, опять 0. Это явно не то, что требовалось для первоначальной задачи, ну да ладно.

TIM3 тактируется тем же клоком, что и TIM2, но из-за gate mode входным сигналом ITR1 (он-же TRGO от TIM2) один клок пропускается, один запрещается. На собственно счётчик TIM3 приходит только каждый второй импульс его входного клока.
Итого, эквивалентный входной клок TIM3 уже 72e6/2/2.
Далее он делится на 1000.
и ещё одно деление на 2 - из-за режима toggle для OC1
72e6/2/2/1000/2 = 9000
вроде совпадает.
zheka
иными словами, при каскадировании второй таймер будет работать минимум в 4 раза медленней, чем первый?

я что хочу получить в идеале - функцию вида : void ДатьОчередьКлоков( unsigend int количество_клоков).
SSerge
Цитата(zheka @ Mar 4 2015, 03:07) *
иными словами, при каскадировании второй таймер будет работать минимум в 4 раза медленней, чем первый?

Ну так TRGO-то можно по-разному формировать.
Например, 100: Compare - OC1REF signal is used as trigger output (TRGO)
тогда на TRGO будет импульс совпадающий по форме с OC1REF.
Пока он ==1 на ведомый таймер поступает его нормальный клок, как стал 0 - так клок запрещается.

Далее, если выходной сигнал формировать как toggle, то этот выход сможет переключаться только каждые 2 такта. Период на OCx будет 4 такта. А можно использовать PWM1 или PWM2, тогда минимальный период на выходе OCx уже 2 такта.

Исходную задачу вообще можно решить только с TIM1 или TIM8 в качестве ведомого, потому что только они сидят на более быстрой шине APB2 и могут тактироваться 64МГц.
Этим таймером формировать OCx в режиме PWM (1 или 2), получится как раз 32МГц.
На вход ITRx ему давать сигнал длительностью 2048 его клоков, он за это время сформирует 1024 импульса на выходе OCx.
zheka
Цитата
Ну так TRGO-то можно по-разному формировать.
Например, 100: Compare - OC1REF signal is used as trigger output (TRGO)
тогда на TRGO будет импульс совпадающий по форме с OC1REF.
Пока он ==1 на ведомый таймер поступает его нормальный клок, как стал 0 - так клок запрещается.

Я правильно понял, вы хотите ведомым, то есть контролирующим количество клоков, таймером останавилвать ведущий? Если да, и это возможно, то идея хорошая.

Цитата
только с TIM1 или TIM8 в качестве ведомого, потому что только они сидят на более быстрой шине APB2 и могут тактироваться 64МГц.
Этим таймером формировать OCx в режиме PWM (1 или 2), получится как раз 32МГц.

Я Вас наверное запутал. Мне не надо на ведомом 32 МГц.
Давайте еще раз по полочкам:

1. Нужна функция SendSomeClocks(unsigned int Clocks_count);
При вызове она должна сформировать на выходе таймера импульсы в количестве, обозначенном Clocks_count c частотой 32 МГц.


Как мне это видится (схематично):

Код
void EXT_FrequencyCounterConfig(void)
{

// Настраиваем ведущий таймер, формирующий клоки. Выбор таймера, источника тактирвоани, а также настройки периода и делителя должны обеспечить 32МГц
TIM_TimeBaseStructInit(&TIM_InitStructure);
  TIM_InitStructure.TIM_Prescaler = 1-1;  
  TIM_InitStructure.TIM_Period = 1;
  TIM_TimeBaseInit(TIM2, &TIM_InitStructure);

// Настраиваем канал, с которого будем снимать клоки.
  TIM_OCStructInit(&TIM_OCConfig);
  TIM_OCConfig.TIM_OCMode = TIM_OCMode_Toggle;
  TIM_OCConfig.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OC1Init(TIM2, &TIM_OCConfig);


// Настраиваем ведомый таймер. Он должен подсчитывать количество генерируемых ведущим клоков. Обратите внимание - не количество смен состояния, а именно количество импульсов. То есть если при каскадировании каким-то образом, если я правильно понял Ваше описание, частота делится на два - отлично, если нет, то нужно учесть это в настройках таймера

TIM_TimeBaseStructInit(&TIM_InitStructure);
  TIM_InitStructure.TIM_Prescaler = 1-1;   // или  2-1, в зависимости от пути решения проблемы, обозначенной выше.
  TIM_InitStructure.TIM_Period = 1;
  TIM_TimeBaseInit(TIM3, &TIM_InitStructure);

// ВРЕМЕННО настраиваем выход, просто чтобы осциллографом проконтролировать результат.
  TIM_OCStructInit(&TIM_OCConfig);
  TIM_OCConfig.TIM_OCMode = TIM_OCMode_Toggle;
  TIM_OCConfig.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OC1Init(TIM3, &TIM_OCConfig);
}

// В вышеописанной функции я пока не описывал настройку связей между таймерами, нужно определиться с режимами.


//По задумке, таймер 3 (ведомый) должен переполняться как раз тогда, когда все клоки протикали.
//Обрабатываем прерывание по переполнению
void TIM3_IRQHandler(void)
{
TIM_Cmd(TIM3, DISABLE); //Выключили
TIM_Cmd(TIM2, DISABLE); //Выключили
TIM3->SR &= ~TIM_SR_UIF; //reset interrupt flag

Ready_FLAG=1; // Доложили об исполнении
}



// СОБСТВЕННО ФУНКЦИЯ SendSomeClocks
void SendSomeClocks (unsigned int Clocks_count)
{
// Сообщаем Ведомому, когда же он должен остановиться, перенастраиваем и запускаем

  TIM_InitStructure.TIM_Period = Clocks_count;
  TIM_TimeBaseInit(TIM3, &TIM_InitStructure);
TIM_Cmd(TIM3, ENABLE); // таймер работает, но не тикает, пока не получены сигналы от TIM2

TIM_Cmd(TIM2, ENABLE); //Включили, пошли клоки.
}

// Пока тикает таймер, контрллер идет заниматься богоугодными делами.


Что скажете насчет режимов, каскадов, выбора таймеров и шины тактирования?
zheka
Скажите, а у TIM1 есть какие-нибудь особенности в режиме OC_Toggle?
У меня почему-то не получается запустить.
Поменял в коде номер, настроил нужную ножку. ТАймер тикает, это точно, проверял отладчиком. Но на выходе ноль.
Код
TIM_TimeBaseInitTypeDef TIM_InitStructure;
TIM_OCInitTypeDef TIM_OCConfig;
  
    RCC->APB1ENR |= RCC_APB1ENR_TIM3EN | RCC_APB1ENR_TIM4EN | RCC_APB1ENR_TIM2EN;//
   RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;//TIM1
//GPIO_PinRemapConfig(GPIO_FullRemap_TIM1, ENABLE);

    
    GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_6 | GPIO_Pin_0 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_1 );
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    
    TIM_TimeBaseStructInit(&TIM_InitStructure);
  TIM_InitStructure.TIM_Prescaler = 10000-1;  
  TIM_InitStructure.TIM_Period = 10;
  TIM_TimeBaseInit(TIM1, &TIM_InitStructure);

  TIM_OCStructInit(&TIM_OCConfig);
  TIM_OCConfig.TIM_OCMode = TIM_OCMode_Toggle;
  TIM_OCConfig.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OC2Init(TIM1, &TIM_OCConfig);
    
    TIM_Cmd(TIM1, ENABLE);
    TIM1->CNT=0;
zheka
Тихо сам с собою....
В принципе, нужную конструкцию я сварганил:

Код
TIM_TimeBaseStructInit(&TIM_InitStructure);
  TIM_InitStructure.TIM_Prescaler = 10000-1;  
  TIM_InitStructure.TIM_Period = 1;
  TIM_TimeBaseInit(TIM2, &TIM_InitStructure);

  TIM_OCStructInit(&TIM_OCConfig);
  TIM_OCConfig.TIM_OCMode = TIM_OCMode_Toggle;
  TIM_OCConfig.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OC1Init(TIM2, &TIM_OCConfig);
    


  
  TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);
    TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);


  TIM_Cmd(TIM2, ENABLE);

  TIM_TimeBaseStructInit(&TIM_InitStructure);
  TIM_InitStructure.TIM_Prescaler = 2-1;  
  TIM_InitStructure.TIM_Period =10;
  TIM_TimeBaseInit(TIM3, &TIM_InitStructure);

  TIM_OCStructInit(&TIM_OCConfig);
  TIM_OCConfig.TIM_OCMode = TIM_OCMode_Toggle;
  TIM_OCConfig.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OC1Init(TIM3, &TIM_OCConfig);

  
    TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Gated);
    TIM_SelectInputTrigger(TIM3, TIM_TS_ITR1);

    
    TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);

    
    TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update);

  TIM_ITConfig(TIM3, TIM_DIER_UIE, ENABLE);
  TIM_Cmd(TIM3, ENABLE);
.........................................................

void TIM3_IRQHandler(void)
{
    TIM_Cmd(TIM2, DISABLE);
    ClockON_FLAG=0;
     TIM3->SR &= ~TIM_SR_UIF; //reset interrupt flag
}

............................................................



while(1) // ЭТО ВМЕСТО ФУНКЦИИ. ПОКА ПРОСТО ЗАЦИКЛИЛ ЗАПУСК ТАЙМЕРА
{
       ClockON_FLAG=1;
    TIM_Cmd(TIM2,ENABLE);
    while(ClockON_FLAG);
    delay_ms(5);
}



Осталось понять что не так с TIM1. Он работает, генерирует прерывания, но не дергает ножкой. Сама ножка в режиме OUT_PP выдает импульсы. НИкакая другая перферия не включена.
У меня контроллер STM32F103RET6, если что...
SSerge
Цитата(zheka @ Mar 5 2015, 01:08) *
Осталось понять что не так с TIM1. Он работает, генерирует прерывания, но не дергает ножкой. Сама ножка в режиме OUT_PP выдает импульсы. НИкакая другая перферия не включена.
У меня контроллер STM32F103RET6, если что...

У TIM1 есть ещё регистр BDTR и бит MOE.
zheka
Цитата(SSerge @ Mar 5 2015, 00:31) *
У TIM1 есть ещё регистр BDTR и бит MOE.


Сделал, клоки пошли. Но все равно не 36 Мгц а вдвое меньше
SSerge
Цитата(zheka @ Mar 5 2015, 03:44) *
Сделал, клоки пошли. Но все равно не 36 Мгц а вдвое меньше

Если вместо TIM_OCMode_Toggle применить TIM_OCMode_PWM1, будет вдвое быстрее.
zheka
Цитата(SSerge @ Mar 5 2015, 03:55) *
Если вместо TIM_OCMode_Toggle применить TIM_OCMode_PWM1, будет вдвое быстрее.

Спасибо! РАботает. 36 МГц!
Остается непонятным не до конца проясненный ранее момент - ставлю период 10 - дает 11 импульсов.
Да, мне кто-то сказал, что считает от 0 до 10 включительно, потому и 11.
Но - я не могу получить один импульс - ставлю ноль, генерации нет вообще.

Вот таймеры
CODE

TIM_TimeBaseStructInit(&TIM_InitStructure);
TIM_InitStructure.TIM_Period = 1;
TIM_InitStructure.TIM_Prescaler = 10000-1;
TIM_InitStructure.TIM_ClockDivision = 0;
TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_InitStructure);

TIM_BDTRStructInit(&bdtr);
bdtr.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
TIM_BDTRConfig(TIM1, &bdtr);

TIM_OCStructInit(&TIM_OCConfig);
TIM_OCConfig.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCConfig.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCConfig.TIM_Pulse = 1;
TIM_OCConfig.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM1, &TIM_OCConfig);

TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM1, ENABLE);


TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);
TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update);


TIM_Cmd(TIM1, ENABLE);

TIM_TimeBaseStructInit(&TIM_InitStructure);
TIM_InitStructure.TIM_Prescaler = 1-1;
TIM_InitStructure.TIM_Period =1;
TIM_TimeBaseInit(TIM3, &TIM_InitStructure);

TIM_OCStructInit(&TIM_OCConfig);
TIM_OCConfig.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCConfig.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCConfig.TIM_Pulse = 1;
TIM_OCConfig.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM3, &TIM_OCConfig);

TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM3, ENABLE);


TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Gated);
TIM_SelectInputTrigger(TIM3, TIM_TS_ITR0);


TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);


TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update);

TIM_ITConfig(TIM3, TIM_DIER_UIE, ENABLE);
TIM_Cmd(TIM3, ENABLE);
TIM3->CNT=0;



А вот осциллограмма - красный график - выход таймера 1, синий - выход таймера 3
SSerge
Цитата(zheka @ Mar 5 2015, 11:39) *
Но - я не могу получить один импульс - ставлю ноль, генерации нет вообще.

А как иначе?
В одном такте переключаемся туда, в другом обратно, меньше двух никак не получается.
zheka
Подождите...
Ведь импульс это и есть -туда плюс обратно. И у меня получается два раза по туда и по обратно.
По Вашей логике, я могу получить только четное число импульсов. А у меня и нечетное число выходит.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.