jenya7 0 23 декабря, 2013 Опубликовано 23 декабря, 2013 · Жалоба Настроить TIM2-TIM5 на генерацию ШИМ довольно просто void PwmInit(void) { //ch1 -PA0 GPIOA->CRL |= GPIO_CRL_MODE0; //50Mhz GPIOA->CRL &= ~GPIO_CRL_CNF0; //clear CNF[1:0] for PA0 GPIOA->CRL |= GPIO_CRL_CNF0_1; //output Push-Pull in alternative function mode //ch2 - PA1 GPIOA->CRL |= GPIO_CRL_MODE1; //50Mhz GPIOA->CRL &= ~GPIO_CRL_CNF1; //clear CNF[1:0] for PA1 GPIOA->CRL |= GPIO_CRL_CNF1_1; //output Push-Pull in alternative function mode //ch3 - PA2 GPIOA->CRL |= GPIO_CRL_MODE2; //50Mhz GPIOA->CRL &= ~GPIO_CRL_CNF2; //clear CNF[1:0] for PA2 GPIOA->CRL |= GPIO_CRL_CNF2_1; //output Push-Pull in alternative function mode //ch4 - PA3 GPIOA->CRL |= GPIO_CRL_MODE3; //50Mhz GPIOA->CRL &= ~GPIO_CRL_CNF3; //clear CNF[1:0] for PA3 GPIOA->CRL |= GPIO_CRL_CNF3_1; //output Push-Pull in alternative function mode //TIM2 Settings RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; TIM2->CR1 |= TIM_CR1_ARPE; //autorelode mode TIM2->CCMR1 |= TIM_CCMR1_OC1PE | TIM_CCMR1_OC2PE; //Output Compare Preload enable TIM2->CCMR2 |= TIM_CCMR2_OC3PE | TIM_CCMR2_OC4PE; //TIM2->PSC = 71; //1us TIM2->ARR = 8000; // 8000*14ns = 112us = 8928Hz TIM2->CCR1 = 4000; //ch1 1duty cycle = 50% TIM2->CCR2 = 4000; //ch2 1duty cycle = 50% TIM2->CCR3 = 4000; //ch2 1duty cycle = 50% TIM2->CCR4 = 4000; //ch2 1duty cycle = 50% //TIM2->CCER |= TIM_CCER_CC2P; //polarity of output signal //Capture/Compare 2 output enable TIM2->CCER |= TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E | TIM_CCER_CC4E; //Output Compare Mode - 110 - PWM mode 1 TIM2->CCMR1 |= (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1); TIM2->CCMR1 |= (TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1); TIM2->CCMR2 |= (TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1); TIM2->CCMR2 |= (TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4M_1); //start counting TIM2->CR1 |= TIM_CR1_CEN; } Все просто все понятно. С TIM1/TIM8 не все так понятно - там другие регистры и я, честно говоря, запутался. Может кто нибудь работал с этими таймерами и может прояснить ситуацию? Заранее спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
smk 0 23 декабря, 2013 Опубликовано 23 декабря, 2013 · Жалоба Настраивается все... что именно нужно объяснить? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 23 декабря, 2013 Опубликовано 23 декабря, 2013 · Жалоба Настраивается все... что именно нужно объяснить? желательно пример. только не на стандартной библиотеке. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
smk 0 23 декабря, 2013 Опубликовано 23 декабря, 2013 · Жалоба void Timer1_Init (void) { RCC->APB2ENR |= (1<<0); //вкл. тактиров. таймера1 TIM1->PSC = 20; //делитель чтоб не лезть в даташит если он понадобится TIM1->CCMR1 |= (7<<12)|(7<<4); //+ канал 1 и 2 - ШИМ TIM1->CCMR2 |= (7<<12)|(7<<4); //+ канал 3 и 4 - ШИМ TIM1->CCER |= (1<<12)|(1<<8)|(1<<4)|(1<<0); //+ TIM1->BDTR |= (1<<15); TIM1->CCR1 = 0xFFFF; //значение ШИМ канал 1 (ТЕМ1.1) чем меньше тем длиннее 1 TIM1->CCR2 = 0xFFFF; //значение ШИМ канал 2 (ТЕМ1.2) TIM1->CCR3 = 0xFFFF; //значение ШИМ канал 3 (ТЕМ2.1) TIM1->CCR4 = 0xFFFF; //значение ШИМ канал 4 (ТЕМ2.2) TIM1->CR1 |= (1<<0); //вкл. таймер 1 } Ну и выводы на выход в альтернативном назначении. Это для 207, но там таймер такой же. Регистры только проверьте, но смсл тот же. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SSerge 4 23 декабря, 2013 Опубликовано 23 декабря, 2013 · Жалоба желательно пример. только не на стандартной библиотеке. Регистры TIM2 это просто подмножество регистров TIM1. У Вас не хватает этой строчки: TIM1->BDTR |= TIM_BDTR_MOE; вот прямо из текущего прожекта, если не нужен DMA, часть текста после //DMA Init можно выбросить, . void InitTIM1(int enable) { TIM1->CR1 = TIM_CR1_ARPE | TIM_CounterMode_Up; TIM1->ARR = 5*24-1; // период повторения, 0 - останов TIM1->PSC = 0; // прескалер на 1, один тик = 1/24 мкс TIM1->RCR = 0; //TIM_RepetitionCounter; // OC1 TIM1->CCR1 = 12; // 0.5мкс. TIM1->CCMR1 = TIM_OCMode_Toggle; //TIM_OCMode_PWM2; TIM1->CCER = TIM_OCPolarity_High | TIM_OutputState_Enable; // OC2 TIM1->CCR2 = 24; // 1.0us TIM1->CCMR1 |= TIM_OCMode_Toggle << 8; TIM1->CCER |= (TIM_OCPolarity_High | TIM_OutputState_Enable) <<4; // OC 3 TIM1->CCR3 = 36; // 1.5us. TIM1->CCMR2 |= TIM_OCMode_PWM1; TIM1->CCER |= ( TIM_OCPolarity_High | TIM_OutputState_Enable | TIM_OCNPolarity_Low | TIM_OutputNState_Enable)<<8; // OC4 TIM1->CCR4 = 24; // 1us TIM1->CCMR2 |= TIM_OCMode_PWM1 << 8; TIM1->CCER |= (TIM_OCPolarity_High | TIM_OutputState_Enable) <<12; TIM1->EGR = TIM_EGR_UG; // генерируем update event для загрузки всех теневых регистров TIM1->BDTR |= TIM_BDTR_MOE + 12; // разрешение выходных сигналов OCx + dead-time 0.5us // DMA Init TIM1->DIER = TIM_DIER_UDE; TIM1->DCR = (0<<8) | (&(TIM1->ARR) - &(TIM1->CR1))/sizeof(TIM1->CR1); DMA1_Channel5->CCR = 0 | 0*DMA_CCR1_EN // Channel enable | 0*DMA_CCR1_TCIE // Transfer complete interrupt enable | DMA_CCR1_DIR // Data transfer direction 1: Mem --> Periph | DMA_CCR1_CIRC // Circular mode | 0*DMA_CCR1_PINC // Peripheral increment mode | DMA_CCR1_MINC // Memory increment mode | DMA_PeripheralDataSize_Word // DMA_CCR1_PSIZE PSIZE[1:0] bits (Peripheral size) | DMA_MemoryDataSize_HalfWord // DMA_CCR1_MSIZE MSIZE[1:0] bits (Memory size) | (3<<12) //*DMA_CCR1_PL // PL[1:0] bits(Channel Priority level) | 0*DMA_CCR1_MEM2MEM; // Memory to memory mode DMA1_Channel5->CNDTR = 2; DMA1_Channel5->CPAR = (uint32_t)&(TIM1->DMAR); DMA1_Channel5->CMAR = (uint32_t) dmabuf; DMA1_Channel5->CCR |= DMA_CCR1_EN; // Channel enable // end DMA Init if(enable) TIM1->CR1 |= TIM_CR1_CEN; // разрешаем счёт } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 23 декабря, 2013 Опубликовано 23 декабря, 2013 · Жалоба спасибо большое. сейчас проверю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 23 декабря, 2013 Опубликовано 23 декабря, 2013 · Жалоба спасибо все классно работает. :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
smk 0 24 декабря, 2013 Опубликовано 24 декабря, 2013 · Жалоба спасибо все классно работает. :) Рад за Вас. Что следующее помочь настроить? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 24 декабря, 2013 Опубликовано 24 декабря, 2013 · Жалоба Рад за Вас. Что следующее помочь настроить? честно говоря опасений много, перевожу апликашку с меги на STM32, пока вобщем камнем доволен, но чувствую еще наступлю на пару граблей - вот тогда и обращусь за помощью. спасибо. :) off-top: засада с напряжениями - с мегой я работал на 5-ти вольтах, и там сигналы с AB энкодера амплитудой 9 вольт я подавал через резистор напрямую на пины и все работало. Тут же нужен преобразователь уровней. Больше всего понравился CD4050. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bzx 0 24 декабря, 2013 Опубликовано 24 декабря, 2013 · Жалоба ...засада с напряжениями - с мегой я работал на 5-ти вольтах, и там сигналы с AB энкодера амплитудой 9 вольт я подавал через резистор напрямую на пины и все работало... Ерундой страдаете... 1. Сложно пересчитать делитель c 9->5 на 9->3.3? 2. Вы не знаете, что I/O в stm32 “5 V-tolerant”? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 25 декабря, 2013 Опубликовано 25 декабря, 2013 · Жалоба Ерундой страдаете... 1. Сложно пересчитать делитель c 9->5 на 9->3.3? 2. Вы не знаете, что I/O в stm32 “5 V-tolerant”? а если всплеск напряжения на входе? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
smk 0 25 декабря, 2013 Опубликовано 25 декабря, 2013 · Жалоба а если всплеск напряжения на входе? Так диоды по входу стоят в питание. Главное чтобы ток не перевалил за 1 мА. Можете еще стабилитрон поставить, но только чтоб на микротоках не работали. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 25 декабря, 2013 Опубликовано 25 декабря, 2013 · Жалоба Так диоды по входу стоят в питание. Главное чтобы ток не перевалил за 1 мА. Можете еще стабилитрон поставить, но только чтоб на микротоках не работали. то есть в стм так же как и в атмеле? подавай хоть 220 вольт, главное поставь соответствующий резистор по току, а внутренние клампинг диоды вытянут? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
smk 0 25 декабря, 2013 Опубликовано 25 декабря, 2013 · Жалоба то есть в стм так же как и в атмеле? подавай хоть 220 вольт, главное поставь соответствующий резистор по току, а внутренние клампинг диоды вытянут? В целом да. Но можно еще и своих диодов поставить для надежности. И резисторов не один, а два. Когдато я давал ссілку на hardware design или подобное. Посмотрите руководство и какие-нибудь примеры от ST. Просто для расширения кругозора. Может что более интересное попадется. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vendict 0 1 сентября, 2014 Опубликовано 1 сентября, 2014 (изменено) · Жалоба Делаю на stm32 (именно на STM32F103C8) кассу для сына, одна из задач - научить кассу говорить. Взял вот этот готовый плеер: http://projectproto.blogspot.ru/2010/06/mi...dio-player.html Поправил под библиотечку с карточкой, что заработала, в итоге в оригинальной конфигурации, ШИМ на PB7 - звук отлично играет. Вот тут и проблема, PB7 у меня изначально занят под I2C для экрана 16х02, попробовал сменить таймер на 1й и ногу на PA8. Получил в итоге шум, треск, скрежет. Вот в чем различия при инициализации ШИМ: Оригинальный код: TIM_OCInitTypeDef TIM_OCInitStructure; void PWM_init(void) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; /* TIM4 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE ); /* GPIOB Configuration:TIM4 Channel 2 as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; // PB7 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); /* Time base configuration */ /* PWM frequency = 72MHz / [Period*(Prescaler+1)] */ TIM_TimeBaseStructure.TIM_Period = 350;//256;//360; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); /* PWM1 Mode configuration: Channel2 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 128; //CCR2 Value; duty cycle = CCR/Period TIM_OC2Init(TIM4, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM4, ENABLE); /* TIM4 enable counter */ TIM_Cmd(TIM4, ENABLE); } void set_pwm_duty(unsigned char duty) { TIM_OCInitStructure.TIM_Pulse = duty; TIM_OC2Init(TIM4, &TIM_OCInitStructure); } void pwm_output_enable(bool on) { GPIO_InitTypeDef GPIO_InitStructure; if(on){ /* GPIOB Configuration:TIM4 Channel 2 as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; // PB7 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); } else{ /* GPIOB7 as input */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; // PB7 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); } } вот мой код: void PWM_init(void) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; /* TIM1 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE ); /* GPIOA Configuration:TIM1 Channel 1 as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; // PA8 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); /* Time base configuration */ /* PWM frequency = 72MHz / [Period*(Prescaler+1)] */ TIM_TimeBaseStructure.TIM_Period = 350;//256;//360; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* PWM1 Mode configuration: Channel */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 128; //CCR2 Value; duty cycle = CCR/Period TIM_OC2Init(TIM1, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM1, ENABLE); /* TIM4 enable counter */ TIM_Cmd(TIM1, ENABLE); } void set_pwm_duty(unsigned char duty) { TIM_OCInitStructure.TIM_Pulse = duty; TIM_OC2Init(TIM1, &TIM_OCInitStructure); } void pwm_output_enable(int on) { GPIO_InitTypeDef GPIO_InitStructure; if(1==on){ /* GPIOA Configuration:TIM4 Channel 2 as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; // PA8 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); } else{ /* GPIOA8 as input */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; // PB8 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); } } во втором случае без форматирования, отличия выделил жирным. Помогите, может неправильно таймер/ШИМ иницируется ? Может какие-то различия должны быть между 1м и 4м таймерами ? Хотя PB8-PB9 вроде свободны, можно ремапом на них I2C. Но может будет ещё решение ? Я так понял, у меня как и у автора текущего топика проблема с инициализацией таймера. Только мне бы не напрямую в регистры, а с помощью GPIO библиотеки... Изменено 2 сентября, 2014 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться