Imax9
НОВОСТИ   ПУБЛИКАЦИИ   FILES   ИНФОРМАЦИЯ

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 */
uint32_t count;
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, который переиначит все по своему.

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

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

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

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


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

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

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