Ir ao conteúdo
  • Comunicados

    • Gabriel Torres

      Seja um moderador do Clube do Hardware!   12-02-2016

      Prezados membros do Clube do Hardware, Está aberto o processo de seleção de novos moderadores para diversos setores ou áreas do Clube do Hardware. Os requisitos são:   Pelo menos 500 posts e um ano de cadastro; Boa frequência de participação; Ser respeitoso, cordial e educado com os demais membros; Ter bom nível de português; Ter razoável conhecimento da área em que pretende atuar; Saber trabalhar em equipe (com os moderadores, coordenadores e administradores).   Os interessados deverão enviar uma mensagem privada para o usuário @Equipe Clube do Hardware com o título "Candidato a moderador". A mensagem deverá conter respostas às perguntas abaixo:   Qual o seu nome completo? Qual sua data de nascimento? Qual sua formação/profissão? Já atuou como moderador em algo outro fórum, se sim, qual? De forma sucinta, explique o porquê de querer ser moderador do fórum e conte-nos um pouco sobre você.   OBS: Não se trata de função remunerada. Todos que fazem parte do staff são voluntários.
    • DiF

      Poste seus códigos corretamente!   21-05-2016

      Prezados membros do Fórum do Clube do Hardware, O Fórum oferece um recurso chamado CODE, onde o ícone no painel do editor é  <>     O uso deste recurso é  imprescindível para uma melhor leitura, manter a organização, diferenciar de texto comum e principalmente evitar que os compiladores e IDEs acusem erro ao colar um código copiado daqui. Portanto convido-lhes para ler as instruções de como usar este recurso CODE neste tópico:  
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

 

Editado por Rafael Pinati

Compartilhar este post


Link para o post
Compartilhar em outros sites
Postado (editado)

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

 

Editado por test man*~

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






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

×