Владимир
7 лет назадp.s.
(шутка) - "наHAL"
- сам нахал.
В этом уроке по микроконтроллеру STM32 вы научитесь:
Остальные настройки оставим без изменений и сгенерируем код, например для KEIL. В папке Src появился основной файл main.c, вспомогательный файл конфигурирования периферии stm32f1xx_hal_msp.c и файл прерываний stm32f1xx_it.c.
Зайдем в файл прерываний stm32f1xx_it.c и в функции обработки прерываний линии 0 запишем наш код между строчками /* USER CODE BEGIN EXTI0_IRQn 0 */ и /* USER CODE END EXTI0_IRQn 0 */ для сохранения пользовательского кода при перегенерации проекта из CubeMX .
/* stm32f1xx_it.c */
/**
* @brief This function handles EXTI line0 interrupt.
*/
void EXTI0_IRQHandler(void)
{
/* USER CODE BEGIN EXTI0_IRQn 0 */
//PC0 - signal
EXTI->PR|=0x00; //сбрасываем флаг прерывания на линии 0
//задержка считается по формуле: 1 тик = (1/8000000 MHz)=0,000000125 сек;
//10 ms = 80000 * 0,000000125 = 0x13880h * 0,000000125;
__IO uint32_t nCount = 0x13880;
while (nCount--) //включаем задержку на срабатывание датчика 10 ms
{
}
if (GPIOC->IDR & GPIO_IDR_IDR0) //проверяем состояние порта PC0 после задержки
{
//если в порте PC0 есть сигнал от датчика после задержки, значит это не помеха
GPIOC->ODR^=GPIO_Pin_8; //переключаем светодиод на порту PC8
//это аналогично HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_8);
}
/* USER CODE END EXTI0_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
/* USER CODE BEGIN EXTI0_IRQn 1 */
/* USER CODE END EXTI0_IRQn 1 */
}
Результатом работы будет включение или отключение синего светодиода после приближения металлического предмета к активной области индуктивного датчика.
Наиболее действенный программный алгоритм защиты от помех представлен ниже. Но этот код лучше выполнять в основной программе, а не в прерывании и лучше всего о отдельном потоке. Т.е. настроить порт PC0 не на внешнее прерывание, а на простой вход.
/* main.c */
uint8_t buffer[3];
uint8_t count = 0;
/* Infinite loop */
for(;;)
{
//Проверка порта PC0
buffer[count] = HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_0);
//если все элементы массива buffer[0...2] будут равны 1, то на PC0 пришел сигнал от датчика
if (buffer[0] == 0x01 && buffer[1] == 0x01 && buffer[2] == 0x01)
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_SET); //включаем светодиод
}
else
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_RESET); //отключаем светодиод
}
count++;
if (count == 3) // при переполнении счетчика обнуляем его и заполняем снова - кольцевой алгоритм
{
count = 0;
}
osDelay(5); //задержка 5 мс для защиты от помех - можно изменять это значение для более лучшей настройки от помех
}
Результатом работы будет включение синего светодиода после приближения металлического предмета к активной области индуктивного датчика и отключение светодиода при отдалении металлического предмета.
Здесь реализована бесконечная проверка на заполнение массива единицами. Если он весь заполняется единицами, это значит датчик сработал и металл находится вблизи него некоторое время. Массив можно сделать любого размера, но чем больше размер, тем больше должен находится металл около датчика. Это все проверяется экспериметальным путем. При массиве уже из 5 элементов этот алгоритм обеспечивает более-менее хорошую помехозащищенность даже при постоянном дребезге контактов при подключении проводников от датчика.
Код проекта доступен по кнопке Скачать пример для всех пользователей.
Теги
Поделиться ссылкой на статью