⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uart.c

📁 一个LCD驱动程序
💻 C
字号:
//*****************************************************************************
//
//  File........: UART.c
//
//  Author(s)...: ATMEL Norway
//
//  Target(s)...: ATmega169
//
//  Compiler....: IAR EWAAVR 2.27b
//
//  Description.: UART transmittion
//
//  Revisions...: 1.0
//
//  YYYYMMDD - VER. - COMMENT                                       - SIGN.
//
//  20021015 - 1.0  - Created                                       - LHM
//
//*****************************************************************************

//  Include files
#include "Main.h"
#include "UART.h"

//  Global variables
unsigned char RX_byte_nr;                     // counts the number of received bytes
unsigned char sPreamble[] = "STK502";         // the preamble to detect start of frame
unsigned char ReceiveBuffer[50];              // recevive buffer to temporary store the received data
unsigned char TransmitBuffer[50];             // transmit buffer to temporary store the data to be transmitted
unsigned char TX_byte_nr;                     // counts the number of transmitted bytes
unsigned char Bytes_to_send;                  // cointains the number of bytes to send
unsigned char RX_Packet_complete = FALSE;     // if received a whole packet it's TRUE, else it will be FALSE
unsigned char RX_Preamble_complete = FALSE;   // if preamble has been received it's TRUE, else it will be FALSE
unsigned char Dec_L;                          // Decimal low byte
unsigned char Dec_M;                          // Decimal medium byte
unsigned char Dec_H;                          // Decimal high byte

/******************************************************************************
*
*   Function name:  UART_init
*
*   returns:        none
*
*   parameters:     baudrate, used to set the baudrate of the UART
*
*   Purpose:        Initialise the UART
*
*******************************************************************************/
void UART_init(unsigned char BaudRate)
{
    RX_byte_nr = 0; 
    UBRR0L = BaudRate;                                                // set the baudrate that is choosen
    UCSR0A = (1<<U2X0);                                                 // double the USART Transmission Speed
    UCSR0B = (1<<RXCIE0) | (1<<TXCIE0) | (1<<RXEN0) | (1<<TXEN0);       // enable Receiver and Transmitter and interrupt
    UCSR0C = (3<<UCSZ00);                                               // character size = 8 bit
}


/******************************************************************************
*
*   Function name:  Store_RX_data
*
*   returns:        none
*
*   parameters:     none
*
*   Purpose:        Convert from ASCII to HEX and store data from the ReceiveBuffer 
*                   to the SRAM locations
*
*******************************************************************************/
void Store_RX_data(void)
{
    unsigned char ASCII_Cnt = 0;      // variable to count the number of ascii-bytes
    unsigned char HEX_Cnt = 0;        // variable to count the number of Hex-bytes
    unsigned char HEX_byte;           // variable to store the Hex-byte
    
    // loop until the Packet is converted from ascii to Hex and loaded in the correct places in SRAM
    while(RX_Packet_complete)
    {
        HEX_byte = 0;                 // clear "HEX_byte"
            
        // loop to convert ASCII to Hex
        // it will loop until a ascii space charater (0x20) or a ascii line feed (0x0D) appears
        while((ReceiveBuffer[ASCII_Cnt] != 0x20) & (ReceiveBuffer[ASCII_Cnt] != 0x0D))
        {
            HEX_byte *= 10;                                     // multiply Hex-byte with 10
            HEX_byte += (ReceiveBuffer[ASCII_Cnt] - '0');       // store and add the ascii-byte
            ASCII_Cnt++;                                        // increment ascii byte counter
        }   // one ascii-byte has been converted to a Hex-byte
        
        if(ASCII_Cnt)                                       // if any byte where converted
        {
            *(&HOUR + HEX_Cnt) = HEX_byte;                      // store the Hex-byte in SRAM
            HEX_Cnt++;                                          // increment Hex-byte counter
        }

        if(ReceiveBuffer[ASCII_Cnt] == 0x20)                // if the ascii byte was a space charater
            ASCII_Cnt++;                                        // increment ascii byte counter
        else                                                // else it means the end of packet
        {
            RX_Packet_complete = FALSE;                         // indicate that a new packet can be converted
        }
    }   //the whole ReceiveBuffer has been converted Hex-bytes and stored in the SRAM-locations
}


