STM32F030F4 задержки

Функция delay() при помощи таймера TIM16

Сперва инициализация

void TIM16_init(void){
  NVIC_InitTypeDef NVIC_InitStructure;
  TIM_TimeBaseInitTypeDef TIM_InitStructure; 

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM16, ENABLE);

  NVIC_InitStructure.NVIC_IRQChannel = TIM16_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPriority = 0x01;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);  
  
  TIM_InitStructure.TIM_Period = 1;
  TIM_InitStructure.TIM_Prescaler = 400;
  TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  TIM_InitStructure.TIM_RepetitionCounter = 0;
  TIM_TimeBaseInit(TIM16, &TIM_InitStructure);

  TIM_ITConfig(TIM16, TIM_IT_Update, ENABLE);
  TIM_Cmd(TIM16, ENABLE);
}


400 реально мэджик нумбер подобраный осцилографом. )) Как оно рассчитывается в теории понятно, но на практике что-то не очень. Вообщем это дает нам прерывание таймера каждые 100 микросекунд.


static volatile uint16_t delay_counter = 0;
void TIM16_IRQHandler(void) {
    if (TIM_GetITStatus(TIM16, TIM_IT_Update) != RESET) {
        delay_counter++;
        TIM_ClearITPendingBit(TIM16, TIM_IT_Update);
    }
}


И собственно функции задержки:

void delay_100us(void) {    // задержка 100 uS
  delay_counter = 0;
  while (!delay_counter);
}

void delay_ms(int ms) {    // задержка N mS
  int i;
  for(i=0;i<ms*10;i++) {
    delay_100us();
  }
}


Код мне кажется не очень оптимальным, — вот как чувствую грабли, — послушал бы ваши замечания.

Использвание (мигание светодиодом):

  while(1)
  {
     GPIO_SetBits(GPIOA, GPIO_Pin_4);
     delay_ms(500);
     GPIO_ResetBits(GPIOA, GPIO_Pin_4);
     delay_ms(500);
  }

STM32F030F4 прерывания

Прерывание дело несложное. Единственный ньюанс — не забудьте подключить файлы startup_stm32f030.s и system_stm32f0xx.c (находятся в архиве с SPL, папка STM32F0xx_StdPeriph_Lib_V1.5.0\Libraries\CMSIS\Device\ST\STM32F0xx\Source\Templates\), иначе прерывание закончится вызовом HardFault_Handler.

Например, прерывание по кнопке. Кнопку подключаем к PA0 и земле. И от PA0 подтягивающий резистор к плюсу питания.

Инициалазация

  EXTI_InitTypeDef   EXTI_InitStructure;
  NVIC_InitTypeDef   NVIC_InitStructure;

  /* Configure PA0 pin as input floating */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* Enable SYSCFG clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
  /* Connect EXTI0 Line to PA0 pin */
  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);

  /* Configure EXTI0 line */
  EXTI_InitStructure.EXTI_Line = EXTI_Line0;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);

  /* Enable and set EXTI0 Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = EXTI0_1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPriority = 0x00;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);


Обработчик

void EXTI0_1_IRQHandler(void)
{
  if(EXTI_GetITStatus(EXTI_Line0) != RESET) {

    // делаем что-нибудь полезное  

    /* Clear the EXTI line 0 pending bit */
    EXTI_ClearITPendingBit(EXTI_Line0);
  }
}

STM32F030F4 SPI

Минздрав предупреждает: данный материал может оскорбить чувства профессионалов и зануд.



Читать дальше

STM32F030F4 инициализируем ADC

ADC на PA0

Инициализация:
void ADC_Config(void)
{
  ADC_InitTypeDef     ADC_InitStructure;
  GPIO_InitTypeDef    GPIO_InitStructure;

  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 ;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  
  ADC_DeInit(ADC1);
  
  ADC_StructInit(&ADC_InitStructure);
  
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; 
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;
  ADC_Init(ADC1, &ADC_InitStructure); 
  
  ADC_ChannelConfig(ADC1, ADC_Channel_0 , ADC_SampleTime_239_5Cycles);
  ADC_GetCalibrationFactor(ADC1);
  ADC_Cmd(ADC1, ENABLE);     
  
  while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADRDY)); 
  
  ADC_StartOfConversion(ADC1);
}


