sexta-feira, 7 de outubro de 2016

Exemplos de uso de memória EEPROM e FLASH do PIC18F4550

Memória EEPROM




Programa para teste da memória EEPROM



   
/*
 * File:   Exemplo_eeprom.c
 * Author: Pilger
 *
 * Created on 3 de Outubro de 2017, 19:13
 *
 * Programa que lê a memória EEPROM e escreve dados sequencialmente
 */

#define _XTAL_FREQ 48000000

#include <stdio.h>
#include <xc.h>
#include "C:\h\Config_PIC18F4550.h"
#include "C:\h\biblioteca_lcd_2x162_48M_XC.h"

void delay_ms( int i );
unsigned char Eeprom_read(unsigned char addr);
void Eeprom_write(char addr, char data);


void main(void) {
    unsigned char address=0;
    unsigned char dado;   
    unsigned char buffer[16]; // buffer para linha de texto
    TRISD = 0;
    PORTD = 0;
    lcd_inicia(0x28, 0x0f, 0x06); // incializa o LCD com 4 linhas
    lcd_LD_cursor(0); // Desliga o cursor
    lcd_posicao(1, 2);
    imprime_string_lcd("EEPROM");
    while (1) {
        dado = Eeprom_read (address);
        lcd_posicao(2, 1);
        sprintf(buffer, "Read  %03d = %02X ",address,dado);
        imprime_buffer_lcd(buffer, 16);
        delay_ms(1000);
        address++;
        dado++;
        Eeprom_write (address,dado);
        lcd_posicao(2, 1);
        sprintf(buffer, "Write %03d = %02X ",address,dado);
        imprime_buffer_lcd(buffer, 16);
        delay_ms(1000);
   }
}

// função que gera um atraso de múltiplos de 1ms
void delay_ms( int i ) {
    for ( int x = 0; x < i; x++ ) {
     __delay_ms( 1 );
     }
}

unsigned char Eeprom_read(unsigned char addr){
EEADR = addr;           // EEADR recebe o endereço passado para a função
    EECON1bits.EEPGD = 0;   // Seleciona  área de mem = eeprom
    EECON1bits.CFGS = 0;    // Seleciona  área de mem = eeprom
    EECON1bits.FREE =0;     // modo de apagamento de flash não selecionada (0)
    EECON1bits.WREN = 0;    // escrita não permitida (0))
    EECON1bits.RD = 1;      // habilita opção de leitura, volta a zero no fim da op
return (EEDATA);        // retorna o conteúdo lido (de EEDATA)
}

void Eeprom_write(char addr, char data){
    char intcon_temp;
while (EECON1bits.WR); // se uma escrita estiver em andamento, aguarda
EEADR = addr; // configura o endereço inicial da escrita
    EECON1bits.EEPGD = 0;   // Seleciona  área de mem = eeprom
    EECON1bits.CFGS = 0;    // Seleciona  área de mem = eeprom   
    EECON1bits.WREN = 1;    // escrita permitida (1))
    EEDATA = data;          // escreve no registrador EEDATA o dado a ser gravado
    intcon_temp = INTCON;   // Guarda o valor do registrador INTCON
    INTCON = 0;             // Erase INTCON e disable interrups
    EECON2 = 0x55;          // senha de escrita em memória
    EECON2 = 0xAA;
    EECON1bits.WR =1;       // habilita a escrita , volta a zero no fim da op
    while (EECON1bits.WR);  // aguarda o fim da escrita, pois leva 4ms
    INTCON = intcon_temp;   // restaura o valor do registrador INTCON
}




   

Memória FLASH




Programa para teste da memória FLASH


   

/*
 * File:   Exemplo_flash.c
 * Author: Pilger
 *
 * Created on 3 de Outubro de 2017, 19:30
 * 
 * Programa de exemplo memória FLASH
 */


#define _XTAL_FREQ 48000000

#include <stdio.h>
#include <xc.h>
#include "C:\h\Config_PIC18F4550.h"
#include "C:\h\biblioteca_lcd_2x162_48M_XC.h"

void delay_ms( int i );
unsigned char Flash_erase(unsigned long address);
unsigned char Flash_read(unsigned long address);
void Flash_write(unsigned long endereco, unsigned char dado);

