AVR USART communication - c

I am implementing USART communication on an AVR micro-controller. Below is my code. At the moment, I can send a character, send a string and receive a character. I have a method to receive a string.
The method is called char* receive_string() and returns the address of the string that I am receiving. This is the 55 element char array to hold the string, char string[55]. However, for example, when I send the word hello to the micro-controller, this method returns only the first character h. What is it that I am doing wrong?
#include <avr/io.h>
#include <util/delay.h>
#include <string.h>
#include <avr/interrupt.h>
// macro definition
#define bit(n) (1 << n) // bit
#define sbit(v, n) v |= (1 << n) // set bit
#define cbit(v, n) v &= !(1 << n) // clear bit
#ifndef F_CPU
#define F_CPU 16000000
#endif
#define BAUD 9600 // baud rate
#define M_UBRR ((F_CPU/16/BAUD)-1) //contents of UBRRnH and UBRRnL registers
// function prototypes
void usart_init();
void send_char(char);
void send_string(char*);
char receive_char();
char* receive_string();
char string[55];
int main() {
usart_init();
char* msg = receive_string();
sei();
while (1) {
send_string(msg);
_delay_ms(1000);
}
return 0;
}
void usart_init() {
UBRR0H = (M_UBRR >> 8); // setting baud rate
UBRR0L = M_UBRR;
UCSR0B = (1 << TXEN0) | (1 << RXEN0) | (1 << RXCIE0); // enable transmitter and receiver
UCSR0C = (1 << USBS0); // 2 stop bit
UCSR0C = (1 << UCSZ00) | (1 << UCSZ01);
}
void send_char(char byte) {
while (!(UCSR0A & (1 << UDRE0))); // wait until the register is empty
UDR0 = byte; // put a char in the UDR0 register
}
void send_string(char* string) {
int i;
int len = strlen(string);
for (i = 0; i < len; i++) {
send_char(string[i]);
}
}
char receive_char() {
while (!(UCSR0A & (1 << RXC0))); // wait until all data in receive buffer is read
return UDR0;
}
char* receive_string() {
char x;
int len = strlen(string);
int i = 0;
while (i < len) {
x = receive_char();
string[i++] = x;
}
string[len] = '\0';
return (string);
}

strlen(string) in your code does not make sense. How can you get the length of a string that has not been sent yet?
Change that to len = 55 or len = sizeof(string).
In C, strlen counts the number of characters before finding the zero terminator.

Related

AVR ATmega328p and MCP3201 issue

