Ir ao conteúdo
  • Cadastre-se
CaueGP

PIC16F877A + Memória 24C256 + RTC DS1307 em assembly

Recommended Posts

Olá!

Pessoal, sou novato no fórum.

Estou buscando um código em assembly para um PIC16F877A trabalhando com um relógio DS1307 e uma memória 24C256, gostaria de exemplos de como utilizar o protocolo I²C em assembly, pois achi somente para CCS e como não to me saindo muito bem com ele resolvi procurar em assembly.

Dei uma pesquisada nos tópicos e não achei muitos tópicos falando sobre este assunto, os que achei os links para download de algo estavam offline e eram antigos.

Ficarei grato se puderem me ajudar!

Obrigado! ^_^

Compartilhar este post


Link para o post
Compartilhar em outros sites

Tenho exemplo em ASM,mas é com o 16F84 e a rotina I2C é por software,mas é LCD,RTC e a memo.

No seu caso precisa dizer se está aprendendo a usar o protocolo ou quer apenas fazer funcionar.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Acho q é mais fácil você resolver o problema com o CCS do que tentar fazer o programa em assembly...Q problema está tendo com o CCS?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Como faço para integrar um PIC, DS1307 e LCD de duas ou três linhas para gravar e ler logs de eventos, a fim de monitorar o funcionamento de um motor. EX:

Log 01 - 01/04/12 - Ligou as 10:00h.

Log 02 - 01/04/12 - Desligou as 11:00h.

Tempo de funcionamento 1:00h.

Log 03 - 01/04/12 - Ligou as 15:30h.

Log 04 - 01/04/12 - Desligou as 16:55h.

Tempo de funcionamento 1:25h.

Log 05 - 01/04/12 - Ligou as 20:30h.

Log 06 - 01/04/12 - Desligou as 21:30h.

Tempo de funcionamento 1:00h.

Log 10 - Dia 01/04/12 total do funcionamento 3:25h.

Existe algum projeto neste estilo?

Compartilhar este post


Link para o post
Compartilhar em outros sites

FelipeMartin

Com ajuda de nosso amigo aqui do CH "Grande Jorge", desenvolvemos a um tempo atrás um relógio com display 16X2, com DS1307, e o LM35. Inclusive foi um projeto interessante, montado e totalmente funcional. Se houver o interesse posso postar o circuito (no Proteus) e o código, só que em HEX.

Valeu.

Jorge Ainda estou por aqui meu grande irmão.

Esqueci o PIC foi um 18F877A

Valeu

JA

Para o DS1307 utilizamos este arquivo

////////////////////////////////////////////////////////////////////////////////

/// DS1307.C ///

/// Driver for Real Time Clock ///

/// ///

/// ds1307_init() - Enable oscillator without clearing the seconds register -///

/// used when PIC loses power and DS1307 run from 3V BAT ///

/// - Disable squarewave output ///

/// ///

/// ds1307_set_date_time(day,mth,year,dow,hour,mim,sec) Set the date/time ///

/// ///

/// ds1307_get_date(day,mth,year,dow) Get the date ///

/// ///

/// ds1307_get_time(hr,mim,sec) Get the time ///

/// ///

////////////////////////////////////////////////////////////////////////////////

#define RTC_SDA PIN_C4

#define RTC_SCL PIN_C3

#use i2c(master, sda=RTC_SDA, scl=RTC_SCL)

#use i2c(sda=PIN_C4, scl=PIN_C3, stream=I2C_HW)

BYTE bin2bcd(BYTE binary_value);

BYTE bcd2bin(BYTE bcd_value);

void ds1307_init(void)

{

BYTE seconds = 0;

i2c_start();

i2c_write(0xD0); // WR to RTC

i2c_write(0x00); // REG 0

i2c_start();

i2c_write(0xD1); // RD from RTC

seconds = bcd2bin(i2c_read(0)); // Read current "seconds" in DS1307

i2c_stop();

seconds &= 0x7F;

delay_us(3);

i2c_start();

i2c_write(0xD0); // WR to RTC

i2c_write(0x00); // REG 0

i2c_write(bin2bcd(seconds)); // Start oscillator with current "seconds value

i2c_start();

i2c_write(0xD0); // WR to RTC

i2c_write(0x07); // Control Register

i2c_write(0x10); // Disable squarewave output pin

i2c_stop();

}

void ds1307_set_date_time(BYTE day, BYTE mth, BYTE year, BYTE dow, BYTE hr, BYTE mim, BYTE sec)

