SPL: работаем с UART

     Краткое описание: Один из самых распространенных интерфейсов среди разработчиков встраиваемых систем это: универсальный асинхронный приемопередатчик UART.

     Для работы с этим примером вам понадобится терминал последовательного порта: например Terminal 1.9b, его легко найти и скачать в интернете. На плате уже присутствует переходник USB->UART поэтому достаточно просто подключится по кабелю USB к компьютеру и в программе Terminal 1.9b найти свое устройство. 

     Задача: Требуется написать с использованием библиотеки StdPeriph код. Программа должна производить настойку аппаратного UART. Через переходник USB->UART подключиться к компьютеру и с помощью функции обмена данными отвечать на полученный из терминала знак '?' сообщением "UART WORKING!!!".

#include "stm32f30x.h"
#include "stm32f30x_rcc.h"
#include "stm32f30x_gpio.h"
#include "stm32f30x_usart.h"

#include "stm32f30x_syscfg.h"

GPIO_InitTypeDef gpio; //Объявляем переменную gpio типа GPIO_InitTypeDef
USART_InitTypeDef usart; //Объявляем переменную usart типа USART_InitTypeDef
NVIC_InitTypeDef nvic; //Объявляем переменную nvic типа NVIC_InitTypeDef

int i;
char* send_buff = "UART WORKING!!! "; //Строка которую хотим отправить по usart
char resive_buff; //Переменная для хранения приходящих значений от usart

void print(char* str) //Функция передачи данных по USART1
{
    for (i = 0; str[i]; i++) //Прокручиваем цикл отправки пока все байты данных не будут отправлены
    {
        while (!USART_GetFlagStatus(USART1, USART_FLAG_TC))
            ; //Проверяем флаг окончания передачи
        USART_SendData(USART1, str[i]); //Отправляем байт данных
    }

    USART_ITConfig(USART1, USART_IT_TXE, DISABLE); //Отключить прерывания по передаче
}

void initAll() //Функция инициализации

{

    RCC_HSICmd(ENABLE); //Включаем тактирование от внутреннего источника
    RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI); //Подаем тактовый сигнал на системную шину

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); //Включаем тактирование порта А
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE); //Включаем тактирование порта С
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //Включаем тактирование порта USART

    gpio.GPIO_Mode = GPIO_Mode_IN; //Выбираем режим работы пинов
    gpio.GPIO_Pin = GPIO_Pin_0; //Выбираем нужны пин
    GPIO_Init(GPIOC, &gpio); //Инициализируем структуру с настройками

    usart.USART_BaudRate = 9600; //Выбираем Бодрейт
    usart.USART_WordLength = USART_WordLength_8b; //Выбираем длину слова
    usart.USART_StopBits = USART_StopBits_1; //Выбираем стоп бит
    usart.USART_Parity = USART_Parity_No; //Выбираем четность
    usart.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //Аппаратное управление передачей данных
    usart.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //Разрешаем прием и передачу данных
    USART_Init(USART1, &usart); //Инициализируем структуру с настройками
    USART_Cmd(USART1, ENABLE); //Включаем USART

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_7); //(TX) Настраиваем ножку для работы в режиме альтернативной функции USART1!
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_7); //(RX) Настраиваем ножку для работы в режиме альтернативной функции USART1!

    gpio.GPIO_Mode = GPIO_Mode_AF; //Выбираем режим работы пинов
    gpio.GPIO_Pin = GPIO_Pin_9; //Выбираем нужны пин
    GPIO_Init(GPIOA, &gpio); //Инициализируем структуру с настройками

    gpio.GPIO_Mode = GPIO_Mode_AF; //Выбираем режим работы пинов
    gpio.GPIO_Pin = GPIO_Pin_10; //Выбираем нужны пин
    GPIO_Init(GPIOA, &gpio); //Инициализируем структуру с настройками

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //Конфигурируем приоритетную группу

    nvic.NVIC_IRQChannel = USART1_IRQn; // Назначает источник прерывания
    nvic.NVIC_IRQChannelPreemptionPriority = 1; // Выставляет приоритет прерывания
    nvic.NVIC_IRQChannelSubPriority = 1; // Выставляет уровень подчинённости
    nvic.NVIC_IRQChannelCmd = ENABLE; //Включаем приоритетный контроллер прерывания
    NVIC_Init(&nvic); //Инициализируем структуру с настройками

    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //Включение прерывания по приему
}

int main(void)
{

    __enable_irq(); //Разрешаем прерывания
    initAll(); //Вызываем функцию инициализации
    NVIC_EnableIRQ(USART1_IRQn); //Разрешаем прерывание по USART1

    while (1) {

        if (resive_buff == '?') //Отправляем данные если пришел символ ?

        {
            USART_ITConfig(USART1, USART_IT_TXE, ENABLE); //Включение прерывания по передаче
            resive_buff = 0; //Очищаем переменную resive_buff для записи новых значений.
        }
    }
}

void USART1_IRQHandler(void) //Функция обработчика прерываний
{
    if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //Если флаг говорящий о приеме данных не сброшен принимаем данные
    {
        USART_ClearFlag(USART1, USART_IT_RXNE); //Сбрасываем флаг говорящий о приеме данных
        resive_buff = USART_ReceiveData(USART1); //Принимаем значение по USART присваиваем его переменной resive_buff
    }

    if (USART_GetITStatus(USART1, USART_IT_TXE) != RESET) //Если флаг говорящий об опустошении регистра с данными для передачи не сброшен отправляем данные
    {
        USART_ClearFlag(USART1, USART_IT_TXE); //Сбрасываем флаг говорящий об опустошении регистра передачи данных
        print(send_buff); //Вызываем функцию отправки данных
    }
}

     Скомпилируйте программу нажав кнопку Build, прошейте микроконтроллер, нажмите RESET. Теперь можно через программу терминал Terminal 1.9b подключится к плате и отправить символ вопроса ?, на что приведенная выше программа ответит сообщением "UART WORKING!!!".

     ВНИМАНИЕ: Приведенный листинг кода не является единственной и оптимальной реализацией поставленной задачи. Пример опубликован с демонстрационной целью. Также автор во избежание переписывания чужих статей, пропускает теоретические основы необходимые для понимания примера, связывая это с тем что всю необходимую информацию можно найти в интернете.

Комментариев (0)

Написать комментарий

Имя *
E-mail
Введите комментарий *
Капча
13 + ? = 18