Последовательная передача по UART с pic16f877a на C

В данной статье мы рассмотрим организацию последовательной связи (UART) между микроконтроллером PIC и персональным компьютером. Код будем писать на языке С в программе MPLAB X IDE 5.35 на российской бесплатной ОС Linux Rosa Fresh R13 Plasma – как всё быстро и бесплатно установить читайте здесь: “микроник.рус/7259/”.

Схема соединения:
Будем использовать HW-597 (на микросхеме CH340) (USB-TTL модуль), драйверы на моей ОС для него уже были установлены по умолчанию.

Код на Си:

// CONFIG
 
#pragma config FOSC = HS       // Oscillator Selection bits (HS oscillator)
 
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
 
#pragma config PWRTE = OFF       // Power-up Timer Enable bit (PWRT enabled)
 
#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
 
#pragma config LVP = OFF        // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
 
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
 
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
 
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)
 
// End of configuration
 
#include <xc.h>
#define _XTAL_FREQ 20000000
#define Baud_rate 9600
//***Initializing UART module for PIC16F877A***//
 
void Initialize_UART(void)
 
{
    //****Setting I/O pins for UART****//
    TRISC6 = 0; // TX Pin set as output
    TRISC7 = 1; // RX Pin set as input
    //________I/O pins set __________//
 
    /**Initialize SPBRG register for required 
    baud rate and set BRGH for fast baud_rate**/
 
    SPBRG = ((_XTAL_FREQ/16)/Baud_rate) - 1;
    BRGH  = 1;  // для высоких скоростей передачи
 
    //_________End of baud_rate setting_________//
 
    //****задействуем асинхронный последовательный порт*******//
 
    SYNC  = 0;    // Asynchronous
    SPEN  = 1;    // Enable serial port pins
 
    //_____Asynchronous serial port enabled_______//
 
    //**Lets prepare for transmission & reception**//
    TXEN  = 1;    // enable transmission (разрешаем передачу)
    CREN  = 1;    // enable reception (разрешаем прием)
    //__UART module up and ready for transmission and reception__//
 
    //**выбираем 8-битный режим**//  
    TX9   = 0;    // 8-bit reception selected
    RX9   = 0;    // 8-bit reception mode selected
    //__8-bit mode selected__//     
}
 
//________UART module Initialized__________//
 
//**функция для передачи одного байта по UART**//
 
void UART_send_char(char bt)  
{
    while(!TXIF);  // придерживаем выполнение программы до тех пор пока буфер передачи не освободится
    TXREG = bt; //записываем в буфер передачи символ, который нужно передать
}
//_____________End of function________________//
 
 
//**функция для приема одного символа из UART**//
char UART_get_char()   
{
    if(OERR) // проверка на ошибку 
    {
        CREN = 0; //If error -> Reset 
        CREN = 1; //If error -> Reset 
    }
 
    while(!RCIF);  // придерживаем выполнение программы до тех пор пока буфер приема не освободится
 
    return RCREG; //принимаем значение из буфера приема и передаем его в основную программу
}
 
//_____________End of function________________//
 
 
//**функция для передачи строки символов**//
void UART_send_string(char* st_pt)
{
    while(*st_pt) //if there is a char
        UART_send_char(*st_pt++); //process it as a byte data
}
//___________End of function______________//
 
