Jump to content

    

pokk

Участник
  • Content Count

    214
  • Joined

  • Last visited

Community Reputation

0 Обычный

About pokk

  • Rank
    Местный

Recent Profile Visitors

3152 profile views
  1. Пользователь выключил устройство, потом убрал сигнал, и заново его подал, сработал детектор сигнала и включил устройство, а оно должно быть выключено. Такая же ситуация может произойти если устройство выключилось по расписанию.
  2. Добрый день, подскажите как правильно разрулить работу устройства по нескольким событиям (из разных модулей) В общем задача такая есть устройство которое может включаться/выключаться по разным событиям 1) пользователь нажал кнопку в web (вкл/выкл) 2) Работа по расписанию (часы реального времени) 3) Защита (превышение параметра выкл, параметр в норме вкл) 4) Детектор сигнала (пропал сигнал выкл, появился сигнал вкл) Как разрулить что бы не было не предвиденного включения т.е пользователь или расписание выключило устройство, а после того как отработала защита либо сработал детектор как заблокировать включение устройства? Так же надо заблокировать сигнал включение из расписания если устройство выключил пользователь. Текущая реализация такая, в каждом модулей сделал свой Callback на событие, а установка всех Callback функций в одном файле в котором производиться логика работы по событиям + запись в журнал. Для разруливания событий думаю добавить в сообщение модуля включения приоритет, MsgDevice(MSG_OFF,1...4), и перед выполнением операции сохранять его, и при следующем включении анализировать сохраненное значение с новым. Как ещё можно это разрулить ?
  3. Правлю драйвер I2c он работает полностью на прерываниях. Создал задачу которая закидывает данные в LCD через PCF (адрес + 2 байта данных) Работало это по событиям START->ADDR->BTF(устанавливаю STOP)->BTF -> освобождаю задачу и запускал отправку следующих данных. Появились грабли, после старта устанавливался сразу стоп, пришел к выводу что это из за того что бит START для новой посылки устанавливался слишком рано, после последнего BTF но перед установкой STOP. Поставил ожидание сброса бита STOP в CR1 или флаг I2C_SR2_BUSYBUSY (что правильнее ?) больше таких граблей не встречал. Есть какие либо варианты кроме как в цикле его ждать?
  4. Пробовал тоже самое. Судя по тому после сбоя считываются единицы из сектора заполненного нулями сдается, что это будет происходит при считывании из любого другого сектора. В ПО присутствует бутлоадер, но по ВКЛ питанию он только CRC прошивки проверяет и переходит на неё.
  5. Просто жду завершение передачи. Это для установки строба //--------------------------------------------------- if(Receive!=0){ //vTaskDelay( 2 / portTICK_RATE_MS ); delay_ms(2); delay_us(550); Debug1_1 delay_us(150); Debug1_0 } Кстати при vTaskDelay( 2 / portTICK_RATE_MS ); гребенка битов сдвигается на другое место. Да так же и гребенку битов там вижу. Это от анализатора файл данных Kingst VIS Вот начало посылки Вот конец поссылки + гребенка единиц Эта целиком пакет считанный из сектора в который ранее записал все нули. Не как не могу понять как ПО только на чтение может ломать данные которые считываются из памяти. Раз 8-10 считываются данные правильно без этих единиц (тоже смотрю через анализатор) на том же ПО
  6. Комп новый не успел нечего такого наставить, убрал все что трее висит не поменялось. Открыл си файл через sublime text 3 там такого нету.
  7. Да не на всех макросах такое происходит, пока тестировал нашел такое что при выделение буквы в макросе или комментария перед выделенной возникает отступ, на пока не сбросишь выделение. PS: windows 10
  8. Схема стандартная CS(програмный) MISO MOSI CLK к процессору, разводка вдалеке от всяких реле и тд (реле уже отключил что бы не мешало). CS подтянут через 4.7кОм на +3.3в MISO MOSI CLK через 1.3 кОм на землю. Скорость 2МГц вместо 60-100, так что с фронтами все с запасом по даташиту наносекунду у меня микросекунды Да сектор стирал, иначе бы при каждом запуске CRC не сходилось бы. Протокол корректный, несколько дней работало потом начала конфигурация слетать, назначил разбираться..,все убрал из прошивки осталось 1 задача (FreeRtos ) для работы с памятью и то уже на основных функциях. В принципе даже одной функцией пользуюсь. //================================================================================================== /* * @Описание: Описание функции. * @Параметр: * @Возврат: Нету */ void A25L0xx_ReadBytes(uint32_t ReadAddr,uint8_t* pBuffer, uint32_t NumByteToRead){ if(NumByteToRead==0){return;} xSemaphoreTakeRecursive(MutexA25L0xx,portMAX_DELAY); TakeMutexSpi(); FLASH_CS_OFF(); //------------------------------------------------------------------------------- TempTransmitBuff[0]=0x03; TempTransmitBuff[1]=((ReadAddr & 0xFF0000) >> 16); TempTransmitBuff[2]=((ReadAddr & 0xFF00) >> 8); TempTransmitBuff[3]=(ReadAddr & 0xFF); //------------------------------------------------------------------------------- Send_Spi_dma(0,TempTransmitBuff,4,TYPE_TRANSMIT,USE_MINC); //------------------------------------------------------------------------------- Send_Spi_dma(pBuffer,&DUMMY,NumByteToRead,TYPE_RECEIVE,TRANSMIT_NOT_MINC); // Без инкримента данных на передачу //------------------------------------------------------------------------------- FLASH_CS_ON(); GiveMutexSpi(); xSemaphoreGiveRecursive(MutexA25L0xx); } Перед чтением ставил задержу в 2с на установку памяти не помогло. Вижу что из памяти считываются мои данные(id совпадает и в конце CRС правильно), но в некоторых местах там где должны быть нули появилась гребенка единиц, думаю и других местах тоже есть, просто пока их ещё не заметил. Под отладчиком все корректно работает. На втором канале строб на тех местах где появляются левые биты. Вот целиком вся задача (SysLogWrite отключены, ReadConfingFromMem это A25L0xx_ReadBytes + CRC ) ErrorMem.kvdat
  9. Записал в память(A25L032) структуру конфигурации, в 0 сектор одноразово. После написал другу программу которая только считываю конфигурацию и проверяет CRC, через 5-8 переключений питания срабатывает ошибка CRC, поймал этот момент на анализаторе вижу что поверх моих данных появились 16 единиц через 1 байт (0x0100010001000100...) и из за этого не сходиться CRC, откуда они взялись ? После переключения питания ещё раз, гребенка единиц пропадает до 5-8 переключений питания. Добавил в ПО дополнительную проверку, после того как CRC не совпала считываю ещё несколько раз структуру конфигурации (при каждом чтении на том же месте находиться гребенка единиц). После добавил считывание нулей из другого сектора (записанного заранее) между считывания конфигурации, увидел гребенку единиц при каждом чтении причем там где должен были быть нули увидел 4 гребенки через равный промежуток времени (длина структуры конфигурации около 1КБ ) Посмотрел осциллографом на левые биты, хорошие фронты явно их выдает память а не наводка. Почему память раз через раз выдает левые денные ?
  10. Очень раздражает непонятная опция в IAR когда ставишь курсор макрос а IAR в этом месте разрывает макрос (как табуляцией только её нету). Причем это срабатывает не везде и не всегда. Кто нибудь встречался с таким?
  11. Надо получать живые данные с другого процессора(по USART) и отобразить их на экране и на web странице. Так вот не могу определить, как лучше сделать 1) Сделать отдельную задачу которая будет периодически получать параметры и складывать их переменную а все остальные задачи буду считывать значение этой переменной, и отображать. 2) Считывание параметра поставить прямо в той задаче где он нужен + таймаут на выход если был сбой в протоколе связи. Время получения параметры около 20ms.
  12. Для передачи данных между процессорами использовал протокол с фиксированной длиной запросного пакета и ответного пакета. Для абстрагирования и переносимости протокола решил написать драйвер USART что бы прием передача происходила только через эти функции. Алгоритм драйвера закладывал такой прием / передача данных происходит через кэш буфер. Для передачи, данных в линию USART ложем данные в кэш (функцией DriverWriteUsart) и запускаем выдачу. Для приема данных в прерывании складываем их в кэш а в протоколе считываем данные из кэша функцией GetDataFromUsartCache(DRIVER_USART_ENCODER) В протоколе это выглядит так SendRequest формирует данные в пакет и ложит в кэш USART после чего данные от туда выдаются в линию с помощью DMA После отправки запроса устанавливаем драйвер на прием ответного пакета функцией DriverReadUsart() с указанием сколько байт будет занимать ответный пакет (с ожиданием приема данных через DMA) а дальше считываем GetDataFromUsartCache все что приняли с проверкой CRC. Теперь решил переделать протокол и ответный пакет расширился (ID,CMD,TYPE,LEN,<DATA>,CRC) где LEN длина данных и теперь я не могу использовать DriverReadUsart с ожиданием конкретного количества байт, так как количество байт неизвестно. Пока думаю в направление сделать выбор в драйвере USART использовать на прием DMA или прерывание, и в прерывание ложить данные в кэш. Но сейчас обработчик прерывание USART находиться в само нижнем уровне (протокол -> драйвер USART -> аппаратная настройка USART) и там обработчик нечего не знает об кэше USART
  13. Да вот это и меня мучило, не хотел вводить ещё одни модуль, но по ходу без него не как Заведу модуль InitTask В си файле будет void WaitInitTask(uint16_t event) // WaitInitTask(WAIT_EVENT_INIT_MEM | WAIT_EVENT_INIT_LCD) xEventGroupWaitBits(xEventAnyName,event, 0, pdTRUE, portMAX_DELAY); } В H файле #define WAIT_EVENT_INIT_MEM (1<<0) #define WAIT_EVENT_INIT_LCD (1<<1) Он будет иклудиться практически во все задачи. Надеюсь 8-16 бит хватит.
  14. Как правильно заблокировать задачу. Есть vTaskMenu, она с определенным интервалом запускает функции из модуля LCD на перерисовку экрана с учетом как было сконфигурировано устройство (данные во внешнем ПЗУ модуль mem) поэтому в момент включения устройства ставлю ожидание, на инициализации LCD и mem (MemWaitInitLcd() и WaitInitMem() находяться в соответственных модулях (LCD и Mem).) void vTaskMenu (void *pvParameters){ WaitInitLcd(); WaitInitMem(); xEventGroupSetBits(xEventMenuStart,WAIT_EVENT_INIT_MENU); while(1){ MsgDisplayUpdate((uint8_t*)LcdMsgShow.msg,TEXT_NORMAL); vTaskDelay( LcdMsgShow.time/ portTICK_RATE_MS ); } void WaitInitLcd(void){ xEventGroupSync(xCreatedEventLcdInit,0,WAIT_EVENT_INIT_LCD,portMAX_DELAY); } void WaitInitMem(void){ xEventGroupSync(xCreatedEventGroup,0,WAIT_EVENT_INIT_MEMORY,portMAX_DELAY); } Так вот проблема возникла, когда я случайно поменял местами WaitInitMem(); WaitInitLcd(); получилось из за того что WaitInitMem(); инициализируеться гораздо дольше за это время задача инициализации LCD уже отрабатывает и выставляет xEventGroupSetBits(xCreatedEventLcdInit,WAIT_EVENT_INIT_LCD); и после отработки WaitInitMem программа зависает на WaitInitLcd(); Знаю, что можно xEventGroupSync поставить ждать несколько флагов Но как это сделать в рамках трех модулей menu LCD и mem ? Где создать общую переменную xCreatedEvent.... (для всех задач ?)
  15. В даташите написано, что максимальный уровень выходного сигнала с ЦАП равен 5.6 В (p-p). Хотя питание 5В, но да ладно. Настроил ЦАП на частоту дискретизации 190 кГц, 24 бита и выдаю с него пилу (0-0xFFFFFF) На осциллографе вижу пилу с 2.7 в (p-p), как выжать с него заданный диапазон до 5 в (p-p) ? Пробовал крутить уровень канала, через SPI уровень сигнала уменьшается, но не увеличивается.