/* * 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!