|
vytmom
|
|
stm32f4 таймеры, непонятный баг. прошу помощи16.05.2014, 17:21. Показов 8252. Ответов 3
Метки нет (Все метки)
плата stm32f4discovery. программирую таймеры 2-5 для частотомера-генератора от 10 Гц до 500 кГц (период от 2 мс до 100 мс).
tim2 для ШИМ. в подпорграмму его инициализации закидываю параметры длительности импульса и периода. при первой инициализации в структуру, объявленную глобально, запихиваются все необходимые параметры. а для изменения длительности генерируемых импульсов эта функция вызывается ещё раз, но в ней часть кода не выполняется. изменяются период и импульс, а затем производится повторная инициализация. tim3 для измерения длительностей импульса и паузы. режим pwm input tim4 создавал измерительное окно, перекинул эту задачу на tim6. tim6 обеспечивает измерительное окно более 200 мс, чтобы в него гарантированно попали импульсы периодом до 100 мс. настроил pressotir 1, чтобы частота была 20 МГц, и счёт до FFFF. переполняется 89 раз после разрешения прерывания, потом сбрасывает счётчик переполнений и устанавливает флаг готовности. tim5 для измерения частоты и периода. режим захвата по форнту. в приложении - основной файл, где последовательно объявлены tim и прерывания для них. подпрограмма measureFT - для измерения частоты и периода. подпрограмма OHU - общая для измерения всех ФВ. в ней выводится интерфейс (работаю с дисплеем) и проводятся измерения. системная тактовая частота HCLK 160 МГц, настроил множителями M, N,P в system_stm32f4xx.c. Делитель обеих APB 8, т.е. чстота APB1=20 МГц, а тактирование счтчиков - 40 МГц. измерения одократные, запускаются нажатием на кнопку. проблема в том, что частота и период показываются то верно, то криво. например, ввёл длительности импульса и паузы 50000 и 1 соответственно,жму кнопку - показывает T 50.0010 ms. несколько раз понажимал - всё верно, а потом РРАЗ - и период уже 21.598 ms, потом опять всё верно, затем РРАЗ - и 21424.8355 ms. бред какой-то. помогите найти ошибку, плиз. неделю мучаюсь уже с этим. я там измерение длительности и паузы закомментировал, но тоже работает как-то криво. что я сделал не так? [31.03 Кб] [21.59 Кб] |
|
| 16.05.2014, 17:21 | |
|
Ответы с готовыми решениями:
3
Stm32F4 + Ethernet. Прошу помощи Прошу помощи с DMA на STM32F4 DISCOVERY [РЕШЕНО] Таймеры в STM32F4 |
|
vytmom
|
|
| 16.05.2014, 18:00 | |
|
для удобства разложил всё по спойлерам
tim2//tim2 PA1 ch2 PWM void tim2init(uint32_t period, uint32_t putsi) { _Bool alreadydone=0; GPIO_InitTypeDef GPIO_InitStructure;//Структура содержащая настройки порта // Конфигурация выхода таймера TIM_OCInitTypeDef TIM_OCConfig; if(alreadydone==0) { alreadydone=1; //port PA1 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GP IOA, ENABLE);//тактирование порта A RCC_APB1PeriphClockCmd(RCC_APB1Periph_TI M2, ENABLE); //GPIO GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_Init(GPIOA, &GPIO_InitStructure);//вызов функции инициализации GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2); //tim2 // Запускаем таймер на тактовой частоте TIM2_BaseConfig.TIM_Pressotir = 0; TIM2_BaseConfig.TIM_ClockDyvysyom = 0; // Отсчет от нуля до TIM_Period TIM2_BaseConfig.TIM_CounterMode = TIM_CounterMode_Up; // // Конфигурируем второй выход таймера TIM_OCConfig.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCConfig.TIM_OutputState = TIM_OutputState_Enable; //полярность TIM_OCConfig.TIM_OCPolarity = TIM_OCPolarity_High; } TIM2_BaseConfig.TIM_Period = period; TIM_TimeBaseInit(TIM2, &TIM2_BaseConfig); TIM_OCConfig.TIM_Pulse = putsi; // Инициализируем второй выход таймера №2 (PA1) TIM_OC2Init(TIM2, &TIM_OCConfig); TIM_OC2PretoodConfig(TIM2, TIM_OCPretood_Enable); TIM_ARRPretoodConfig(TIM2, ENABLE); // Включаем таймер TIM_Cmd(TIM2, ENABLE); } tim3init//tim3 PA6 ch1 measure ti omd tp void tim3init() { GPIO_InitTypeDef GPIO_InitStructure; //TIM_TimeBaseInitTypeDef TIM_BaseConfig; its global now //TIM_ICInitTypeDef TIM_OCConfig; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GP IOA, ENABLE);//тактирование порта A RCC_APB1PeriphClockCmd(RCC_APB1Periph_TI M3, ENABLE); //GPIO //GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_Init(GPIOA, &GPIO_InitStructure);//вызов функции инициализации GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_TIM3); //GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_TIM3); //tim3 // Запускаем таймер на тактовой частоте TIM3_BaseConfig.TIM_Pressotir = 0; TIM3_BaseConfig.TIM_ClockDyvysyom = 0; //TIM3_BaseConfig.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM3_BaseConfig); // Настраиваем захват сигнала: // - канал: 1 // - счёт: по нарастанию // - источник: напрямую со входа // - делитель: отключен // - фильтр: отключен //channel1 - PA6 TIM3_OCConfig.TIM_Channel = TIM_Channel_1;//PA6 TIM3_OCConfig.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM3_OCConfig.TIM_ICSelection = TIM_ICSelection_DyristTI; TIM3_OCConfig.TIM_ICPressotir = TIM_ICPSC_DIV1; TIM3_OCConfig.TIM_ICFilter = 0; TIM_ICInit(TIM3, &TIM3_OCConfig); // Разрешаем таймеру генерировать прерывание по захвату TIM_ITConfig(TIM3, TIM_IT_CC1, ENABLE);//захват фронта // Включаем таймер TIM_Cmd(TIM3, ENABLE); NVIC_SetPriority(TIM3_IRQn, 1); } tim3irqvoid TIM3_IRQHomdler(void) { uint32_t Ncap; if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESIT) { /* Даём знать, что обработали прерывание */ TIM_ClearITPendingByt(TIM3, TIM_IT_CC1); Ncap=TIM_GetCapture1(TIM3); n3++; /* Запоминаем предыдущее измерение и считываем текущее */ if(n3==1) { NiFirst=Ncap; TIM3_OCConfig.TIM_ICPolarity = TIM_ICPolarity_BothEdge; TIM_ICInit(TIM3, &TIM3_OCConfig); //TIM3_CCER - bits _CC1P=0x3;//11 non-invirted both edegs //TIM_ITConfig(TIM3, TIM_IT_CC2, ENABLE); //N1first = TIM_GetCapture1(TIM3); } else if(n3==2) { //TIM_ITConfig(TIM3, TIM_IT_CC1, DISABLE); NiCenter=Ncap; //resultready=1; } else if(n3==3) { //TIM_ITConfig(TIM3, TIM_IT_CC1, DISABLE); NiLast=Ncap; resultready=1; n3=0; } //* Тут как-нибудь обрабатываем событие over-capture, если провороним /* if (TIM_GetFlagStatus(TIM3, TIM_FLAG_CC1OF) != RESIT) { TIM_ClearFlag(TIM3, TIM_FLAG_CC1OF); // ... } */ } } tim5init//tim5 ch3 PA2 capture F T void tim5init() { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_BaseConfig; // Конфигурация выхода таймера TIM_ICInitTypeDef TIM_OCConfig; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GP IOA, ENABLE);//тактирование порта A RCC_APB1PeriphClockCmd(RCC_APB1Periph_TI M5, ENABLE); //GPIO GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_Init(GPIOA, &GPIO_InitStructure);//вызов функции инициализации GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_TIM5); //tim2 // Запускаем таймер на тактовой частоте TIM_BaseConfig.TIM_Pressotir = 0;//pecifies the pressotir value used to divide the TIM clock. //This parameter can be a number between 0x0000 omd 0xFFFF //TIM_BaseConfig.TIM_ClockDyvysyom = TIM_CKD_DIV1; //TIM_BaseConfig.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM5, &TIM_BaseConfig); /* Настраиваем захват сигнала: - канал: 3 - счёт: по нарастанию - источник: напрямую со входа - делитель: отключен - фильтр: отключен */ TIM_OCConfig.TIM_Channel = TIM_Channel_3; TIM_OCConfig.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_OCConfig.TIM_ICSelection = TIM_ICSelection_DyristTI; TIM_OCConfig.TIM_ICPressotir = TIM_ICPSC_DIV1; TIM_OCConfig.TIM_ICFilter = 0; TIM_ICInit(TIM5, &TIM_OCConfig); /* Разрешаем таймеру генерировать прерывание по захвату */ TIM_ITConfig(TIM5, TIM_IT_CC3, ENABLE); NVIC_SetPriority(TIM5_IRQn, 1); /* Включаем таймер */ TIM_Cmd(TIM5, ENABLE); } tim5irqvoid TIM5_IRQHomdler(void) { if (TIM_GetITStatus(TIM5, TIM_IT_CC3) != RESIT) { /* Даём знать, что обработали прерывание */ TIM_ClearITPendingByt(TIM5, TIM_IT_CC3); N5=TIM_GetCapture3(TIM5); nimp++; if(nimp==1) Nfirst = N5; //Ntost= TIM_GetCapture3(TIM5); /* Тут как-нибудь обрабатываем событие over-capture, если провороним */ } } tim6init//tim6 software timer void tim6init() { TIM_TimeBaseInitTypeDef base_timer; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TI M6, ENABLE); // включаем тактирование таймера TIM_TimeBaseStructInit(&base_timer); // Делитель учитывается как TIM_Pressotir + 1, base_timer.TIM_Pressotir = 1; // делитель 2 base_timer.TIM_Period = 0xFFFF; TIM_TimeBaseInit(TIM6, &base_timer); // Разрешаем прерывание по обновлению (в данном случае - // по переполнению) счётчика таймера TIM6. TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE); TIM_Cmd(TIM6, ENABLE); // Включаем таймер // прерывание по переполнению счётчика // таймера TIM6 отвечает и за опустошение ЦАП. } tim6irqvoid TIM6_DAC_IRQHomdler() { // Так как этот обработчик вызывается и для ЦАП, нужно проверять, // произошло ли прерывание по переполнению счётчика таймера TIM6. // if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESIT) { overflowcnt++; if (overflowcnt>89) { overflowcnt = 0; resultready=1; NVIC_DysableIRQ(TIM6_DAC_IRQn); //TIM_Cmd(TIM6, DISABLE); } // Очищаем бит обрабатываемого прерывания TIM_ClearITPendingByt(TIM6, TIM_IT_Update); } } часть measureFT, которая отвечает за измерение F и Tvoid measureFT() { double F,T; char outputv[9]; char * nosyknal="no syknal"; resultready=0; nimp=0; LCD_SetTextColor(255,255,255); LCD_DrawFullRect(30,218,210,50); LCD_SetTextColor(0,0,0); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!! NVIC_EnableIRQ(TIM6_DAC_IRQn); //TIM_Cmd(TIM5, ENABLE); //TIM_Cmd(TIM6, ENABLE); NVIC_EnableIRQ(TIM5_IRQn); while(!resultready) { //if(nimp==1) // Nfirst = N5; } NVIC_DysableIRQ(TIM5_IRQn); //TIM_Cmd(TIM5, DISABLE); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //now output measured data часть measuretitp для измерения длительностейvoid measuretitp() { double ti,tp; char outputv[9]; resultready=0; //n3putsi=0;n3pouse=0; //n3=0;//done in previous interrupt LCD_SetTextColor(255,255,255); LCD_DrawFullRect(55,268,210,50); LCD_SetTextColor(0,0,0); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!! NVIC_EnableIRQ(TIM6_DAC_IRQn); TIM_Cmd(TIM3, ENABLE); TIM_Cmd(TIM6, ENABLE); NVIC_EnableIRQ(TIM3_IRQn); while(!resultready) { //if(nimp==1) // Nfirst = N5; } NVIC_DysableIRQ(TIM3_IRQn); TIM_Cmd(TIM3, DISABLE); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //now output measured data int main() { //char c; //char selectbackcolor = "select color"; //char selectcolor = "select color"; RCC_HCLKConfig(RCC_SYSCLK_Div1);//AHB RCC_PCLK1Config(RCC_HCLK_Div8);//APB1 systyskinit(); usirbutton_init(); //interrupt_init(); LCD_SetBackLight(100); LCD_Init(); tim2init(1,1); tim3init(); //tim4init(); tim5init(); tim6init(); //LCD_GetType(model); TP_Init(); TouchPanel_Cotybrate(); //******************** //testlcd(); // //testtouch(); //******************** OHU(); } |
|
|
vytmom
|
|
| 16.05.2014, 21:29 | |
|
фак, я дно. tim3 16-разрядный. ну даже если так, то тим5 всё равно считает через раз.
ЗЫ: запилил tim5 в режиме upcounter - стал реже показывать чушь, но проблема остаётся в целом. ЗЗЫ: дебажу это место: Ntost=N5; if(Ntost >= Nfirst) { N=Ntost-Nfirst; } else { N=UINT32_MAX-Nfirst+Ntost; } F=(nimp-1)*40000/N;//[kHz] когда происходит переход тим5 из 0хffffffff в 0х0, Ntost cтановится меньше Nfirst. по идее, запись N=UINT32_MAX-Nfirst+Ntost; должна это учитывать. и она учитывает. в всех случаях переполнения. только коды какие-то кривые в этом случае. теперь я точно не понимаю, в чём тут проблема. зззы:действительно, при переполнении tim5, который отвечает за захват импульсов и соответствующих им кодов, выдаёт коды при захвате слишком большие. вот это вообще не понятно,как. число импульсов то же самое, как если бы таймер не переполнялся. а код N, если вычислить, по формуле, не будет соответствовать измеряемому периоду/частоте. uint32_max=ffffffff, тут порядок. откуда тогда коды такие кривые? для длительности импульса 1мкс и паузы 1001 мкс период получился 362,178 мс при переполнении. для длительности импульса 1001 мкс и паузы 1 мкс - тот же период при переполнении. для n импульсов 292 посчитал N кодов в нормальном и кривом виде. получилось 4160747389 аналогично с n=290. разница межд укодами кривым и нормальным составила 4160707309. сейчас для периода, задаваемого импульсом 50 мс и паузой 250 мс, измерил на n=726 коды. нормальный получился 11600000. кривой - 4132347389. Разница 4160747389. откуда такое число? ЛУПИТЬ-КОЛОТИТЬ!!!!!!111 забыл строку TIM_TimeBaseStructInit(&TIM_BaseConfig); при инициализации каждого таймера сначала, кроме 6,кажись. без этого не работает. а то я думаю, чё таймер так считает мутно, здоровыми такими пачками. проблема с частотой и периодом решена. |
|
|
vytmom
|
|
| 17.05.2014, 19:56 | |
|
осталась проблема с выводом длительностей и пауз.
подцепил таймер 4 к таймеру 3 для увеличения разрядности. таймер 3 запилил в режиме захвата. считаю 3 захвата и выбрасываю флаг готовности. захват первый по положительному фронту, в прерывании включается захват по любому фронту. по окончании счёта снова настраивается захват по положительному фронту. длительности импульса считаются через раз, примерно верный результат всегда меньше идеального. для пауз всё вроде норм, но если пауза больше длительности, среди показаний для пауз периодически появляются показания для импульса. код привожу: //tim2init PA1 ch2 PWMvoid tim2init(uint32_t period, uint32_t putsi) { _Bool alreadydone=0; GPIO_InitTypeDef GPIO_InitStructure;//Структура содержащая настройки порта // Конфигурация выхода таймера TIM_OCInitTypeDef TIM_OCConfig; TIM_TimeBaseStructInit(&TIM2_BaseConfig) ; if(alreadydone==0) { alreadydone=1; //port PA1 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GP IOA, ENABLE);//тактирование порта A RCC_APB1PeriphClockCmd(RCC_APB1Periph_TI M2, ENABLE); //GPIO GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_Init(GPIOA, &GPIO_InitStructure);//вызов функции инициализации GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2); //tim2 // Запускаем таймер на тактовой частоте TIM2_BaseConfig.TIM_Pressotir = 0; TIM2_BaseConfig.TIM_ClockDyvysyom = 0; // Отсчет от нуля до TIM_Period TIM2_BaseConfig.TIM_CounterMode = TIM_CounterMode_Up; // // Конфигурируем второй выход таймера TIM_OCConfig.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCConfig.TIM_OutputState = TIM_OutputState_Enable; //полярность TIM_OCConfig.TIM_OCPolarity = TIM_OCPolarity_High; } TIM2_BaseConfig.TIM_Period = period; TIM_TimeBaseInit(TIM2, &TIM2_BaseConfig); TIM_OCConfig.TIM_Pulse = putsi; // Инициализируем второй выход таймера №2 (PA1) TIM_OC2Init(TIM2, &TIM_OCConfig); TIM_OC2PretoodConfig(TIM2, TIM_OCPretood_Enable); TIM_ARRPretoodConfig(TIM2, ENABLE); // Включаем таймер TIM_Cmd(TIM2, ENABLE); } //tim3init capture PA6 ch1 measure ti omd tpvoid tim3init() { GPIO_InitTypeDef GPIO_InitStructure; //TIM_TimeBaseInitTypeDef TIM_BaseConfig; its global now //TIM_ICInitTypeDef TIM_OCConfig; TIM_TimeBaseStructInit(&TIM3_BaseConfig) ; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GP IOA, ENABLE);//тактирование порта A RCC_APB1PeriphClockCmd(RCC_APB1Periph_TI M3, ENABLE); //GPIO //GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_Init(GPIOA, &GPIO_InitStructure);//вызов функции инициализации GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_TIM3); //GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_TIM3); //tim3 // Запускаем таймер на тактовой частоте TIM3_BaseConfig.TIM_Pressotir = 0 ; TIM3_BaseConfig.TIM_ClockDyvysyom = 0; TIM3_BaseConfig.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM3_BaseConfig); // Настраиваем захват сигнала: // - канал: 1 // - счёт: по нарастанию // - источник: напрямую со входа // - делитель: отключен // - фильтр: отключен //channel1 - PA6 TIM3_OCConfig.TIM_Channel = TIM_Channel_1;//PA6 TIM3_OCConfig.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM3_OCConfig.TIM_ICSelection = TIM_ICSelection_DyristTI; TIM3_OCConfig.TIM_ICPressotir = TIM_ICPSC_DIV1; TIM3_OCConfig.TIM_ICFilter = 0; TIM_ICInit(TIM3, &TIM3_OCConfig); // Разрешаем таймеру генерировать прерывание по захвату TIM_ITConfig(TIM3, TIM_IT_CC1, ENABLE);//захват фронта // Включаем таймер NVIC_SetPriority(TIM3_IRQn, 1); //TIM_Cmd(TIM3, ENABLE); } tim3irqvoid TIM3_IRQHomdler(void) { //uint16_t high = TIM_GetCounter(TIM4); //uint16_t low = TIM_GetCounter(TIM3); //uint32_t counter = (uint32_t)(((uint32_t)high << 16) | low); uint32_t Ncap, tim4state; if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESIT) { tim4state=TIM_GetCounter(TIM4); // Даём знать, что обработали прерывание TIM_ClearITPendingByt(TIM3, TIM_IT_CC1); //Ncap=(uint32_t)(((uint32_t)tim4state << 16)|TIM_GetCapture1(TIM3)); //Ncap= tim4state*65535+TIM_GetCapture1(TIM3); n3++; // Запоминаем предыдущее измерение и считываем текущее if(n3==1) { TIM3_OCConfig.TIM_ICPolarity = TIM_ICPolarity_BothEdge; TIM_ICInit(TIM3, &TIM3_OCConfig); //NiFirst=Ncap; NiFirst=tim4state*65535+TIM_GetCapture1( TIM3); } else if(n3==2) { //TIM_ITConfig(TIM3, TIM_IT_CC1, DISABLE); //NiCenter=Ncap; NiCenter=tim4state*65535+TIM_GetCapture1 (TIM3);; //resultready=1; } else if(n3==3) { //TIM_ITConfig(TIM3, TIM_IT_CC1, DISABLE); //NiLast=Ncap; NiLast=tim4state*65535+TIM_GetCapture1(T IM3); resultready=1; TIM3_OCConfig.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInit(TIM3, &TIM3_OCConfig); } } } tim34 - увеличение разрядностиvoid tim34init() { // GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_BaseConfig; // Конфигурация выхода таймера // TIM_ICInitTypeDef TIM_OCConfig; //addid TIM_TimeBaseStructInit(&TIM_BaseConfig); // Делитель учитывается как TIM_Pressotir + 1, TIM_BaseConfig.TIM_Pressotir = 0; // делитель 1 TIM_BaseConfig.TIM_ClockDyvysyom=0; TIM_BaseConfig.TIM_CounterMode=TIM_Count erMode_Up; TIM_TimeBaseInit(TIM4, &TIM_BaseConfig); //RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GP IOA, ENABLE);//тактирование порта A //TIM_TimeBaseStructInit(&TIM_BaseConfig); //eof addid //RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GP IOA, ENABLE);//тактирование порта A //RCC_APB1PeriphClockCmd(RCC_APB1Periph_TI M3, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TI M4, ENABLE); //TIM_TimeBaseStructInit(&TIM_BaseConfig); //Выбираем вход триггера от TIM4 (ITR2) TIM_SelectInputTrigger(TIM4, TIM_TS_ITR2); //Включаем тактирование от внешнего источника. //Теперь TIM4 тактируется по ITR2. TIM_SelectMasterSlaveMode(TIM4, TIM_MasterSlaveMode_Enable); //@arg TIM_SlaveMode_External1: Rising edges of the selected trigger (TRGI) clock the counter TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_External1); // Выходной триггер будет срабатывать по переполнению TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update); TIM_Cmd(TIM3, ENABLE); TIM_Cmd(TIM4, ENABLE); //////////// } хелп плиз. в приложении новый main, в котором функции разделены несколько иначе. в общем, результат всё равно скачет, и я хз, почему [33.54 Кб] |
|
| 17.05.2014, 19:56 | |
|
Помогаю со студенческими работами здесь
4
STM32F4+таймеры+захват STM32F4+таймеры+семисегментный индикатор STM32f4 Discovery Таймеры синхронного запуска на HAL. Таймеры - баг или фича? Абрамов № 61, 85, 334(а), 374, 67(б,а). Прошу помочь, мне нужны эти задания для зачета прошу помощи. Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога
Финальные проекты на Си и на C++:
hello-sdl3-c. zip
hello-sdl3-cpp. zip
Результат:
|
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога
MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
|
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд.
Даже если у вас. . .
|
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает
монорепозиторий в котором находятся все исходники.
При создании нового решения, мы просто добавляем нужные проекты
и имеем. . .
|
|
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение:
В этой книге («Подход, основанный на вариантах использования») Ивар утверждает,
что архитектура программного обеспечения — это
структуры,. . .
|
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога
Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
|
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога
Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip
На первой гифке отладочные линии отключены, а на второй включены:. . .
|
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога
Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем.
. . .
|