Posted on Leave a comment

How to use UART and Interrupts of PIC16F877A

The PIC16F877A has a single ISR function which is called every time some things generate an interrupt. Inside the ISR you have to check for individual flag bits to know which peripheral has generated that interrupt.

/* 
 * File:   main.c
 * Author: abhay
 *
 * Created on July 15, 2023, 11:48 PM
 */

// PIC16F877A Configuration Bit Settings

// 'C' source line config statements

// 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 disabled)
#pragma config BOREN = OFF      // Brown-out Reset Enable bit (BOR disabled)
#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)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#define _XTAL_FREQ 16000000
#include <xc.h>
#include <pic16f877a.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include<string.h>




void GPIO_init(void);
void UART_init(void) ;
void tx(unsigned char a);
unsigned char rx();
void txstr(unsigned char *s);

uint8_t RX_chr;
void clear_flag(void);
unsigned char msgACK[16] = "Received";

void __interrupt() myISR() {
    if (RCIF == 1) {
        if (RCSTAbits.OERR) {
            CREN = 0;
            NOP();
            CREN = 1;
        }
        RX_chr = RCREG;
 
        RCIF = 0;
    }

}

/*
 * 
 */
int main(int argc, char** argv) {
    GPIO_init();
    UART_init();
    

    /*
     * Interrupt Setup START
     */
    INTCONbits.GIE = 1;
    INTCONbits.PEIE = 1;
    PIE1bits.TXIE = 0;
    PIE1bits.RCIE = 1;
    /*
     * Interrupt Setup END
     */


    while (1) {

        if (RX_chr == '0') {
        tx(RX_chr);
        RD1 = 0 ; // LED OFF
        txstr(msgACK);
        clear_flag();
    }

    if (RX_chr == 'a') {
        RD1 = 1; // LED ON
        txstr(msgACK);
        clear_flag();
    }

    }

    return (EXIT_SUCCESS);
}


void clear_flag(void) {
    RX_chr = 0;
}

void GPIO_init(void) {

    TRISD &= ~(1 << 1);
    RD1 = 0;
    
    /*
     * UART Pins Initialize
     */
    TRISCbits.TRISC6 = 0; // TX
    TRISCbits.TRISC7 = 1; //RX


}
void UART_init() {
        TXSTAbits.CSRC = 0;
        TXSTAbits.TX9 = 0;
        TXSTAbits.TXEN = 1;
        TXSTAbits.SYNC = 0;
        /* BRGH - High Baud Rate Select Bit
         * 1: High Speed
         * 0: Low Speed
         */
        TXSTAbits.BRGH = 1;
        TXSTAbits.TRMT = 0;
        TXSTAbits.TX9D = 0;

        RCSTAbits.SPEN = 1;
        RCSTAbits.RX9 = 0;
        RCSTAbits.SREN = 0;
        RCSTAbits.CREN = 1;
        RCSTAbits.ADDEN = 0;
        RCSTAbits.FERR = 0;
        RCSTAbits.OERR = 0;
        RCSTAbits.RX9D = 0;

        /*
         * Baud Rate Formula
         *  Asynchronous 
         *      Baud Rate = Fosc / (64 (x + 1))
         *          Baud Rate x (64 (x+1)) = FOSC
         *        SPBRG=  (x) = ( Fosc/( Baud_Rate * 64 ) ) - 1
         */

        SPBRG = 103; // Baud Rate 9600
        TXIF = RCIF = 0;
    }

void tx(unsigned char a) {
        
        while (TXIF == 0); // Wait till the transmitter register becomes empty
        TXIF = 0; // Clear transmitter flag
        TXREG = a; // load the char to be transmitted into transmit reg
    }

    unsigned char rx() {
        while (!RCIF);
        RCIF = 0;
        return RCREG;
    }

 void txstr(unsigned char *s) {
        while (*s) {
            tx(*s++);

            __delay_us(10);
        }

    }
Posted on Leave a comment

How to Transmit Data via UART with ATmega328P in AVR C using Arduino IDE

