Главная страница
Навигация по странице:

  • Мигание светодиодом с помощью кнопки.

  • Мигание светодиодами с помощью разных кнопок.

  • Включение и выключение светодиода с помощью ПК по

  • Управление яркостью свечения светодиода с помощью программной реализации широтно-импульсной модуляции

  • Отчет по лабораторной работе. Программа реализует включения встроенного на отладочной плате светодиода по нажатии и удержании кнопки


    Скачать 254.96 Kb.
    НазваниеПрограмма реализует включения встроенного на отладочной плате светодиода по нажатии и удержании кнопки
    АнкорОтчет по лабораторной работе
    Дата21.10.2021
    Размер254.96 Kb.
    Формат файлаdocx
    Имя файлаOtchyot_po_laboratornym_rabotam_Anokhin_V_R.docx
    ТипПрограмма
    #252856


    ОТЧЁТ

    По дисциплине:

    Микроконтроллеры в кибернитических системах

    Подготовил:

    Студент группы 91-УТ

    Кочергин Максим Юрьевич

    Мигание светодиодом с помощью кнопки.

    Программа реализует включения встроенного на отладочной плате светодиода по нажатии и удержании кнопки.

    Т.к на отладочной плате кнопка SW1 подключена к порту C, он будет инициализироваться, как порт на вход и будет считывать сигнал нажата кнопка, или нет.

    #include "MDR32Fx.h"

    #include "core_cm3.h"

    #include "MDR32F9Qx_config.h"

    #include "system_MDR32F9Qx.h"

    #include "MDR32F9Qx_rst_clk.h"

    #include "MDR32F9Qx_port.h"

    #define LED1 PORT_Pin_0 //определить нулевой вывод как LED1 static PORT_InitTypeDef PortInit; //объявление структуры

    int main(){

    RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTC, ENABLE);//включить тактирование порта С

    RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTFB, ENABLE); );//включить тактирование порта B

    //Инициализация порта С на вход

    PortInit.PORT_OE = PORT_OE_IN; // направление передачи данных = вход

    PortInit.PORT_FUNC = PORT_FUNC_PORT; // режим работы вывода порта = Порт

    PortInit.PORT_MODE = PORT_MODE_DIGITAL; // режим работы выводе = цифровой

    PortInit.PORT_SPEED = PORT_SPEED_SLOW; // скорость фронта вывода

    = медленный

    PortInit.PORT_Pin = (PORT_Pin_2); // выбор вывода 2 для инициализации

    PORT_Init(MDR_PORTC, &PortInit); //инициализация порта С заданными параметрами

    //Инициализация порта B на выход

    PortInit.PORT_OE = PORT_OE_OUT; // направление передачи данных = Выход

    PortInit.PORT_FUNC = PORT_FUNC_PORT; // режим работы вывода порта

    = Порт

    PortInit.PORT_MODE = PORT_MODE_DIGITAL; // режим работы вывода = Цифровой

    PortInit.PORT_SPEED = PORT_SPEED_SLOW; // скорость фронта вывода = медленный

    PortInit.PORT_Pin = (PORT_Pin_all);// выбор всех выводов для инициализации

    PORT_Init(MDR_PORTB, &PortInit); //инициализация порта B заданными параметрами

    while(1){ //бесконечный цикл if (PORT_ReadInputDataBit(MDR_PORTC,PORT_Pin_2) == 0)

    //если кнопка не нажата…

    {

    PORT_SetBits(MDR_PORTB, LED1); // включить светодиод на выводе 0 порта B

    }

    else //иначе

    {

    PORT_ResetBits(MDR_PORTB, LED1); // выключить светодиод на выводе 0 порта B

    }

    }

    }

    Сначала в программе подключаются бибилиотеки,

    Затем определяется постоянная LED1 к которой привязывается значение Port_pin_0 ( порт под номером 0)

    Затем объявляется структура инициализации портов.

    Далее инициализируются сами порты Порт С на вход.

    Светодиоды на Плате подключены к порту B Поэтому следом мы инициализируем его, и определяем выходным.

    Сама программа реализуется с помощью бесконечного цикла образованного функцией while(1)

    Затем с помощью функции (PORT_ReadInputDataBit(MDR_PORTC,PORT_Pin_2) == 0)

    Мы считываем значение с кнопки SW1 расположенной на пине 2 порта C

    А затем с помощью функций

    PORT_SetBits(MDR_PORTB, LED1);

    Мы устанавливаем бит ( 1 ) в 0вой пин порта B (Зажигаем светодиод)

    PORT_ResetBits(MDR_PORTB, LED1);

    Мы очищаем бит (0) в 0вой пин порта B (перестаём подавать напряжение на светодиод

    Мигание светодиодами с помощью разных кнопок.

    При нажатии кнопок должны загораться лишь определённые светодиоды

    При нажатии кнопки SW1 будут загораться светодиоды VD5 и VD7

    При нажатии кнопки SW3 будут загораться светодиоды VD4 и VD6

    А при нажатии кнопки SW4 будут загораться светодиоды VD(4-7)

    #include "MDR32Fx.h"

    #include "core_cm3.h"

    #include "MDR32F9Qx_config.h"

    #include "system_MDR32F9Qx.h"

    #include "MDR32F9Qx_rst_clk.h"

    #include "MDR32F9Qx_port.h"

    #define LED1 PORT_Pin_0 //определить нулевой пин как LED1

    #define LED2 PORT_Pin_1 //определить первый пин как LED2

    #define LED3 PORT_Pin_2 //определить второй пин как LED3

    #define LED4 PORT_Pin_3 //определить третий пин как LED4

    static PORT_InitTypeDef PortInit; //объявление структуры

    int main(){

    RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTC, ENABLE);//включить тактирование порта С

    RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTC, ENABLE);//включить тактирование порта E

    RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTFB, ENABLE); );//включить тактирование порта B

    //Инициализация порта С на вход

    PortInit.PORT_OE = PORT_OE_IN; // направление передачи данных = вход

    PortInit.PORT_FUNC = PORT_FUNC_PORT; // режим работы вывода порта = Порт

    PortInit.PORT_MODE = PORT_MODE_DIGITAL; // режим работы выводе = цифровой

    PortInit.PORT_SPEED = PORT_SPEED_SLOW; // скорость фронта вывода

    = медленный

    PortInit.PORT_Pin = (PORT_Pin_2); // выбор вывода 2 для инициализации

    PORT_Init(MDR_PORTC, &PortInit); //инициализация порта С заданными параметрами

    PortInit.PORT_Pin = (PORT_Pin_1); // выбор вывода 1 для инициализации

    PORT_Init(MDR_PORTE, &PortInit); //инициализация порта E заданными параметрами

    PortInit.PORT_Pin = (PORT_Pin_3); // выбор вывода 3 для инициализации

    PORT_Init(MDR_PORTE, &PortInit); //инициализация порта E заданными параметрами

    //Инициализация порта B на выход

    PortInit.PORT_OE = PORT_OE_OUT; // направление передачи данных = Выход

    PortInit.PORT_FUNC = PORT_FUNC_PORT; // режим работы вывода порта

    = Порт

    PortInit.PORT_MODE = PORT_MODE_DIGITAL; // режим работы вывода = Цифровой

    PortInit.PORT_SPEED = PORT_SPEED_SLOW; // скорость фронта вывода = медленный

    PortInit.PORT_Pin = (PORT_Pin_all);// выбор всех выводов для инициализации

    PORT_Init(MDR_PORTB, &PortInit); //инициализация порта B заданными параметрами

    while(1){ //бесконечный цикл if (PORT_ReadInputDataBit(MDR_PORTC,PORT_Pin_2) == 0)

    //если кнопка не нажата…

    {

    PORT_SetBits(MDR_PORTB, LED1);

    PORT_SetBits(MDR_PORTB, LED3);

    }

    else //иначе

    {

    PORT_ResetBits(MDR_PORTB, port_pin_all); // выключить все светодиоды

    }

    if (PORT_ReadInputDataBit(MDR_PORTE,PORT_Pin_1) == 0)

    {

    PORT_SetBits(MDR_PORTB, LED2);

    PORT_SetBits(MDR_PORTB, LED4);

    }

    else

    {

    PORT_ResetBits(MDR_PORTB, PORT_Pin_all);

    }

    if (PORT_ReadInputDataBit(MDR_PORTE,PORT_Pin_3) == 0)

    {

    PORT_SetBits(MDR_PORTB, PORT_Pin_all);

    }

    else

    {

    PORT_ResetBits(MDR_PORTB, port_pin_all);

    }

    }

    }

    В данной программе дополнительно подключается порт E т.к к нему на плате подключены кнопки SW3 и SW4. Кнопку SW2 использовать нельзя. Она подключена к порту b и по условию он инициализируются как порт на выход т.к к нему подключены светодиоды

    Светодиоды, мигающие раз в секунду


    К выводам 0 и 1 порта B подключены светодиоды(VD2 и VD3), которые должны переключаться раз в секунду. Это можно сделать с помощью прерываний при переполнении системного таймера SysTick.

    #include "MDR32Fx.h"

    #include "core_cm3.h"

    #include "MDR32F9Qx_config.h"

    #include "system_MDR32F9Qx.h"

    #include "MDR32F9Qx_rst_clk.h"

    #include "MDR32F9Qx_port.h"

    static PORT_InitTypeDef PortInit;//объявление структуры PortInit volatile uint32_t delay_dec = 0;// объявление переменной delay_dec

    //Обработчик прерывания системного таймера void SysTick_Handler (void)

    {

    if (delay_dec !=0) delay_dec--;//вычитать из delay_dec, пока не станет равен 0

    }

    //функцияв ременной задержки void delay_ms (uint32_t delay_ms)

    { delay_dec = delay_ms;//присвоить delay_dec значение delay_ms while (delay_dec) {}; // выполнять функцию пока delay_dec не станет равным 0

    } int main(){

    RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTB, ENABLE); );//включить тактирование порта B

    //Инициализация порта F на выход

    PortInit.PORT_OE = PORT_OE_OUT; // направление передачи данных = Выход

    PortInit.PORT_FUNC = PORT_FUNC_PORT; // режим работы вывода порта = Порт

    PortInit.PORT_MODE = PORT_MODE_DIGITAL; // режим работы вывода= цифровой

    PortInit.PORT_SPEED = PORT_SPEED_SLOW; // скорость фронта вывода = медленная

    PortInit.PORT_Pin = (PORT_Pin_All);// выбор вывода для инициализации

    PORT_Init(MDR_PORTB, &PortInit); //инициализация порта

    B заданными параметрами

    //Инициализация системного таймера

    SysTick->LOAD |= (8000000/1000)-1; //значение задержки прерывания при тактовой частоте 8 МГц = 1мс

    SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Pos; //источник тактирования HCLK

    SysTick->CTRL |= SysTick_CTRL_COUNTFLAG_Pos;// при досчитывании до нуля таймер генерирует прерывание

    SysTick->CTRL |= SysTick_CTRL_ENABLE_Pos;//включить работу таймера

    while(1){

    delay_ms(1000); //задержка 1 с PORT_SetBits(MDR_PORTB, PORT_Pin_All); // включить светодиоды

    delay_ms(1000);//задержка 1 с

    PORT_ResetBits(MDR_PORTB, PORT_Pin_All); // выключить светодиоды

    }

    }

    Передача символа на ПК каждые 5 секунд через интерфейс RS-232


    Вывод 1 порта F назначен в качестве линии передачи TXD приемопередатчика UART1, а вывод 0 того же порта – в качестве линии приема RXD. Для преобразования уровней последовательных сигналов, используемых микроконтроллером к уровням используемых интерфейсом RS-232 на демонстрационно-отладочной плате 1986EvBrd используется микросхема 5559ИН4.

    При старте микроконтроллер начинает отсылать по последовательному интерфейсу на вход приемопередатчика UART1 цифровое значение переменной I каждые 5 секунды. Значение переменной i после каждой отправки увеличивается на 1.

    #include "MDR32F9Qx_config.h"

    #include "MDR32Fx.h"

    #include "MDR32F9Qx_uart.h"

    #include "MDR32F9Qx_port.h"

    #include "MDR32F9Qx_rst_clk.h"

    static PORT_InitTypeDef PortInit;//объявление структуры PortInit static UART_InitTypeDef UART_InitStructure;//объявление структуры UART_InitStructure volatile uint32_tdelay_dec = 0;// объявление переменной delay_dec

    //Обработчик прерывания системного таймера

    void SysTick_Handler (void)

    {

    if (delay_dec !=0)

    delay_dec--;

    }

    //функция временной задержки

    void delay_ms (uint32_tdelay_ms)

    {

    delay_dec = delay_ms; while (delay_dec) {};

    }

    int main (void)

    {

    uint8_t i = 0;//объявление переменной счетчика, хранящей передаваемое по UARTзначение

    //Инициализация системного таймера для функции задержки

    SysTick->LOAD |= (8000000/1000)-1;

    SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Pos;

    SysTick->CTRL |= SysTick_CTRL_COUNTFLAG_Pos;

    SysTick->CTRL |= SysTick_CTRL_ENABLE_Pos;

    RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTB,ENABLE); );//включить тактирование порта F

    //Инициализация порта F для функции UART

    PortInit.PORT_PULL_UP = PORT_PULL_UP_OFF;//подтяжка в питание выключена

    PortInit.PORT_PULL_DOWN = PORT_PULL_DOWN_OFF;//подтяжка в ноль выключена

    PortInit.PORT_PD_SHM = PORT_PD_SHM_OFF;//режим триггера Шмитта выключен

    PortInit.PORT_PD = PORT_PD_DRIVER;//режим управляемого драйвера

    PortInit.PORT_GFEN = PORT_GFEN_OFF;//входной фильтр выключен

    PortInit.PORT_FUNC = PORT_FUNC_ALTER;//альтернативная функция порта

    PortInit.PORT_SPEED = PORT_SPEED_MAXFAST;//скорость фронта вывода = быстрая

    PortInit.PORT_MODE = PORT_MODE_DIGITAL; //режим работы вывода = цифровой

    //Инициализация вывода 1 как UART_TX

    PortInit.PORT_Pin = PORT_Pin_1;

    PORT_Init(MDR_PORTF, &PortInit);

    //Инициализация вывода 0 как UART_RX

    PortInit.PORT_OE = PORT_OE_IN;

    PortInit.PORT_Pin = PORT_Pin_0;

    PORT_Init(MDR_PORTF, &PortInit);

    RST_CLK_CPU_PLLconfig

    (RST_CLK_CPU_PLLsrcHSIdiv2,0);//конфигурация источника тактирования HSI делением частоты на 2 и без умножения

    RST_CLK_PCLKcmd(RST_CLK_PCLK_UART1, ENABLE); );//включить тактирование UART1

    UART_BRGInit(MDR_UART1, UART_HCLKdiv1);//делитель тактовой частоты UART = 1

    //КонфигурацияUART

    UART_InitStructure.UART_BaudRate = 115000; //скорость передачи данных 15000 бод/сек

    UART_InitStructure.UART_WordLength = UART_WordLength8b;//длина слова в посылке = 8бит

    UART_InitStructure.UART_StopBits = UART_StopBits1;//один стоповый бит

    UART_InitStructure.UART_Parity = UART_Parity_No;//без проверки четности

    UART_InitStructure.UART_FIFOMode = UART_FIFO_ON;//включить работу буфера FIFO приемника и передачи

    UART_InitStructure.UART_HardwareFlowControl =

    UART_HardwareFlowControl_RXE | UART_HardwareFlowControl_TXE;//Разрешить прием, разрешить передачу данных

    //ИнициализацияUART1 с заданными параметрами

    UART_Init (MDR_UART1,&UART_InitStructure); UART_Cmd(MDR_UART1,ENABLE); //включить сконфигурированный UART

    while (1) //бесконечный цикл

    {

    UART_SendData (MDR_UART1, i++); //Послать значение счетчика по UART1, и прибавить к нему 1 delay_ms(5000);//подождать 5 секунд

    }

    }

    Приём Сигналов на компьютер осуществляется с помощью программы terminal. Для этого в ней требуется точно указать конфигурацию порта, к которому подключается микроконтроллер.

    Должны совпадать скорость передачи данных, количество битов в “слове” количество стоповых битов, функция проверки четности и т.д.

    Включение и выключение светодиода с помощью ПК по интерфейсу RS-232

    Вывод 1 порта F назначен в качестве линии передачи TXD приемопередатчика UART1, а вывод 0 того же порта – в качестве линии приема RXD. К выводам 0 и 1 порта B подключены светодиоды VD5 и VD4.

    При получении определенной команды от ПК по интерфейсу RS-232 происходит включение или выключение светодиодов. Код команды и ее описание представлены в таблице 4.

    Прием команды микроконтроллером от ПК по интерфейсу RS-232 реализован на основе сигнала прерывания .
    Таблица4 – Описание команд управления светодиодами

    Код команды

    Описание

    0x0A

    Включить светодиод VD2

    0x1A

    Выключить светодиод VD2

    0x0B

    Включить светодиод VD3

    0x1B

    Выключить светодиод VD3

    0xAA

    Включить светодиоды VD2 и VD3

    0x11

    Выключить светодиоды VD2 и VD3

    #include "MDR32F9Qx_config.h"

    #include "MDR32Fx.h"

    #include "MDR32F9Qx_uart.h"

    #include "MDR32F9Qx_port.h"

    #include "MDR32F9Qx_rst_clk.h"

    #include "core_cm3.h"

    #include "system_MDR32F9Qx.h

    static PORT_InitTypeDef PortInit;//объявление структуры PortInit static UART_InitTypeDef UART_InitStructure;//объявление структуры UART_InitStructure

    uint8_t Recieve_buff[256]; //объявление массива Recieve_buff, выполняющего роль буфера для приема

    uint8_t Recieve_Wr = 0,Recieve_Rd = 0,Recieve_Cnt = 0; //Recieve_Wr – счетчик при записи элемента в массив, //Recieve_Rd – счетчик при чтении элемента из массива, //Recieve_Cnt –общий счетчик обработанных элементов массива.

    // Обработчик прерывания UART

    void UART1_IRQHandler (void)

    {

    if(UART_GetITStatus(MDR_UART1, UART_IT_RX == 1 ))//если

    сигнал прерывания от приема нового пакета

    {

    UART_ClearITPendingBit(MDR_UART1, UART_IT_RX);

    //сбросить флаг прерывания

    Recieve_buff[Recieve_Wr] =

    UART_ReceiveData(MDR_UART1); //записать полученные данные в массив Recieve_buff

    Recieve_Wr++; //увеличитьRecieve_Wr

    Recieve_Cnt++; //увеличить Recieve_Cnt

    }

    }

    //Функция инициализации светодиодов

    void init_leds(void)

    {

    RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTB, ENABLE);

    PortInit.PORT_Pin = PORT_Pin_0|PORT_Pin_1;

    PortInit.PORT_OE = PORT_OE_OUT;

    PortInit.PORT_FUNC = PORT_FUNC_PORT;

    PortInit.PORT_MODE = PORT_MODE_DIGITAL;

    PortInit.PORT_SPEED = PORT_SPEED_FAST;

    PORT_Init(MDR_PORTB, &PortInit);

    }

    //Функция инициализации UART

    void init_UART(void)

    {

    RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTF,ENABLE);

    PortInit.PORT_PULL_UP = PORT_PULL_UP_OFF;

    PortInit.PORT_PULL_DOWN = PORT_PULL_DOWN_OFF;

    PortInit.PORT_PD_SHM = PORT_PD_SHM_OFF;

    PortInit.PORT_PD = PORT_PD_DRIVER;

    PortInit.PORT_GFEN = PORT_GFEN_OFF;

    PortInit.PORT_FUNC = PORT_FUNC_ALTER;

    PortInit.PORT_SPEED = PORT_SPEED_MAXFAST;

    PortInit.PORT_MODE = PORT_MODE_DIGITAL;

    PortInit.PORT_Pin = PORT_Pin_1;

    PORT_Init(MDR_PORTF, &PortInit);

    PortInit.PORT_Pin = PORT_Pin_0;

    PORT_Init(MDR_PORTF, &PortInit);

    RST_CLK_CPU_PLLconfig (RST_CLK_CPU_PLLsrcHSIdiv2,0);

    RST_CLK_PCLKcmd(RST_CLK_PCLK_UART1, ENABLE);

    UART_BRGInit(MDR_UART1, UART_HCLKdiv1);

    UART_InitStructure.UART_BaudRate = 115000;

    UART_InitStructure.UART_WordLength = UART_WordLength8b;

    UART_InitStructure.UART_StopBits = UART_StopBits1;

    UART_InitStructure.UART_Parity = UART_Parity_No;

    UART_InitStructure.UART_FIFOMode = UART_FIFO_OFF;

    UART_InitStructure.UART_HardwareFlowControl =

    UART_HardwareFlowControl_RXE | UART_HardwareFlowControl_TXE;

    UART_Init (MDR_UART1,&UART_InitStructure);

    UART_Cmd(MDR_UART1,ENABLE);

    NVIC_EnableIRQ(UART1_IRQn);//включить прерывания UART UART_ITConfig(MDR_UART1,UART_IT_RX, ENABLE);//включить прерывания по приходу нового пакета вUART

    }

    int main (void)

    { init_leds(); //инициализация светодиодов

    init_UART();// инициализацияUART

    while (1) //бесконечный цикл

    { if(Recieve_Cnt> 0) //если общий счетчик больше 0, т.е. в массиве Recieve_buff есть необработанные данные, выполнить обработку в машине состояний switch-case в соответствии с таблицей 4.

    {

    switch(Recieve_buff[Recieve_Rd]){ case 0x0A : PORT_SetBits(MDR_PORTB, PORT_Pin_0); break; case 0x1A : PORT_ResetBits(MDR_PORTB, PORT_Pin_0); break; case 0x0B : PORT_SetBits(MDR_PORTB, PORT_Pin_1); break; case 0x1B : PORT_ResetBits(MDR_PORTB, PORT_Pin_1); break; case 0xAA : PORT_SetBits(MDR_PORTB, PORT_Pin_0|PORT_Pin_1); break; case 0x11 : PORT_ResetBits(MDR_PORTB,PORT_Pin_0|PORT_Pin_1); break;

    default : break;

    }

    Recieve_Rd++; //увеличить Recieve_Rd

    Recieve_Cnt--;// уменьшить Recieve_Cnt

    }

    }

    }

    Управление яркостью свечения светодиода с помощью

    программной реализации широтно-импульсной модуляции


    Широтно-Импульсная Модуляция (ШИМ) – управление средней мощностью нагрузки с помощью серии высокочастотных импульсов. Регулируется усреднённая мощность изменением длительности импульсов и пауз между ними. Чем длиннее импульсы и короче паузы между ними, тем средняя мощность в нагрузке выше. ШИМ – простой случай цифро-аналогового преобразования – плавного управления напряжением или мощностью цифровыми схемами, имеющими только два состояния.

    ШИМ представляет собой импульсный сигнал постоянной частоты и переменной скважности (отношение длительности импульса к периоду его следования). С помощью задания скважности можно менять среднее напряжение на выходе ШИМ. Таким способом, меняя выходную мощность, можно управлять яркостью светодиода.

    К выводу 0 порта B подключен светодиод VD5. К выводу 2 порта C подключена кнопка SW1. С помощью метода широтно-импульсной модуляции будем управлять яркостью светодиода. Кнопка SW1 задает уровень скважности. ШИМ генерируется на основе 8 разрядного счетчика заданного переменной PWM_Counter.



    #include "MDR32F9Qx_config.h"

    #include "MDR32Fx.h"

    #include "MDR32F9Qx_rst_clk.h"

    #include "MDR32F9Qx_port.h"

    #define LED1 PORT_Pin_0 //ОпределитьPORT_Pin_0 как LED1

    #define Button_1 PORT_Pin_2

    static PORT_InitTypeDefPortInit;

    //Функция инициализации порта B на выход

    void init_leds()

    {

    RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTB, ENABLE);

    PortInit.PORT_Pin = (LED1);

    PortInit.PORT_OE = PORT_OE_OUT;

    PortInit.PORT_FUNC = PORT_FUNC_PORT;

    PortInit.PORT_MODE = PORT_MODE_DIGITAL;

    PortInit.PORT_SPEED = PORT_SPEED_FAST;

    PORT_Init(MDR_PORTB,&PortInit); }

    //Функция инициализация порта С на вход

    void init_button()

    {

    RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTC, ENABLE);

    PortInit.PORT_Pin = (Button_1);

    PortInit.PORT_OE = PORT_OE_IN;

    PortInit.PORT_FUNC = PORT_FUNC_PORT;

    PortInit.PORT_MODE = PORT_MODE_DIGITAL;

    PortInit.PORT_SPEED = PORT_SPEED_FAST;

    PORT_Init(MDR_PORTC, &PortInit);

    }

    uint8_t PWM_Counter = 0; //объявление счетчика PWM_Counter uint8_t PWM_A = 0; //объявление переменной PWM_A (задает длительность импульса)

    uint8_t PWM_B = 40; //объявление переменной PWM_B (задает период импульса)

    static uint8_t btn_old_state = 0; //переменная, хранящая предыдущее состояние кнопки

    static uint8_t btn_state; //переменная, хранящая текущее состояние кнопки

    int main(){

    init_leds(); //инициализация светодиода init_button();////инициализация кнопки while(1){ //бесконечный цикл

    //Увеличение переменной PWM_A только в момент нажатия кнопки btn_state = PORT_ReadInputDataBit(MDR_PORTC, Button_1);

    //запомнить текущее состояние кнопки (нажата или нет) if(btn_old_state == 0 && btn_state == 1)//если кнопка была не нажата, а теперь нажата

    {

    PWM_A++;м // увеличитьPWM_A

    if(PWM_A >=PWM_B) // если досчитали до значенияPWM_B

    {

    PWM_A = 0; //сбросить в ноль

    }

    }

    btn_old_state = btn_state; // запомнить предыдущее состояние кнопки

    //Генерация ШИМ

    if(PWM_Counter>= PWM_B) //если счетчик досчитал до значения PWM_B

    {





    PWM_Counter = 0; //сбросить счетчик



    светодиод

    PORT_SetBits(MDR_PORTB, LED1);//включить

    } равен PWM_A

    else if (PWM_Counter == PWM_A){ //если счетчик



    PWM_Counter++; //увеличить счетчик



    PORT_ResetBits(MDR_PORTB, LED1);

    //выключить светодиод

    }else { //иначе

    PWM_Counter++; //увеличить счетчик

    }

    }

    }

    Управление яркостью свечения светодиода с помощью

    программной реализации широтно-импульсной модуляции


    По нажатии одной кнопки SW1 светодиод должен увеличивать свою яркость, а по нажатию кнопки SW3 светодиод должен уменьшать свою яркость.

    #include "MDR32F9Qx_config.h"

    #include "MDR32Fx.h"

    #include "MDR32F9Qx_rst_clk.h"

    #include "MDR32F9Qx_port.h"

    #define LED1 PORT_Pin_0 //ОпределитьPORT_Pin_0 как LED1

    #define Button_1 PORT_Pin_2

    #define Button_1 PORT_Pin_1

    static PORT_InitTypeDefPortInit;

    //Функция инициализации порта B на выход

    void init_leds()

    {

    RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTB, ENABLE);

    PortInit.PORT_Pin = (LED1);

    PortInit.PORT_OE = PORT_OE_OUT;

    PortInit.PORT_FUNC = PORT_FUNC_PORT;

    PortInit.PORT_MODE = PORT_MODE_DIGITAL;

    PortInit.PORT_SPEED = PORT_SPEED_FAST;

    PORT_Init(MDR_PORTB,&PortInit); }

    //Функция инициализация порта С на вход

    void init_buttons()

    {

    RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTE, ENABLE);

    RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTC, ENABLE);

    PortInit.PORT_Pin = (Button_1);

    PortInit.PORT_OE = PORT_OE_IN;

    PortInit.PORT_FUNC = PORT_FUNC_PORT;

    PortInit.PORT_MODE = PORT_MODE_DIGITAL;

    PortInit.PORT_SPEED = PORT_SPEED_FAST;

    PORT_Init(MDR_PORTC, &PortInit);

    PortInit.PORT_Pin = (Button_2);

    PORT_Init(MDR_PORTE, &PortInit);

    }

    uint8_t PWM_Counter = 0; //объявление счетчика PWM_Counter uint8_t PWM_A = 0; //объявление переменной PWM_A (задает длительность импульса)

    uint8_t PWM_B = 40; //объявление переменной PWM_B (задает период импульса)

    uint8_t PWM_С = 0; //объявление переменной PWM_С ( нужна для отсчёта минимума PWM_A

    static uint8_t btn_old_state = 0; //переменная, хранящая предыдущее состояние кнопки1

    static uint8_t btn_state; //переменная, хранящая текущее состояние кнопки1

    static uint8_t btn_old_state2 = 0; //переменная, хранящая предыдущее состояние кнопки2

    static uint8_t btn_state2; //переменная, хранящая текущее состояние кнопки2

    int main(){

    init_leds(); //инициализация светодиода init_button();////инициализация кнопки while(1){ //бесконечный цикл

    //Увеличение переменной PWM_A только в момент нажатия кнопки btn_state = PORT_ReadInputDataBit(MDR_PORTC, Button_1);

    btn_state2 = PORT_ReadInputDataBit(MDR_PORTE, Button_2);

    //запомнить текущее состояние кнопки (нажата или нет) if(btn_old_state == 0 && btn_state == 1)//если кнопка была не нажата, а теперь нажата

    {

    PWM_A++;м // увеличитьPWM_A

    if(PWM_A >=PWM_B) // если досчитали до значенияPWM_B

    {

    PWM_A = 0; //сбросить в ноль

    }

    }

    if(btn_old_state2 == 0 && btn_state2 == 1

    {

    PWM_A--;м

    if(PWM_A <=PWM_C) // если досчитали до значенияPWM_C

    {

    PWM_A = 39; // увеличить до макимума

    }

    }

    btn_old_state = btn_state; // запомнить предыдущее состояние кнопки

    btn_old_state2 = btn_state2; // запомнить предыдущее состояние кнопки

    //Генерация ШИМ

    if(PWM_Counter>= PWM_B) //если счетчик досчитал до значения PWM_B

    {





    PWM_Counter = 0; //сбросить счетчик



    светодиод

    PORT_SetBits(MDR_PORTB, LED1);//включить

    } равен PWM_A

    else if (PWM_Counter == PWM_A){ //если счетчик



    PWM_Counter++; //увеличить счетчик



    PORT_ResetBits(MDR_PORTB, LED1);

    //выключить светодиод

    }else { //иначе

    PWM_Counter++; //увеличить счетчик

    }

    }

    }

    Аппаратная реализация широтно-импульсной модуляции


    В общем случае рекомендуется реализовывать аппаратный ШИМ микроконтроллера на основе прерываний от счетчика таймера. Таймер микроконтроллера работает независимо от центрального процессора и в таком случае не требует дополнительных вычислительных ресурсов.

    На выводах 1, 2, 3, 4, 5 порта А располагается каналы 1, 2 и 3 таймера1, которые могут быть сконфигурированы в режиме ШИМ. Зафиксировать сигнал ШИМ с разной скважностью можно на ножках 7, 8, 9, 10,12 разъема Х25 с помощью цифрового осциллографа.

    #include "MDR32F9Qx_config.h"

    #include "MDR32Fx.h"

    #include "MDR32F9Qx_timer.h"

    #include "MDR32F9Qx_rst_clk.h"

    #include "MDR32F9Qx_port.h"

    TIMER_CntInitTypeDef sTIM_CntInit;

    TIMER_ChnInitTypeDef sTIM_ChnInit;

    TIMER_ChnOutInitTypeDef sTIM_ChnOutInit;

    PORT_InitTypeDef PORT_InitStructure;

    uint16_t CCR1_Val = 500;

    uint16_t CCR2_Val = 1000;

    uint16_t CCR3_Val = 2000;

    int main(void)

    {

    RST_CLK_PCLKcmd((RST_CLK_PCLK_RST_CLK),ENABLE);

    RST_CLK_PCLKcmd((RST_CLK_PCLK_TIMER1), ENABLE);

    RST_CLK_PCLKcmd((RST_CLK_PCLK_PORTA), ENABLE);

    PORT_InitStructure.PORT_Pin = (PORT_Pin_1 | PORT_Pin_2 |

    PORT_Pin_3 | PORT_Pin_4 | PORT_Pin_5);

    PORT_InitStructure.PORT_OE = PORT_OE_OUT;

    PORT_InitStructure.PORT_FUNC = PORT_FUNC_ALTER;

    PORT_InitStructure.PORT_MODE = PORT_MODE_DIGITAL;

    PORT_InitStructure.PORT_SPEED = PORT_SPEED_FAST;

    PORT_Init(MDR_PORTA, &PORT_InitStructure);

    /*

    TIM1CLK = 8 MHz, Prescaler = 0, TIM1 counter clock = 8 MHz

    TIM1 = TIM1CLK/(TIM1_Period + 1) = 1.95 KHz

    TIM1 = TIM1->CCR1 / (TIM1_Period +1) = 12.5%

    TIM1 = TIM1->CCR2 / (TIM1_Period +1) = 25%

    TIM1 = TIM1->CCR3 / (TIM1_Period + 1) = 50%

    */

    sTIM_CntInit.TIMER_Prescaler = 0x0;

    sTIM_CntInit.TIMER_Period = 4000;

    sTIM_CntInit.TIMER_CounterMode = TIMER_CntMode_ClkFixedDir;

    sTIM_CntInit.TIMER_CounterDirection = TIMER_CntDir_Up;

    sTIM_CntInit.TIMER_EventSource = TIMER_EvSrc_None;

    sTIM_CntInit.TIMER_FilterSampling = TIMER_FDTS_TIMER_CLK_div_1;

    sTIM_CntInit.TIMER_ARR_UpdateMode =TIMER_ARR_Update_Immediately;

    sTIM_CntInit.TIMER_ETR_FilterConf =TIMER_Filter_1FF_at_TIMER_CLK;

    sTIM_CntInit.TIMER_ETR_Prescaler = TIMER_ETR_Prescaler_None;

    sTIM_CntInit.TIMER_ETR_Polarity = TIMER_ETRPolarity_NonInverted;

    sTIM_CntInit.TIMER_BRK_Polarity = TIMER_BRKPolarity_NonInverted;

    TIMER_CntInit (MDR_TIMER1,&sTIM_CntInit);

    sTIM_ChnInit.TIMER_CH_Mode = TIMER_CH_MODE_PWM;

    sTIM_ChnInit.TIMER_CH_REF_Format = TIMER_CH_REF_Format6;

    sTIM_ChnInit.TIMER_CH_Number = TIMER_CHANNEL1;

    TIMER_ChnInit(MDR_TIMER1, &sTIM_ChnInit);

    sTIM_ChnInit.TIMER_CH_Number = TIMER_CHANNEL2;

    TIMER_ChnInit(MDR_TIMER1, &sTIM_ChnInit);

    sTIM_ChnInit.TIMER_CH_Number = TIMER_CHANNEL3;

    TIMER_ChnInit(MDR_TIMER1, &sTIM_ChnInit);

    TIMER_SetChnCompare(MDR_TIMER1, TIMER_CHANNEL1, CCR1_Val);

    TIMER_SetChnCompare(MDR_TIMER1, TIMER_CHANNEL2, CCR2_Val);

    TIMER_SetChnCompare(MDR_TIMER1, TIMER_CHANNEL3, CCR3_Val);

    sTIM_ChnOutInit.TIMER_CH_DirOut_Polarity = TIMER_CHOPolarity_NonInverted;

    sTIM_ChnOutInit.TIMER_CH_DirOut_Source = TIMER_CH_OutSrc_REF;

    sTIM_ChnOutInit.TIMER_CH_DirOut_Mode = TIMER_CH_OutMode_Output;

    sTIM_ChnOutInit.TIMER_CH_NegOut_Polarity = TIMER_CHOPolarity_NonInverted;

    sTIM_ChnOutInit.TIMER_CH_NegOut_Source = TIMER_CH_OutSrc_REF;

    sTIM_ChnOutInit.TIMER_CH_NegOut_Mode = TIMER_CH_OutMode_Output;

    sTIM_ChnOutInit.TIMER_CH_Number = TIMER_CHANNEL1;

    TIMER_ChnOutInit(MDR_TIMER1, &sTIM_ChnOutInit);

    sTIM_ChnOutInit.TIMER_CH_Number = TIMER_CHANNEL2;

    TIMER_ChnOutInit(MDR_TIMER1, &sTIM_ChnOutInit);

    sTIM_ChnOutInit.TIMER_CH_Number = TIMER_CHANNEL3;

    TIMER_ChnOutInit(MDR_TIMER1, &sTIM_ChnOutInit);

    TIMER_BRGInit(MDR_TIMER1,TIMER_HCLKdiv1);

    TIMER_Cmd(MDR_TIMER1,ENABLE);

    while(1)

    {

    }

    }


    написать администратору сайта