

alux
Свой-
Posts
583 -
Joined
-
Last visited
Reputation
0 ОбычныйAbout alux
-
Rank
Знающий
Контакты
-
ICQ
Array
-
Вопросы по трансиверам Si446x
alux replied to Ruslan-maniak's topic in RF & Microwave Design
Проблема была связана с SPI STM32F0. С использованием прерывания по SPI и ожидания завершения текущей операции решило проблему: void SPI_WriteData(uint8_t* Buff, uint8_t size) { if(HAL_SPI_TransmitReceive_IT(&pSpiHandle, (uint8_t*)Buff, (uint8_t*)Buff, size) != HAL_OK) { /* Transfer error in transmission process */ Error_Handler(); } /* Wait for the end of the transfer */ while (HAL_SPI_GetState(&pSpiHandle) == HAL_SPI_STATE_BUSY_TX); } void SPI_ReadData(uint8_t* Buff, uint8_t size) { if(HAL_SPI_TransmitReceive_IT(&pSpiHandle, (uint8_t*)Buff, (uint8_t*)Buff, size) != HAL_OK) { /* Transfer error in transmission process */ Error_Handler(); } /* Wait for the end of the transfer */ while (HAL_SPI_GetState(&pSpiHandle) == HAL_SPI_STATE_BUSY_RX); } -
Вопросы по трансиверам Si446x
alux replied to Ruslan-maniak's topic in RF & Microwave Design
Имею проблему с трансивером si4461. Плата с трансивером из фирменного демокита. За основу был взят проект Si446x_BidirectionalPacket из папки с примерами WDS. Микроконтроллер STM32F0. Проблема в том, что не проходит команда POWER_UP в функции Radio_Init(). При ожидании готовности CTS после отправки команды POWER_UP вылетает в таймаут: uint8_t radio_comm_GetResp(uint8_t byteCount, uint8_t* pData) { uint8_t ctsVal = 0; uint16_t errCnt = RADIO_CTS_TIMEOUT; while (errCnt != 0) //wait until radio IC is ready with the data { radio_hal_ClearNsel(); radio_hal_SpiWriteByte(0x44); //read CMD buffer ctsVal = radio_hal_SpiReadByte(); if (ctsVal == 0xFF) { if (byteCount) { radio_hal_SpiReadData(byteCount, pData); } radio_hal_SetNsel(); break; } radio_hal_SetNsel(); errCnt--; } if (errCnt == 0) { while(1) { BSP_LED_Toggle(LED_RED); /* ERROR!!!! CTS should never take this long. */ } } if (ctsVal == 0xFF) { ctsWentHigh = 1; } return ctsVal; } При этом команда PART_INFO выполняется без проблем (см. осциллограммы). Аппаратный сброс трансивера также выполняется. Осциллограммы прилагаю. В чем может быть дело? Буду рад любому дельному совету. Спасибо. osc.7z -
"Надбавка" около 140 мсек, добавляемая к периоду генерируемого Alarm A, возникает из-за синхронизации shadow registers with calendar. /* Wait for RTC APB registers synchronization (needed after start-up from Reset)*/ if (HAL_RTC_WaitForSynchro(&RTCHandle) != HAL_OK) { Error_Handler(); } А по поводу проблемы обновления показания часов есть соображения?
-
Так результаты измерений каждого канала ложатся в буфер согласно RANK. Для серии STM32F0 Rank есть номер канала, и это нельзя изменить. В серии F4 "тасовать" каналы можно в любом порядке, присвоив определенному каналу уникальный Rank. По-моему, с двумерным массивом проще не придумаешь. Не вижу проблемы...
-
По условию задачи необходимо, чтобы контроллер (STM32F051) находился в режиме STANDBY и периодически просыпался 4 раза в сек. RTC тактируется от LSE. Настройка Alarm происходит после проверки конфигурации RTC по содержимому BACKUP регистра. Конфигурация RTC происходит один раз: #define RTC_ASYNCH_PREDIV 0x7F #define RTC_SYNCH_PREDIV 0x00FF //--------------------------------------------------------- void MX_RTC_Init(void) { /* Configure RTC prescaler and RTC data registers */ /* RTC configured as follows: - Hour Format = Format 24 - Asynch Prediv = Value according to source clock - Synch Prediv = Value according to source clock - OutPut = Output Disable - OutPutPolarity = High Polarity - OutPutType = Open Drain */ RTCHandle.Init.HourFormat = RTC_HOURFORMAT_24; RTCHandle.Init.AsynchPrediv = RTC_ASYNCH_PREDIV; RTCHandle.Init.SynchPrediv = RTC_SYNCH_PREDIV; RTCHandle.Init.OutPut = RTC_OUTPUT_DISABLE; RTCHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; RTCHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; RTCHandle.Instance = RTC; if (HAL_RTC_Init(&RTCHandle) != HAL_OK) { /* Initialization Error */ Error_Handler(); } /*##-2- Check if Data stored in BackUp register0: No Need to reconfigure RTC ##*/ /* Read the Back-Up Register 0 Data */ if (HAL_RTCEx_BKUPRead(&RTCHandle, RTC_BKP_DR0) != CONFIGURATION_DONE) {BSP_LED_On(LED_GREEN); /* Configure RTC Calendar */ RTC_CalendarConfig(); } else {BSP_LED_On(LED_BLUE); /* Check and Clear the Wakeup flag */ if (__HAL_PWR_GET_FLAG(PWR_FLAG_WU) != RESET) { __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU); } /* Check if the system was resumed from StandBy mode */ if (__HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET) { /* Clear StandBy flag */ __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB); /* Disable the write protection for RTC registers */ __HAL_RTC_WRITEPROTECTION_DISABLE(&RTCHandle); /* Wait for RTC APB registers synchronization (needed after start-up from Reset)*/ if (HAL_RTC_WaitForSynchro(&RTCHandle) != HAL_OK) { /* Initialization Error */ Error_Handler(); } /* Enable the write protection for RTC registers */ __HAL_RTC_WRITEPROTECTION_ENABLE(&RTCHandle); /* No need to configure the RTC as the RTC config(clock source, enable, prescaler, ...) * are kept after wake-up from STANDBY */ } /* Check if the Power On Reset flag is set */ if (__HAL_RCC_GET_FLAG(RCC_FLAG_PORRST) != RESET) { /* Turn on LED2: Power on reset occured */ ///BSP_LED_On(LED_RED); } /* Check if Pin Reset flag is set */ if (__HAL_RCC_GET_FLAG(RCC_FLAG_PINRST) != RESET) { /* Turn on LED4: External reset occured */ //BSP_LED_On(LED_BLUE); } /* Clear source Reset Flag */ __HAL_RCC_CLEAR_RESET_FLAGS(); } RTC_AlarmConfig(); // установить генерацию Alarm A каждые 250+140=390 мсек } //-------------------------------------- void RTC_AlarmConfig(void) { RTC_AlarmTypeDef RTC_AlarmStructure; RTC_TimeTypeDef RTC_TimeStructure; RTC_DateTypeDef RTC_DateStructure; //HAL_RTC_DeactivateAlarm(&RTCHandle, RTC_ALARM_A); /* Get Time Stamp of the current time */ HAL_RTC_GetTime(&RTCHandle, &RTC_TimeStructure, FORMAT_BIN); HAL_RTC_GetDate(&RTCHandle, &RTC_DateStructure, FORMAT_BIN); /* Set the alarm to current time + 250ms + offset 140ms */ RTC_AlarmStructure.Alarm = RTC_ALARM_A; RTC_AlarmStructure.AlarmTime.TimeFormat = RTC_TimeStructure.TimeFormat; RTC_AlarmStructure.AlarmTime.Hours = RTC_TimeStructure.Hours; RTC_AlarmStructure.AlarmTime.Minutes = RTC_TimeStructure.Minutes; RTC_AlarmStructure.AlarmTime.Seconds = RTC_TimeStructure.Seconds; //(RTC_TimeStructure.Seconds + 2) % 60; // RTC_AlarmStructure.AlarmTime.SubSeconds = 255; //(RTC_TimeStructure.SubSeconds + 255) % 256; RTC_AlarmStructure.AlarmDateWeekDay = RTC_DateStructure.Date; RTC_AlarmStructure.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE; RTC_AlarmStructure.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY | RTC_ALARMMASK_HOURS | RTC_ALARMMASK_MINUTES | RTC_ALARMMASK_SECONDS; RTC_AlarmStructure.AlarmSubSecondMask =RTC_ALARMSUBSECONDMASK_SS14_6; // RTC_ALARMSUBSECONDMASK_None; // if (HAL_RTC_SetAlarm_IT(&RTCHandle, &RTC_AlarmStructure, FORMAT_BIN) != HAL_OK) { /* Initialization Error */ Error_Handler(); } //---------------------- void RTC_CalendarShow(uint8_t *showtime, uint8_t *showdate) { RTC_DateTypeDef sdatestructureget; RTC_TimeTypeDef stimestructureget; /* Get the RTC current Time */ HAL_RTC_GetTime(&RTCHandle, &stimestructureget, FORMAT_BIN); /* Get the RTC current Date */ HAL_RTC_GetDate(&RTCHandle, &sdatestructureget, FORMAT_BIN); /* Display time Format : hh:mm:ss */ sprintf_((char *)showtime, "%02d:%02d:%02d", stimestructureget.Hours, stimestructureget.Minutes, stimestructureget.Seconds); /* Display date Format : mm-dd-yy */ sprintf_((char *)showdate, "%02d-%02d-%02d", sdatestructureget.Month, sdatestructureget.Date, 2000 + sdatestructureget.Year); } Прерывание AlarmA настроено и в обработчике деактивизирую Alarm: void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc){HAL_RTC_DeactivateAlarm(&RTCHandle, RTC_ALARM_A);} И в главном цикле: MX_RTC_Init(); //HAL_Delay(1000); //while (1) //{ /* Display the updated Time and Date */ RTC_CalendarShow(aShowTime, aShowDate); printf_("%s \n\r", aShowTime); printf_("%s \n\r", aShowDate); BSP_LED_On(LED_RED); // индикация работы программы HAL_Delay(10); //} /* Request to enter STANDBY mode */ HAL_PWR_EnterSTANDBYMode(); /* Infinite Loop */ while (1); Пробуждение по Alarm происходит почти как положено. Вместо ожидаемого периода 250 мс реальное значение на 140 мс больше. И эта "надбавка" сохраняется при разных значениях RTC_ALARMSUBSECONDMASK_SS14_X. Но это меня устраивает... Проблема в том, что при вызове RTC_CalendarShow() отображается одно и то же значение времени. Если раскомментировать while (1), в котором вечно отображать время (т.е. в режим STANDBY не входим), то все в порядке - время "тикает". Если закомментировать while (1) (т.е. вход в режим STANDBY), но добавить задержку в 1 сек, то показания часов обновляются. Проблема с обновлением показания часов также имеет место, если сбрасывать контроллер вручную кнопкой RESET чаще, чем 1 сек. Почему так происходит?
-
При использовании регулярных каналов данные складываются последовательно с каждого канала в определенный массив. Достаточно объявить этот массив как двумерный: /** * Configuration: * Defines the size of the ADC sample array. Defining a larger value here will significantly increase * the amount of static RAM usage, but more values will be used for averaging, leading to lower noise. */ #define ADCNUMCHAN 5 /* Number of channel */ #define ADCNUMSAMPLES 16 /* Number of samples */ #define ADCCONVERTEDVALUES_BUFFER_SIZE ((uint32_t)(ADCNUMCHAN*ADCNUMSAMPLES)) /* Size of array ADCxConvertedValues[num_chan * num_samples]: set to ADC sequencer number of ranks converted, to have a rank in each address */ /* Array containing ADC conversions results */ __IO uint16_t ADCxConvertedValues[ADCNUMSAMPLES][ADCNUMCHAN]; -------------------- // -- Enables ADC DMA request if (HAL_ADC_Start_DMA(&AdcHandle, (uint32_t*)&ADCxConvertedValues, ADCCONVERTEDVALUES_BUFFER_SIZE) != HAL_OK) { Error_Handler(); } ... и в обработчике прерывания ADC-DMA всей последовательности: void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { uint32_t accum = 0; for (uint8_t ch = 0; ch < ADCNUMCHAN; ch++) { for (uint16_t i = 0; i < ADCNUMSAMPLES; i++) { accum += ADCxConvertedValues[i][ch]; } Value.codeADC[ch] = accum / ADCNUMSAMPLES; accum = 0;}
-
IAP_InfoPage
alux posted a topic in ARM, 32bit
У LPC1227 есть flash information block по адресу 0x0004 0200 размером 3 страницы по 512 байт для записи пользовательских данных. Программирую в CodeRed. Пробую пример, поставляемый nxp. По UART шлю символы. Программа зависает при попытке вызова функций из IAP.c, кроме функций чтения. Кварц 12МГц. В настройках линкера указатель стека смещен на 256 байт для работы функций IAP. В чем может быть проблема? PS. Тестовый проект прилагаю. test.zip -
Пытаюсь собрать USB-driver for AVR из примера hid-custom-rq. Собрал проект на IAR для mega88PA. В результате система (Windows XP) HID-устройство определяется, но при попытке обратится к нему по команде set-led status выдает сообщение Could not find device with vid=0x16c0 pid=5df. То же самое происходит и на другом компьютере с Linux. Собрал тот же проект на такой же схеме , только вывод D- подключен к PD0, на такой же плате на Mega8. Все определяется и работает, как положено. А под мега88 никак не хочет. Пробовал запитать мк мега88 без последовательных диодов, но с установленными стабилитронами на +3,6В на выводах D+, D-. Та же фигня. Пробовал и с стабилитронами +3,9В, и без стабилитронов. :( В проекте IAR для меги88 пробовал создать отдельный начальный сегмент размером 254 байт для usbRxBuffer[]. Не помогает... В общем, версии закончились. Выкладываю проект на всеобщее обозрение. Может скажет кто, в чем может быть дело? Кто-нибудь запускал этот проект на мк кроме мега8 и тини2313 ? test_led.7z
-
ИУ AD8231 + фильтр на внутреннем ОУ =>
alux replied to alux's topic in Вопросы аналоговой техники
Проблема оказалась в микросхеме. Монтажники перепаивали микросхему, а она, как написано в даташите на стр.7, при температуре свыше 130 градусов теряет свою функциональность или вовсе выходит из строя. -
ИУ AD8231 + фильтр на внутреннем ОУ =>
alux replied to alux's topic in Вопросы аналоговой техники
Хуже всего, когда то работает нормально, то, бывает, включу, считывает минимальное отрицательное значение. Еще у меня "земля" подключена к thermalpad ИУ и к выводу 4 (NC). Может в этом дело? Значение резисторов играют роль? В схеме должны стоять 499кОм для частоты среза фильтра 32Гц. Из обычного ряда ближайшее значение 510кОм. Или лучше поставить два в параллель по 1МОм ? -
ИУ AD8231 + фильтр на внутреннем ОУ =>
alux replied to alux's topic in Вопросы аналоговой техники
Попробовал закоротить резисторы 150к и выпаял конденсаторы, т.е. ОУ работает просто как буферный повторитель. На входе ОУ нормальные 1,2 В, а на выходе похоже генерация - скачет напряжение от 0.3 до 2.1 В. Может микросхема все-таки бракованная? Я ее дважды перепаивал, феном сдувал с монтажной платы. -
ИУ AD8231 + фильтр на внутреннем ОУ =>
alux posted a topic in Вопросы аналоговой техники
Усилитель сигнала с термопары. Схема на ИУ AD8231. Для теста подаю на вход усилителя напряжение около +10 мВ от батарейки через делитель. GAIN (ad8231) = 128. На выходе ИУ тестером меряю ожидаемых +1.20 В относительно REF = +2.5В. Между ИУ и АЦП (ADS1110) стоит фильтр второго порядка с единичным усилением, собранный на внутреннем ОУ. Схема фильтра взята из даташита AD8231 (стр.22). Отличие только в том, что для установления единичного усиления фильтра R3 = 0, R4 => не впаян. Почему на выходе фильтра (на входе АЦП) максимальный отрицательный сигнал не пойму никак. Ошибок в монтаже нет. Руки чешутся перепаять микросхему. Может скажет кто, в чем может быть проблема? PS. Номиналы резисторов фильтра не 510 кОм, а 150 кОм. _________.pdf -
FreeModbus
alux replied to andrewlekar's topic in Интерфейсы
как выяснилось, проблема не в этой функции (0x10), а в адресе регистров, в которые нужно писать. У меня регистры (переменные типа int) упакованы в структуру : typedef struct { int NumSensorsDS; int TemperatureTC[NUM_SENSORS]; int Parameter[2][NUM_SENSORS]; int Temperature[2]; int NumSensorsTC; int Cable; int Average; int Data; long Accum; }TValue; В регистры Cable, Average записываются значения и отдается нормальный ответ от устройства при помощи ф-ций PresetSingleRegister,PresetMultipleRegisters, а если указать адрес записываемого регистра в NumSensorsTC, то запрос остается без ответа. Почему, не пойму никак?.. PS. Callback-функции написаны и работают. PS2. Вроде нашел... В Callback-функции использую ф-ции записи во флеш. WriteFlashByte(FLASH_PARAMETER_LOCATION + 2 + 1, *(pucRegBuffer)); WriteFlashByte(FLASH_PARAMETER_LOCATION + 2, *(pucRegBuffer + 1)); Если закоментировать эти строки, то ответ нормальный появляется. Наверно, правильно сделать так : в колбэк-функции устанавливать флаг, а в главном цикле по этому флагу писать во флеш. -
FreeModbus
alux replied to andrewlekar's topic in Интерфейсы
При использовании функции 0x10 PresetMultipleRegisters запрос от мастера идет как положено (проверяю в Serial Port Monitor), а ответа от слева не поступает. Функция 0x06 PresetSingleRegister работает как положено. В mbconfig.h функция 0x10 разрешена : #define MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED ( 1 ) В чем может быть проблема? -
FreeModbus
alux replied to andrewlekar's topic in Интерфейсы
Еще для полного счастья нужно использовать функции для записи\чтения битов ForceSingleCoil (0x05), ReadSingleCoil(0x01). Приведите, пожалуйста, пример с использованием этих функций. Флаги, битовое поле в области ввода-вывода ниже 0x1f. // Flags typedef union { unsigned char Complete; // Access all 8 bits struct { bool IsTestCompleted : 1; bool IsDataReady : 1; bool IsRelayOn : 1; bool IsReset : 1; bool IsOverheat : 1; bool IsKeyPressed : 1; bool IsOpenoff : 1; bool IsShortcut : 1; }; } FLAGS; __no_init volatile FLAGS [email protected]; // Флаги, битовое поле в области ввода-вывода ниже 0x1f (ACSR Register)