{

sec &= 0x7F;

hr &= 0x3F;

i2c_start();

i2c_write(0xD0); // I2C write address

i2c_write(0x00); // Start at REG 0 - Seconds

i2c_write(bin2bcd(sec)); // REG 0

i2c_write(bin2bcd(mim)); // REG 1

i2c_write(bin2bcd(hr)); // REG 2

i2c_write(bin2bcd(dow)); // REG 3

i2c_write(bin2bcd(day)); // REG 4

i2c_write(bin2bcd(mth)); // REG 5

i2c_write(bin2bcd(year)); // REG 6

i2c_write(0x10); // REG 7 - Disable squarewave output pin

i2c_stop();

}

void ds1307_get_date(BYTE &day, BYTE &mth, BYTE &year, BYTE &dow)

{

i2c_start();

i2c_write(0xD0);

i2c_write(0x03); // Start at REG 3 - Day of week

i2c_start();

i2c_write(0xD1);

dow = bcd2bin(i2c_read() & 0x7f); // REG 3

day = bcd2bin(i2c_read() & 0x3f); // REG 4

mth = bcd2bin(i2c_read() & 0x1f); // REG 5

year = bcd2bin(i2c_read(0)); // REG 6

i2c_stop();

}

void ds1307_get_time(BYTE &hr, BYTE &mim, BYTE &sec)

{

i2c_start();

i2c_write(0xD0);

i2c_write(0x00); // Start at REG 0 - Seconds

i2c_start();

i2c_write(0xD1);

sec = bcd2bin(i2c_read() & 0x7f);

mim = bcd2bin(i2c_read() & 0x7f);

hr = bcd2bin(i2c_read() & 0x3f);

i2c_stop();

}

BYTE bin2bcd(BYTE binary_value)

{

BYTE temp;

BYTE retval;

temp = binary_value;

retval = 0;

while(1)

{

// Get the tens digit by doing multiple subtraction

// of 10 from the binary value.

if(temp >= 10)

{

temp -= 10;

retval += 0x10;

}

else // Get the ones digit by adding the remainder.

{

retval += temp;

break;

}

}

return(retval);

}

// Input range - 00 to 99.

BYTE bcd2bin(BYTE bcd_value)

{

BYTE temp;

temp = bcd_value;

// Shifting upper digit right by 1 is same as multiplying by 8.

temp >>= 1;

// Isolate the bits for the upper digit.

temp &= 0x78;

// Now return: (Tens * 8) + (Tens * 2) + Ones

return(temp + (temp >> 2) + (bcd_value & 0x0f));

}

Compartilhar este post


Link para o post
Compartilhar em outros sites

Este é o código

#include <16F877A.h>
#device adc=10 //Habilitar ADC de 10 bits, obrigatório. Pode
//ser utilizado de 8 bits também.
#FUSES NOWDT //No Watch Dog Timer
#FUSES XT //Clock <=4Mhz
#FUSES PUT //Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection

#use delay(clock=4000000)

#include <ds1307.c>
#include <lcd.c>

#define botao_incremento PIN_B0
#define botao_decremento PIN_B1

BYTE sec;
BYTE mim;
BYTE hrs;
BYTE day;
BYTE month;
BYTE yr;
BYTE dow;

int8 modo;
int16 adc;
float temperatura;

int8 tempo;

char dia_da_semana[7][8]=
{
"DOMINGO",
"SEGUNDA",
"TERCA",
"QUARTA",
"QUINTA",
"SEXTA",
"sábado",
};

#int_timer1
void trata_tempo()
{
tempo++;

if (tempo == 10)
{
output_toggle (PIN_B7);
tempo=0;
disable_interrupts( INT_TIMER1); //Habilita interrupção timer1
}
set_timer1 (3036);
}

#int_ccp1
void trata_ccp_1()
{
if ((modo == 0) && (tempo ==0))
{
output_toggle (PIN_B7);
enable_interrupts( INT_TIMER1); //Habilita interrupção timer1
set_timer1 (3036);
}
}

#int_ccp2
void trata_ccp_2()
{
modo++;
if (modo == 1)
{
disable_interrupts(INT_TIMER1); //Habilita interrupção timer1
output_high (PIN_b7);
}

if (modo > 7 )
{
modo = 0;
}

if (modo == 0 )
{
enable_interrupts( INT_TIMER1); //Habilita interrupção timer1
}
}

