Ir ao conteúdo
  • Cadastre-se
Rafael Pinati

PIC Programação em PIC para Calculo check sum

Recommended Posts

Boa tarde galera, estou programando um algoritmo para calculo de check sum, porém o calculo não está sendo compilado corretamente, por favor deem uma olhada para ver aonde estou errando, já estou quebrando a cabeça uma semana nesse trem kkk

Segue também o fluxograma para o calculo.

Utilização de PIC 18f4550, cristal 20MHZ

 

/* 
 * File:   newmain.c
 * Author: Dev
 *
 * Created on 27 de Março de 2018, 11:07
 */
#include "newfile.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <plib.h>
#include <usart.h>
#define _XTAL_FREQ 20000000
#define U_ENABLE 0x8008    //enable UART, BREGH=1, 1 stop, no parity
#define U_TX 0x0400    //enable transmission, clear all flags
/*
 * 
 */
//Variaveis Globais


void main()
{
    //Rotina de Iniciação
    unsigned char config = 0, spbrg=0, baudconfig = 0,i=0;
    unsigned char TxData[12] = {0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x03, 0x9D, 0x32, 0x00, 0x01};
    unsigned char RxData [25];
    unsigned char outi [14];
    configuration ();
    CloseUSART ();
    
    //configuração USART
    config = USART_TX_INT_OFF & USART_RX_INT_OFF & USART_BRGH_LOW & USART_CONT_RX & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_ADDEN_OFF;
    spbrg = 129; //129
    baudconfig = BAUD_8_BIT_RATE & BAUD_AUTO_OFF & BAUD_WAKEUP_OFF;
    
    baudUSART(baudconfig);
    OpenUSART (config, spbrg);

    do {
       
        
        CRC (&TxData, outi); //adiciona o checksum ao pedido
        putsUSART (outi);
        delay(1000);
        
        }while (1);
    CloseUSART ();     
} 
#include <pic18F4550.h>
#include <string.h>
#include <xc.h>
 
// CONFIG1L
  #pragma config  PLLDIV = 1            // PLL Prescaler Selection bits (No prescale (8 MHz oscillator input drives PLL directly))
  #pragma config  CPUDIV = OSC1_PLL2    // System Clock Postscaler Selection bits ([Primary Oscillator Src: /1][96 MHz PLL Src: /2])
  #pragma config  USBDIV = 1            // USB Clock Selection bit (used in Full-Speed USB mode only// UCFG:FSEN = 1) (USB clock source comes directly from the primary oscillator block with no postscale)

// CONFIG1H
  #pragma config  FOSC = HS            // Oscillator Selection bits (HS oscillator (HS))
  #pragma config  FCMEN = OFF           // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
  #pragma config  IESO = OFF            // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)

// CONFIG2L
  #pragma config  PWRT = OFF            // Power-up Timer Enable bit (PWRT disabled)
  #pragma config  BOR = ON              // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
  #pragma config  BORV = 1              // Brown-out Reset Voltage bits (Minimum setting)
  #pragma config  VREGEN = OFF          // USB Voltage Regulator Enable bit (USB voltage regulator disabled)

// CONFIG2H
  #pragma config  WDT = OFF             // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
  #pragma config  WDTPS = 32768         // Watchdog Timer Postscale Select bits (1:32768)

// CONFIG3H
  #pragma config  CCP2MX = OFF          // CCP2 MUX bit (CCP2 input/output is multiplexed with RB3)
  #pragma config  PBADEN = OFF           // PORTB A/D Enable bit (PORTB<4:0> pins are pragma configured as analog input channels on Reset)
  #pragma config  LPT1OSC = OFF         // Low-Power Timer 1 Oscillator Enable bit (Timer1 pragma configured for higher power operation)
  #pragma config  MCLRE = ON            // MCLR Pin Enable bit (MCLR pin enabled// RE3 input pin disabled)

// CONFIG4L
  #pragma config  STVREN = ON           // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
  #pragma config  LVP = OFF             // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
  #pragma config  ICPRT = OFF           // Dedicated In-Circuit Debug/Programming Port (ICPORT) Enable bit (ICPORT disabled)
  #pragma config  XINST = OFF           // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))

