Перейти к содержанию
    

Brain13

Участник
  • Постов

    67
  • Зарегистрирован

  • Посещение

Репутация

0 Обычный

Информация о Brain13

  • Звание
    Участник
    Участник
  1. Александр, спасибо за ответ! Пробовал и с портом по верхней границе полигона - то же самое. Но в итоге удалось победить проблему. Я по совету коллеги нарисовал кубик c материалом vacuum "вокруг" платы с небольшим запасом. И назначил этот кубик radiation boundary. HFSS поругался, что wave port не на грани и предложил закрыть его с одной стороной pec-блоком (ну это вполне логично). Я нарисовал эти pec-блоки(красные), поставил порты на их внутренних гранях, и в итоге всё заработало.
  2. Добрый день! Понадобилось мне научиться пользоваться HFSS. Нужно в итоге сделать рефлектометрический датчик. Набрёл на это видео. Повторил - получилось. Теперь решил сделать то же самое на микрополоске, но тут я получаю ошибку на Wave Port'е: . Вроде есть земляной полигон, есть микрополосок. Wave Port делаю существенно больше по высоте и ширине, чем микрополосок. Терминалы отображаются в портах: Файл прилагаю. Уже несколько дней мучаюсь. Знатоки, помогите, пожалуйста. Что я делаю не так? tdr_microstrip.aedt
  3. Нет, запрещенное походу не разбудит... http://infocenter.arm.com/help/index.jsp?t...a/BABGGICD.html То есть разбудит процессор только разрешенное(я так понимаю в NVIC) прерывание с более выским приоритетом.
  4. Тема начинается со слов "Предположим, что программа должна дождаться получения байта по UART" В системе присутствует множество источников прерываний: SPI, UART, SysTick, Таймеры, Внешние прерывания и прочее. Но все это к решению задачи не относится. Если это так важно, то я делал код для бутлоадера, который при переполнении буфера ждет пока хотябы один байт будет отправлен в UART и тогда в буфере появится место для добавления еще одного байта. Та же самая песня с чтением байта из пустого буфера. И да, в момент когда мы работаем с UARTом другая периферия пока не используется и у МК другой работы нет. Только обьясните как это знание поможет Вам решить проблему с WFI? Использовать таймер или любую другую периферию для ожидания байта по UART - вот это решение через анус. Понятое дело, что в конечом итоге процессор проснется, но это костыль и надежда на "авось его что-нибудь другое разбудит".
  5. Я делаю реальную систему, но если я хочу дождаться прервания по UART причем тут прерывание по таймеру? Часто бывают случаи когда нужно дождаться какого либо события и только потом действовать. А while(xxx) {} не сильно хороший вариант, ибо потребление. Вот именно, что не кирпич, ведь мы запрещаем не само прерывание, а вызов его обработчика. При появлении запроса на прерывание процессор проснется, а вызов обработчика произойдет после __enable_irq();. Я проверил, такой код работает и не виснет(STM32F3DISCOVERY): int main(int argc, char* argv[]) { RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); GPIO_InitTypeDef gpio; gpio.GPIO_Mode = GPIO_Mode_OUT; gpio.GPIO_OType = GPIO_OType_PP; gpio.GPIO_Pin = GPIO_Pin_9; gpio.GPIO_PuPd = GPIO_PuPd_NOPULL; gpio.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOE, &gpio); GPIO_ResetBits(GPIOE, GPIO_Pin_9); gpio.GPIO_Mode = GPIO_Mode_IN; gpio.GPIO_OType = GPIO_OType_PP; gpio.GPIO_Pin = GPIO_Pin_0; gpio.GPIO_PuPd = GPIO_PuPd_NOPULL; gpio.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOA, &gpio); EXTI_InitTypeDef exti; exti.EXTI_Line = EXTI_Line0; exti.EXTI_Mode = EXTI_Mode_Interrupt; exti.EXTI_Trigger = EXTI_Trigger_Rising; exti.EXTI_LineCmd = ENABLE; EXTI_Init(&exti); NVIC_InitTypeDef nvic; nvic.NVIC_IRQChannel = EXTI0_IRQn; nvic.NVIC_IRQChannelPreemptionPriority = 0x0F; nvic.NVIC_IRQChannelSubPriority = 0x0F; nvic.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvic); // Infinite loop while (1) { for(;;) { __disable_irq(); if(flag) break; __WFI(); __enable_irq(); __NOP(); __NOP(); __NOP(); } __enable_irq(); if(GPIO_ReadOutputData(GPIOE) & GPIO_Pin_9) { GPIO_ResetBits(GPIOE, GPIO_Pin_9); } else { GPIO_SetBits(GPIOE, GPIO_Pin_9); } flag = 0; } } void EXTI0_IRQHandler(void) { if((EXTI_GetITStatus(EXTI_Line0) != RESET)) { flag = 1; EXTI_ClearITPendingBit(EXTI_Line0); } }
  6. Кажется, я нашел ответ: http://infocenter.arm.com/help/index.jsp?t...a/BABGGICD.html Т. е. код должен быть примерно таким: while(1) { __disable_irq(); if(Uart.DataAvailable()) { break; } __WFI(); __enable_irq(); __NOP(); } Соотетственно если байт придет перед инструкией WFI, то произойдет запрос прерывания, но обработчик не вызовется(прерывания запрещены), потом вызовется WFI, но он не усыпит прессор так как есть запрос на прерывание, потом исполнится enable_irq, после которого(в течение 0-2 инструкций) вызовется обработчик прерывания. Теперь осталось это проверить. Во-первых, это - костыль. Во-вторых, еще не хватает мне таймер на это тратить, они же не бесплатно в МК даются - это ценный ресурс.
  7. Не уверен, что понял Ваш вопрос, но постараюсь расписать поподробнее. В крайнем случае имеем код типа __disable_irq(); // тут проверки на наличие принятого байта __enable_irq(); __WFI(); Если проверка покажет, что байт еще не пришел, то исполнение дойдет до строчки __enable_irq. Если искомый байт придет вот в этот момент - исполненится прерывание. После возвращения из прерывания исполнится инструкция WFI, которая будет ожидать нового прерывания, соответственно ядро не проснется. (понятное дело, других прерываний в примере нет) Вопрос: как дождаться прерывания с использованием WFI и гарантированно проснуться?
  8. Есть ли жизнь после WFI?

    Здравствуйте! Я тут задумался о такой потенциальной проблеме при использовании инструкции WFI: Предположим, что программа должна дождаться получения байта по UART, логичным был бы код while(!Uart.DataAvailable()) { __WFI(); } // тут обработка данных Но проблема в том что искомый байт может придти между Uart.DataAvailable() и __WFI(), вызовется обработчик прерывания, после которого вызовется __WFI() и МК больше никогда не проснется. Вставка критических секций: __disable_irq(); // тут что-то __enable_irq(); __WFI(); не спасет ситуацию, так как между __enable_irq(); и __WFI(); может проскочить нужное прерывание(а может не проскочить). Поиски вывели меня на вот эту англоязычную тему: http://community.arm.com/message/8927 и доку http://infocenter.arm.com/help/index.jsp?t...a/BIHBFEIB.html Но я так и не понял, что есть решение проблемы. Так есть ли в Cortex-M гарантированный способ проснуться после WFI?
  9. Да, спасибо, видел такое решение. Версию компилятора менять не собираюсь. Если надо, буду пользоваться одной версией хоть всю жизнь устройства. Выигрыш около 700-800байт, при размере флеша 8к. У меня и так все под завязку, так что стоит. Кстати, а есть в природе простой и надежный алгоритм шифрования для 8 битников? что-то подобное xtea, но без 32 битных чисел?
  10. Размещение библиотеки

    Здравствуйте. Имеется проект на stm8 на iar'е. Устройство имеет шифрованный протокол связи с верхним уровнем. Устройство должно иметь возможность обновлять прошивку через бутлоадер. Дело в том, что шифрование занимают много места и используют операции с 32 битными числами. Компилятор, понятное дело подтянул все необходимые функции для работы с такими числами. Я собираюсь сделать библиотеку с функциями шифрования и разместить ее в области бутлоадера. Но у меня появился ряд вопросов: 1) Как мне разместить библиотеку в области бутлоадера? 2) Как сделать так, чтобы и основная программа и бутлдоадер могли обращаться к функциям одной и той же библиотеки ? 3) Я правильно понимаю, что функции для работы с 32 битными числами уже будут в библиотеке? 4) Если я буду использовать операции с 32 битными числами в основной программе, то будут использоваться функции из библиотеки или подтянутся новые экземпляры тех же функций?
  11. stm32f4, EXTI, PD6

    Тактирование порта подано?
  12. STM32F4: ADC Interleaved + DMA

    С одним АЦП то же самое(между периодами 300 отсчетов). Но если включить DMA FIFO работает нормально (75 отсчетов). Без DMA FIFO, но с ADC_EOCOnEachRegularChannelCmd(ADC1, ENABLE); тоже нормально. С DMA FIFO и EOC одновременно - тоже норм. С двумя/тремя ни с FIFO, ни без него не пашет.
  13. STM32F4: ADC Interleaved + DMA

    Есть некоторые наблюдения: Если закомментировать строку ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE); Ничего не изменяется, все равно период между фронтами 300 отсчетов на 32кгц. Попробовал запустить 2 ацп в ADC_DMAAccessMode_2. DMA пересылает по 4 байта(DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;) И все равно период между фронтами 300 отсчетов на 32кгц! O_o. Такое ощущение, что параметры АЦП не влияют ни на что. Но, при увеличении делителя частоты АЦП в два раза(ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;) период между фронтами уменьшается почти вдвое до 148 отсчетов. Мне кажется, что проблема с триггером DMA. Но вот где она не знаю.
  14. STM32F4: ADC Interleaved + DMA

    Частота семплирования 9.6 Мгц - много. Да, это triple interleaved mode. По идее максимум 2.4 на 1 АЦП, 7.2 на все три. А у меня 9.6, соответственно что-то не так. А что нормального в дребезге результатов АЦП? Первый раз слышу, что дергание результатов от нуля до максимума это нормально. Пара единиц - нормально, а у меня - фигня какая-то.
  15. STM32F4: ADC Interleaved + DMA

    Подобные темы уже поднимались, но уже приведенные исходники у меня так и не заработали стабильно. Плата STM32F4Discovery. Имеется код: void init() { ADC_InitTypeDef ADC_InitStructure; DMA_InitTypeDef DMA_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; ADC_CommonInitTypeDef ADC_CommonInitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOC, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 | RCC_APB2Periph_ADC3, ENABLE); /* Configure ADC Channel 12 pin as analog input */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; GPIO_Init(GPIOC, &GPIO_InitStructure); DMA_InitStructure.DMA_Channel = DMA_Channel_0; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC_CDR_ADDRESS; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADCConvertedValue; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_BufferSize = adc_buffer_count; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA2_Stream0, &DMA_InitStructure); /* DMA2_Stream0 enable */ DMA_Cmd(DMA2_Stream0, ENABLE); /******************************************************************************/ /* ADCs configuration: triple interleaved with 5cycles delay to reach 6Msps */ /******************************************************************************/ /* ADC Common configuration *************************************************/ ADC_CommonInitStructure.ADC_Mode = ADC_TripleMode_Interl; ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1; ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; ADC_CommonInit(&ADC_CommonInitStructure); /* ADC1 regular channel 12 configuration ************************************/ ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; ADC_InitStructure.ADC_ExternalTrigConv = 0; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfConversion = 1; ADC_Init(ADC1, &ADC_InitStructure); ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_3Cycles); /* Enable ADC1 DMA */ ADC_DMACmd(ADC1, ENABLE); /* ADC2 regular channel 12 configuration ************************************/ ADC_Init(ADC2, &ADC_InitStructure); /* ADC2 regular channel12 configuration */ ADC_RegularChannelConfig(ADC2, ADC_Channel_11, 1, ADC_SampleTime_3Cycles); /* ADC3 regular channel 12 configuration ************************************/ ADC_Init(ADC3, &ADC_InitStructure); /* ADC3 regular channel12 configuration *************************************/ ADC_RegularChannelConfig(ADC3, ADC_Channel_11, 1, ADC_SampleTime_3Cycles); /* Enable DMA request after last transfer (multi-ADC mode) ******************/ ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE); /* Enable ADC1 **************************************************************/ ADC_Cmd(ADC1, ENABLE); /* Enable ADC2 **************************************************************/ ADC_Cmd(ADC2, ENABLE); /* Enable ADC3 **************************************************************/ ADC_Cmd(ADC3, ENABLE); /* Start ADC1 Software Conversion */ ADC_SoftwareStartConv(ADC1); } int main() { for(int i=0;i<adc_buffer_count;i++) { ADCConvertedValue[i] = 0; } init(); delay(10000000); for(;;); return 0; } Изменения относительно примера в комплекте STMF4 Periferial Lib: DMA в режиме normal, режим доступап dma 1. Частоты настроены: SYSCLK 144 МГц, APB2 72 МГц, APB1 36 МГц. На PC1 подаю меандр 32кГц. Ставлю брейкпоинт на строке "for(;;);", массив ADCConvertedValue заполнен значениями. Но вот в чем странность: Между период меандра судя по отсчетам АЦП - ровно 300 отсчетов. То есть: Частота семплирования 300*32000 = 9,6 МГц. Что многовато. Есть и вторая странность. Такое ощущение, что отсчеты складываются в неправильном порядке, привожу кусок массива(повторяющиеся значения убрал): переменная тип значение ADCConvertedValue[144] short 4 ADCConvertedValue[145] short 3 ADCConvertedValue[146] short 4 ADCConvertedValue[147] short 4095 ADCConvertedValue[148] short 4095 ADCConvertedValue[149] short 4 ADCConvertedValue[150] short 4095 ADCConvertedValue[151] short 4095 ADCConvertedValue[152] short 4095 ADCConvertedValue[153] short 4095 ADCConvertedValue[154] short 4095 ... ADCConvertedValue[292] short 4095 ADCConvertedValue[293] short 4095 ADCConvertedValue[294] short 4095 ADCConvertedValue[295] short 4095 ADCConvertedValue[296] short 10 ADCConvertedValue[297] short 4095 ADCConvertedValue[298] short 4095 ADCConvertedValue[299] short 16 ADCConvertedValue[300] short 4 ADCConvertedValue[301] short 12 ADCConvertedValue[302] short 16 ADCConvertedValue[303] short 2 ADCConvertedValue[304] short 3 ADCConvertedValue[305] short 3 ... ADCConvertedValue[300] short 4 ADCConvertedValue[301] short 12 ADCConvertedValue[302] short 16 ADCConvertedValue[303] short 2 ADCConvertedValue[304] short 3 ADCConvertedValue[305] short 3 Видно дергание сигнала при переходе из единицы в ноль и обратно. Иногда получается без дергания. Мозг уже кипит, не могу найти ошибку. Подскажите в чем дело.
×
×
  • Создать...