EnglishDeutschHindi

To transmit data via UART with the ATmega328P microcontroller in AVR C using the Arduino IDE, you can follow these steps:

  1. Include the necessary header files:
   #include <avr/io.h>
   #include <util/delay.h>
   #include <avr/interrupt.h>
   #include <stdlib.h>
  1. Define the UART settings:
   #define BAUDRATE 9600
   #define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)
  1. Initialize UART by configuring the baud rate and other settings:
   void uart_init() {
     UBRR0H = (uint8_t)(BAUD_PRESCALLER >> 8);
     UBRR0L = (uint8_t)(BAUD_PRESCALLER);

     UCSR0B = (1 << TXEN0);  // Enable transmitter
     UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);  // 8-bit data format
   }
  1. Implement the function to transmit data:
   void uart_transmit(uint8_t data) {
     while (!(UCSR0A & (1 << UDRE0)));  // Wait for empty transmit buffer
     UDR0 = data;  // Put data into the buffer, sends the data
   }
  1. Call the uart_init() function in your setup() function to initialize UART communication:
   void setup() {
     // Other setup code...
     uart_init();
     // More setup code...
   }
  1. Use uart_transmit() to send data:
   void loop() {
     // Transmit a character
     uart_transmit('A');

     // Delay between transmissions
     _delay_ms(1000);
   }

Make sure to connect the appropriate UART pins (TX) to the corresponding pins on your Arduino board. Additionally, set the correct BAUDRATE value based on your desired communication speed.

Complete Code
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#define BAUDRATE 9600
#define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)
void uart_init() {
  UBRR0H = (uint8_t)(BAUD_PRESCALLER >> 8);
  UBRR0L = (uint8_t)(BAUD_PRESCALLER);

  UCSR0B = (1 << TXEN0);  // Enable transmitter
  UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);  // 8-bit data format
}
void uart_transmit(uint8_t data) {
  while (!(UCSR0A & (1 << UDRE0)));  // Wait for empty transmit buffer
  UDR0 = data;  // Put data into the buffer, sends the data
}
void setup() {
  // Other setup code...
  uart_init();
  // More setup code...
}
void loop() {
  // Transmit a character
  uart_transmit('A');

  // Delay between transmissions
  _delay_ms(1000);
}

Demo Program That Transmits String of Characters

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

#define BAUDRATE 9600
#define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)

void uart_init() {
  UBRR0H = (uint8_t)(BAUD_PRESCALLER >> 8);
  UBRR0L = (uint8_t)(BAUD_PRESCALLER);

  UCSR0B = (1 << TXEN0);  // Enable transmitter
  UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);  // 8-bit data format
}

void uart_transmit(uint8_t data) {
  while (!(UCSR0A & (1 << UDRE0)));  // Wait for empty transmit buffer
  UDR0 = data;  // Put data into the buffer, sends the data
}

void uart_transmit_string(const char* str) {
  for (size_t i = 0; str[i] != '\0'; ++i) {
    uart_transmit(str[i]);
    _delay_ms(100);  // Delay between character transmissions
  }
}

void setup() {
  // Initialize UART
  uart_init();
}

void loop() {
  // Transmit a string
  uart_transmit_string("Hello, world!");

  // Delay before transmitting again
  _delay_ms(2000);
}

Um Daten über UART mit dem ATmega328P Mikrocontroller in AVR C unter Verwendung der Arduino IDE zu übertragen, können Sie die folgenden Schritte befolgen:

Fügen Sie die erforderlichen Header-Dateien ein:

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

Definieren Sie die UART-Einstellungen:

   #define BAUDRATE 9600
   #define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)

Initialisieren Sie UART, indem Sie die Baudrate und andere Einstellungen konfigurieren:

   void uart_init() {
     UBRR0H = (uint8_t)(BAUD_PRESCALLER >> 8);
     UBRR0L = (uint8_t)(BAUD_PRESCALLER);

     UCSR0B = (1 << TXEN0);  // Sender aktivieren
     UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);  // 8-Bit Datenformat
   }