I have a problem with SPI Interface in ATmega328p. I wrote a code that can SPI communicate with MCP3201(analog to digital converter), but I received the wrong value from MCP3201. The value should be between 600 - 700, but I get 2.
I use MCP9700(temperature sensor) to received voltage value and convert with ADC with MCP3201. I read the MCP3201' data sheet. It needs to remove trash bit. I wrote the code to show you below.
Can you check my code and schematic?
main.c
#define F_CPU 8000000L
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include <string.h>
#define CS PB2
#define CS_DDR DDB2
#define MOSI DDB3
#define CLK DDB5
void USART_Init(unsigned int ubrr) {
UBRR0 = ubrr;
UCSR0B |= (1 << RXEN0) | (1 << TXEN0);
UCSR0C |= (1 << UCSZ01) | (1 << UCSZ00);
}
void USART_Transmit( unsigned char data ) {
while ( !( UCSR0A & (1 << UDRE0)) );
UDR0 = data;
}
void print(unsigned char *buffer) {
for(int i=0; buffer[i] != 0; i++){
USART_Transmit(buffer[i]);
}
}
void SPI_Init()
{
/* set MOSI CLK CS as Output*/
DDRB |= (1 << CS_DDR) | (1 << CLK) | (1 << MOSI);
// Chip select high
PORTB |= (1 << CS);
// Chip select low
PORTB &= ~(1 << CS);
/* Enable SPI, Master mode, clk/16 */
SPCR |= (1 << SPE) | (1 << MSTR) | (1 << SPR0);
}
uint16_t SPI_READ()
{
uint8_t rx_byte;
uint16_t rx_12bits;
PORTB &= ~(1 << CS); // Chip select low
SPDR = 0xFF; // put dummy byte in SPDR
while(!(SPSR & (1<<SPIF))); // wait for SPIF high
rx_byte = SPDR & 0b00111111; // copy SPDR out
rx_12bits = rx_byte << 7;
SPDR = 0xFF; // put dummy byte in SPDR
while(!(SPSR & (1<<SPIF))); // wait for SPIF high
rx_byte = SPDR >>= 1; // copy SPDR out
rx_12bits |= rx_byte; // Concat bit
PORTB |= (1 << CS); // Chip select high
return rx_12bits;
}
int main(void) {
USART_Init(53);
SPI_Init();
uint16_t sensor;
// uint16_t temp;
unsigned char text[] = "Temperature = ";
unsigned char buffer[10];
while (1) {
sensor = SPI_READ(); // Read data from sensor
// temp = (((sensor/4096.0) * 5) - 0.5) * 100 ;
sprintf(buffer,"%u",sensor ); // convert to string test with raw data
strcat(buffer, " °C\n");
print(text);
print(buffer);
_delay_ms(1000);
}
}
schematic
EDIT 1:
#define F_CPU 8000000L
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define CS PB2
#define CS_DDR DDB2
#define MOSI DDB3
#define CLK DDB5
void USART_Init(unsigned int ubrr) {
UBRR0 = ubrr;
UCSR0B |= (1 << RXEN0) | (1 << TXEN0);
UCSR0C |= (1 << UCSZ01) | (1 << UCSZ00);
}
void USART_Transmit( unsigned char data ) {
while ( !( UCSR0A & (1 << UDRE0)) );
UDR0 = data;
}
void print(unsigned char *buffer) {
for(int i=0; buffer[i] != 0; i++){
USART_Transmit(buffer[i]);
}
}
void SPI_Init()
{
/* set MOSI CLK CS as Output*/
DDRB |= (1 << CS_DDR) | (1 << CLK) | (1 << MOSI);
// Chip select high
PORTB |= (1 << CS);
// Chip select low
PORTB &= ~(1 << CS);
/* Enable SPI, Master mode, clk/16 */
SPCR |= (1 << SPE) | (1 << MSTR) | (1 << SPR0);
}
uint16_t SPI_READ()
{
uint16_t high_byte;
uint16_t low_byte;
uint16_t out_12bits;
PORTB &= ~(1 << CS); // Chip select low
SPDR = 0xFF; // put dummy byte in SPDR
while(!(SPSR & (1<<SPIF))); // wait for SPIF high
/*xx0[B11][B10][B9][B8][B7]*/
high_byte = SPDR; // copy SPDR out
SPDR = 0xFF; // put dummy byte in SPDR
while(!(SPSR & (1<<SPIF))); // wait for SPIF high
/*[B6][B5][B4][B3][B2][B1][B0][B1]*/
low_byte = SPDR; // copy SPDR out
/*xx0[B11][B10][B9][B8][B7] 0 0 0 0 0 0 0 0 */
/* OR */
/*000 0 0 0 0 0 [B6][B5][B4][B3][B2][B1][B0][B1]*/
/*---------------------------------------------------------*/
/*xx0[B11][B10][B9][B8][B7][B6][B5][B4][B3][B2][B1][B0][B1]*/
out_12bits = (high_byte << 8) | low_byte; // Concatenate bit
/*[B11][B10][B9][B8][B7][B6][B5][B4][B3][B2][B1][B0][B1]000*/
out_12bits <<= 3; // Shift left 3
/*0000[B11][B10][B9][B8][B7][B6][B5][B4][B3][B2][B1][B0]*/
out_12bits >>= 4; // Shift right 4
PORTB |= (1 << CS); // Chip select high
return out_12bits;
}
int main(void) {
USART_Init(53); // SPI intial
SPI_Init(); // USART initial
uint16_t sensor;
float temp;
unsigned char text[] = "Temperature = ";
unsigned char buffer[10];
while (1) {
sensor = SPI_READ(); // Read data from sensor
temp = (((sensor/4096.0) * 5.0) - 0.5) * 100.0 ; // Convert Analog value to temperature
dtostrf(temp, 3, 2, buffer); // Convert Float to string
strcat(buffer, " °C\n"); // Concatenate unit
print(text); // Print First Text
print(buffer); // Print temperature and unit
_delay_ms(1000);
}
}
Actually i do not have the chance to test the code, but maybe this helps:
#define F_CPU 8000000L
#define BAUD 9600UL // Used within setbaud.h
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <avr/io.h>
#include <util/delay.h>
#include <util/setbaud.h>
#define CS PB2
#define MOSI PB3
#define MISO PB4
#define CLK PB5
void uart_init() {
#if USE_2X // Defined within setbaud.h
UCSRA |= (1<<U2X); // Setup 8 samples/bit
#else
UCSRA &= ~(1<<U2X); // Setup 16 samples/bit
#endif
UBRR0 = UBRRH_VALUE; // Defined within setbaud.h
UCSR0B |= (1<<RXEN0) | (1<<TXEN0);
UCSR0C |= (1<<UCSZ01) | (1<<UCSZ00);
}
void uart_transmit(unsigned char data ) {
while (!(UCSR0A & (1<<UDRE0)));
UDR0 = data;
}
void print(unsigned char *buffer) {
for(unsigned int i=0; buffer[i] != 0; i++){
uart_transmit(buffer[i]);
}
}
void spi_init()
{
// Set MISO and Chip Select as Input
DDRB &= ~((1<<CS) | (1<<MISO));
// Set pullup resistors for MISO and Chip Select
PORTB |= (1<<CS) | (1<<MISO);
// SPI
// - Mode: Master
// - Prescaler: 16
SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR0);
// Setup SCK, MOSI and SS as output
// PORT configuration gets overwritten from SPI controller
DDRB &= (1<<CLK) | (1<<MOSI) | (1<<CS);
}
void spi_select()
{
DDRB &= ~(1<<CS);
}
void spi_deselect()
{
DDRB |= (1<<CS);
}
unsigned char spi_read()
{
SPDR = 0xFF; // Write data into the SPI Data Register and initiate a transmission
// Wait until transmission is Complete
while(!(SPSR & (1<<SPIF)))
asm volatile("NOP");
return SPDR
}
unsigned int mcp3201_data()
{
spi_select();
unsigned char high_data = spi_read();
unsigned char low_data = spi_read();
spi_deselect();
// +-------------------------------+-------------------------------+
// | HIGH | LOW |
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// | - | - | - | - | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? |
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
//
// Value between 0 to (2^12 - 1) = 0 to 4095
return (((high_data & 0x0F)<<8) | low_data);
}
int main(void) {
uart_init();
spi_init();
const unsigned char text[] = "Temperature = ";
unsigned char buffer[100];
while (1)
{
unsigned int mv; = ((mcp3201_data * 5000)>>12); // Analog Voltage in mV
double temp = mv; // Calculate your temperature
dtostrf(temp, 3, 2, buffer); // Convert Float to string
strcat(buffer, " °C\n"); // Concatenate unit
print(text); // Print First Text
print(buffer); // Print temperature and unit
_delay_ms(1000);
}
}
Indeed i have not calculated the temperature. Thats your turn...

