Jump to content

    

EasyToUse

Участник
  • Posts

    12
  • Joined

  • Last visited

Reputation

0 Обычный

About EasyToUse

  • Birthday February 20

Информация

  • Город
    Array
  1. Использование UART + DMA позволяет аппаратно формировать временные слоты чтения и записи. Не нужно думать, что твою посылку прервет прерывание или какая-нибудь более приоритетная задача. Задаче чтения 1820 можно присвоить самый низкий приоритет и она себе спокойно будет работать. А схемотехника вся сводится к соединению приемника и передатчика в кучу. Пробуйте! Рекомендую! EasyToUse))) Можно читать и регистры как вы говорите. Но в HAL лучше использовать макросы. И у меня в начале на HAL не полетело. Оказалось UART+DMA не хотел работать в NORMAL режиме. У индусов там какая-то ерунда написана. Видимо посмотрели, что в CIRCULAR работает - ну и ладно. Пришлось немножно подправить. После генерации кода кубом нужно лезть в библиотеку и ремить их функцию, а ставить свою. Писать на регистрах это чем-то будет напоминать программирование на ассемблере. Я все-таки за бОльшую абстракцию))) Хотя везде есть плюсы и минусы. Причем в данном случае за аппаратный уровень не надо платить))) Вы имеете ввиду, что к устройствам надо обращаться по адресу, а для этого на шине надо оставить один датчик, считать его имя и запомнить? Есть некоторые неудобства. Радует, что это надо делать лишь раз. Еще есть хитрая процедура поиска всех адресов на шине. Но потом все равно устройство нужно связать с его расположением. У DALLAS есть кажется и шинные ключи, которые могут сегментировать шину. Так что насчет перспектив я бы не согласился с Вами.
  2. Когда сидят 2 на шине, то работает первый. Если "на горячую" отключить первый, то правильно начинает отвечать и второй. При обратном подключении первого второй затыкается, первый работает правильно. По даташиту время преобразования 750 мс, должно хватать. А вот готовность флагов посмотреть в кубе сложно. Уровень абстракции такой, что считается флаги проверять программисту необязательно. Хотя, наверно, через макросы и можно. SPL в этом плане по-приятней была. Друзья, взял другие датчики и проблема исчезла! Правда новые датчики на совсем короткой линии. Проверю влияние длины линии. В результате получил практически аппаратное измерение температуры, МК ядро практически не используется.
  3. Здравствуйте, люди добрые! Помогите отладить задачку под FreeRTOS. Задачка запускает измерение температуры двумя датчиками DS18S20 и через 1000мс читает значение температуры из каждого датчика, используя его адрес. Значения записываются в очередь, из которой другая задачка берет их и отображает на индикаторе. Датчики сидят на одной шине, а шиной управляет USART. Использую HAL от Cube. Когда подключены два датчика на шине, то правильно работает только первый, второй отвечает FF-ми. Вот сама задача uint8_t dma_rec[8]; uint8_t dma_trans[8]; uint8_t ow_rec[20]; uint8_t ow_trans[20]; extern UART_HandleTypeDef huart2; extern char* empty_str; //***************************************************************************** void OneWire_Task (void){ TTemp Temp; uint8_t adr_DS1[8]; uint8_t adr_DS2[8]; restore_adr(EEPROM_ADR_DS1, adr_DS1); restore_adr(EEPROM_ADR_DS2, adr_DS2); while(1){ if(OW_Reset() == OW_OK){ ow_trans[0] = 0xCC; ow_trans[1] = 0x44; OW_Send(2); vTaskDelay(1000); DS1820_getConvertedValue(adr_DS1, &Temp.t1); DS1820_getConvertedValue(adr_DS2, &Temp.t2); xQueueOverwrite(Temp_QueueHandle, &Temp); } else{ vTaskDelay(1000); } } } Функция сброса и обнаружения импульса присутствия uint8_t OW_Reset(void){ uint8_t ow_presence; huart2.Init.BaudRate = 9600; HAL_UART_Init(&huart2); ow_trans[0] = 0xF0; HAL_UART_Receive_DMA(&huart2, ow_rec, 1); HAL_UART_Transmit_DMA(&huart2, ow_trans, 1); xSemaphoreTake(OW_Complete_BinarySemHandle, portMAX_DELAY); ow_presence = ow_rec[0]; huart2.Init.BaudRate = 115200; HAL_UART_Init(&huart2); if (ow_presence != 0xF0) return OW_OK; else return OW_NO_DEVICE; } Отправка N байт по шине 1-wire void OW_Send(uint8_t kol){ uint8_t i; uint8_t rec_byte; for(i = 0; i < kol; i++){ OW_convert(ow_trans[i],dma_trans); HAL_UART_Receive_DMA(&huart2, dma_rec, 8); HAL_UART_Transmit_DMA(&huart2, dma_trans, 8); xSemaphoreTake(OW_Complete_BinarySemHandle, portMAX_DELAY); rec_byte = OW_restore(dma_rec); ow_rec[i] = rec_byte; } } вот эта функция работает неправильно при втором вызове uint8_t DS1820_getConvertedValue(uint8_t* adr, float* t){ uint8_t i; float sign; float a; uint8_t ml_byte; uint8_t st_byte; uint8_t count_remain; uint8_t count_per_c; uint16_t temp_read; uint8_t err = 0; uint8_t crc; OW_Reset(); ow_trans[0] = 0x55; OW_Send(1); vTaskDelay(5); for(i = 0; i < 8; i++){ ow_trans[i] = *(adr + i); } OW_Send(8); vTaskDelay(5); ow_trans[0] = 0xBE; OW_Send(1); vTaskDelay(5); for(i = 0; i < 9; i++){ ow_trans[i] = 0xFF; } OW_Send(9); vTaskDelay(5); ml_byte = ow_rec[0]; st_byte = ow_rec[1]; count_remain = ow_rec[6]; count_per_c = ow_rec[7]; crc = ow_rec[8]; temp_read = (((uint16_t)st_byte << 8) + (uint16_t)ml_byte) / 2; if(temp_read & 0xFF00) sign = -1.0; else sign = 1.0; if(sign == -1.0){ temp_read = ~temp_read + 1; a = sign * (float)temp_read; } else{ a = (float)temp_read; } a = a - 0.25 + ((float)count_per_c - (float)count_remain) / (float)count_per_c; *t = a; return err; } каждый бит кодируем байтом void OW_convert(uint8_t ow_byte, uint8_t* buf){ uint8_t i; for(i = 0; i < 8; i++){ if((ow_byte >> i) & 0x01){ *(buf + i) = OW_1; } else{ *(buf + i) = OW_0; } } } из 8 байт по USART делаем один uint8_t OW_restore(uint8_t* buf){ uint8_t ow_byte; uint8_t i; ow_byte = 0; for(i = 0; i < 8; i++){ ow_byte >>= 1; if(buf[i] == OW_R_1) ow_byte |= 0x80; else ow_byte &= (~0x80); } return ow_byte; } читаем адрес датчика температуры void DS1820_readROM(void){ uint8_t i; OW_Reset(); ow_trans[0] = 0x33; OW_Send(1); vTaskDelay(5); for(i = 0; i < 8; i++){ ow_trans[i] = 0xFF; } OW_Send(8); } после приема N байт по USART_DMA отдаем семафор void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){ static portBASE_TYPE xHigherPriorityTaskWoken; xHigherPriorityTaskWoken = pdFALSE; if(huart == &huart2){ xSemaphoreGiveFromISR(OW_Complete_BinarySemHandle, &xHigherPriorityTaskWoken); portEND_SWITCHING_ISR( xHigherPriorityTaskWoken ); } } Не хотел работать HAL_USART_DMA в режиме NORMAL. Не вызывался колбек. Пришлось подправить. [code]static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma) { UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; /* DMA Normal mode*/ if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) ) { huart->TxXferCount = 0; /* Disable the DMA transfer for transmit request by setting the DMAT bit in the UART CR3 register */ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); /* Enable the UART Transmit Complete Interrupt */ //__HAL_UART_ENABLE_IT(huart, UART_IT_TC); huart->State = HAL_UART_STATE_READY; HAL_UART_TxCpltCallback(huart); } /* DMA Circular mode */ else { HAL_UART_TxCpltCallback(huart); } }
  4. HAL

    А лучше одну и ту же периферию не использовать в разных задачах.
  5. HAL

    А если проверку этого флажка делать в критической секции?
  6. HAL

    На укладку парашюта еще никто не жаловался... Реентерабельные функции можно вызывать из разных задач, а используя HALовский LOCK для устройств периферии не нужны мьютексы RTOS.
  7. HAL

    Помните, как мы работали раньше? ))) Как конфигурировали порты и флеш, настраивали тактирование? Как энтузиасты писали макросы для настройки и ПО высокого уровня для того же? И вы скажете HAL это плохо? HAL это великолепно! ))) Идея витала в воздухе. И ее неплохо реализовали. Концепция HAL с ее реентерабельностью функций и механизмом блокировки объектов отлично подходит, когда используешь RTOS. Есть некоторые шероховатости, но это детские болезни и они пройдут! Нашел баг - напиши в ST! P.S. И индусы молодцы! Они, вообще, ребята умные - шахматы придумали )))
  8. Если проект сгенерирован в Кубе, то PriorityGroup = 4 будет автоматически. Смотрите файл stm32l1xx_hal_msp.c. HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); В Кейле удобно названия функций HAL смотреть выбрав закладку Function в окне менеджера проектов.
  9. Хотелось поддержать отечественного производителя. Требований к креплению особых нет. Мотор планирую использовать для открывания дверей в теплице. Скорость вращения мне не важна, момент хотелось побольше получить. Стремно 127В заводить в теплицу - сыро и летом босиком люблю ходить. Включу, конечно, через УЗО на 10мА, но все же... Смотрел на привод стеклоочистителей ВАЗ. 12В, 30 об/мин и момента может хватить. Надо пробовать. А вот здесь немного не понял.
  10. Здравствуйте, люди добрые! И недобрые тоже здравствуйте... Подскажите, чем можно заменить реверсивный электродвигатель с редуктором типа РД-09, Д-219П1. Хочется иметь похожие механические характеристики, но при питании 12В.
  11. У меня была похожая в первом приближении задача. Делаю измеритель влажности почвы для теплицы. У воздуха е=1, а у воды уже 80! Два электрода, лучше из нержавейки в землю или воду и измеряем емкость полученного конденсатора. Работаем на переменке, чтобы не было электролиза воды. Для STM32L с его DMA получается частота 5-10 кГц легко. Выделяем емкостную составляющую тока синхронным детектором. В МК все обсчитываем, хоть в % влажности, хоть в кубометрах для вашего случая, и по RS-485 передаем в избу. Еще можно задействовать ШИМ МК, тогда показания можно снимать со стрелочного вольтметра ))). Деталей пошло - МК, счетверенный ОУ и интефейсная микросхема.
  12. Интересное предложение. Да и оплата, пожалуй, адекватная для такого устройства. Смущает требование запитать все устройство от USB. Насколько оно принципиально? Оплата по безналу предполагает что исполнителем может быть только юридическое лицо?