Implementieren Sie die Funktion zum Senden von Daten:

   void uart_transmit(uint8_t data) {
     while (!(UCSR0A & (1 << UDRE0)));  // Warten auf leeren Sendepuffer
     UDR0 = data;  // Daten in den Puffer schreiben und senden
   }

Rufen Sie die Funktion uart_init() in Ihrer setup() Funktion auf, um die UART-Kommunikation zu initialisieren:

   void setup() {
     // Andere Setup-Code...
     uart_init();
     // Weitere Setup-Code...
   }

Verwenden Sie uart_transmit(), um Daten zu senden:

   void loop() {
     // Ein Zeichen übertragen
     uart_transmit('A');

     // Verzögerung zwischen den Übertragungen
     _delay_ms(1000);
   }

Stellen Sie sicher, dass Sie die entsprechenden UART-Pins (TX) mit den entsprechenden Pins auf Ihrem Arduino-Board verbinden. Stellen Sie außerdem den korrekten BAUDRATE-Wert entsprechend Ihrer gewünschten Kommunikationsgeschwindigkeit ein.

Vollständiger Code
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#define BAUDRATE 9600
#define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)
void uart_init() {
  UBRR0H = (uint8_t)(BAUD_PRESCALLER >> 8);
  UBRR0L = (uint8_t)(BAUD_PRESCALLER);

  UCSR0B = (1 << TXEN0);  // Enable transmitter
  UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);  // 8-bit data format
}
void uart_transmit(uint8_t data) {
  while (!(UCSR0A & (1 << UDRE0)));  // Wait for empty transmit buffer
  UDR0 = data;  // Put data into the buffer, sends the data
}
void setup() {
  // Other setup code...
  uart_init();
  // More setup code...
}
void loop() {
  // Transmit a character
  uart_transmit('A');

  // Delay between transmissions
  _delay_ms(1000);
}

Demo-Programm zum Senden einer Zeichenkette von Zeichen

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

#define BAUDRATE 9600
#define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)

void uart_init() {
  UBRR0H = (uint8_t)(BAUD_PRESCALLER >> 8);
  UBRR0L = (uint8_t)(BAUD_PRESCALLER);

  UCSR0B = (1 << TXEN0);  // Enable transmitter
  UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);  // 8-bit data format
}

void uart_transmit(uint8_t data) {
  while (!(UCSR0A & (1 << UDRE0)));  // Wait for empty transmit buffer
  UDR0 = data;  // Put data into the buffer, sends the data
}

void uart_transmit_string(const char* str) {
  for (size_t i = 0; str[i] != '\0'; ++i) {
    uart_transmit(str[i]);
    _delay_ms(100);  // Delay between character transmissions
  }
}

void setup() {
  // Initialize UART
  uart_init();
}

void loop() {
  // Transmit a string
  uart_transmit_string("Hello, world!");

  // Delay before transmitting again
  _delay_ms(2000);
}

एटीमेगा328पी माइक्रोकंट्रोलर के साथ AVR C और Arduino IDE का उपयोग करके UART के माध्यम से डेटा भेजने के लिए, आप निम्नलिखित चरणों का पालन कर सकते हैं:

आवश्यक हेडर फ़ाइलें शामिल करें:

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

UART सेटिंग्स को परिभाषित करें:

   #define BAUDRATE 9600
   #define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)

बॉड दर और अन्य सेटिंग्स को कॉन्फ़िगर करके UART को प्रारंभ करें:

   void uart_init() {
     UBRR0H = (uint8_t)(BAUD_PRESCALLER >> 8);
     UBRR0L = (uint8_t)(BAUD_PRESCALLER);

     UCSR0B = (1 << TXEN0);  // ट्रांसमीटर सक्षम करें
     UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);  // 8-बिट डेटा फ़ॉर्मेट
   }