AVR Microcontrollers memory game

I am making a game where you need to repeat the sequence of LEDs that light up. This sequence is set by two LEDs. To repeat the sequence, I use the joystick.
I had an idea to make two bool arrays where True will indicate the left LED, and False will indicate the right LED. The first array must contain a random sequence(True/False) that needs to be repeated. When I push to one or the other side of the joystick, I want to write to the second array, respectively, True / False and all this time compare them.
This is what I have at the moment. (AT90USB647)
#define F_CPU 2000000UL
#include <avr/io.h>
#include <stdbool.h>
int main(void) {
MCUCR |= 0x80;
MCUCR |= 0x80;
DDRA = 0xFF;
PORTF = 0x20;
bool seq2[100];
while(1)
{
uint8_t x = PINF;
if(!(x & 0x20)) {
PORTA = 0x80;
}
else if(!(x & 0x08)) {
PORTA = 0x01;
}
else {
PORTA = 0x00;
}
}
}
The main question is how do I write True or False to an array when I push the joystick?
A basic approach could be:
#define F_CPU 2000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
volatile unsigned int counter;
static unsigned char pattern_position;
static unsigned char array_position;
static unsigned char pattern[] = {
0b01010101,
0b11010101,
0b10010101
};
ISR(TIMER0_COMPA_vect)
{
counter++;
}
int main(void)
{
MCUCR |= 0x80;
DDRA = 0xFF;
PORTF = 0x20;
// Timer initialization
// Mode: CTC
// Prescaler: 1024
TCCR0A = (1<<WGM01);
TCCR0B = (1<<CS02) | (1<<CS00);
// Calculate a correct time
//
// we want 1 ms -> f_TIMER0 = 1/T = 1/(1 * 10^-3)s = 1 kHz
//
// f_CPU f_CPU 20 MHz
// f_TIMER0 = ------------- -> OCR0A = ---------------- = ------------- = ~ 20 (It is not exactly 1ms but it is ok)
// k_H * OCR0A k_H * f_TIMER0 256 * 1 kHz
//
OCR0A = 20;
TIMSK0 = (1<<OCF0A); // Enable Timer0 Overflow Compare Match interrupt
// Show the sequence that the user should input
for (unsigned char i=0; i < sizeof(pattern)/sizeof(&pattern[0]); i++)
{
for (unsigned char j=0; j < 8; j +=2)
{
// There is possible a signal missing to show the user that the next pattern occurs!
PORTA = ((pattern[i]>>(j+1))<<PINA7) | ((pattern[i]>>j)<<PINA0);
// That the user can see the patterns a delay is necessary!
_delay_ms(1000);
}
}
// Signalize that the game starts
for (unsigned char i=0; i <8; i++)
{
PORTA ^= 0x81;
_delay_ms(1000);
}
TCNT0 = 0x00;
sei();
while(1)
{
// There is possible a signal missing to trigger next pattern input to the user!!!
if(!(PINF & (1<<PINF5)))
{
PORTA |= 0x80;
}
if(!(PINF & (1<<PINF3)))
{
PORTA |= 0x01;
}
// Time is 4 seconds to match the correct pattern
if(counter >= 4000)
{
if(!((pattern[pattern_position] & (1<<array_position)) == (0x01 & PORTA)))
{
// Wrong input end of game
}
array_position++;
if(!((pattern[pattern_position] & (1<<array_position)) == (0x01 & (PORTA>>8))))
{
// Wrong input end of game
}
array_position++;
if(array_position >= 8)
{
array_position = 0;
pattern_position++;
}
if(pattern_position >= (sizeof(pattern)/sizeof(&pattern[0])))
{
// End of game reached winning!
}
counter = 0x00;
PORTA = 0x00;
TCNT0 = 0x00;
}
}
}
I´m not sure if you are exactly trying this to do and i also can not test the code on your target platform but maybe this is a rudimental approach to solve your problem...