// **********START of Main Function**************//
void main(void)
{
    int get_value;
    TRISB = 0b00000000; //Instruct the MCU that the PORTB pins are used as Output.
    PORTB = 0b11000000; //для проверки оставим включёнными RB6 и RB7
    
    Initialize_UART();    // ?????????????? ?????? UART                    

    UART_send_string("UART Module Initialized and active");    // ?????????????? ?????????
    while(1) //??????????? ????
    {
      get_value = UART_get_char(); 
        if (get_value == '1') //???? ???????????? ??????? "1"
        {
            PORTB = 0b00010000; // включаем светодиод на RB4
            UART_send_string("RED LED -> ON"); //???????? ??????????? ?? ????????? 
            UART_send_char(10);//ASCII value 10 is used for carriage return (to print in new line)
        }

        if (get_value == '0') // ???? ???????????? ??????? "0"
        {
           PORTB = 0b00000000; // включаем светодиоды
           UART_send_string("RED -> OFF"); // ???????? ??????????? ?? ????????? 

           UART_send_char(10);//ASCII value 10 is used for carriage return (to print in new line)
        }
      
        if (get_value == '3') //???? ???????????? ??????? "1"
        {
            PORTB = 0b00100000; // включаем светодиод на RB5
            UART_send_string("RED LED -> ON"); //???????? ??????????? ?? ????????? 
            UART_send_char(10);//ASCII value 10 is used for carriage return (to print in new line)
        }

        if (get_value == '2') // ???? ???????????? ??????? "0"
        {
           PORTB = 0b00000000; // включаем светодиоды
           UART_send_string("RED -> OFF"); // ???????? ??????????? ?? ????????? 

           UART_send_char(10);//ASCII value 10 is used for carriage return (to print in new line)
        }

    }
}

// **********END of Main Function**************//

Скачать hex и С файлы:
– скачать в zip архиве
– скачать в tar.gz архиве

Прошивку микросхемы делал в IC-Prog – скачать её для Windows XP можно здесь в конце записи: “микроник.рус/5666/”

Примечание:

Включать и выключать светодиоды более правильно вот так:

int main(void)
{
 
     
     
    DDRD = 0x00;    //????????? ??? ????? DDRD ??? ?????
    PORTD = 0x00;   //????????? ?????????? 0 ?? ??? ????? DDRD
     
    DDRB = (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2) | (1 << 1) | (1 << 0); //????????? ????? PC5 ? PC4 ???????? DDRC ?? ?????
    PORTB &= ~(1 << 7) | ~(1 << 6) | ~(1 << 5) | ~(1 << 4) | ~(1 << 3) | ~(1 << 2) | ~(1 << 1) | ~(1 << 0); 
     
    DDRC = (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2) | (1 << 1) | (1 << 0); //????????? ????? PC5 ? PC4 ???????? DDRC ?? ?????
    PORTC &= ~(1 << 5) | ~(1 << 4) | ~(1 << 3) | ~(1 << 2) | ~(1 << 1) | ~(1 << 0); 
 
    char data;
 
    uart_init();
 
    while(1)
        {
            data=uart_receive();
 
            if(data=='1')
            {
                PORTC |= 1 << 0; 
                
            }
            if(data=='2')
            {
                PORTC &= ~(1 << 0); //????????????? ?????????? 0 ?? ????? PC5 ???????? DDRC
            }
 
            if(data=='3')
            {
                PORTC |= 1 << 1;    //????????????? ?????????? 1 ?? ???? PC4 ???????? DDRC
            }
            if(data=='4')
            {
                PORTC &= ~(1 << 1); //????????????? ?????????? 0 ?? ????? PC4 ???????? DDRC
            }
             
            if(data=='5')
            {
                PORTC |= 1 << 2;    //????????????? ?????????? 1 ?? ???? PC4 ???????? DDRC
            }
            if(data=='6')
            {
                PORTC &= ~(1 << 2); //????????????? ?????????? 0 ?? ????? PC4 ???????? DDRC
            }
 
            if(data=='7')
            {
                PORTC |= 1 << 3;    //????????????? ?????????? 1 ?? ???? PC4 ???????? DDRC
            }
            if(data=='8')
            {
                PORTC &= ~(1 << 3); //????????????? ?????????? 0 ?? ????? PC4 ???????? DDRC
            }
             
            if(data=='9')
            {
                PORTC |= 1 << 4;    //????????????? ?????????? 1 ?? ???? PC4 ???????? DDRC
            }
            if(data=='a')
            {
                PORTC &= ~(1 << 4); //????????????? ?????????? 0 ?? ????? PC4 ???????? DDRC
            }
             
            if(data=='b')
            {
                PORTC |= 1 << 5;    //????????????? ?????????? 1 ?? ???? PC4 ???????? DDRC
            }

Скачать pdf инструкцию можно здесь.

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