i2C воообще шина интересная :) к примеру на STM32F103 ее проше ногодрыгом самому написать чем заставить нормально работать аппаратную . На новых STM работа с i2C доставляет удовольствие, главное не забывать заглушки тайминга ставить дабы не пойматься на вечный "while" Типа вот такой конструкции: void ax5043_spi_tx(uint8_t *byte, uint16_t len) { volatile uint16_t timeout; for (uint16_t i = 0; i < len; i++) { SPI2->DR = byte[i]; timeout = SPI_TIMEOUT; while (!(SPI2->SR & SPI_SR_TXE) && timeout) { timeout--; } timeout = SPI_TIMEOUT; while ((SPI2->SR & SPI_SR_BSY) && timeout) { timeout--; } if (SPI2->SR & SPI_SR_OVR) SPI2->DR; }
Комментарии: 30
Evgeniy
С HAL i2c тоже нормально работает.
Aleksey
проблема только в том что сам HAL не всегда работает так как хочет разработчик буквально может 3 недели назад разбирался в чужом коде там где было много переносов и указателей на функции, так вот степень вложения калбэков была такая что на камне с 20 кб памяти, свободной памяти оставалось менее 1 кб. После того как было детально разобрано что и как работает, выкинуты к чертям калбэки с вложениями и функции которые сами себя запускали и вся эта шляпа заменена на конечный автомат со флагами - памяти оно стало жрать всего 4,5 кб
Evgeniy
Ну бывает
Ogurezzz
На F103 аппаратный косяк есть. И этотописано в ERRATA
Aleksey
Да F103 вообще камень у которого ERRATA толще Description :)
Ogurezzz
точно
Dmitriy
Вопрос в том, что есть кривая стандартная. Если делаем постоянный коэффициент, то получаем ошибку 8 град на 1000 градусов, как у максима. Если ее раздробить по участкам, то можно добиться большей точности .. но пока математически я не могу это решить... На сколько нужно раздробить кривую, чтобы выйти на ту или иную точность. Графически решил, но математикой для меня не понятно... Тут нужен чел с матанализом
Aleksey
Ну если бы там была поддержка FPU можно было бы зафигачить сплайн апроксимацию - а потом еще и фильтр кальмана прикрутить :) Но коэффициенты сплайна рассчитать на микроконтроллере - очень тяжело, тут нужен мощный комп а потом уже константы забивать в контроллер
Dmitriy
Чел решал какими-то полиномами, писал что точность выше, чем у стандартных коэффициентов международных на к тип. У него и числитель и знаменатель с уравнениями, те что-то подобное полинома с фильтром.. но там да, нужен фпу .. Я хочу кусками, грубо говоря менять наклон передаточной характеристики в зависимости от диапазона температур... Это компромисс между полиномом к типа термопары и производительностью мк
Aleksey
я делал еще в институте рассчет параметров выпарных установок 3х секционных сплайном, комп задумывался на 2..3 секунды :) и это для 5го порядка
Dmitriy
Да, в новом проекте на пике хочу влепить системные софтовые таймера, один из которых на и2ц пойдет...
Aleksey
У меня теперь главный таймер системный это LPTIM
Dmitriy
Я мя такого нет. )))
Setpf
1) Кто видал может вводные статьи какие по дизасму\реверсу ЭБУ автомобильных? 2) Может у кого осталась макетка на 68HC16 со сталинских времен, я бы может за какую символическую сумму купил.
Dmitriy
Но хочу повесить на tmr0, и софтварно распараллелить
Aleksey
какой камень ?
Dmitriy
Буду на 18ф2525 делать. Он для меня новый.... Но в принципе похож... Если влезит проект Я думаю линейную аппроксимацию на кривую термопар, но если не взлетит таблицей придется делать
Ogurezzz
В ардуине вешают тикалку в 32 бита на 1мс таймер. А "уже приехали" проверяют вычитанием из тикалки последнего времени срабатывания, если разница больше периода - выполняется код. Называется "таймер на миллис" есть еще таймер на микрос.
Dmitriy
Вот будет типа 1 мс тик на таймере 0 и распараллеливаться на 16 битные переменные. Переменные вычитаются одновременно, и поднимается флаг
Aleksey
гы :) прилетело сейчас - реклама от администрации:
Ogurezzz
Ниче не понятно... Но очень интересно. Надеюсь меня на сборы никто не заберет
Aleksey
Главный цикл выглядит вот так: if ((flag_ds18b20 < 7)) // && (!flag_ax5043)) DS18B20_task(); if (flag_adc < 7) //ADC rutine ADC_task(); if (flag_ADS124S06 < 7) //ADS124S06 - rutine ADS124S06_task(); if (flag_rtc < 7) //RTC - rutine RTC_task();
Ogurezzz
Ну или так. Я делал массив 16битных таймеров дошло до нуля - выполняем задачу...
Aleksey
У меня такая же канитель сейчас !
Dmitriy
Типа того, ))) мысли сходятся ))
Ogurezzz
Я сейчас сделал в каждом модуле функциб [имя модуля]Tick(). И там уже в статисеской переменной считаю 1мс тики. И запускаю нужные процедуры в можуле
Aleksey
Обработчки вот такой: void LPTIM1_IRQHandler(void) { if ((LPTIM1->ISR & LPTIM_ISR_ARRM) != RESET) { LPTIM1->ICR |= LPTIM_ICR_ARRMCF; if (timer_ds18b20 > 0) timer_ds18b20--; if (timer_ax5043 > 0) timer_ax5043--; if (timer_axtx > 0) timer_axtx--; if (timer_ads > 0) timer_ads--; if (timer_wire_mode > 0) timer_wire_mode--; } if ((LPTIM1->ISR & LPTIM_ISR_ARROK) != RESET) { LPTIM1->ICR |= LPTIM_ICR_ARROKCF; } } как только в ноль упали поднимается флаг задачи
Ogurezzz
Да. Вполне стандартный алгоритм. Я вчера наконец-то добрался до изучения avr-libc... Как много там полезного
Aleksey
просто оно реально получается - псевдо-многозадачность, если где то нужна пауза выполняется остальной код Но самое интересное это смотреть на график переключения ядра между задачами - он просто завораживает. за один системный тик 1мс, камень делает хренову тучу скачков, и как правило болше 800 мкс дрыхнет потом :)
Ogurezzz
Как ты делаешь график?