डेटा भेजने के लिए फ़ंक्शन को लागू करें:

   void uart_transmit(uint8_t data) {
     while (!(UCSR0A & (1 << UDRE0)));  // खाली ट्रांसमिट बफर के लिए प्रतीक्षा करें
     UDR0 = data;  // डेटा को बफर में डालें, डेटा भेजें
   }

आपकी सेटअप() फ़ंक्शन में uart_init() फ़ंक्शन को कॉल करें, UART संचार को प्रारंभ करने के लिए:

   void setup() {
     // अन्य सेटअप कोड...
     uart_init();
     // अधिक सेटअप कोड...
   }

डेटा भेजने के लिए uart_transmit() का उपयोग करें:

   void loop() {
     // एक वर्ण भेजें
     uart_transmit('A');

     // भेजने के बीच में विलंब
     _delay_ms(1000);
   }

उचित UART पिन (TX) को अपने Arduino बोर्ड के संबंधित पिनों से कनेक्ट करने का सुनिश्चित करें। इसके अलावा, अपनी इच्छित संचार गति के आधार पर सही BAUDRATE मान सेट करें।

पूरा कोड:
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#define BAUDRATE 9600
#define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)
void uart_init() {
  UBRR0H = (uint8_t)(BAUD_PRESCALLER >> 8);
  UBRR0L = (uint8_t)(BAUD_PRESCALLER);

  UCSR0B = (1 << TXEN0);  // Enable transmitter
  UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);  // 8-bit data format
}
void uart_transmit(uint8_t data) {
  while (!(UCSR0A & (1 << UDRE0)));  // Wait for empty transmit buffer
  UDR0 = data;  // Put data into the buffer, sends the data
}
void setup() {
  // Other setup code...
  uart_init();
  // More setup code...
}
void loop() {
  // Transmit a character
  uart_transmit('A');

  // Delay between transmissions
  _delay_ms(1000);
}

वर्ण स्ट्रिंग भेजने का डेमो प्रोग्राम

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

#define BAUDRATE 9600
#define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)

void uart_init() {
  UBRR0H = (uint8_t)(BAUD_PRESCALLER >> 8);
  UBRR0L = (uint8_t)(BAUD_PRESCALLER);

  UCSR0B = (1 << TXEN0);  // Enable transmitter
  UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);  // 8-bit data format
}

void uart_transmit(uint8_t data) {
  while (!(UCSR0A & (1 << UDRE0)));  // Wait for empty transmit buffer
  UDR0 = data;  // Put data into the buffer, sends the data
}

void uart_transmit_string(const char* str) {
  for (size_t i = 0; str[i] != '\0'; ++i) {
    uart_transmit(str[i]);
    _delay_ms(100);  // Delay between character transmissions
  }
}

void setup() {
  // Initialize UART
  uart_init();
}

void loop() {
  // Transmit a string
  uart_transmit_string("Hello, world!");

  // Delay before transmitting again
  _delay_ms(2000);
}

Posted on Leave a comment

How to Initialize UART Communication with ATmega328P in AVR C using Arduino IDE

EnglishDeutschHindi

To initialize UART communication with the ATmega328P microcontroller in AVR C using the Arduino IDE, you can follow these steps:

Include the necessary header files:

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

Define the UART settings:

#define BAUDRATE 9600
#define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)

Initialize UART by configuring the baud rate and other settings:

void uart_init() {
  UBRR0H = (uint8_t)(BAUD_PRESCALLER >> 8);
  UBRR0L = (uint8_t)(BAUD_PRESCALLER);

  UCSR0B = (1 << RXEN0) | (1 << TXEN0);  // Enable receiver and transmitter
  UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);  // 8-bit data format
}

Implement functions for transmitting and receiving data:

void uart_transmit(uint8_t data) {
  while (!(UCSR0A & (1 << UDRE0)));  // Wait for empty transmit buffer
  UDR0 = data;  // Put data into the buffer, sends the data
}

uint8_t uart_receive() {
  while (!(UCSR0A & (1 << RXC0)));  // Wait for data to be received
  return UDR0;  // Get and return received data from buffer
}

(Optional) Implement a function to transmit a string:

void uart_transmit_string(const char* str) {
  for (size_t i = 0; str[i] != '\0'; ++i) {
    uart_transmit(str[i]);
  }
}

Finally, call the uart_init() function in your setup() function to initialize UART communication:

void setup() {
  // Other setup code...
  uart_init();
  // More setup code...
}

Now, you can use uart_transmit() to send individual characters and uart_receive() to receive data. If needed, you can use uart_transmit_string() to send strings.

Note that the above code assumes you are using the default hardware UART (UART0) on the ATmega328P, and the UART pins (RX and TX) are connected to the corresponding pins on your Arduino board.

Make sure to set the correct BAUDRATE value based on your desired communication speed. Also, ensure that the F_CPU macro is defined with the correct clock frequency of your microcontroller.

Remember to include the necessary header files in your Arduino sketch and define the setup() and loop() functions as required for Arduino compatibility.

Please note that configuring the UART in this way bypasses some of the Arduino’s built-in serial functionality, so you won’t be able to use Serial.print() or Serial.read() with this setup.

Code for a demo program

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

#define BAUDRATE 9600
#define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)

void uart_init() {
  UBRR0H = (uint8_t)(BAUD_PRESCALLER >> 8);
  UBRR0L = (uint8_t)(BAUD_PRESCALLER);

  UCSR0B = (1 << RXEN0) | (1 << TXEN0);
  UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
}

void uart_transmit(uint8_t data) {
  while (!(UCSR0A & (1 << UDRE0)));
  UDR0 = data;
}

uint8_t uart_receive() {
  while (!(UCSR0A & (1 << RXC0)));
  return UDR0;
}

void uart_transmit_string(const char* str) {
  for (size_t i = 0; str[i] != '\0'; ++i) {
    uart_transmit(str[i]);
  }
}

void setup() {
  // Initialize UART
  uart_init();

  // Set PB5 (Arduino digital pin 13) as output
  DDRB |= (1 << PB5);
}

void loop() {
  // Read input from UART
  uint8_t receivedData = uart_receive();

  // Echo back received data
  uart_transmit(receivedData);

  // Toggle the built-in LED (PB5) on each received character
  PORTB ^= (1 << PB5);

  // Delay for a short period to observe the LED blink
  _delay_ms(500);
}

In this demo program, the ATmega328P’s UART is initialized in the setup() function, and then in the loop() function, it continuously reads incoming data and sends it back (echo) over UART. Additionally, it toggles the built-in LED (PB5) on each received character, providing a visual indication.

Um die UART-Kommunikation mit dem ATmega328P-Mikrocontroller in AVR C mithilfe der Arduino IDE zu initialisieren, können Sie den folgenden Schritten folgen:

Fügen Sie die erforderlichen Header-Dateien hinzu:

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

Definieren Sie die UART-Einstellungen:

#define BAUDRATE 9600
#define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)

Initialisieren Sie UART, indem Sie die Baudrate und andere Einstellungen konfigurieren:

void uart_init() {
  UBRR0H = (uint8_t)(BAUD_PRESCALLER >> 8);
  UBRR0L = (uint8_t)(BAUD_PRESCALLER);

  UCSR0B = (1 << RXEN0) | (1 << TXEN0);  // Empfänger und Sender aktivieren
  UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);  // 8-Bit-Datenformat
}

Implementieren Sie Funktionen zum Senden und Empfangen von Daten:

void uart_transmit(uint8_t data) {
  while (!(UCSR0A & (1 << UDRE0)));  // Auf leeren Sendepuffer warten
  UDR0 = data;  // Daten in den Puffer schreiben und senden
}

uint8_t uart_receive() {
  while (!(UCSR0A & (1 << RXC0)));  // Auf empfangene Daten warten
  return UDR0;  // Empfangene Daten aus dem Puffer lesen und zurückgeben
}

(Optional) Implementieren Sie eine Funktion zum Senden einer Zeichenkette:

void uart_transmit_string(const char* str) {
  for (size_t i = 0; str[i] != '\0'; ++i) {
    uart_transmit(str[i]);
  }
}

Rufen Sie schließlich die Funktion uart_init() in Ihrer setup() Funktion auf, um die UART-Kommunikation zu initialisieren:

void setup() {
  // Anderer Setup-Code...
  uart_init();
  // Weitere Setup-Code...
}

Jetzt können Sie uart_transmit() verwenden, um einzelne Zeichen zu senden, und uart_receive() zum Empfangen von Daten. Bei Bedarf können Sie uart_transmit_string() verwenden, um Zeichenketten zu senden.

Beachten Sie, dass der obige Code davon ausgeht, dass Sie die standardmäßige Hardware-UART (UART0) des ATmega328P verwenden und dass die UART-Pins (RX und TX) mit den entsprechenden Pins auf Ihrem Arduino-Board verbunden sind.

Stellen Sie sicher, dass Sie den korrekten BAUDRATE-Wert entsprechend Ihrer gewünschten Übertragungsgeschwindigkeit festlegen. Stellen Sie außerdem sicher, dass die F_CPU-Makrodefinition die richtige Taktgeschwindigkeit Ihres Mikrocontrollers enthält.

Vergessen Sie nicht, die erforderlichen Header-Dateien in Ihren Arduino-Sketch einzufügen und die setup() und loop() Funktionen gemäß den Anforderungen der Arduino-Kompatibilität zu definieren.

Bitte beachten Sie, dass durch die Konfiguration der UART auf diese Weise einige der integrierten seriellen Funktionen des Arduino umgangen werden. Sie können daher nicht Serial.print() oder Serial.read() mit dieser Konfiguration verwenden.

Code für ein Demo-Programm

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

#define BAUDRATE 9600
#define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)

void uart_init() {
  UBRR0H = (uint8_t)(BAUD_PRESCALLER >> 8);
  UBRR0L = (uint8_t)(BAUD_PRESCALLER);

  UCSR0B = (1 << RXEN0) | (1 << TXEN0);
  UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
}

void uart_transmit(uint8_t data) {
  while (!(UCSR0A & (1 << UDRE0)));
  UDR0 = data;
}

uint8_t uart_receive() {
  while (!(UCSR0A & (1 << RXC0)));
  return UDR0;
}

void uart_transmit_string(const char* str) {
  for (size_t i = 0; str[i] != '\0'; ++i) {
    uart_transmit(str[i]);
  }
}

void setup() {
  // UART initialisieren
  uart_init();

  // PB5 (Arduino digitaler Pin 13) als Ausgang festlegen
  DDRB |= (1 << PB5);
}

void loop() {
  // Eingabe von UART lesen
  uint8_t receivedData = uart_receive();

  // Empfangene Daten zurückschicken (Echo)
  uart_transmit(receivedData);

  // Die integrierte LED (PB5) bei jedem empfangenen Zeichen umschalten
  PORTB ^= (1 << PB5);

  // Eine kurze Verzögerung, um das Blinken der LED zu beobachten
  _delay_ms(500);
}

In diesem Demo-Programm wird die UART des ATmega328P im setup() Funktion initialisiert. In der loop() Funktion liest es kontinuierlich eingehende Daten und sendet sie zurück (Echo) über UART. Darüber hinaus wird die integrierte LED (PB5) bei jedem empfangenen Zeichen umgeschaltet, um eine visuelle Anzeige zu bieten.

ATmega328P माइक्रोकंट्रोलर के साथ AVR C और Arduino IDE का उपयोग करके UART संचार को प्रारंभ करने के लिए, आप निम्नलिखित चरणों का पालन कर सकते हैं:

आवश्यक हैडर फ़ाइलें शामिल करें:

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

UART सेटिंग्स को परिभाषित करें:

#define BAUDRATE 9600
#define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)

बॉडरेट और अन्य सेटिंग्स को कॉन्फ़िगर करके UART को प्रारंभ करें:

void uart_init() {
  UBRR0H = (uint8_t)(BAUD_PRESCALLER >> 8);
  UBRR0L = (uint8_t)(BAUD_PRESCALLER);

  UCSR0B = (1 << RXEN0) | (1 << TXEN0);  // प्राप्तकर्ता और प्रेषक को सक्षम करें
  UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);  // 8 बिट डेटा प्रारूप
}

डेटा भेजने और प्राप्त करने के लिए फ़ंक्शन को अमल में लाएं:

void uart_transmit(uint8_t data) {
  while (!(UCSR0A & (1 << UDRE0)));  // खाली भेजने वाले बफ़र के लिए प्रतीक्षा करें
  UDR0 = data;  // डेटा बफ़र में डेटा डालें, डेटा भेजें
}

uint8_t uart_receive() {
  while (!(UCSR0A & (1 << RXC0)));  // डेटा प्राप्त होने की प्रतीक्षा करें
  return UDR0;  // बफ़र से प्राप्त और डेटा लौटाएं
}

(ऐच्छिक) स्ट्रिंग भेजने के लिए एक फ़ंक्शन को अमल में लाएं:

void uart_transmit_string(const char* str) {
  for (size_t i =

 0; str[i] != '\0'; ++i) {
    uart_transmit(str[i]);
  }
}

अंतिम रूप में, अपने सेटअप() फ़ंक्शन में uart_init() फ़ंक्शन को बुलाएं और UART संचार को प्रारंभ करें:

void setup() {
  // अन्य सेटअप कोड...
  uart_init();
  // अधिक सेटअप कोड...
}

अब, आप uart_transmit() का उपयोग अक्षरों को भेजने के लिए कर सकते हैं और uart_receive() का उपयोग डेटा प्राप्त करने के लिए कर सकते हैं। आवश्यकता होने पर, आप uart_transmit_string() का उपयोग स्ट्रिंग भेजने के लिए कर सकते हैं।

ध्यान दें कि ऊपर का कोड मानता है कि आप ATmega328P पर डिफ़ॉल्ट हार्डवेयर UART (UART0) का उपयोग कर रहे हैं, और UART पिन (RX और TX) आपके Arduino बोर्ड पर संबंधित पिनों से कनेक्ट हैं।

अपनी Arduino स्केच में आवश्यक हैडर फ़ाइलें शामिल करने और Arduino संगतता के लिए सेटअप() और लूप() फ़ंक्शन को परिभाषित करने के लिए याद रखें।

कृपया ध्यान दें कि इस तरीके से UART को कॉन्फ़िगर करने से अर्डुइनो के कुछ निर्मित सीरियल कार्यक्षमता का बाहर जाना होता है, इसलिए इस सेटअप के साथ Serial.print() या Serial.read() का उपयोग नहीं कर सकेंगे।

डेमो प्रोग्राम के लिए कोड

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

#define BAUDRATE 9600
#define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)

void uart_init() {
  UBRR0H = (uint8_t)(BAUD_PRESCALLER >> 8);
  UBRR0L = (uint8_t)(BAUD_PRESCALLER);

  UCSR0B = (1 << RXEN0) | (1 << TXEN0);
  UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
}

void uart_transmit(uint8_t data) {
  while (!(UCSR0A & (1 << UDRE0)));
  UDR0 = data;
}

uint8_t uart_receive() {
  while (!(UCSR0A & (1 << RXC0)));
  return UDR0;
}

void uart_transmit_string(const char* str) {
  for (size_t i = 0; str[i] != '\0'; ++i) {
    uart_transmit(str[i]);
  }
}

void setup() {
  // UART को प्रारंभ करें
  uart_init();

  // PB5 (Arduino डिजिटल पिन 13) को आउटपुट के रूप में सेट करें
  DDRB |= (1 << PB5);
}