// CONFIG5L
  #pragma config  CP0 = OFF             // Code Protection bit (Block 0 (000800-001FFFh) is not code-protected)
  #pragma config  CP1 = OFF             // Code Protection bit (Block 1 (002000-003FFFh) is not code-protected)
  #pragma config  CP2 = OFF             // Code Protection bit (Block 2 (004000-005FFFh) is not code-protected)
  #pragma config  CP3 = OFF             // Code Protection bit (Block 3 (006000-007FFFh) is not code-protected)

// CONFIG5H
  #pragma config  CPB = OFF             // Boot Block Code Protection bit (Boot block (000000-0007FFh) is not code-protected)
  #pragma config  CPD = OFF             // Data EEPROM Code Protection bit (Data EEPROM is not code-protected)

// CONFIG6L
  #pragma config  WRT0 = OFF            // Write Protection bit (Block 0 (000800-001FFFh) is not write-protected)
  #pragma config  WRT1 = OFF            // Write Protection bit (Block 1 (002000-003FFFh) is not write-protected)
  #pragma config  WRT2 = OFF            // Write Protection bit (Block 2 (004000-005FFFh) is not write-protected)
  #pragma config  WRT3 = OFF            // Write Protection bit (Block 3 (006000-007FFFh) is not write-protected)

// CONFIG6H
  #pragma config  WRTC = OFF            // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) are not write-protected)
  #pragma config  WRTB = OFF            // Boot Block Write Protection bit (Boot block (000000-0007FFh) is not write-protected)
  #pragma config  WRTD = OFF            // Data EEPROM Write Protection bit (Data EEPROM is not write-protected)

// CONFIG7L
  #pragma config  EBTR0 = OFF           // Table Read Protection bit (Block 0 (000800-001FFFh) is not protected from table reads executed in other blocks)
  #pragma config  EBTR1 = OFF           // Table Read Protection bit (Block 1 (002000-003FFFh) is not protected from table reads executed in other blocks)
  #pragma config  EBTR2 = OFF           // Table Read Protection bit (Block 2 (004000-005FFFh) is not protected from table reads executed in other blocks)
  #pragma config  EBTR3 = OFF           // Table Read Protection bit (Block 3 (006000-007FFFh) is not protected from table reads executed in other blocks)

// CONFIG7H
  #pragma config  EBTRB = OFF           // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) is not protected from table reads executed in other blocks)

//configuração serial

   /* TXSTA =   0b00100100; 
    RCSTA =   0b10000000;
    BAUDCON = 0b01000000;
   
    INTCONbits.GIE = 0x00;
    INTCONbits.PEIE = 0x00;
 */
//Functions
void delay (int );
void ADC_init ();
unsigned long ADC_read();
//void senddata(char* );
//void readdata(char* );
void CRC (char* , char* );


void delay(int c){
    for(long j = 0; j<20000*c; j++);
}
 
void configuration()
{
    
    OSCCONbits.IRCF = 0b111; //Configura oscilador interno (FOSC = 8Mhz)
    OSCCONbits.SCS = 0b10; // Fuente de Fosc del sistema = interno
    
    INTCONbits.GIE = 0x00;
    INTCONbits.PEIE = 0x00;
    //desabilita ccp
    CMCON =  0x07;
    
    TRISA = 0b00100011;                
    TRISC= 0b10111111;

    
    TXSTA =   0b00100100; 
    RCSTA =   0b10000000;
    BAUDCON = 0b01000000;
    
            
}

void ADC_init()
{
    ADCON0 = 0b00000000;
    ADCON1 = 0b00001110;
    ADCON2 = 0b00100101;
}

unsigned long ADC_read()
{
    unsigned long adc_rd;
    ADCON0bits.ADON = 1;
    delay (100); 
    ADCON0bits.GODONE = 1; // Inicia a conversão
    while (ADCON0bits.GODONE==1); // Aguarda fim da conversão
    ADCON0bits.ADON = 0;
    delay(200);
    adc_rd = ((ADRESH << 8) + ADRESL);
    return adc_rd;    
}


/*void senddata(dado) {
    char l;
    int i = 0;
    while(1)
    {
        l = dado[i];
        if(l == 0x00) break;
        while(!TRMT);
        TXREG = l;
        i++;
    }
    while(!TRMT);
    TXREG = '\r';
    while(!TRMT);
    TXREG = '\n';
}


void readdata(*buffer) { 
    int i=0;
    while (1) {
        //while(!RCIF);
        while((buffer[i] = RCREG) == 0x00);
        /*
        buffer[i] = RCREG;
        
        if (buffer[i]=='\r') break;
        i++;
    }
}
*/
void CRC (char *msg,char *out)
{
	//char CRC16[2] = {0xFF,0xFF};
	int CRC16 = 0xffff;
    int poly =  0xA001;
    char msgi [12];
	char data[14];
    char crc [2];
    
	strcpy (msgi,msg);
    
	for (int i=0; i<12; i++)
	{	
        CRC16 = msgi[i] ^ CRC16; //alteração data para msg
		
        for (int z=0; z<8; z++)
		{  
			CRC16 = CRC16 >> 1;
			if(CRC16%2 == 1) 
			{
				CRC16 = CRC16^poly; 
			}
		}
	}
    
    crc[0]= CRC16>>8;
    crc[1] = CRC16 & 0b0000000011111111 ;
    strcpy (data,msgi);
    strcat (data,crc);
    strcpy (out,data);
        
} 

 

Screenshot_21.png

adicionado 30 minutos depois

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Quando fiz a minha biblioteca para calcular o CRC (8 bits) usei uma lookup table para consumir menos tempo do AVR. Segue o códgo talvez te ajude, comentários em inglês com um monte de erros (estava treinando xD). Funcionou que é uma beleza! Estava até chato pois ele ficava denunciando meus erros de temporização na comunicação serial, eu não estava dando tempo suficiente entre os envios do pacote HAHA.

 

O que eu acho que vai te ajudar mesmo é este site ele explica não só como implementar mas também copmo funciona e também todos os detalhes. Foi através dele que consegui fazer o código acima.

Sub _compute_lookuptable(byval _crc_generator As Byte)
   Local _crc8_lookuptable_current_byte As Byte , _crc8_lookuptable_bit As Byte , _crc8_lookuptable_aux As Byte , _crc8_lookuptable_divident As Byte , _current_lookuptable_byte As Byte , _crc8_data As Byte

   For _crc8_lookuptable_divident = 0 To 255
      _current_lookuptable_byte = _crc8_lookuptable_divident

      For _crc8_lookuptable_bit = 1 To 8
         _crc8_lookuptable_aux = _current_lookuptable_byte And &H80

         If _crc8_lookuptable_aux <> 0 Then
            Shift _current_lookuptable_byte , Left , 1
            _current_lookuptable_byte = _current_lookuptable_byte Xor _crc_generator

            Else
               Shift _current_lookuptable_byte , Left , 1

         End If

         _crc8_lookup_table(_crc8_lookuptable_divident + 1) = _current_lookuptable_byte

      Next _crc8_lookuptable_bit
   Next _crc8_lookuptable_divident
End Sub

Function _compute_crc8(byref _string As String) As Byte     
   Local _ascii_byte As Byte , _crc8 As Byte , _i As Byte , _data As Byte

   _crc8 = 0                                                ' Init the CRC variable with zero (clear it)

   For _i = 1 To Len(_string)                               ' Goes trough every byte of the string (each cha ris a byte)
      _ascii_byte = Asc(_string , _i)                       ' The variable _acii_byte receives the byte that represents the character in ascii
      _data = _crc8 Xor _ascii_byte                         ' XOR with the next string byte
      _crc8 = _crc8_lookup_table(_data + 1)                 ' now takes the result that was pre calculataed and stored in the lookup table
   Next _i

   _compute_crc8 = _crc8                                    ' Return the computed CRC
End Function

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora





Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×