Blog the XELFAER

Заметки *NIX

Управление устройством на микроконтроллере с ПК по UART —

Всегда хотелось попробовать управлять своим устройством на микроконтроллере с компьютера. Самое простое это управление по UART, с помощью которого мы и будем пробовать это сделать.

Возьмем для пробы самую простую схему — включение/выключение светодиодов. Делать будем на МК ATMEGA8. Схема устройства представлена ниже:
atmega8_led_uart
Детали:
R1 — 10 кОм;
R2, R3 — 300 Ом;
С1 — 100 нФ;
C2, C3 — 24 нФ;
Q1 — 12 Mhz;
LED1, LED2 — светодиоды любые маломощные.
Напряжение питания — стабилизированный источник 5V.

Также нам понадобится преобразователь USB-UART например как вот этот:
USB-UART

Данный преобразователь собран по статье автора DI HALT. Собрать его не составит особого труда, особенно после внимательного прочтения статьи, где все разжевано от и до.

Собрав схему приступим к расчету и написанию прошивки.
Для начала необходимо рассчитать скорости обмена по UART с учетом использования наших данных:

кварцевый резонатор = 12 Mhz;
скорость передачи = 9600;
количество бит данных = 8;
количество стоп-бит = 1;
контроль четности = запрещен.

За настройку скорости отвечает регистр UBRR.
Рассчитать его можно по формуле:

UBRR = ( F /( B * 16 ) ) — 1
где: F — тактовая частота МК (частота кварца в Hz); B — требуемая скорость (бит/с).

подставив наши данные получим:
UBRR = (12000000/(9600*16))-1 = (12000000/153600)-1 = 78,125 — 1 = 77,125 = ~77

Теперь стоит оговорится что мы хотим реализовать в прошивке:
— включение/выключение светодиодов;
— отправка/прием данных по UART.

Собственно код прошивки:

#include <avr/io.h>
#include <util/delay.h>

//*** Инициализация UART ***//
void uart_init(void)
    {
        //скорость обмена данными
        UBRRH = 0;  //старший байт
        UBRRL = 77; //младший байт
        //8 бит данных, 1 стоп бит, без контроля четности
        UCSRC = ( 1 << URSEL ) | ( 1 << UCSZ1 ) | ( 1 << UCSZ0 );
        //разрешить прием и передачу данных
        UCSRB = ( 1 << TXEN ) | ( 1 <<RXEN );
    }

//*** Прием данных по UART ***//
unsigned char uart_receive(void)
    {
        while ( ! ( UCSRA & ( 1 << RXC )));
        return UDR;
    }

//*** Передача данных по UART ***//
void uart_transmit(unsigned char data)
    {
        while ( ! ( UCSRA & ( 1 << UDRE )));
        UDR = data;
    }

//*** Главная программа ***//
int main(void)
{
    DDRD = 0x00;    //установим все порты DDRD как входы
    PORTD = 0x00;   //установим логический 0 на все порты DDRD

    DDRC = (1 << 5) | (1 << 4); //установим порты PC5 и PC4 регистра DDRC на выход
    PORTC &= ~(1 << 5) | ~(1 << 4); //установим сигнал низкого уровня (логическай 0) на выводы PC5 и PC4 регистра DDRC

    char data;
   
    uart_init();
   
    while(1)
        {
            data=uart_receive();
           
            if(data=='1')
            {
                PORTC |= 1 << 5;    //устанавливаем логическую 1 на порт PC5 регистра DDRC
            }
            if(data=='2')
            {
                PORTC &= ~(1 << 5); //устанавливаем логический 0 на порту PC5 регистра DDRC
            }

            if(data=='3')
            {
                PORTC |= 1 << 4;    //устанавливаем логическую 1 на порт PC4 регистра DDRC
            }
            if(data=='4')
            {
                PORTC &= ~(1 << 4); //устанавливаем логический 0 на порту PC4 регистра DDRC
            }
           
            uart_transmit(data);

        };
}

Инициализация UART, прием и передача данных сделаны отдельными функциями для удобства и упрощения читабельности кода.

В зависимости от получаемого значения по UART происходит включение/отключение соответствующего светодиода подключенного к указанному порту МК с последующей отправкой этого значения обратно.

Теперь собираем все это добро дабы получить долгожданную прошивку в hex:

avr-gcc -mmcu=atmega8 -I. -gdwarf-2 -DF_CPU=12000000UL -Os -o main.o main.c
avr-objcopy -O ihex main.o main.hex

Заливаем прошивку:

avrdude -c avr910 -p m8 -P /dev/ttyACM0 -U flash:w:main.hex

и выставляем fuse:
hfuse: 0xc9
lfuse: 0xff

avrdude -c avr910 -p m8 -P /dev/ttyACM0 -U hfuse:w:0xC9:m
avrdude -c avr910 -p m8 -P /dev/ttyACM0 -U lfuse:w:0xFF:m

Так как я делал на макетке которая была под рукой то у меня вышло так:

prototyping_board

Теперь можно приступить к написанию программы для ПК. Писать будем на Lazarus с использованием компонента 5dpo который нам позволит общаться с нашим будущим устройством.
Раскидываем компоненты на форму:

program_UART

Включение/отключение светодиодов будет происходить по нажатии на соответствующую кнопку. Поле Memo использовано для отображения статуса устройства и приходящих данных с устройства.
Вот собственно как выглядит окно программы с выводом данных:

program_UART_use

Теперь осталось собрать все до кучи и приступить к тесту. Конвертер USB-UART подключаем к выводам PD0(RXD) и PD1(TXD) микроконтроллера c учетом того, что RX конвертера подключаем к TX микроконтроллера и TX конвертера подключаем к RX микроконтроллера. Если используются разные источники питания устройства и конвертера необходимо соединить также вместе их GND.

И напоследок видео работы:

Скачать архив прошивки: firmware
Скачать архив исходника программы: uart_led

© 2014 — 2015, XELFAER. Все права защищены. Использование материалов блога разрешается только при указании активной ссылки на статью.

Print Friendly, PDF & Email

Рубрики: Linux | Microcontrollers | Radioelectronica



Добавить комментарий