AVR programming, displaying wrong value on 7 seg. LED

I am interfacing LM35 with Atmega8. To display digits I use 7 segment LED anode display that I connect to AVR both ends (it handles it without transistors so why not). Strange thing happens:
res value after assigning it from adc is 237 (23.7 degrees). I want to print on my display the first digit (2).
If I leave last line in the while commented out, the display first shows digit 2 correctly but after the first delay it shows 1 instead of 2. Otherwise I get correctly digit 2. Why is this happening?
#ifndef F_CPU
#define F_CPU 1000000UL
#endif // F_CPU
#include <avr/io.h>
#include <util/delay.h>
#define DELAY_IN_MS 500 /* 0.5 sec */
int numbers[] = {
0b01000000,
0b01110011,
0b00100100,
0b00100001,
0b00010011,
0b00001001,
0b00001000,
0b01100011,
0b00000000,
0b00000001,
0b11111111 // off
};
uint8_t digits[3];
void initADC()
{
ADMUX=(1<<REFS1)|(1<<REFS0);
ADCSRA=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
}
uint16_t ReadADC(uint8_t ch)
{
//Select ADC Channel ch must be 0-7
ch=ch&0b00000111;
ADMUX|=ch;
//Start Single conversion
ADCSRA|=(1<<ADSC);
//Wait for conversion to complete
while(!(ADCSRA & (1<<ADIF)));
//Clear ADIF by writing one to it
ADCSRA|=(1<<ADIF);
return(ADC);
}
int main()
{
DDRD = 0xFF;
PORTD = 0xFF;
DDRB = 0b00000001;
PORTB = 1;
initADC();
uint16_t adc_value;
uint16_t res;
while(1)
{
adc_value = 0;
for (int i = 0; i < 250; i++)
{
adc_value += ReadADC(0);
}
adc_value=(adc_value/25)/4;
res = adc_value;
for(int j = 2; j >= 0; j--) {
digits[j] = res%10;
res /= 10;
}
uint8_t dig = digits[0];
PORTD = numbers[dig];
_delay_ms(DELAY_IN_MS);
// if following is uncommented there blinks digit two correctly
// if commented there is unblinking digit 1
PORTD = numbers[10]; // display off
}
return 0;
}
The problem was induction.
My circuit had many wires in non-soldering-field. When the display was on, there was a lot of induction going on changing resulting voltage on ADC input/LM35 output.
There is more than one solution.
1) Software: I moved ADC conversion into the interruption function. It turns of the displays, converts value from lm35 and displays digit on proper display. It happens so fast that the eye cant perceive it.
I prefer this one for now, because it makes my circuit simpler.
2) Hardware: adding L/C or R/C filter to adc pin should resolve the issue.
Full code for 1)
#ifndef F_CPU
#define F_CPU 1000000UL
#endif // F_CPU
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define DELAY_IN_MS 5000 /* ms */
#define NUM_OF_MEASUREMENTS 100
#define NUM_DISPLAYS 3
int numbers[] = {
0b10000001,
0b10011111,
0b10100100,
0b10010100,
0b10011010,
0b11010000,
0b11000000,
0b10011101,
0b10000000,
0b10010000,
0b11111111 // off
};
int display = 0;
uint8_t digits[NUM_DISPLAYS];
volatile uint16_t adc_values[NUM_OF_MEASUREMENTS];
int adc_read_cycle_index = 0;
uint32_t res;
void initADC()
{
ADMUX=(1<<REFS1)|(1<<REFS0);
ADCSRA=(1<<ADEN)|(1<<ADPS2);
}
uint16_t ReadADC(uint8_t ch)
{
//Select ADC Channel ch must be 0-7
ch=ch&0b00000111;
ADMUX|=ch;
//Start Single conversion
ADCSRA|=(1<<ADSC);
//Wait for conversion to complete
while (ADCSRA & (1<<ADSC));
return(ADC);
}
void readDegrees()
{
adc_values[adc_read_cycle_index] = (ReadADC(0)*10)/4;
if(adc_read_cycle_index + 1 == NUM_OF_MEASUREMENTS) {
adc_read_cycle_index = 0;
} else {
adc_read_cycle_index++;
}
}
void fetchTemperatureDigits() {
res = 0;
for(int i = 0; i < NUM_OF_MEASUREMENTS; i++) {
res += adc_values[i];
}
res /= NUM_OF_MEASUREMENTS;
for(int j = 2; j >= 0; j--) {
digits[j] = res%10;
res = res / 10;
}
}
void initTimer0()
{
// Prescaler = FCPU/64
TCCR0|=(1<<CS01);//|(1<<CS00);
//Enable Overflow Interrupt Enable
TIMSK|=(1<<TOIE0);
//Initialize Counter
TCNT0=0;
}
ISR(TIMER0_OVF_vect)
{
// turn off displays
PORTD = numbers[10];
// read ADC and convert to degrees
readDegrees();
// turn on proper anode
PORTB &= 0b11111000;
PORTB |= (1<<display);
// show digit
PORTD = numbers[digits[display]];
// show decimal point for second display (21.5 - second display shows "1.")
if(display == 1) {
PORTD &= 0b01111111;
}
// next display for next interruption
display++;
if(display == NUM_DISPLAYS) {
display = 0;
}
}
int main()
{
initADC();
for(int i = 0; i < NUM_OF_MEASUREMENTS; i++) {
readDegrees();
}
DDRD = 0xFF;
PORTD = 0;
DDRB |= 0b00000111;
PORTB |= 1;
initTimer0();
sei();
while(1) {
fetchTemperatureDigits();
_delay_ms(DELAY_IN_MS);
}
return 0;
}