Использование:

ADC_Config();
while(1) {
    while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
    ADCValue = ADC_GetConversionValue(ADC1);
}


Вместо ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; можно написать ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;, тогда перед каждой оцифровкой надо будет вызывать ADC_StartOfConversion(ADC1);

Заодно есть вопрос. Подключаю PA0 через делитель к +3.3V, гоняю по циклу ADC_GetConversionValue(). Оцифрованые значения имеют разбежку +/-10. Это нормально поведение АЦП или я что-то не так делаю?

Шрифты с GLCD Font Creator на коленке

Известная тема графических дисплеев — необходимость носить шрифты с собой.

Задача:
— IAR, STM32;
— есть дисплей 128х64 OLED(монохром);
— нужен один хороший шрифт с Кириллицей;
— нужна приемлемая читаемость и размер;
— нужна хорошая плотность записи на экране;
— нужно вводить строки прямо в коде программы, не задумываясь над кодировками.


Читать дальше

Приличный (без bit-banging) и дешёвый SPI-flash программатор, c DMA SPI и USB на основе flashrom и maple-mini (stm32).

В общем, понадобилось слить прошивку и прошить роутер TP-link (пересадить его с S25FL032A/P на M25P128). В итоге в сусеках интернета был найден на гитхабе проект github.com/dword1511/stm32-vserprog, который реализует то, что и указано в заголовке. Учитывя, что стоит она $4.2, и она у меня уже есть, я был очень рад.


Читать дальше

Новогодний светильник

С наступающим!


Я свою «гирлянду» сделал так (извиняюсь за качество видео):



Читать дальше

Стек для W5200 без циклов задержек + STM32F103

Чипы корейской фирмы WIZnet весьма широко известны и популярны. Так же полно где можно скачать драйверы для этих микросхем. Последняя реализация выполнена на W5500 здесь
Однако все драйверы построены по принципу вызова функций, которые весьма надолго стопорят основной цикл программы, мучительно и многократно ожидая события от внешней системы. Особенно «умиляет» ожидание в функции отправки по TCP и выход из нее по Timeout. А ведь это может растянуться не на одну секунду, и даже не 10! (При стандартных настройках — 28 сек). В некоторых случаях, если программа заточена полностью на Ethernet — это не критично, но не в моем случае. Да и вообще, инструкции вида
while(!Внешнее событие);
меня вымораживает напрочь, так как устройство полностью оказывается неработоспособным длительное время.
Мною были написаны несколько модулей, в которых я реализовал стек для W5200 без задержек.

Читать дальше
  • +5
  • 26 декабря 2015, 22:52
  • Mihail
  • 1

Программный многозадачный таймер на STM32.

После начало освоения STM32 с применением библиотеки HAL и STM32Cube и наигравшись с LEDBlink пришло время прокачатся до уровня 1, благо экспириенса получил прилично, спасибо за это СООБЩЕСТВУ. Глаз положил решил написать модуль для программных таймеров на базе SysTick, но без особых проблем под эту задачу можно использовать любой другой аппаратный таймер.
И тут многие скажут, зачем изобретать велосипед? Почему не использовать уже обкатанные варианты?
Все эти варианты хороши, выбирай на вкус, но все таки я попробую изобрести свой велосипед в этой области, к тому же это:
  1. бесценный опыт
  2. попробовать реализовать другой подход к решению задачи
  3. удовлетворить свое самолюбие
  4. ну и т.д.

Итак, мы приступаем…

Читать дальше
  • +4
  • 09 декабря 2015, 13:19
  • Helix
  • 1

Изучение STM32. Уроки по программированию STM32F4 Discovery.

На просторах РУНЕТа можно много найти инфы по изучению STM32, оформленные в виде статей, уроков, видео уроков. Подавляющее большинство материала на эту тему написано на SPL или чистом CMSIS. Но компания ST довольно упорно продвигает в массы библиотеку HAL и его генератор STM32CubeMX. Данная библиотека уже многим пришлась по вкусу. Так как я программист гуру не от бога, то при переходе от 8-ми битных мк на STM32 использование данной библиотеки показалось мне довольно правильным решением.

Читать дальше
  • +1
  • 05 декабря 2015, 09:23
  • Helix