# [AVR]CRC using ATMEGA8 microcontroller

#### djc

##### Full Member level 6
Hello all.

I am writing a code for MODBUS protocol using Atmega8 and Mikroc compiler. I have done UART programming. I am able to receive the data and send the data serially over the UART. I used the c code for CRC generation mentioned in the Mod-bus PDF. I tried that code using C compiler. I send manual data '0x82' and received '213F' which is correct as i calculated it manually too. Now my question is while implementing it with the micro controller, when we receive the data through UART which contains address of the slave,function code, data and CRC code, the received data is in ASCII format. how to process this data. Do we need to give this data as it is to the CRC generator function or do we need to process it first to take out each byte and then send it to the CRC function. And in general to work on the UART first we have to minus 48 from each received character and then process it, then convert it into string and then send to LCD or back to UART again. So if i want to see the generated CRC on LCD or UART again, what do i need to do. Please guide me on this. Below is the code.

C:
#define FOSC 8000000//1843200// Clock Speed
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1

sbit LCD_RS at PORTD4_bit;
sbit LCD_EN at PORTD3_bit;
sbit LCD_D4 at PORTD5_bit;
sbit LCD_D5 at PORTD6_bit;
sbit LCD_D6 at PORTD7_bit;
sbit LCD_D7 at PORTB0_bit;

sbit LCD_RS_Direction at DDD4_bit;
sbit LCD_EN_Direction at DDD3_bit;
sbit LCD_D4_Direction at DDD5_bit;
sbit LCD_D5_Direction at DDD6_bit;
sbit LCD_D6_Direction at DDD7_bit;
sbit LCD_D7_Direction at DDB0_bit;

char Mydata[1],i=0,j=0,flag=0;
char Data[15];
int len=8;

unsigned char cur_crc;

unsigned short ModBus_CRC16( unsigned char * Buffer, unsigned short Length )
{
cur_crc=0xFFFF;
do
{
unsigned int i = 8;
cur_crc = cur_crc ^ *Buffer++;
do
{
if (0x0001 & cur_crc)
{
cur_crc >>= 1;
cur_crc ^= 0xA001;
}
else
{
cur_crc >>= 1;
}
}
while (--i);
}
while (--Length);
return cur_crc;
}

void main() {
DDRD |= 1 << PIND1;//pin1 of portD as OUTPUT
DDRD &= ~(1 << PIND0);//pin0 of portD as INPUT
PORTD |= 1 << PIND0;
Lcd_Init();
LCD_Out(1,1,"Test");
UART1_Init(9600);      // initialize UART1 module
Delay_ms(100);

while(1){
j=i;
flag=1;
for(j=0;j<=i;j++){
Delay_ms(2);
}
i=0;j=0;
}
else{i++;}
//i=0;
}
if(flag==1){
Mydata[0] = (Received_Data[0]-48)*10 + (Received_Data[1]-48);//Here i am processing first byte of data

IntToStr(Mydata[0], Data); //Convert it into string
UART1_Write_Text(Data);       //Display it
Delay_ms(1);

ModBus_CRC16(Data,1);    //Call the function to calculate CRC

IntToStr(cur_crc, Data); //Convert into string to display
LCD_Out(2,1,Data); //Display it on LCD
Delay_ms(1);

UART1_Write_Text(Data); //Display it on UART
Delay_ms(1);
flag=0;i=0;
}
}

}

#### KlausST

##### Super Moderator
Staff member
Hi,

A byte is a byte, it does not matter whether you "see" it as
* hex
* ASCII
* binary
* octal
* signed int
* unsigned int
* or anything else

The range will be always from 0x00 to 0xFF.
No special treatment necessary.

Just follow the CRC calculation rule and you are done.

Klaus

### djc

points: 2

#### djc

##### Full Member level 6
It helped me a lot Klaus, Means at the end i have to check it manually whether generated CRC code is right or wrong and if i want to see it on UART, process it as usual. Right. Means i just wanted to make sure that calculated CRC code is right by sending it on LCD or UART.

Last edited: