Imax9
NEWS   ARTICLES   MINIMIG   FILES   ABOUT

STM32F407 Урок 02. Мигаем светодиодами при помощи ШИМ таймера.

Добрый день, уважаемые читатели, сегодня мы освоим работу с таймерами, с помощью ШИМ поморгаем светодиодами, изучим работу с DMA.

Запускаем CubeMX, хотите отредактируйте проект из прошлого урока, я же рекомендую создать новый, как говорят: "Повторенье - мать ученья (или заикикания)". Сперва выберем наш кристалл и обязательно включим DEBUG :

Настроим режим тактирования от внешних резонаторов HSE 8MHz и LSE 32768 Hz :

Во вкладке Clock Configuration определимся с рабочей частотой :

Светодиоды на этой плате подключены к выходам PA6, PA7, соответственно настраиваем таймер каналы 1 и 2 таймера TIM3 как ШИМ выходы :

Рекомендую сразу включить DMA для Channel 1 и 2, направление передачи из памяти, 16 бит, циклический режим, чтобы каждый раз не отлавливать окончание и снова запускать DMA. Потом скажу почему мы сделали это сначала :

Не забываем про делители Prescaler =12000, Counter Period=100, Pulse сделаем для одного 10, другого 90 :

При желании можете включить USB_OTG_FS, как это сделать вспомните из первого урока. Назовите типа ledtim3 обязательно выберете свою среду - Atollic и генерите проект. Если ошиблись и сперва выбрали не ту среду, обязательно перед генерацией сотрите то что создал Куб до этого, иначе огребете непонятные ошибки при компиляции из Atollic.

Не забывем размещать свой код между вставками /* USER CODE BEGIN xxx */ и * USER CODE END xxx */. Полюбуемся сперва горящими с разной яркостью светодиодами, запустим поочередно каналы таймера :

/* USER CODE BEGIN 2 */
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);
/* USER CODE END 2 */

Можете не перегенерируя проект в функции static void MX_TIM3_Init(void) поиграться с параметрами sConfigOC.Pulse=10;

Поменяйте в sConfigOC.OCMode параметр на TIM_OCMODE_PWM2;

А в sConfigOC.OCPolarity на TIM_OCPOLARITY_LOW;

Только не все скопом, а поочереди, иначе не поймете что за что отвечает.

Наигрались ? Идем дальше, напишем в бесконечном цикле свой цикл :

/* USER CODE BEGIN WHILE */
while (1)
{
for(uint16_t i = 0; i <= 100; i+=1)
{
TIM3->CCR1 = 100-i;
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, i);
HAL_Delay(5);
}
/* USER CODE END WHILE */

Как вы, наверное, догадались строка TIM3->CCR1 = 100-i; не что иное, как прямое обращение к регистру Pulse первого канала, а __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, i); - макрос HAL для изменения регистра второго канала. Компилируйте и любуйтесь как плавно гаснет один и разгарается другой светодиод.

Возможности STM позволяют без участия (почти) CPU управлять регистрами ШИМ через насторойки DMA. Удаляем наш код и перед бесконечным циклом напишем :

/* USER CODE BEGIN 2 */
uint16_t tim3ch1[200];
for(uint16_t i = 0; i < 100; i+=1)
{
tim3ch1[i]=i;
tim3ch1[i+100]=99-i;
}
HAL_TIM_PWM_Start_DMA(&htim3,TIM_CHANNEL_1,tim3ch1,200);
HAL_Delay(1500);
HAL_TIM_PWM_Start_DMA(&htim3,TIM_CHANNEL_2,tim3ch1,200);
/* USER CODE END 2 */

В бесконечном цикле вставьте задержку, чтоб процессор не молотил впустую :

/* USER CODE BEGIN WHILE */
while (1)
{
HAL_Delay(100);
/* USER CODE END WHILE */

У вас возникнет резонный вопрос для чего перед запуском второго канала 1,5 сек задержка. У меня резонный ответ - потому что без нее не работает ! Если включать другой таймер (соответственно и вывод с светодиодом) с DMA2, то работает. Некоторые другие каналы DMA1 запускаются сразу без задержки, некоторые с задержкой, закономерность я не понял, в manual тоже не нашел, может плохо искал.

Если у вас не работает DMA вообще даже и первый не запускается - проверьте порядок инициализации таймеров и DMA, должно быть так :

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_TIM3_Init(void);
/* USER CODE BEGIN PFP */

Иногда CubeMX меняет порядок сначала идет инициализация таймеров, потом DMA, если вы включили и настроили его самым последним. Помогает перестановка строк, но до следующей генерации проекта из CubeMX, который переиначит все по своему.

По таймерам рекомендую шикарные статьи по таймерам часть 1 , часть 2 на ресурсе stD. Лучше них только Reference manual на английском.

В следующем уроке мы напишем мини библиотеку для работы с графическим OLED дисплеем SSD1306, на который выведем текущее время и температуру кристала.

Адрес для контактов : imax9@narod.ru

Если вам понравились мои работы и вы желаете поддержать сайт - сделайте дотацию.


При копировании статьи – обязательна ссылка на авторство и источник. Без разрешения автора копирование запрещено.

© Максим Ильин 2020 г.

Яндекс.Метрика