void main(void) {
    // variáveis locais
    unsigned char i;
    unsigned long address=0x000F00;
    unsigned char dado;
    
    unsigned char buffer[16]; // buffer para linha de texto
    TRISD = 0;
    PORTD = 0;
    lcd_inicia(0x28, 0x0f, 0x06); // incializa o LCD com 4 linhas
    lcd_LD_cursor(0); // Desliga o cursor
    lcd_posicao(1, 2);
    imprime_string_lcd("Flash");
    while (1) {
        // apaga a memória grava 0xFF
        address = 0x000F00;
        lcd_posicao(1, 9);
        imprime_string_lcd("Erase");
        Flash_erase(0x000F00);
        delay_ms(2000);
        // escreve de 20 a 0
        address = 0x000F00;
        lcd_posicao(1, 9);
        imprime_string_lcd("Write");
        for (i = 0; i < 20; i++){
            Flash_write(address, 19-i);
            address++;
        }
        delay_ms(2000);
        // le a memoria
        address = 0x000F00;
        lcd_posicao(1, 9);
        imprime_string_lcd("Read ");
        for (i = 0; i < 20; i++) {
            dado = Flash_read(address+i);
            lcd_posicao(2, 1);
            sprintf(buffer, "%06X = %02X", 0x000F00+i,dado);
            imprime_buffer_lcd(buffer, 11);
            delay_ms(1000);
        }
        // apaga a memória grava 0xFF
        address = 0x000F00;
        lcd_posicao(1, 9);
        imprime_string_lcd("Erase");
        Flash_erase(0x000F00);
        delay_ms(2000);
        // le a memória apagada
        address = 0x000F00;
        lcd_posicao(1, 9);
        imprime_string_lcd("Read ");
        for (i = 0; i < 20; i++) {
            dado = Flash_read(address+i);
            lcd_posicao(2, 1);
            sprintf(buffer, "%06X = %02X",0x000F00+i,dado);
            imprime_buffer_lcd(buffer, 11);
            delay_ms(1000);
        }
        // escreve de 00 a 20
        address = 0x000F00;
        lcd_posicao(1, 9);
        imprime_string_lcd("Write");
        for (i = 0; i < 20; i++){
            Flash_write(address, i);
            address++;
        }
        delay_ms(2000);
        // le as 20 posições
        address = 0x000F00;
        lcd_posicao(1, 9);
        imprime_string_lcd("Read ");
        for (i = 0; i < 20; i++) {
            dado = Flash_read(address+i);
            lcd_posicao(2, 1);
            sprintf(buffer, "%06X = %02X", 0x000F00+i,dado);
            imprime_buffer_lcd(buffer, 11);
            delay_ms(1000);
        }
   }
}

// função que gera um atraso de múltiplos de 1ms
void delay_ms( int i ) {
    for ( int x = 0; x < i; x++ ) {
     __delay_ms( 1 );
     }
}

unsigned char Flash_read(unsigned long address) {
    TBLPTRU = *(((char *)& address)+2);
    TBLPTRH = *(((char *)& address)+1);
    TBLPTRL = *((char *)& address);
    asm("TBLRDPOSTINC");
    return TABLAT;
}

unsigned char Flash_erase (unsigned long address) {
    unsigned char intcon_temp;
    TBLPTRU = *(((char *)& address)+2);
    TBLPTRH = *(((char *)& address)+1);
    TBLPTRL = *((char *)& address); // load address
    EECON1bits.EEPGD = 1;   // Access Flash program memory
    EECON1bits.FREE = 1;    // Erase the program memory row addressed by TBLPTR on the next WR command (cleared by completion of erase operation)
    EECON1bits.WREN = 1;    // Allows write cycles to Flash program/data EEPROM
    intcon_temp = INTCON;   // Store value INTCON register
    INTCON = 0;             // Erase INTCON e disable interrups
    EECON2 = 0x55;          // senha de escrita em memória
    EECON2 = 0xAA;
    EECON1bits.WR = 1;      // seta WR w inicia a escrita
    Nop();
    EECON1bits.WREN = 0;    // erase WREN - Inhibits write cycles to Flash program/data EEPROM
    INTCON = intcon_temp;   // restore INTCON register
    asm("TBLRDPOSTINC");
    return TABLAT;
}

void Flash_write(unsigned long endereco, unsigned char dado)
{
unsigned char intcon_temp, cnt;
TBLPTRU = *(((char *)&endereco)+2); // parte alta do endereço
TBLPTRH = *(((char *)&endereco)+1);
TBLPTRL = *((char *)&endereco); // parte baixa do endereço
cnt = endereco & 0x20; // CNT contém o offset do endereço
TABLAT = 0xFF;          // TABLAT = 0xFF
                            // escreve 0xFF nas posições de memória que precedem o endereço desejado
while (cnt--) 
        asm("TBLWTPOSTINC");// enquanto CNT>0 escreve 0xFF na flash
TABLAT = dado;     // agora escreve o dado
asm("TBLWTPOSTINC"); // escreve o dado na memória
EECON1bits.EEPGD = 1;   // Access Flash program memory
    EECON1bits.WREN = 1;    // Allows write cycles to Flash program/data EEPROM
intcon_temp = INTCON; // salva o estado atual do INTCON
INTCON = 0;             // apaga INTCON, desabilita interrupções
EECON2 = 0x55;          // senha de escrita na memória
EECON2 = 0xAA;
EECON1bits.WR = 1;      // seta WR, inicia a escrita
Nop();                  // NOP recomendado pelo fabricante
EECON1bits.WREN = 0; // apaga WREN
INTCON = intcon_temp; // restaura INTCON
}



   






4 comentários:

  1. mas cara, onde estão essas bibliotecas .h que você importou?

    ResponderExcluir
  2. tem algum desse elabore um firmware que escreva no display de LCD os numero
    digitados no teclado e limpe o mesmo quando pressionado RB3.
    pic18f4550

    ResponderExcluir