/******************************************************************************
*
*   Function name:  Send_TX_data
*
*   returns:        none
*
*   parameters:     none
*
*   Purpose:        Send data from the TransmitBuffer
*
*******************************************************************************/
void Send_TX_data(void)
{
    unsigned char Nr_bytes_in_TX_buffer;
    unsigned char Cnt;
    unsigned char Nr_ASCII_bytes;
    
    if(!(UCSR0B & 0x20))        // do not make a new transmit-buffer if there's an on-going transmition (UDRIE-bit is set)
    {
        //FILL THE TRANSMITBUFFER WITH NEW DATA
            
        Nr_bytes_in_TX_buffer = 0;              // clear number of bytes in buffer
    
        // load preamble byte in the transmit-buffer
        while(sPreamble[Nr_bytes_in_TX_buffer])
        {
            TransmitBuffer[Nr_bytes_in_TX_buffer++] = sPreamble[Nr_bytes_in_TX_buffer];   //put the preamble to the Transmit buffer
        }// finished loading the preamble byte
        
        Cnt = 0;    // clear "Cnt", which is used to count the number of bytes loaded from SRAM in the loop below

        // load data bytes in the transmit-buffer
        while(Cnt < Nr_of_hex_bytes_to_send)       // loop until "Cnt" is equal to "Nr_of_hex_bytes_to_send
        {
            TransmitBuffer[Nr_bytes_in_TX_buffer++] = 0x20;   // add one space character
            
            Nr_ASCII_bytes = HEX2ASCII(*(&HOUR + Cnt++));     // format Hex-byte to ACSII data-bytes
                        
            while(Nr_ASCII_bytes)       // loop while there's ASCII to left
            {
                Nr_ASCII_bytes--;       // decrement "Nr_ASCII_bytes"
                TransmitBuffer[Nr_bytes_in_TX_buffer++] = *(&Dec_L + Nr_ASCII_bytes); // load ASCII-bytes in the transmit-buffer
            }
        }// finished loading data bytes in the transmit-buffer

        TransmitBuffer[Nr_bytes_in_TX_buffer++] = 0x20;     // add one space character
        TransmitBuffer[Nr_bytes_in_TX_buffer++] = REVISION_H;     // add the revisions number in the transmit packet
        TransmitBuffer[Nr_bytes_in_TX_buffer++] = REVISION_L;     // add the revisions number in the transmit packet
        
        TransmitBuffer[Nr_bytes_in_TX_buffer++] = 0x0D; // load ASCII for carriage return
        TransmitBuffer[Nr_bytes_in_TX_buffer++] = 0x0A; // load ASCII for line feed
        TX_byte_nr = 0;                                 // no bytes sent
        Bytes_to_send = Nr_bytes_in_TX_buffer;          // set number of bytes to send = nr_bytes_in-TX_buffer
                
        UCSR0B |= (1<<UDRIE0);      // Enable UDRE interrupt (starts transfer)
    }
}

/******************************************************************************
*
*   Function name:  HEX2ASCII
*
*   returns:        Number of decimal-bytes
*
*   parameters:     The Hex-byte to be converted
*
*   Purpose:        Converts a Hex-byte to 2 or 3 decimal-bytes
*
*******************************************************************************/
unsigned char HEX2ASCII(unsigned char Hex)
{
    unsigned char Nr_ASCII_bytes = 2; 
    
    Dec_L = 0;          //clear decimal-bytes
    Dec_M = 0;
    Dec_H = 0;
   
    while(Hex)                  // loop until the Hex is zero
    {
        Dec_L = Hex;            // store decimal-byte to Dec_L
        Hex -= 10;              // subtract 10 from the Hex-byte
        if(!(SREG & 0x01))      // if carry flag is not set 
        {
            Dec_M++;            // incrase Dec_M-byte
            if(Dec_M > 9)       // if Dec_M-byte over 100 decimal
            {
                Dec_M = 0;      // clear Dec_M
                Dec_H++;        // increase Dec_H
            }
            if(!Hex)            // if the Hex is zero
                Dec_L = 0;      // clear Dec_L
        }
        else
            Hex = 0;   
    }
    
    Dec_L += 0x30;              // add 0x30 to get the rigth ascii-value
    Dec_M += 0x30;              // add 0x30 to get the rigth ascii-value
    
    if(Dec_H)                   // if over 100d
    {
        Dec_H += 0x30;          // add 0x30 to get the rigth ascii-value
        Nr_ASCII_bytes++;       // increase number of bytes    
    }        
        
    return Nr_ASCII_bytes;      // return number of bytes
}

/******************************************************************************
*
*   USART0 Receive Interrupt Routine
*
*******************************************************************************/
#pragma vector = USART0_RXC_vect
__interrupt void USART0_RXC_interrupt(void)  
{
    unsigned char RX_byte;

    RX_byte = UDR0;           // read the UDR0 register
    
    if((RX_byte == sPreamble[RX_byte_nr]) & !RX_Preamble_complete)    // if received byte matches predicted preamble byte
    {                                                                 // and Preamble string hasn't been received
        RX_byte_nr++;
        if(RX_byte_nr == (sizeof(sPreamble) - 1))         // if all preamble bytes has been received
        {
            RX_Preamble_complete = TRUE;                  // indicate that the preable byte is OK
            RX_byte_nr = 0;
        }
    }        
    else if(RX_Preamble_complete)               //  if the Preamble string has been received
    {
        ReceiveBuffer[RX_byte_nr++] = RX_byte;    // store the received byte to the receivebuffer

        if(RX_byte == 0x0D)             // if Packet_length is zero, send back a buffer immediately 
        {
            ReceiveBuffer[RX_byte_nr++] = RX_byte;  // store the received byte in to the reveivebuffer
            RX_Preamble_complete = FALSE;           // set the RX_Preamble_complete to FALSE, so the function will start to search for a new preamble
            RX_Packet_complete = TRUE;              // set RX_Packet_complete so the converting of the received packet can start
            RX_byte_nr = 0;
        }
    }
    else
        RX_byte_nr = 0;
}


/******************************************************************************
*
*   USART0 Data Register Empty Interrupt Routine
*
*******************************************************************************/
#pragma vector = USART0_UDRE_vect
__interrupt void USART0_UDRE_interrupt(void)
{
    if (TX_byte_nr < Bytes_to_send)
    {
        UDR0 = (TransmitBuffer[TX_byte_nr++]);    //Put byte from Transmit buffer to USART I/O Data Register
    }
    else
    {            
        UCSR0B &= ~(1<<UDRIE0);         // Disable UDRE interrupt, transmission finshied
    }    
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -