Wednesday, September 30, 2020

ATMega32 AVR USART C programming examples

In the previous post I have shown about a few details of the USART module the ATMega32 device with some working examples. Here I put some more USART examples with some AVR C programming techniques - making a condition with the received characters, and using the ANSI C string functions library.

Conditioning the receiving characters

Within this simple example, The user sends some characters to the MCU USART module via the host PC USART terminal. The MCU keeps track of the characters and store them in an array at a size of 15 characters, or any size up to the programmer. 


Whenever the user send the ENTER key ( ASCII value of 0x0D) the MCU terminates the the next character storing and send back all the previous characters back to the host PC terminal.

/*
 * uart_example_1.c
 *
 * Created: 9/30/2020 10:21:10 AM
 * Author : aki-technical
 */ 

#include <avr/io.h>

#define F_CPU 16000000UL
#include <util/delay.h>

#define uartReady UCSRA&(1<<RXC)

void uartInit(unsigned long baud){
unsigned int UBRR;
/*Baud rate calculator*/
UBRR=(F_CPU/(16*baud))-1;
UBRRH=(unsigned char)(UBRR>>8);
UBRRL=(unsigned char)UBRR;
/*Enable the transmitter and receiver*/
UCSRB=(1<<RXEN)|(1<<TXEN)|(1<<RXEN);
/*asynchronous mode, 8-bit, 1-stop bit*/
UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
}

void uartTransmit(unsigned char data){
/*Stay here until the buffer is empty*/
while(!(UCSRA&(1<<UDRE)));
/*Put the data into the buffer*/
UDR=data;
}

char uartReceive(){
/*Wait until the buffer is full*/
while(!(UCSRA&(1<<RXC)));
/*Get the data ready to use*/
return UDR;
}

void sendText(char *txt){
while(*txt) uartTransmit(*txt++);
}


int main(void)
{
char tmp,i=0;
char txt[15];
DDRC=0xFF;
uartInit(9600);
sendText("ATMEGA32 AVR UART Example 1\n\r");
while (1)
{
/*If There is a character in the buffer*/
if (uartReady)
{
tmp=uartReceive();
PORTC=tmp;
txt[i]=tmp;
i++;
}
/*If the ENTER Key Is Presented*/
if (tmp==0x0D)
{
/*Send text back to the terminal*/
sendText(txt);
/*Clear the character storage*/
tmp='\0';
/*Clear all the texts*/
while(i>0){
txt[i]='\0';
i--;
}
}
}
}

The overall source codes of the program is a little different from the previous post, except the a few block of C code that make the conditioning the received characters.

ATMega32 AVR USART examples.
schematic diagram 

I set the clock to 16 MHz to work with my own prototyping board. The output LED bar graph at PORTC indicates the present of data received.

ATMega32 AVR USART C programming examples.
A sample of this program

Click here to download the zip file of this working example.

Using the ANSI C string functions library

This example I use the string compare function from the ANSI C string library function. There are a lot of string processing functions in this library. However I pick up only one's that only required in this example. 

The string compare - strcmp()

int strcmp(char *string1,char *string2);

where,
- string1 is the first string to be compared
- string2 is the second string to be compared

This function returns:
  • less than zero if string1 is less than string2
  • greater than zero if string1 is greater than string2
  • zero if these two string are equal.
Now let move the overall processes of this example. Once the user sends the command the MCU reads the character stored in the USART buffer, and make it a string. Whenever the user enter a new line or ENTER, the MCU start process the string comparison. When the comparison is matched the MCU toggles its corresponding output pin.

Let see the source code.

/*
 * uart_example_2.c
 *
 * Created: 9/30/2020 5:34:08 PM
 * Author : aki-technical
 */ 

#include <avr/io.h>

#define F_CPU 16000000UL
#include <util/delay.h>

#include <string.h>

#define uartReady UCSRA&(1<<RXC)

void uartInit(unsigned long baud){
unsigned int UBRR;
/*Baud rate calculator*/
UBRR=(F_CPU/(16*baud))-1;
UBRRH=(unsigned char)(UBRR>>8);
UBRRL=(unsigned char)UBRR;
/*Enable the transmitter and receiver*/
UCSRB=(1<<RXEN)|(1<<TXEN)|(1<<RXEN);
/*asynchronous mode, 8-bit, 1-stop bit*/
UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
}

void uartTransmit(unsigned char data){
/*Stay here until the buffer is empty*/
while(!(UCSRA&(1<<UDRE)));
/*Put the data into the buffer*/
UDR=data;
}

unsigned char uartReceive(void){
/*Wait until the buffer is full*/
while(!(UCSRA&(1<<RXC)));
/*Get the data ready to use*/
return UDR;
}

void sendText(char *txt){
while(*txt) uartTransmit(*txt++);
}

char tmp,i=0;
char txt[15];
/*Some string constants to compare with USART command*/
const char cmp1_on[]="rl1On\r",cmp1_off[]="rl1Off\r";
const char cmp2_on[]="rl2On\r",cmp2_off[]="rl2Off\r";
const char cmp3_on[]="rl3On\r",cmp3_off[]="rl3Off\r";
const char cmp4_on[]="rl4On\r",cmp4_off[]="rl4Off\r";
const char allOn[]="allOn\r",allOff[]="allOff\r";

void clearAll(void){
/*Clear the character storage*/
tmp='\0';
/*Clear all the texts*/
while(i>0){
txt[i]='\0';
i--;
}
}

int main(void)
{
DDRC=0xFF;
uartInit(9600);
sendText("ATMEGA32 AVR UART With C String Library Example\r");
while (1)
{
/*If There is a character in the buffer*/
if (uartReady)
{
tmp=uartReceive();
uartTransmit(tmp);
txt[i]=tmp;
i++;
}
/*ENTER or new line is 0x0D in hex*/
if(tmp=='\r'){
/*Toggling pin PC0*/
if(strcmp(txt,cmp1_on)==0){
PORTC|=(1<<0);
sendText("Relay 1 Turns On.\r");
}
else if (strcmp(txt,cmp1_off)==0){
PORTC&=~(1<<0);
sendText("Relay 1 Turns Off.\r");
}
/*Toggling pin PC1*/
if(strcmp(txt,cmp2_on)==0){
PORTC|=(1<<1);
sendText("Relay 2 Turns On.\r");
}
else if(strcmp(txt,cmp2_off)==0){
PORTC&=~(1<<1);
sendText("Relay 2 Turns Off\r");
}
/*Toggling pin PC2*/
if(strcmp(txt,cmp3_on)==0){
PORTC|=(1<<2);
sendText("Relay 3 Turns On.\r");
}
else if(strcmp(txt,cmp3_off)==0){
PORTC&=~(1<<2);
sendText("Relay 3 Turns Off\r");
}
/*Toggling pin PC3*/
if(strcmp(txt,cmp4_on)==0){
PORTC|=(1<<3);
sendText("Relay 4 Turns On.\r");
}
else if(strcmp(txt,cmp4_off)==0){
PORTC&=~(1<<3);
sendText("Relay 4 Turns Off.\r");
}
/*Overall Controls*/
if (strcmp(txt,allOn)==0)
{
PORTC=0x0F;
sendText("All relays turn on\r");
}
else if (strcmp(txt,allOff)==0)
{
PORTC=0x00;
sendText("All relays turn off\r");
}
/*Clearing all the data*/
clearAll();
}
}
}

In the source code I mentioned the relay. However the output devices in schematic diagram are the LED rather than the relays.

ATMega32 AVR USART C programming examples
Schematic Diagram

Click here to download the zip file of this working example.


If you want a standard PCB for ATMega32 micro-controller, you can order my AVR Microcontroller project from PCBWay with a reasonable price. Click here to get a free $5 credit for new account.

Interfacing ATMega32 to 74HC595 shift register
ATMega16 ATMega32 Experiment Board PCB from PCBWay

No comments:

Post a Comment

Search This Blog

Labels

25AA010A (1) 8051 (7) 93AA46B (1) ADC (30) Analog Comparator (1) Arduino (15) ARM (6) AT89C52 (7) ATMega32 (54) AVR (57) CCS PICC (28) DAC (1) DHT11 (2) Display (105) Distance Sensor (3) DS18B20 (3) dsPIC (2) dsPIC30F1010 (2) EEPROM (5) Environment Sensor (4) esp8266 (1) I2C (29) Input/Output (67) Interrupt (19) Keil (5) Keypad (10) LCD (46) Master/Slave (1) MAX7221 (1) MCP23017 (5) MCP23S17 (4) Meter (3) MikroC (2) Motor (15) MPLABX (66) Nokia 5110 LCD (3) OLED (2) One-Wire (6) Oscillator (8) PCB (6) PCD8544 (3) PCF8574 (5) PIC (107) PIC12F (2) PIC16F628A (2) PIC16F630 (1) PIC16F716 (3) PIC16F818 (10) PIC16F818/819 (2) PIC16F84A (15) PIC16F876A (1) PIC16F877A (9) PIC16F88 (1) PIC16F887 (60) PIC18 (19) PIC18F1220 (4) PIC18F2550 (3) PIC18F4550 (12) PWM (11) RTC (8) Sensor (10) SH1106 (1) Shift Register (11) Shift Registers (2) SPI (24) STM32 (6) STM32 Blue Pill (6) STM32CubeIDE (6) STM32F103C8T6 (6) SysTick (3) temperature sensor (11) Thermometer (21) Timer/Counter (30) TM1637 (2) UART (7) Ultrasonic (4) Voltmeter (7) WDT (1) XC16 (2) XC8 (94)