Jump to content

    

evsx1

Участник
  • Content Count

    58
  • Joined

  • Last visited

Community Reputation

0 Обычный

About evsx1

  • Rank
    Участник
  • Birthday 10/10/1985

Контакты

  • Сайт
    http://
  • ICQ
    0

Recent Profile Visitors

959 profile views
  1. STM32F105 GPIO interrupts

    esaulenka и Сергей Борщ Большое спасибо за помощь, с прерываниями все было в порядке, а вот с логикой обработки прерывания было не в порядке. В прерывании я устанавливал флаг, только вот этот флаг мог быть обработан не моментально, а по истечению 3-4мс, таким образом я читал не те данные,которые вызвали прерывание
  2. STM32F105 GPIO interrupts

    Нет ,проверил данный факт первым делом, использованы прерывания 3 таймеров. Один для счета 60 мс для включения приема или передачи, другой для счета таймаут по приему, третий выдает время когда ведомый должен послать. У ведомых еще задействована линия PA1 (EXTI_Line1)
  3. STM32F105 GPIO interrupts

    Работаю с приемопередатчиком DW1000 и МК STM32F105RC. Приемопередатчик настроен таким образом ,что на отправку и прием сообщений он генерирует прерывание,которое поступает на PB5 микроконтроллера. Работаем по TDMA схеме, проблема в том,что МК видит прерывания каждые 60мс (прерывания по отправке синхросообщения), но при этом пропускает прерывания,которые генерирует микросхема на приеме. (к линии прерывания подключаемся логическим анализатором и видим,что эти прерывания идут четко после каждого синхросообщения). Однако в получение сообщения мы попадаем каждые 1-2с, а по идее должны попадать в промежутке из 60мс. Обработчик прерывания составляет из себя чтение регистров приемопередатчика с последующим определением,что вызвало прерывание. Таким образом на одном и том же пине вижу стабильные прерывания по отправке, но прерывания,которые генерирует приемопередатчик по приему,пропускаются. В коде есть только один запрет на прием прерываний,в момент записи и чтения регистров по SPI. Однако это происходит только в момент обработки прерывания, SPI работает на скорости 8МГц, если верить системному таймеру общее время работы прерывания меньше 1мс. Те это не должно влиять на прерывание,которое идет через несколько мс. На всякий случай выкладываю код инициализации GPIO_InitTypeDef GPIO_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; // Enable GPIO used as DECA IRQ for interrupt GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //IRQ pin should be Pull Down to prevent unnecessary EXT IRQ while DW1000 goes to sleep mode GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(DECAIRQ_GPIO, &GPIO_InitStructure); /* Connect EXTI Line to GPIO Pin */ GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource5); /* Configure EXTI line */ EXTI_InitStructure.EXTI_Line = EXTI_Line5; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //MPW3 IRQ polarity is high by default EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); /* Set NVIC Grouping to 16 groups of interrupt without sub-grouping */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); /* Enable and set EXTI Interrupt to the lowest priority */ NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 15; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);
  4. В целом всем спасибо.!Особенно Arlleex ! Название темы можно изменить на "Решено"
  5. Вот этого и не могу понять, он подключен к APB1. Частота на ней равна половине системной частоты, те 36МГц, APB1=1, те на таймер должно приходить 36МГц, но я считаю, что там 72МГц, но такого не должно быть.
  6. да,доступна, просто она больше не обновляется. Вся проблема была,что таймер в дебаг режиме продолжал работать. Строки ,которые завставляют его останавливаться в дебаг режиме были выше, с ним в дебаг режиме он не считал и я увидел сброс бита в прерывании У меня возникло непонимание с тактирование таймера. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); скакой частотой он будет тактироваться? как я вижу из картинки, почти все таймера висят на APB1, те ее скорость 36МГц, чтобы получить искомые 100us мне надо в прескалер положить 3600-1, но с таким значение выходит в 2 раза быстрее. ТЕ, записав 7200-1 я получаю желаемое. Но не могу понять почему так.
  7. Каким образом он сам сотрется ? просто из-за того что прерывание выполненыно? нет.
  8. Большое спасибо! Использование данных функций SPL которые конфигурируют этот регистр,помогло увидеть сброс прерывания у этого таймера DBGMCU_Config(DBGMCU_TIM3_STOP,ENABLE); DBGMCU_Config(DBGMCU_TIM4_STOP,ENABLE); DBGMCU_Config(DBGMCU_TIM6_STOP,ENABLE);
  9. как написано в начале поста,я пробовал и с ней. не помогло. Видимо, CooCox устарел уже,не вижу я таких регистров в описании МК. но за подсказку спасибо. В настройках таймера явных ошибок нет?
  10. Настройки по-умолчанию в CooCox, вроде бы тактирование продолжается(значения в Value меняются при пошаговой отладке, хотя в принципе так и должно быть), но сказать точно не могу. Можете подсказать где это проверить?
  11. Добрый день, возникла проблема с обработкой прерывания по переполнению от таймера общего назначения TIM6 в микроконтроллере STM32F105RC. Среда разработки CooCox. TIM_ClearITPendingBit(TIM6, TIM_IT_Update) не сбрасывает флаг прерывания и я соответсвенно попдаю в него снова, но уже не по времени,которое мне необходимо,если верить системному таймеру. Данную строку двигал в разные часть обработчика прерывания, но в показанном мной коде,она должна стоять в этом месте,как я выяснил из литературы(проверяем, что прерывание от таймера и затем чистим(насколько я выяснил это надо сделать как можно быстрее)). Так же меня скорость тиков таймера с требуемых 100us до 1ms, так как думал,что не успеваю очистить и попадаю снова в прерывание из-за скорости. Результат один и тот же. По идее мне нужны настройки тиков таймера каждые 0,1ms и дальше период прерываний задается конфигурированием, пока работаю с конфигурацией,что прерывание должно быть каждые 96ms, те период 960 тиков или 96ms. Вопрос , что я сделал неправильно,что таймер так себя ведет? void TIM6_IRQHandler(void) // обработчик прерывания { time = portGetTickCount(); // тут получаем время от системного таймера //TIM6 ->SR &= ~TIM_SR_UIF; //TIM_ClearITPendingBit(TIM6, TIM_IT_Update); if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET) { TIM_ClearITPendingBit(TIM6, TIM_IT_Update); // ДАННАЯ СТРОКА судя по отладчику не сбрасывает флаг прерывания if (sync_timer_callbacks[0]) { if ( sync_timer_callbacks[0]() ) { } } } } //настройка таймера void sync_timer_now_setup(uint16 alarm, uint16 ticks, uint16 period) { uint16 now; NVIC_InitTypeDef NVIC_InitStructure; sync_timer_periods[alarm]=period; now = portGetTickCnt(); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); switch (alarm) { case 0: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); //beacon timer setup TIM_TimeBaseStructInit(&base_timer0); base_timer0.TIM_Prescaler =(3600)-1; //one tick every 100us base_timer0.TIM_Period = ticks; TIM_TimeBaseInit(TIM6, &base_timer0); TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE); TIM_Cmd(TIM6, ENABLE); NVIC_InitStructure_timer0.NVIC_IRQChannel = TIM6_IRQn; NVIC_InitStructure_timer0.NVIC_IRQChannelPreemptionPriority = 13; NVIC_InitStructure_timer0.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure_timer0.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure_timer0); break; case 1: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); // timeout timer TIM_TimeBaseStructInit(&base_timer1); base_timer1.TIM_Prescaler = 3600-1; base_timer1.TIM_Period = ticks; TIM_TimeBaseInit(TIM3, &base_timer1); TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); TIM_Cmd(TIM3, ENABLE); NVIC_InitStructure_timer1.NVIC_IRQChannel = TIM3_IRQn; NVIC_InitStructure_timer1.NVIC_IRQChannelPreemptionPriority = 14; NVIC_InitStructure_timer1.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure_timer1.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure_timer1); break; case 2: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //timer for sending in nodes TIM_TimeBaseStructInit(&base_timer2); base_timer2.TIM_Prescaler = 3600-1; base_timer2.TIM_Period = ticks; TIM_TimeBaseInit(TIM4, &base_timer2); TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE); TIM_Cmd(TIM4, ENABLE); NVIC_InitStructure_timer2.NVIC_IRQChannel = TIM4_IRQn; NVIC_InitStructure_timer2.NVIC_IRQChannelPreemptionPriority = 12; NVIC_InitStructure_timer2.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure_timer2.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure_timer2); break; default: break; } } //настройка системной частоты, выбор источников тактирования int RCC_Configuration(void) { ErrorStatus HSEStartUpStatus; RCC_ClocksTypeDef RCC_ClockFreq; /* RCC system reset(for debug purpose) */ RCC_DeInit(); /* Enable HSE */ RCC_HSEConfig(RCC_HSE_ON); /* Wait till HSE is ready */ HSEStartUpStatus = RCC_WaitForHSEStartUp(); if(HSEStartUpStatus != ERROR) { /* Enable Prefetch Buffer */ FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); /****************************************************************/ /* * HCLK=72MHz, PCLK2=72MHz, PCLK1=36MHz */ /****************************************************************/ /* 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); /* ADCCLK = PCLK2/4 */ RCC_ADCCLKConfig(RCC_PCLK2_Div6); /* Configure PLLs *********************************************************/ /* PLL2 configuration: PLL2CLK = (HSE / 4) * 8 = 24 MHz */ RCC_PREDIV2Config(RCC_PREDIV2_Div4); RCC_PLL2Config(RCC_PLL2Mul_8); /* Enable PLL2 */ RCC_PLL2Cmd(ENABLE); /* Wait till PLL2 is ready */ while (RCC_GetFlagStatus(RCC_FLAG_PLL2RDY) == RESET){} /* PLL1 configuration: PLLCLK = (PLL2 / 3) * 9 = 72 MHz */ RCC_PREDIV1Config(RCC_PREDIV1_Source_PLL2, RCC_PREDIV1_Div3); RCC_PLLConfig(RCC_PLLSource_PREDIV1, 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){} } RCC_GetClocksFreq(&RCC_ClockFreq); /* Enable SPI1 clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); /* Enable SPI2 clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); /* Enable GPIOs clocks */ RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE); return 0; } //запуск системного таймера int SysTick_Configuration(void) { if (SysTick_Config(SystemCoreClock / CLOCKS_PER_SEC)) { /* Capture error */ while (1); } NVIC_SetPriority (SysTick_IRQn, 0); return 0; }
  12. Цитата(Aner @ Sep 17 2014, 13:05) Понятна ваша промашка. Вам спасибо за посильную помощь. Заметка про флюс так же была очень полезной.
  13. Цитата(alexf @ Sep 17 2014, 00:00) Рад, что решили. Меня несколько дней не было, но хочу на всякий случай добавить по полосе пропускания. Значит лучше с/ш. Как всегда за улучшение дальности надо платить скоростью передачи данных (тут не важно) и качеством кварцев. Спасибо. To Aner. Да,он подключен на GPIO0 и GPIO1 выводами 4 и 6. Я настраивал саму SI4432 как цифровой вход(с подтягом), на эти ноги. Сами выводы GPIO0,GPIO1 выведены так же на плате модуля, их я подключил к ножкам контроллера и управлял в обход микросхемы(только отслеживал уровень). А в теле передачи/приема, просто выставлял уровни на ножках контроллера.
  14. Спасибо,Aner. Проблему приема решил. Вся загвоздка была в том,что антенным переключателем я управлял с микроконтроллера напрямую(с порта контроллера). Если на передачу это не оказывало влияния(я так полагаю,так как мощность измеренная SDRом не менялась),то на приеме выходила данная проблема. Передал управление антенным переключателем микросхеме SI4432, сразу же вырос RSSI до 220 единиц в зоне 3 метра и заработал прием сквозь стены.