how to use AD convertion in Atmega 1281

hi guys im trying alot to make ADC as an input pin in my Atmega1281 controller but no success
all i want is to control a micro servo with a potentiometer
here is my code please assist me with this it wont work on my controller
#define F_CPU 16000000 //16MHz
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdlib.h>
//#include <stdio.h>
//#include "uart/uart.h"
#define PWM_PRESCALLER 64
#define ICR_MAX (long double)F_CPU/PWM_PRESCALLER/50
#define OCR_MIN ICR_MAX/20
#define OCR_MAX ICR_MAX/10
//char uart_s[150];
volatile unsigned long adc_val=0;
volatile unsigned long counter=0;
unsigned long curr_adc=0;
ISR (ADC_vect)
{
adc_val += ADC;
counter++;
}
int main(void)
{
//uart_init(uart_calc_ubrr(F_CPU));
DDRB |= (1<<DDB1);
ICR1 = ICR_MAX;
OCR1A = OCR_MIN;
TCCR1A = (1 << COM1A1) | (1<<WGM11);
TCCR1B = (1<<WGM13) | (1<<WGM12) | (1<<CS11) | (1<<CS10);
ADMUX = (1 << REFS0);
ADCSRA = (1 << ADEN)|(1 << ADFR)|(1 << ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
sei();
ADCSRA |= (1<<ADSC);
while(1)
{
if(counter >= 500)
{
cli();
unsigned long round_val = round(adc_val / counter);
adc_val=0;
counter=0;
if(abs(round_val - curr_adc) > 1)
{
curr_adc = round_val;
}
long double ocr = OCR_MIN + ((long double)curr_adc * (OCR_MAX - OCR_MIN)/1024);
/*sprintf(uart_s, "ADC = %8lu, OCR = %f, rounded = %d\r\n", curr_adc, ocr, (int)round(ocr));
uart_send_string((unsigned char*) uart_s);*/
OCR1A = (int)round(ocr);
//_delay_ms(100);
sei();
}
}
}

Atmega16 USART initialization

I can't for the life of me find why this code is not working to send a byte to my computer terminal window. It receives and works fine when I omit that line though. Receiving and sending also work seperately. Please note that this is over rs485 so I must disable TXEN if I want anything received to make it through the line driver ic.
#define F_CPU 7800000UL // 7.8 MHz
#include <avr/io.h>
//#include <util/delay.h>
#include <avr/interrupt.h>
#include <math.h>
#define USART_BAUDRATE 57600
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
volatile unsigned int value = 0;
volatile int recievearray[4] = {0,0,0,0};
volatile int x=0;
void USART_Init(void)
{
DDRD = 0x7E; //you have to assign TXEN as output for some reason
//PORTD = 0xFF;
UCSRB = 0;
//Put the upper part of the baud number here (bits 8 to 11)
UBRRH = (unsigned char) (BAUD_PRESCALE >> 8);
//Put the remaining part of the baud number here
UBRRL = (unsigned char) BAUD_PRESCALE;
//PORTD = 2;
// ASYNCRONOUS
UCSRC = (0 << UMSEL);
//Enable the receiver and transmitter
UCSRB = (1 << RXEN) | (1 << TXEN) | (0 << UCSZ2) | (1<<RXCIE);
//Set 1 stop bits and data bit length is 8-bit
UCSRC = (1 << URSEL) | (0 << USBS) | (3 << UCSZ0);
//no parity
UCSRC |= (0 << UPM1);
UCSRC |= (0 << UPM0);
}
void USART_SendByte(uint8_t u8Data)
{
UCSRB = (1 << TXEN) | (1<<TXCIE);
// Wait until last byte has been transmitted
while((UCSRA &(1<<UDRE))==0);
UDR = u8Data;
UCSRB = (0 << TXEN) | (0<<TXCIE);
}
void Led_init(void){
DDRC = 0xFF;
}
ISR(USART_RXC_vect)
{
//PORTC = 0xFF;
while((UCSRA &(1<<RXC)) == 0);
value = UDR;
if (x < 4)
{
recievearray[x++] = value;
}
else
{
x = 0;
recievearray[x++] = value;
PORTC = 0x00;
}
}
int main(void)
{
USART_Init();
sei();
Led_init();
//PORTC = 0xFF;
for(;;)
{
if (recievearray[0] + recievearray[1] + recievearray[2] + recievearray[3] > 100)
{
PORTC = 0xFF;
USART_SendByte(value);
}
//_delay_ms(1000);
}
}

Resources