terça-feira, 22 de abril de 2014

Usando sensor de temperatura TC72 da microchip.

Olá vou demonstrar como usar o sensor de temperatura TC72 da microchip com o microcontrolador PIC 18F13K22 , a comunicação com este sensor é via SPI , vamos ao código fonte :
/*
 *                                 Usando sensor de temperatura TC72
 *
 * Compilador : MPlabXC8
 * Microcontrolador: 18F13K22
 * Autor: aguivone
 * Versão: 1
 * Data :  22 de abril 2014
 * Descrição : como usar o sensor de temperatura TC72 e enviar via porta serial 
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "GenericTypeDefs.h"
#define _XTAL_FREQ 16000000    // cristal de 16 Mhz
#include <xc.h>

/////////////////////////////////////////////////////configuraçôes do pic //////////////////////////////////////////////////
//**************************************************************************************************
// CONFIGURAÇÃO DOS FUSÍVEIS
//**************************************************************************************************
// CONFIG1H
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
//#pragma config PLLEN = ON       // Se igual a 1(on) o clock será multiplicado por 4
#pragma config PLLEN = OFF      // desabilitado
#pragma config PCLKEN = ON      // Primary Clock Enable bit (Primary clock enabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF       // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)

// CONFIG2L
#pragma config PWRTEN = ON     // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = SBORDIS  // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
#pragma config BORV = 19        // Brown Out Reset Voltage bits (VBOR set to 1.9 V nominal)

// CONFIG2H
#pragma config WDTEN = OFF      // Watchdog Timer Enable bit (WDT is controlled by SWDTEN bit of the WDTCON register)
#pragma config WDTPS = 32768    // Watchdog Timer Postscale Select bits (1:32768)

// CONFIG3H
#pragma config HFOFST = ON      // HFINTOSC Fast Start-up bit (HFINTOSC starts clocking the CPU without waiting for the oscillator to stablize.)
#pragma config MCLRE = OFF       // MCLR Pin Enable bit (MCLR pin enabled, RA3 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 BBSIZ = OFF      // Boot Block Size Select bit (512W boot block size)
#pragma config XINST = OFF      // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))

// CONFIG5L
#pragma config CP0 = ON        // Code Protection bit (Block 0 not code-protected)
#pragma config CP1 = ON        // Code Protection bit (Block 1 not code-protected)

// CONFIG5H
#pragma config CPB = ON       // Boot Block Code Protection bit (Boot block not code-protected)
#pragma config CPD = ON        // Data EEPROM Code Protection bit (Data EEPROM not code-protected)

// CONFIG6L
#pragma config WRT0 = ON       // Write Protection bit (Block 0 not write-protected)
#pragma config WRT1 = ON       // Write Protection bit (Block 1 not write-protected)

// CONFIG6H
#pragma config WRTC = ON       // Configuration Register Write Protection bit (Configuration registers not write-protected)
#pragma config WRTB = ON       // Boot Block Write Protection bit (Boot block not write-protected)
#pragma config WRTD = ON       // Data EEPROM Write Protection bit (Data EEPROM not write-protected)

// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protection bit (Block 0 not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF      // Table Read Protection bit (Block 1 not protected from table reads executed in other blocks)

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


/////////////////////////////Defines utilizados////////////////////////////////////////////////////////////////////////
#define SPI_SS    LATCbits.LATC6 //configura pino de Slave selected
#define LED       LATCbits.LATC0

// Wiznet W5200 endereço dos registradores
#define LER_LSB         0x01   // lê o byte menos significativo
#define LER_MSB         0x02   // lê o byte mais significativo
#define LER_ID          0x03   // lê o ID do chip

#define ESCREVE         0x80   // escreve dados
////variaveis usadas /////////////
unsigned int temp_msb;
unsigned char temp_lsb,sensor_id;
unsigned int temperatura;
char caracter;
bit flag_interrupcao = 0;
////////////////////////////////////rotina de tempo////////////////////////////////////////////////////////////
void delay_ms(long mili) {
    while (mili > 0) {
        _delay(15600); //aprox. 1ms com clock de 64mhz
        mili--;
    }
}
void delay_us(long micro) {
    while (micro > 0) {
        _delay(15); //aprox. 1us com clock de 64mhz
        micro--;
    }
}

unsigned char ler_SPI( unsigned char dado )
{
  unsigned char TempVar;
  SPI_SS    = 1;
   delay_us(5);
  TempVar = SSPBUF;        // limpa BF
  SSPBUF = dado;           // escreve no buffer
  while ( !SSPSTATbits.BF );//espera terminar o envio
  SSPBUF = 0X00;           // envia um dado qual qualquer
  while ( !SSPSTATbits.BF );
   SPI_SS    = 0;
  return (SSPBUF);       // byte lido
}
void escreve_SPI( unsigned char dado )
{
   unsigned char TempVar;
   SPI_SS    = 1;
   delay_us(5);
   TempVar = SSPBUF;        // limpa BF
   SSPBUF = 0x80;           // escreve no buffer
   while ( !SSPSTATbits.BF ); //espera terminar o envio
   SSPBUF = dado;           // escreve no buffer
   while ( !SSPSTATbits.BF );
   SPI_SS    = 0;
}
void inicializa_spi_mestre(void)//inicialica modo mestre
{    
    SSPCON1 = 0X20; //habilita pinos de spi // FOSC/4 //clock em nivel 0
    SSPSTAT = 0X80; //pega amostras no fim do byte e a trasmissão será na borda de subida
    SPI_SS = 0;
}

void inicializa_TC72(void)
 {
     escreve_SPI(0x40);//solicita escrita - configura o TC72
    //configura registrado de controle, configura para captura continua e shutdown desabilitado
 }

/////////////////////////////////funçoes usadas pela uart //////////////////////////////////////////////////////
void inicializa_RS232(long velocidade,int modo)
{////por padrão é usado o modo 8 bits e sem paridade, mas se necessario ajuste aqui a configuração desejada.
    //verifique datasheet para ver a porcentagem de erro e se a velocidade é possivel para o cristal utilizado.
    RCSTA = 0X90;//habilita porta serial,recepção de 8 bit em modo continuo,assincrono.
    int valor;
        if(modo == 1)
        {//modo = 1 ,modo alta velocidade
         TXSTA = 0X24;//modo assincrono,trasmissao 8 bits.
         valor =(int)(((_XTAL_FREQ/velocidade)-16)/16);//calculo do valor do gerador de baud rate
        }
        else
        {//modo = 0 ,modo baixa velocidade
         TXSTA = 0X20;//modo assincrono,trasmissao 8 bits.
         valor =(int)(((_XTAL_FREQ/velocidade)-64)/64);//calculo do valor do gerador de baud rate
        }
    SPBRG = valor;
   // PIE1 = 0X20;
    RCIE = 1;//habilita interrupção de recepção
    TXIE = 0;//deixa interrupção de transmissão desligado(pois corre se o risco de ter uma interrupção escrita e leitura ao mesmo tempo)
}
void escreve(char valor)
{
    TXIF = 0;//limpa flag que sinaliza envio completo.
    TXREG = valor;
    while(TXIF ==0);//espera enviar caracter
}

void imprime(const char frase[])
{
     char indice = 0;
     unsigned char tamanho = strlen(frase);
      while(indice < tamanho ) ///veja que o programa pode travar se aqui não tiver as duas aspas
       {
           escreve(frase[indice]);
           indice++;
       }
}

void int_to_char(int quant)
{
    char convert_char3='0';
    char  convert_char2='0';
    char convert_char1='0';
        int temp = quant;
      
       while(quant>=100)
        {
         quant=quant-100;
         convert_char3++;
         }
       while(quant>=10)
        {
         quant=quant-10;
        convert_char2++;
         }
       while(quant>=1)
        {
           quant=quant-1;
         convert_char1++;
         }
           if(temp>=100)
           {
             escreve(convert_char3);
           }
          if(temp>=10)
           {
            escreve(convert_char2);
           }
        escreve(convert_char1);
            escreve('\n');//pula linha
            escreve('\r');//vai ao inicio da linha
}

//////////////////////////////////////////////////////Rotina principal///////////////////////////////////////////////////////////////

void main(void)
{

    TRISA = 0XFF;
    TRISB = 0X30; //configura portB como saida exceto o pino b4(SDI)e b5(RX da serial)
    TRISC = 0X00; //configura portc como saida
    ANSEL = 0xFF; //desabilita porta analogicas(para não atrapalhar recepção no pino)
    ANSELH = 0xFF; //em alguns casos não funciona nem a interrupção de recepção.
    CM1CON0 = 0X00;
    CM2CON0 = 0X00;
    CM2CON1 = 0X00;
    inicializa_RS232(9600,1);//modo de alta velocidade
    inicializa_spi_mestre();
    INTCON = 0xC0;//interrrupção global e de periferico habilitadas
    inicializa_TC72();
    imprime("Usando sensor de temperatura TC72! \n\r");
    for (;;)
    {
        LED = ~LED;
        temp_msb = ler_SPI(LER_MSB);//solicita escrita
      //  temp_lsb = ler_SPI(LER_LSB);//vamos usar somente a parte inteira da temperatura
        sensor_id = ler_SPI(LER_ID);//solicita escrita
        imprime(" \n\r Temperatura : ");
        if((temp_msb&0b10000000)< 127)//o maximo que o sensor vai é até 125°C
        {
          int_to_char(temp_msb&0b01111111);
        }
        else
         {
           escreve('-');
           int_to_char(128 -(temp_msb&0b01111111));//o valor é negativo
        }
        imprime(" \n\r Numero do chip: ");
        int_to_char(sensor_id);
        delay_ms(500);
    }//chave do laço infinito (for)
}//chave de main

Esquemático e simulação:

Nenhum comentário :

Postar um comentário

olá,digite aqui seu comentário!