Neste exemplo é demonstardo como escrever e ler na eeprom do pic16F877A,depois de lido os dados e então enviado a porta serial do pic:
O código fonte:
/* * voltimetro usando RS-232 no MPlab XC8 * * Compilador : MPlabXC8 * Microcontrolador: 16F877A * Autor: aguivone * Versão: 1 * Data : 04 de março de 2013 */ #include <stdio.h> #include <string.h> //para usar funçoes de string deve se adicionar este header #include <stdlib.h> #define _XTAL_FREQ 20000000 // cristal de 20 Mhz #include <xc.h> /////////////////////////////////////////////////////////configuraçôes////////////////////////////////////////////////// #pragma config FOSC = HS // Oscillator Selection bits (HS oscillator) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled) #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled) #pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled) #pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming) #pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off) #pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control) #pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off) ////////////////////////////////////////////////variaveis globais/////////////////////////////////////////////////////////// char caracter,dados; bit flag_interrupcao = 0; ///////////////////////////////////////////////////interrupção////////////////////////////////////////////////////////////// void interrupt interrupcoes(void)//vetor de interrupção { if(RCIF) {//se interrupção de recepção da serial //aqui não será usado essa funcão caracter = RCREG; flag_interrupcao = 1; RCIF = 0;// limpa flag de interrupção de recepção } } /////////////////////////////////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; 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_RS232(char valor) { TXIF = 0;//limpa flag que sinaliza envio completo. TXREG = valor; while(TXIF ==0);//espera enviar caracter } void imprime_RS232(const char frase[]) { char indice = 0; char tamanho = strlen(frase); while(indice < tamanho ) ///veja que o programa pode travar se aqui não tiver as duas aspas { escreve_RS232(frase[indice]); indice++; } } char ler_memoria(char ende) { RP0 = 1; RP1 = 0;//acessa banco de memoria 2,para acessar o registrador EEADR EEADR = ende;//endereço 1 , verifique qual o endereço maximo de seu microcontrolador RP0 = 1; RP1 = 1;//acessa banco de memoria 3,para acessar o registrador EECON1 EEPGD = 0;//ponteiro da memoria de dados RD = 1;//inicia leitura RP0 = 1; RP1 = 0;//retorna ao banco para ler os dados return(EEDATA); } void escreve_memoria(char endereco,char dados) { char interrupcao; if(GIE == 1)//pega o estado da interrupção { interrupcao = 1; } RP0 = 1; RP1 = 1;//acessa banco de memoria 3,para acessar o registrador EECON1 while(WR == 1);//checa se está havendo escrita ,espera terminar algum processo de escrita se existir RP0 = 1; RP1 = 0;//acessa banco de memoria 2,para acessar o registrador EEADR EEDATA = dados; //escreve dados(é um bug do compilador mas os dados devem ser escritos antes do endereço) EEADR = endereco;//endereço 1 , verifique qual o endereço maximo de seu microcontrolador RP0 = 1; RP1 = 1;//acessa banco de memoria 3,para acessar o registrador EECON1 EEPGD = 0; WREN = 1;//habilita escrita GIE = 0;//desabilita as interrupções EECON2 = 0X55;//ação requerida conforme datasheet EECON2 = 0XAA;//é um codigo de segurança WR = 1;//inicia escrita na memoria if(interrupcao == 1) { GIE = 1;} WREN = 0;//disabilita escrita } //////////////////////////////////////////////////////Rotina principal/////////////////////////////////////////////////////////////// void main(void) { TRISB = 0X02;//configura portB B1 (pino RX) como entrada PORTB = 0; // limpar as portas que estão configuradas como saidas inicializa_RS232(9600,1);//modo de alta velocidade PEIE = 1;//habilita interrupção de perifericos do pic GIE = 1; //GIE: Global Interrupt Enable bit imprime_RS232("acessando a eeprom \n\r"); escreve_memoria(0X01,'T');//escreve dados escreve_memoria(0X02,'E'); escreve_memoria(0X03,'S'); escreve_memoria(0X04,'T'); escreve_memoria(0X05,'E'); imprime_RS232("Dados da memoria : \n\r"); escreve_RS232(ler_memoria(0X01)) ;//ler os dados do endereço escreve_RS232( ler_memoria(0X02)) ;//da eeprom escreve_RS232( ler_memoria(0X03)) ; escreve_RS232( ler_memoria(0X04)) ; escreve_RS232(ler_memoria(0X05)) ; for(;;) { }//loop infinito }
Olá
ResponderExcluirMe ajudou muito em um projeto, era só isto que me faltava.
Parabéns pelo blog muito bom mesmo.
Ola
ResponderExcluirPrimeiramente parabéns pelo blog, comecei a trabalhar com o xC8 e estou usando seus exemplos como base.
Quanto ao exemplo acima, acredito que as linhas que seta o BANK2 estão invertidas. Não seria RP0 = 0 e RP1 = 1.
Estou com um projeto montado e usando o 16F873 e fui obrigado a inverter agora esta 100%.
Novamente parabéns pelo blog e obrigado por compartilhar.
Abraço.
onde esta o rp0 e rp1 no data sheet?
ResponderExcluirObrigado
como fazer para escrever valor int por exemplo? Já Q cada local da memoria só comporta 8 bits
ResponderExcluir