void main()
{
output_high (PIN_B7);
setup_ccp1(CCP_CAPTURE_RE);
setup_ccp2(CCP_CAPTURE_RE);
setup_timer_1 (T1_INTERNAL | T1_DIV_BY_8); //Configuração do Timer1 para clock interno = 1E6 dividido por 8
set_timer1 (3036); //Preload do Timer1

enable_interrupts( INT_TIMER1); //Habilita interrupção timer1
enable_interrupts (int_ccp1);
enable_interrupts (int_ccp2);
enable_interrupts (global);

setup_adc_ports(AN0); //Configura canal 0 analógico
setup_adc(ADC_CLOCK_INTERNAL); //De acordo com relógio interno.

set_adc_channel(0); //Habilita canal 0
delay_us(20); //Espera um pouco, obrigatório!

ds1307_init();
lcd_init();
modo = 0;

while(1)
{
switch (modo)
{
case 1:
{
if (input(BOTAO_INCREMENTO))
{
delay_ms (75);
hrs++;
}

if (input(BOTAO_DECREMENTO))
{
delay_ms (75);
hrs--;
}

if (hrs == 24 )
{
hrs = 0;
}

if (hrs == 255 )
{
hrs = 23;
}

printf(lcd_putc,"\fAjustar Hora:\n%u",hrs);
delay_ms (100);
break;
}

case 2:
{
if (input(BOTAO_INCREMENTO))
{
delay_ms (75);
mim++;
}

if (input(BOTAO_DECREMENTO))
{
delay_ms (75);
mim--;
}

if (mim == 60 )
{
mim = 0;
}

if (mim == 255 )
{
mim = 59;
}

printf(lcd_putc,"\fAjustar Minutos:\n%u",mim);
delay_ms (100);
break;
}

case 3:
{
if (input(BOTAO_INCREMENTO))
{
delay_ms (75);
sec++;
}

if (input(BOTAO_DECREMENTO))
{
delay_ms (75);
sec--;
}

if (sec == 60 )
{
sec = 0;
}

if (sec == 255 )
{
sec = 59;
}

printf(lcd_putc,"\fAjustar Segundos:\n%u",sec);
delay_ms (100);
break;
}

case 4:
{
if (input(BOTAO_INCREMENTO))
{
delay_ms (75);
day++;
}

if (input(BOTAO_DECREMENTO))
{
delay_ms (75);
day--;
}

if (day == 32 )
{
day = 1;
}

if (day == 0 )
{
day = 31;
}

printf(lcd_putc,"\fDia do Mes:\n%u",day);
delay_ms (100);
break;
}

case 5:
{
if (input(BOTAO_INCREMENTO))
{
delay_ms (75);
month++;
}

if (input(BOTAO_DECREMENTO))
{
delay_ms (75);
month--;
}

if (month == 13 )
{
month = 1;
}

if (month == 0 )
{
month = 12;
}

printf(lcd_putc,"\fAjustar Mes:\n%u",month);
delay_ms (100);
break;
}

case 6:
{
if (input(BOTAO_INCREMENTO))
{
delay_ms (75);
yr++;
}

if (input(BOTAO_DECREMENTO))
{
delay_ms (75);
yr--;
}

if (yr == 100 )
{
yr = 1;
}

if (yr == 0 )
{
yr = 99;
}

printf(lcd_putc,"\fAjustar Ano:\n%u",yr);
delay_ms (100);
break;
}

case 7:
{
if (input(BOTAO_INCREMENTO))
{
delay_ms (75);
dow++;
}

if (input(BOTAO_DECREMENTO))
{
delay_ms (75);
dow--;
}

if (dow > 7 )
{
dow = 1;
}

if (dow == 0)
{
dow = 7;
}

printf(lcd_putc,"\fDia da Semana:\n%s",dia_da_semana[dow-1]);
delay_ms (100);
ds1307_set_date_time(day,month,yr,dow,hrs,mim,sec);

break;
}

default:
{
adc = read_adc(); //Lê canal 0
temperatura = (5.0 * adc * 100) / 1024.0; //Conversão para tensão.


ds1307_get_date(day,month,yr,dow);
ds1307_get_time(hrs,mim,sec);

printf(lcd_putc,"\f%s %02d:\%02d:\%02d\n%02d/\%02d/\%02d %2.0f%cC",dia_da_semana[dow-1],hrs,mim,sec,day,month,yr,temperatura,0xdf);
delay_ms(1000);
}
}
}
}

Compartilhar este post


Link para o post
Compartilhar em outros sites

:) Valeu!! Sou novo com programação em PIC e vou fazer um projeto com o PIC18F2550, onde quero utilizar três botões que são: Função, Seleciona, Confirma. Deve guardar os eventos diários com data e horário, o somatório semanal e mensal/ano.

Agradeço por qualque ajuda que possa me dar e que sabe lhe mando um quilo de castanha de caju do Ceará.

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

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora





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

×