void loop() {
  // UART से इनपुट पढ़ें
  uint8_t receivedData = uart_receive();

  // प्राप्त डेटा को वापस भेजें (इको)
  uart_transmit(receivedData);

  // प्राप्त वर्णकों पर बिल्ट-इन LED (PB5) को टॉगल करें, यह दिखाने के लिए
  PORTB ^= (1 << PB5);

  // LED ब्लिंक को देखने के लिए थोड़ी सी देरी के लिए विलंब करें
  _delay_ms(500);
}

इस डेमो प्रोग्राम में, ATmega328P का UART सेटअप() फ़ंक्शन में प्रारंभित होता है, और फिर लूप() फ़ंक्शन में, यह निरंतर आने वाले डेटा को पढ़ता है और उसे वापस (इको) UART के माध्यम से भेजता है। इसके अलावा, यह प्राप्त प्रत्येक आंकड़े पर बिल्ट-इन LED (PB5) को टॉगल करता है, जिससे एक लैंप एफेक्ट प्रदर्शित होता है।

Posted on Leave a comment

How to use UART Receive complete ISR of ATmega328PB using microchip studio

When you enable the communication using the UART. You have the flexibility to either use the Polling or Interrupt method to continue with your programming.

Polling halts the execution of the program and waits for the UART peripheral to receive something so that program execution must continue. But it eats a lot of the computing time.

So, Interrupt Service Routine is written and implemented such the program execution does not stop. It will stop when there is an interrupt and when there is data in the UDR0 register of UART. Then the ISR will execute and then transfer the control to the main program. Which saves a lot of computing time.

you have to add an interrupt library in your program.

#include <avr/interrupt.h>

Then you need to enable the Global interrupt flag.

.
.
.
int main()
{
.
.
.
sei();            // This is Set Enable Interryupt

   while(1)
  {
     // This is your application code.
   }

}

Then you need to enable the UART receive complete interrupt. by setting ‘1’ to RXCIE0 bit of USCR0B register.

Write the ISR function which takes “USART0_RX_vect” as the argument.

char Received_char;
ISR(USART0_RX_vect)
{
	Received_char = UDR0;
}

int main()
{
UCSR0B = (1 << RXCIE0)|(1<<RXEN0)|(1<<TXEN0); 
.
.
.
sei();
while(1);
{
}

}

The above code shows you how to implement UART receive complete ISR. It is not a full initialisation code. You still have to write the UBRR and the frame control to enable the uart peripheral.

Posted on Leave a comment

How to set up UART of ATmega328pb in Atmel Studio 7.0

To set up uart in Atmel studio 7.0.

Firstly you will need a common baud rate.

Then you go to section 24.11 of the datasheet. You will find common calculated values for the UBRRn register.

UBRRn register is comprised of high and low registers.

First, you have to initialise the Data direction registers for the RX and Tx Pins. Then you initialise the UART peripheral.

DDRD &= ~(1 << DDD0);				// PD0 - Rx Input
DDRD |= (1 << DDD1);				// PD1 - Tx Ouput
USART_Init();					// UART intialise

Here is the basic UART library code.

/*
* Name: UART library Code
*/
void USART_Init( )
{
	/*Set baud rate */
	
	UBRR0L = 103;
	/* Enable receiver and transmitter */
	UCSR0B = (1 << RXCIE0)|(1<<RXEN0)|(1<<TXEN0);
	/* Set frame format: 8data, 1stop bit */
	UCSR0C = (3<<UCSZ00);
}

void USART_Transmit(uint8_t data )
{
	
	/* Wait for empty transmit buffer */
	while ( !( UCSR0A & (1<< UDRE0 )) )
	;
	/* Put data into buffer, sends the data */
	UDR0 = data;
	
}

unsigned char USART_Receive( void )
{
	/* Wait for data to be received */
	while ( !(UCSR0A & (1<<RXC0)) )
	;
	/* Get and return received data from buffer */
	return UDR0;
}

void USART_SendString(char *str)
{
	unsigned char j=0;
	
	while (str[j]!=0)		/* Send string till null */
	{
		USART_Transmit(str[j]);
		j++;
	}
}