Jump to content

    

alux

Свой
  • Content Count

    589
  • Joined

  • Last visited

Community Reputation

0 Обычный

About alux

  • Rank
    Знающий
  1. Проблема была связана с SPI STM32F0. С использованием прерывания по SPI и ожидания завершения текущей операции решило проблему: CODEvoid 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); }
  2. Имею проблему с трансивером si4461. Плата с трансивером из фирменного демокита. За основу был взят проект Si446x_BidirectionalPacket из папки с примерами WDS. Микроконтроллер STM32F0. Проблема в том, что не проходит команда POWER_UP в функции Radio_Init(). При ожидании готовности CTS после отправки команды POWER_UP вылетает в таймаут: CODEuint8_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 выполняется без проблем (см. осциллограммы). Аппаратный сброс трансивера также выполняется. Осциллограммы прилагаю. В чем может быть дело? Буду рад любому дельному совету. Спасибо.
  3. STM32F051 : RTC + Alarm + Subseconds

    "Надбавка" около 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(); }А по поводу проблемы обновления показания часов есть соображения?
  4. Так результаты измерений каждого канала ложатся в буфер согласно RANK. Для серии STM32F0 Rank есть номер канала, и это нельзя изменить. В серии F4 "тасовать" каналы можно в любом порядке, присвоив определенному каналу уникальный Rank. По-моему, с двумерным массивом проще не придумаешь. Не вижу проблемы...
  5. STM32F051 : RTC + Alarm + Subseconds

    По условию задачи необходимо, чтобы контроллер (STM32F051) находился в режиме STANDBY и периодически просыпался 4 раза в сек. RTC тактируется от LSE. Настройка Alarm происходит после проверки конфигурации RTC по содержимому BACKUP регистра. Конфигурация RTC происходит один раз:CODE#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);}И в главном цикле: CODE 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 сек. Почему так происходит?
  6. Цитата(Salamander @ Feb 23 2015, 19:51) 1. Как прочесть данные из определенного канала? При использовании регулярных каналов данные складываются последовательно с каждого канала в определенный массив. Достаточно объявить этот массив как двумерный: CODE/** * 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 всей последовательности: CODEvoid 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;}
  7. IAP_InfoPage

    У LPC1227 есть flash information block по адресу 0x0004 0200 размером 3 страницы по 512 байт для записи пользовательских данных. Программирую в CodeRed. Пробую пример, поставляемый nxp. По UART шлю символы. Программа зависает при попытке вызова функций из IAP.c, кроме функций чтения. Кварц 12МГц. В настройках линкера указатель стека смещен на 256 байт для работы функций IAP. В чем может быть проблема? PS. Тестовый проект прилагаю.
  8. Проблема V-USB на ATmega88

    Пытаюсь собрать 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 ?
  9. Проблема оказалась в микросхеме. Монтажники перепаивали микросхему, а она, как написано в даташите на стр.7, при температуре свыше 130 градусов теряет свою функциональность или вовсе выходит из строя.
  10. Хуже всего, когда то работает нормально, то, бывает, включу, считывает минимальное отрицательное значение. Еще у меня "земля" подключена к thermalpad ИУ и к выводу 4 (NC). Может в этом дело? Значение резисторов играют роль? В схеме должны стоять 499кОм для частоты среза фильтра 32Гц. Из обычного ряда ближайшее значение 510кОм. Или лучше поставить два в параллель по 1МОм ?
  11. Попробовал закоротить резисторы 150к и выпаял конденсаторы, т.е. ОУ работает просто как буферный повторитель. На входе ОУ нормальные 1,2 В, а на выходе похоже генерация - скачет напряжение от 0.3 до 2.1 В. Может микросхема все-таки бракованная? Я ее дважды перепаивал, феном сдувал с монтажной платы.
  12. Усилитель сигнала с термопары. Схема на ИУ AD8231. Для теста подаю на вход усилителя напряжение около +10 мВ от батарейки через делитель. GAIN (ad8231) = 128. На выходе ИУ тестером меряю ожидаемых +1.20 В относительно REF = +2.5В. Между ИУ и АЦП (ADS1110) стоит фильтр второго порядка с единичным усилением, собранный на внутреннем ОУ. Схема фильтра взята из даташита AD8231 (стр.22). Отличие только в том, что для установления единичного усиления фильтра R3 = 0, R4 => не впаян. Почему на выходе фильтра (на входе АЦП) максимальный отрицательный сигнал не пойму никак. Ошибок в монтаже нет. Руки чешутся перепаять микросхему. Может скажет кто, в чем может быть проблема? PS. Номиналы резисторов фильтра не 510 кОм, а 150 кОм.
  13. FreeModbus

    как выяснилось, проблема не в этой функции (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)); Если закоментировать эти строки, то ответ нормальный появляется. Наверно, правильно сделать так : в колбэк-функции устанавливать флаг, а в главном цикле по этому флагу писать во флеш.
  14. FreeModbus

    При использовании функции 0x10 PresetMultipleRegisters запрос от мастера идет как положено (проверяю в Serial Port Monitor), а ответа от слева не поступает. Функция 0x06 PresetSingleRegister работает как положено. В mbconfig.h функция 0x10 разрешена : Код#define MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED  (  1 ) В чем может быть проблема?
  15. FreeModbus

    Еще для полного счастья нужно использовать функции для записи\чтения битов 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 Flags@0x28; // Флаги, битовое поле в области ввода-вывода ниже 0x1f (ACSR Register)