Перейти к содержанию

Вуйко

Members
  • Постов

    133
  • Зарегистрирован

  • Посещение

Весь контент Вуйко

  1. А что за МК? У некотрых STM USART умеет определять заданный символ в потоке. И вызывать прерывание по этому событию. Вот в прерывании и можно DMA остановить.
  2. Контроллер тоже ток потребляет. Его учитывать при расчетах нужно. А так, можно попробовать предложенный вариант. Только я бы ток немного снизил, что бы запас был. Названные диоды и так довольно яркие.
  3. А код проверки вообще правильный? Выкладывай сюда.
  4. Брак встречаться может, но его вероятность не такая уж высокая. Последовательность проверки должна быть следующая: 1. Включить тактирование порта. 2. Настроить определенный вывод на push-pull выход. 3. Установить его в высокий/низкий уровень и проверить сигнал выводе. Можно ничего не настраивать, а просто мультиметром замерить напряжение на определенном выводе. По умолчанию все выводы, кроме некоторых, настроены в режим плавающего входа. Напряжение на них будет в диапазоне 0,5-1,5 В.
  5. А как определялась неработоспособность?
  6. Как в любом другом STM. Включить тактирование GPIO порта. Настроить требуемый вывод. Включать / выключать лампочку.
  7. У STM32F030R8T6 нет бита разрешения тактирования альтернативных функций.
  8. USB устройство на шине обнаруживается по появлению подтяжки линии D+ на +3,3В. Что бы после перезагрузки не нужно было вручную отключать/подключать устройство, тем самым имитируя включение/отключение подтяжки, нужно этой подтяжкой управлять програмно. Тоесть просто добавить транзистор. Устройство отключено - транзистор закрыт, подтяжки нет, ничего не опознается. Нужно подключится - открываем транзистор, линия D+ подключается к +3,3В через резистор. Сопротивление резистора - 1,5 к.
  9. Вуйко

    STM32F103: ADC+DMA

    Это не пропуск запроса от АЦП. Это приход лишних запросов. Стоит очень внимательно проанализировать все возможные пути запуска преобразования у АЦП. И весь код работы с таймерами №2 и №4, если они используются. Ноги у проблемы отсюда растут. Где-то лишние запуски генерируются. Ну и судя по этой строке ADC1->CR2 |= ADC_CR2_EXTTRIG; //ADC_CR2_SWSTART; АЦП должно начинать новое преобразование сразу же по окончанию предыдущего. Только вот настройки EXTSEL битов на работу с SWSTART событием я в коде не вижу.
  10. void SPI_RW() { while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_IT_RXNE) == RESET); return SPI_I2S_ReceiveData(SPI1); } Функция возвращает void, но return не пустой. void должен быть заменен на тип идентичный возвращаемому функцией SPI_I2S_ReceiveData(SPI1). Иначе в буффер данных будет записан мусор. uint8_t RX_LEN = 32; uint8_t RX_BUF[RX_LEN] = {0}; Инициализация массивов переменной длинны вообще стандартом языка С запрещена. Добавление const тут не поможет. RX_LEN должен быть задан через #define. Все эти ошибки компилятор прекрасно отлавливает. Ну и править код прямо в первом посте непринято. Да еще и снова на неправильный.
  11. А этот код даже работал? Его компилятор не пропустит. Для начала убрать явные ошибки вроде: void SPI_RW() { while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_IT_RXNE) == RESET); return SPI_I2S_ReceiveData(SPI1); } Или: uint8_t RX_LEN = 32; uint8_t RX_BUF[RX_LEN] = {0}; Потом выкинуть StdPeripheralLibrary и переписать код на регистрах, или на HAL, в крайнем случае. Ну и разобраться как должны быть настроены GPIO для работы SPI.
  12. Вуйко

    Отладчик

    А есть полный проект в котором это странное поведение наблюдается? Ради интереса у себя попробую воспроизвести.
  13. Вуйко

    Отладчик

    Если оптимизация включена, то вполне закономерное поведение может быть.
  14. И что там по адресам? Записанные данные есть? Переменная FLASH_BASE правильно задана? Если данных нет, то только по шагам смотреть что в функции записи происходит отладчиком.
  15. Приведенный код нормально пишет в память. Значения после подключения/отключения питания в памяти сохраняются. Советую искать ошибку в алгоритме отладки. Проверить правильность записи можно и без дополнительных усилий. После записи и повторного подключения питания нужно просто подключится к МК с помощью ST-Link Utility и его средствами посмотреть что там по заданному адресу в памяти записалось.
  16. uint8_t Flash_Write( uint16_t *address, uint16_t *data, uint16_t size_nbytes ) { if((uint32_t)address < FLASH_START || (uint32_t)address >= FLASH_START + FLASH_SIZE_NBYTES || (uint32_t)address % 2) /* Address to write must be 2-byte aligned and in FLASH addresses range. */ return 1; if( data == NULL || (uint32_t)data % 2 ) /* Data pointer must be 2-byte aligned. */ return 1; if( !size_nbytes || size_nbytes > FLASH_PAGE_NBYTES || (size_nbytes % 2) ) return 1; if( ((uint32_t)address + size_nbytes) >= FLASH_START + FLASH_SIZE_NBYTES ) return 1; for( uint16_t index = 0; index < size_nbytes / 2; index++ ) { if( address[index] != 0xFFFF ) return 1; /* Flash not erased. Write cannot be done! */ } __disable_irq(); while( GET_BIT_BOOL(FLASH, , SR, BSY) ) continue; if( GET_BIT_BOOL(FLASH, , CR, LOCK) ) { /* Unlock flash memory. */ WRITE_REG( FLASH, , KEYR, 0x45670123 ); WRITE_REG( FLASH, , KEYR, 0xCDEF89AB ); } SET_BIT( FLASH, , CR, PG ); /* Enable Flash programming */ for( uint16_t index = 0; index < size_nbytes / 2; index++ ) { *(address++) = *(data++); while( GET_BIT_BOOL(FLASH, , SR, BSY) || !GET_BIT_BOOL(FLASH, , SR, EOP) ) continue; SET_BIT( FLASH, , SR, EOP ); /* Clear End Of Programming flag */ } CLEAR_BIT( FLASH, , CR, PG ); /* Disable Flash programming */ SET_BIT( FLASH, , CR, LOCK ); /* Lock Flash memory */ __enable_irq(); return 0; }
  17. RCC->CFGR |= RCC_CFGR_SW_HSE; //PLL selected as system clock while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSE) {} //wait for PLL is used Источником тактирования выбран внешний кварц, а нужно выбирать PLL. Должно быть как-то так: RCC->CFGR |= RCC_CFGR_SW_PLL; //PLL selected as system clock while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL) {} //wait for PLL is used
  18. Ядро Cortex-M0 не поддерживает доступ к данным без выравнивания. Отсюда и HardFault. Структура должна быть выровнена по границе в 8 байт, исходя из использования типа double. Почему заполняются первые два поля, а потом наступает HardFault. Начальный адрес структуры 0х01, она выровнена по границе в 1 байт. Первые две переменные типа uint8_t, требуют выравнивания по границе в 1 байт. Адреса переменных 0х01, 0х02. Все верно Третья переменная типа uint32_t, требует выравнивания по границе в 4 байта. Адрес переменной 0х03, выравнивание в 1 байт. Попытка записи -> HardFault.
  19. В последних двух строчках слово struct лишнее. Структуры итак через typedef объявлены. А как не работает, если компилится?
  20. А блоки после 32 читаются? Если да, то что в них?
  21. if(z>(0xFF-1)) Может тут должно быть 0x100 вместо 0xFF, а то получается запись 255 байт за раз. И новый блок начинает писаться с адреса не кратного числу 256.
  22. Так прямо в даташите написано, что "The Page Program instruction allows from one byte to 256 bytes (a page) of data to be programmed at previously erased (FFh) memory locations." То есть больше 256 байт за раз записать нельзя.
  23. __attribute__((always_inline)) __STATIC_INLINE uint32_t __REV(uint32_t value) { #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) return __builtin_bswap32(value); #else uint32_t result; __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); return(result); #endif } Для GCC правда, а не для IAR.
  24. Так все правильно работает. В массиве 0х01, 0x02, 0x03, 0xB4, в переменной "х" те же 0х01, 0x02, 0x03, 0xB4. Если посмотреть содержимое памяти по адресу 0х20000080, то там как раз и будет эта последовательность. Микроконтроллер работает в Little-Endian кодировке, а естественный для человека порядок - Big-Endian. Отладчик значения переменных выводит именно в последней кодировке, хотя хранятся они в первой. Отсюда и путаница.
×
×
  • Создать...