Contoh Code perhitungan CRC16 untuk AVR dengan CodeVision

Sedikit modifikasi CRC16 dari code C#  buat protokol MODBUS untuk slave / microcontroller  silahkan dipelajari dan dicoba.

Untuk mengecek hasil bisa dibandingkan dengan perhitungan CRC  disini 

/*****************************************************
Date : 6/21/2011
CPU : ATmega8535
Program type : Application
Clock frequency : 4.000000 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 128
program by :https://pccontrol.wordpress.com
/*****************************************************/

#include <mega8535.h>
#include <math.h>
#include <delay.h>
// Alphanumeric LCD Module functions
#asm
   .equ __lcd_port=0x15 ;PORTC
#endasm
#include <lcd.h>
#include <string.h>
#include <stdio.h>

#define RXB8 1
#define TXB8 0
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7

#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)

// USART Receiver buffer
#define RX_BUFFER_SIZE 30
unsigned char rx_buffer[RX_BUFFER_SIZE];
unsigned char tampung1[16];
unsigned char tampung2[16];
//char tampung3[16];
unsigned char tampungAlamat[10];
unsigned char tampungCRCLow[10];
unsigned char tampungCRCHigh[10];

unsigned char CRC[5];
unsigned char tampung3[10];
unsigned char r_ready,alamat;
unsigned int crcfull ,crclow,crchigh;
unsigned int GetCRC(char message[], char panjangdata);
unsigned char rx_wr_index;

// This flag is set on USART Receiver buffer overflow
//bit rx_buffer_overflow;

// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
   {
     if (data != '\r')
       {

        rx_buffer[rx_wr_index]=data;
        rx_wr_index++;
        }
        else
        {
        lcd_clear();
         rx_buffer[rx_wr_index]=''; 

       crcfull =  GetCRC(rx_buffer,rx_wr_index);
           crclow = ((crcfull >> 8) & 0xFF);
           crchigh= (crcfull & 0xFF);
           alamat = rx_buffer[0];
        //tampilkan byte ke 1 CRC High  di LCD 2x16  dlm bentuk desimal
           lcd_gotoxy(0,0);
           sprintf(tampungAlamat,"%i",alamat);
           lcd_puts(tampungAlamat); 

           //tampilkan CRC High  di LCD 2x16  dlm bentuk desimal
           lcd_gotoxy(5,1);
           sprintf(tampungCRCHigh,"%i",crchigh);
           lcd_puts(tampungCRCHigh);
           //Tampilkan CRC Low di LCD 2x16   dlm bentuk desimal
             lcd_gotoxy(0,1);
           sprintf(tampungCRCLow,"%i",crclow);
           lcd_puts(tampungCRCLow); 

         sprintf(tampung3,"%i",rx_wr_index);
         lcd_gotoxy(14,0);
         lcd_puts(tampung3); 

         rx_wr_index=0;
         r_ready=1;
         UCSRB.7=0;

        }

   };
}

void main(void)
{

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud rate: 9600
UCSRA=0x00;
UCSRB=0x98;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x19;

// LCD module initialization
lcd_init(16);
lcd_gotoxy(0,0);
lcd_putsf("waiting data");
// Global enable interrupts
#asm("sei")

 r_ready=0;
 rx_wr_index=0;
 UCSRB.7=1;  

while (1)
      {

        if(r_ready==1)
           {
             r_ready=0;

       rx_wr_index=0;

       UCSRB.7=1;
            } 

      }; //end of while(1)
}

        unsigned  int GetCRC(char message[], char panjangdata)
        {
            //Function expects a modbus message of any length as well as a 2 byte CRC array in which to
            //return the CRC values:
           unsigned char i,j;
            unsigned int  CRCFull = 0xFFFF;
           unsigned char CRCHigh = 0xFF, CRCLow = 0xFF;
           unsigned  char CRCLSB;

            for (i = 0; i < (panjangdata) ; i++)
            {
                CRCFull = (CRCFull ^ message[i]);

                for ( j = 0; j < 8; j++)
                {
                    CRCLSB = (CRCFull & 0x0001);   //ambil LSB
                    CRCFull = ((CRCFull >> 1) & 0x7FFF);  // geser 

                    if (CRCLSB == 1)
                        CRCFull = CRCFull ^ 0xA001;
                }
            }
           // CRC[1] = CRCHigh = ((CRCFull >> 8) & 0xFF);
           // CRC[0] = CRCLow = (CRCFull & 0xFF); 

           return CRCFull;
        }

Program C# untuk mengirim data Byte ke Microcontroller

private void button2_Click(object sender, EventArgs e)
        {
            byte[] message = new byte[4]; // termasuk 0x0D
            byte data1 = Convert.ToByte(textBox1.Text);
            byte data2 = Convert.ToByte(textBox2.Text);
            byte data3 = Convert.ToByte(textBox3.Text);

            message[0] = data1;
            message[1] = data2;
            message[2] = data3 ;
            message[message.Length-1] = 0x0D;   //byte  terakhir diberi  0x0DH atau '\r'
                                                //  supaya matching sama micon :-)
            serialPort1.Write(message, 0, message.Length);

        }
 private void buttonStart_Click(object sender, EventArgs e)
        {
            serialPort1.PortName = "COM1";
            serialPort1.BaudRate = 9600;

            serialPort1.Open();
            if (serialPort1.IsOpen)
            {
                buttonStart.Enabled = false;
                buttonStop.Enabled = true;
                textBox1.ReadOnly = false;
            }
        }

        private void buttonStop_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                serialPort1.Close();
                buttonStart.Enabled = true;
                buttonStop.Enabled = false;
                textBox1.ReadOnly = true;
            }

        }

Hasil Pengujian :
bandingkan dengan di salah satu perhitungan online :

Perhitungan Online Modbus CRC16

Advertisements

About pccontrol

Berisi Tutorial Menggunakan PC untuk mengontrol Peralatan dengan cara mudah & praktis untuk pemula.

Posted on 21/06/2011, in Contoh-contoh Aplikasi. Bookmark the permalink. 5 Comments.

  1. assalamualikum, mas mw tanya untuk listing program pembacaan data per blok(biner atau hexa) memori dalam LCD 2×16 ketika menampilkan karakter, dan hasilnya dikirim serial melalui PC. gmna ia mas? mohon bantuannya untuk skripsi saya. email : andi_rachmansyah_12p2@yahoo.com

  1. Pingback: Contoh Aplikasi Vb.Net

  2. Pingback: Contoh Aplikasi Database Menggunakan Vb.Net

  3. Pingback: Contoh Program Vb.Net Database

  4. Pingback: Contoh Program Vb.Net

Komentar ,Saran atau Pertanyaan

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: