Ir ao conteúdo
  • Cadastre-se

Problemas com I2c e o pic


Micael77

Posts recomendados

Olá

eu estou desenvolvendo um projeto que preciso comunicar com um RTC (PFC8583) e uma EEPROM externa (ATMEL24C64) por i2c com um pic16f877a

estou fazendo por partes, no momento estou tentando testar com o rtc mas não consigo fazer ele contar as horas. eu até consigo atualizar a hora, mas ele só mostra o numero q eu digitei e -1

não faço a minima ideia do que esta acontecendo e preciso entregar esse projeto semana que vem

por favor me ajudem

Obrigado

Link para o comentário
Compartilhar em outros sites

Primeiro passo, poste seu codigo atual e o esquema de ligação, pois pode ser problema no teu barramento I2C.

voce consegue fazer a leitura do RTC? ele te envia as informações?

Tem um pino nele que gera um pulso a cada 1 segundo, verificou se ele esta chegando ao teu RTC?

duvidas estamos a disposição, vamo achar esse problema!

abs.

Link para o comentário
Compartilhar em outros sites

ele comunica com o rtc

e recebo uma resposta dele (-1 ou a hora q eu digitar) cou colocar o código abaixo

programa principal:


#device ADC=10 // define AD para 10 bits, variando de 0 a 1023
#use delay (clock=4000000) // <- define cristal para 4Mhz. Para outros valores, mude e recompile.
#include <cuscostdio.h> // inclui biblioteca de funções do projeto CUSCOPiC
#use i2c(MASTER, SDA=PIN_C4, SCL=PIN_C3)

#include "RTC.h"
#fuses HS, NOWDT, NOPROTECT, NOBROWNOUT, NOLVP, PUT




//long tempo = 0;
short flag = 0;

#int_timer0
void funcao_intermitente() // esta função não precisará ser chamada. Será executada de tempos em tempos automaticamente.
{
//tmoto[i] = tempo;
flag = 1;
set_timer0(255); // seta contador para valor máximo. No próximo pulso, esta função será disparada novamente.
}



void PCF8583_set_datetime()
{
//int8 bcd_hsec, msec = 0;
int8 bcd_sec, seg = 0;
int8 bcd_min, min = 0;
int8 bcd_hrs, hr = 0;

//PCF8583_stop();

printf(lcd_putc, "\fajuste a hora\n%02d: %02d: %02d", hr, min, seg);
lcd_send_byte(0,0x0F);
lcd_gotoxy(1,2);
do
{
hr = cusco_readkbd(0);
if (hr == -1)
{
lcd_gotoxy(1,2);
}
}while(hr == -1);
lcd_gotoxy(5,2);
do
{
min = cusco_readkbd(0);
if (min == -1)
{
lcd_gotoxy(5,2);
}
}while(min == -1);
lcd_gotoxy(9,2);
do
{
seg = cusco_readkbd(0);
if (seg == -1)
{
lcd_gotoxy(9,2);
}
}while(seg == -1);
lcd_gotoxy(13,2);
lcd_send_byte(0,0x0C);


// Convert the input date/time into BCD values
// that are formatted for the PCF8583 registers.
//printf (lcd_putc, "\fteste");

//bcd_hsec = bin2bcd(msec);
bcd_sec = dec_to_bcd(seg);
bcd_min = dec_to_bcd(min);
bcd_hrs = dec_to_bcd(hr);

// Stop the RTC from counting, before we write to
// the date and time registers.


// Write to the date and time registers. Disable interrupts
// so they can't disrupt the i2c operations.
disable_interrupts(GLOBAL);
i2c_start();
i2c_write(PCF8583_WRITE_ADDRESS);
i2c_write(PCF8583_100S_REG); // Start at 100's reg.
i2c_write(0x00); // Set 100's reg = 0
i2c_write(bcd_sec);
i2c_write(bcd_min);
i2c_write(bcd_hrs);
i2c_stop();
enable_interrupts(GLOBAL);

// Write the year byte to the first NVRAM location.
// Leave it in binary format.
//PCF8583_write_byte(PCF8583_YEAR_REG, dt->year);

// Now allow the PCF8583 to start counting again.
//PCF8583_init();
}



void main()
{
int8 h, m, s, ms, hora[10], minuto[10], segundo[10], miliseg[10];
long tmoto[10];
int i = 0;

output_float(pin_c3);
output_float(pin_c4);
//PCF8583_init();

i2c_start();
i2c_write(PCF8583_WRITE_ADDRESS);
i2c_write(PCF8583_100S_REG); // Start at hundread sec. reg.
i2c_start();
i2c_write(PCF8583_READ_ADDRESS);

ms = i2c_read();
s = i2c_read();
m = i2c_read();
h = i2c_read();

i2c_stop();
if((ms == 0) && (s == 0) && (m == 0) && (h == 0))
{
PCF8583_set_datetime();
}

enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER0);
while(1)
{
printf(lcd_putc, "\f%02d: %02d: %02d", h, m, s );
delay_ms(500);
if (flag == 1)
{
disable_interrupts(GLOBAL);
disable_interrupts(INT_TIMER0);
i2c_start();
i2c_write(PCF8583_WRITE_ADDRESS);
i2c_write(PCF8583_100S_REG); // Start at seconds reg.
i2c_start();
i2c_write(PCF8583_READ_ADDRESS);

miliseg[i] = bcd_to_dec(i2c_read());
segundo[i] = bcd_to_dec(i2c_read());
minuto[i] = bcd_to_dec(i2c_read());
hora[i] = bcd_to_dec(i2c_read());
i2c_stop();

flag = 0;
printf(lcd_putc, "\ftempo registrado\n %02d: %02d: %02d: %02d", hora[i], minuto[i], segundo[i], miliseg[i]);
delay_ms(1000);
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER0);


i++;
if (i > 9)
{
i = 0;
}

}
if (TECLA_1 && TECLA_3)
{
printf (lcd_putc, "\fajuste o relogio");
delay_ms(500);
PCF8583_set_datetime();
}
disable_interrupts(GLOBAL);
disable_interrupts(INT_TIMER0);
i2c_start();
i2c_write(PCF8583_WRITE_ADDRESS);
i2c_write(PCF8583_SECONDS_REG);
i2c_start();
i2c_write(PCF8583_READ_ADDRESS);
s = bcd_to_dec(i2c_read());
m = bcd_to_dec(i2c_read());
h = bcd_to_dec(i2c_read())-;
i2c_stop();
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER0);

}
}
#include <16f877.h>         // identifica microcontrolador alvo

bibliotecas:

cuscostdio.h(desenvolvida pelo meu professor do senai [muito util])


/*
BIBLIOTECA PADRÃO PARA CUSCOPIC
Desenvolvida para PICs famílias 16 ou 18 de 28 ou 40 pinos.
Autor: Daniel Corteletti
Desenvolvido em agosto de 2007
Revisão em setembro 2007

*/

#define RELE1 pin_e0
#define RELE2 pin_e1
#define BUZZER pin_e2
#define C0 pin_c0
#define C1 pin_c1
#define C2 pin_c2
#define C3 pin_c3
#define C4 pin_c4
#define C5 pin_c5
#define C6 pin_c6
#define C7 pin_c7
#define D0 pin_d0
#define D1 pin_d1
#define D2 pin_d2
#define D3 pin_d3
#define D4 pin_d4
#define D5 pin_d5
#define D6 pin_d6
#define D7 pin_d7
#define A0 pin_a0
#define A1 pin_a1
#define A2 pin_a2
#define A3 pin_a3
#define A4 pin_a4
#define A5 pin_a5



// Esta biblioteca foi modificada a partir da biblioteca original CCS, com o
// intuito de manter o padrão de programação atendendo as necessidades do LCD
// para a estação didática CUSCOPIC. A definição dos pinos é :
// PINOS PIC PINOS LCD
// B0 enable
// B1 rs
// B2 rw
// B4 D4
// B5 D5
// B6 D6
// B7 D7
//
// Os pinos D0 a D3 do LCD não são usados.

struct lcd_pin_map { // This structure is overlayed
BOOLEAN enable; // on to an I/O port to gain
BOOLEAN rs; // access to the LCD pins.
BOOLEAN rw; // The bits are allocated from
BOOLEAN unused; // low order up. ENABLE will
int data : 4; // be pin B0.
} lcd;

#byte lcd = 6
#define set_tris_lcd(x) set_tris_b(x)
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 linhas
#define lcd_line_two 0x40 // Endereco de RAM da segunda linha


BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
// Estes bytes sao enviados ao lcd para incicializa-lo

struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out
struct lcd_pin_map const LCD_READ = {0,0,0,0,15}; // For read mode data pins are in

#separate
BYTE lcd_read_byte()
{
BYTE low,high;
set_tris_lcd(LCD_READ);
lcd.rw = 1;
delay_cycles(1);
lcd.enable = 1;
delay_cycles(1);
high = lcd.data;
lcd.enable = 0;
delay_cycles(1);
lcd.enable = 1;
delay_us(1);
low = lcd.data;
lcd.enable = 0;
set_tris_lcd(LCD_WRITE);
return( (high<<4) | low);
}

#separate
void lcd_send_nibble( BYTE n )
{
lcd.data = n;
delay_cycles(1);
lcd.enable = 1;
delay_us(2);
lcd.enable = 0;
}


// funcao abaixo modificada para evitar que o LCD trave o programa no caso de nao responder.

#separate
void lcd_send_byte( BYTE address, BYTE n )
{
int cont = 200;
lcd.rs = 0;
while ( bit_test(lcd_read_byte(),7) )
{
delay_us(50);
cont --;
if (!cont) break;
}
lcd.rs = address;
delay_cycles(1);
lcd.rw = 0;
delay_cycles(1);
lcd.enable = 0;
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}

short lcd_initialized = 0;

#separate
void lcd_init()
{
BYTE i;
set_tris_lcd(LCD_WRITE);
lcd.rs = 0;
lcd.rw = 0;
lcd.enable = 0;
delay_ms(15);
for(i=1;i<=3;++i)
{
lcd_send_nibble(3);
delay_ms(5);
}
lcd_send_nibble(2);
for(i=0;i<=3;++i)
lcd_send_byte(0,LCD_INIT_STRING[i]);
lcd_initialized = 1;
}


#separate
void lcd_gotoxy( BYTE x, BYTE y)
{
BYTE address;
if(y!=1)
address=lcd_line_two;
else
address=0;
address+=x-1;
lcd_send_byte(0,0x80|address);
}

#separate
void lcd_putc( char c)
{
if (!lcd_initialized) lcd_init();
else
switch (c)
{
case '\f' : lcd_send_byte(0,1);
delay_ms(2);
break;
case '\n' : lcd_gotoxy(1,2); break;
case '\b' : lcd_send_byte(0,0x10); break;
default : lcd_send_byte(1,c); break;
}
}

#separate
char lcd_getc( BYTE x, BYTE y)
{
char value;
lcd_gotoxy(x,y);
while ( bit_test(lcd_read_byte(),7) ); // wait until busy flag is low
lcd.rs=1;
value = lcd_read_byte();
lcd.rs=0;
return(value);
}

// funcoes adicionadas por Daniel Corteletti

#separate
short lcd_connected()
{
int cont = 200;
lcd.rs = 0;
while ( bit_test(lcd_read_byte(),7) )
{
delay_us(50);
cont --;
if (!cont) return(0);
}
lcd.rs = 1;
return(1);
}

#separate
void lcd_cursor_on()
{
lcd_send_byte(0,0x0E);
}

#separate
void lcd_cursor_blink()
{
lcd_send_byte(0,0x0F);
}

#separate
void lcd_cursor_off()
{
lcd_send_byte(0,0x0C);
}

#separate
void lcd_shift_left()
{
lcd_send_byte(0,0x18);
}

#separate
void lcd_shift_right()
{
lcd_send_byte(0,0x1C);
}




/*
*********************************************************************************
FUNCOES DE TECLADO
Baseada no layout da CUSCO IHM

B7----[ ]---[ ]---[ ]
| | |
B5----[ ]---[ ]---[ ]
| | |
B3----[ ]---[ ]---[ ]
| | |
B2----[ ]---[ ]---[ ]
| | |
| | |
B6 B4 B1

esta função retorna o código da tecla pressionada, conforme a seguinte tabela :

00h - TECLA 0 PRESSIONADA 01h - TECLA 1 PRESSIONADA 02h - TECLA 2 PRESSIONADA
03h - TECLA 3 PRESSIONADA 04h - TECLA 4 PRESSIONADA 05h - TECLA 5 PRESSIONADA
06h - TECLA 6 PRESSIONADA 07h - TECLA 7 PRESSIONADA 08h - TECLA 8 PRESSIONADA
09h - TECLA 9 PRESSIONADA 10h - TECLA * PRESSIONADA 11h - TECLA # PRESSIONADA
FFh - NENHUMA TECLA PRESSIONADA
*/
#define KBD_NADA 0xff
#define KBD_0 0x00
#define KBD_1 0x01
#define KBD_2 0x02
#define KBD_3 0x03
#define KBD_4 0x04
#define KBD_5 0x05
#define KBD_6 0x06
#define KBD_7 0x07
#define KBD_8 0x08
#define KBD_9 0x09
#define KBD_ASTERISCO 0x10
#define KBD_SUSTENIDO 0x11

#define TECLA_NADA cusco_tecla_press(KBD_NADA)
#define TECLA_0 cusco_tecla_press(KBD_0)
#define TECLA_1 cusco_tecla_press(KBD_1)
#define TECLA_2 cusco_tecla_press(KBD_2)
#define TECLA_3 cusco_tecla_press(KBD_3)
#define TECLA_4 cusco_tecla_press(KBD_4)
#define TECLA_5 cusco_tecla_press(KBD_5)
#define TECLA_6 cusco_tecla_press(KBD_6)
#define TECLA_7 cusco_tecla_press(KBD_7)
#define TECLA_8 cusco_tecla_press(KBD_8)
#define TECLA_9 cusco_tecla_press(KBD_9)
#define TECLA_AST cusco_tecla_press(KBD_ASTERISCO)
#define TECLA_SUS cusco_tecla_press(KBD_SUSTENIDO)



short cusco_tecla_press(int ctecla)
{
short flag=0;
output_b(0);
delay_us(500);
switch (ctecla)
{
case KBD_0 : output_high(PIN_B4);
output_low(PIN_B2);
input(PIN_B4);
delay_us(20);
if (!input(PIN_B4)) flag=1;
output_low(PIN_B4);
output_high(PIN_B2);
input(PIN_B4);
delay_us(20);
if (!input(PIN_B4)) flag=0;
break;

case KBD_1 : output_high(PIN_B6);
output_low(PIN_B7);
input(PIN_B6);
delay_us(20);
if (!input(PIN_B6)) flag=1;
output_low(PIN_B6);
output_high(PIN_B7);
input(PIN_B6);
delay_us(20);
if (!input(PIN_B6)) flag=0;
break;

case KBD_2 : output_high(PIN_B4);
output_low(PIN_B7);
input(PIN_B4);
delay_us(20);
if (!input(PIN_B4)) flag=1;
output_low(PIN_B4);
output_high(PIN_B7);
input(PIN_B4);
delay_us(20);
if (!input(PIN_B4)) flag=0;
break;

case KBD_3 : output_high(PIN_B7);
output_low(PIN_B1);
input(PIN_B7);
delay_us(20);
if (!input(PIN_B7)) flag=1;
output_low(PIN_B7);
output_high(PIN_B1);
input(PIN_B7);
delay_us(20);
if (!input(PIN_B7)) flag=0;
break;

case KBD_4 : output_high(PIN_B6);
output_low(PIN_B5);
input(PIN_B6);
delay_us(20);
if (!input(PIN_B6)) flag=1;
output_low(PIN_B6);
output_high(PIN_B5);
input(PIN_B6);
delay_us(20);
if (!input(PIN_B6)) flag=0;
break;

case KBD_5 : output_high(PIN_B4);
output_low(PIN_B5);
input(PIN_B4);
delay_us(20);
if (!input(PIN_B4)) flag=1;
output_low(PIN_B4);
output_high(PIN_B5);
input(PIN_B4);
delay_us(20);
if (!input(PIN_B4)) flag=0;
break;

case KBD_6 : output_high(PIN_B5);
output_low(PIN_B1);
input(PIN_B5);
delay_us(20);
if (!input(PIN_B5)) flag=1;
output_low(PIN_B5);
output_high(PIN_B1);
input(PIN_B5);
delay_us(20);
if (!input(PIN_B5)) flag=0;
break;

case KBD_7 : output_high(PIN_B6);
output_low(PIN_B3);
input(PIN_B6);
delay_us(20);
if (!input(PIN_B6)) flag=1;
output_low(PIN_B6);
output_high(PIN_B3);
input(PIN_B6);
delay_us(20);
if (!input(PIN_B6)) flag=0;
break;

case KBD_8 : output_high(PIN_B4);
output_low(PIN_B3);
input(PIN_B4);
delay_us(20);
if (!input(PIN_B4)) flag=1;
output_low(PIN_B4);
output_high(PIN_B3);
input(PIN_B4);
delay_us(20);
if (!input(PIN_B4)) flag=0;
break;

case KBD_9 : output_high(PIN_B3);
output_low(PIN_B1);
input(PIN_B3);
delay_us(20);
if (!input(PIN_B3)) flag=1;
output_low(PIN_B3);
output_high(PIN_B1);
input(PIN_B3);
delay_us(20);
if (!input(PIN_B3)) flag=0;
break;

case KBD_SUSTENIDO : output_high(PIN_B2);
output_low(PIN_B1);
input(PIN_B2);
delay_us(20);
if (!input(PIN_B2)) flag=1;
output_low(PIN_B2);
output_high(PIN_B1);
input(PIN_B2);
delay_us(20);
if (!input(PIN_B2)) flag=0;
break;

case KBD_ASTERISCO : output_high(PIN_B6);
output_low(PIN_B2);
input(PIN_B6);
delay_us(20);
if (!input(PIN_B6)) flag=1;
output_low(PIN_B6);
output_high(PIN_B2);
input(PIN_B6);
delay_us(20);
if (!input(PIN_B6)) flag=0;
break;

case KBD_NADA : output_b(0b01010010);
input(PIN_B6);
input(PIN_B4);
input(PIN_B1);
delay_us(20);
if (input(PIN_B6) && input(PIN_B4) && input(PIN_B1)) flag=1;
break;



}
return(flag);
}


int cusco_tecla()
{
output_b(0x7E); //01111110
if (!input(PIN_B6)) return(KBD_1);
if (!input(PIN_B4)) return(KBD_2);
if (!input(PIN_B1)) return(KBD_3);
output_b(0xDE); //11011110
if (!input(PIN_B6)) return(KBD_4);
if (!input(PIN_B4)) return(KBD_5);
if (!input(PIN_B1)) return(KBD_6);
output_b(0xF6); //11110110
if (!input(PIN_B6)) return(KBD_7);
if (!input(PIN_B4)) return(KBD_8);
if (!input(PIN_B1)) return(KBD_9);
output_b(0xFA); //11111010
if (!input(PIN_B6)) return(KBD_ASTERISCO);
if (!input(PIN_B4)) return(KBD_0);
if (!input(PIN_B1)) return(KBD_SUSTENIDO);
return(0xFF); // caso nada tenha sido pressionado
}

// fim da função de teclado LE_KB()
// ****************************************************************************************


/*
funcao cusco_readkbd()
retorna um valor do tipo INT32 (até 9 digitos) lidos via teclado, escrevendo ou nao o valor
no display, na posicao onde estiver o cursor.

uso:

INT32 x;

x = cusco_readkbd(0); <--- mostra o valor digitado.

ou

x = cusco_readkbd(1); <--- mostra asteriscos no lugar do valor digitado

ou

x = cusco_readkbd(2); <--- nao mostra nada mas busca valor do teclado

o valor deverá ser inserido usando o teclado numerico matricial.
o valor finaliza com um enter (ou #)
a funcao retornará o valor digitado ou -1 se for cancelado com um (*)
*/

signed int32 cusco_readkbd(int echo)
{
int cont=0;
int32 lido=0;
int tecla;
while(1)
{
tecla = cusco_tecla();
if (tecla == 0xff) continue;
if (tecla == 0x11)
{
while(cusco_tecla() != 0xff) delay_ms(10);
delay_ms(10);
return(lido);
}
if (tecla == 0x10)
{
while(cusco_tecla() != 0xff) delay_ms(10);
delay_ms(10);
return(-1);
}
delay_ms(10);
if (cont < 9)
{
cont ++;
lido = lido * 10;
lido = lido + tecla;
if(echo == 0) printf(lcd_putc,"%i",tecla);
if(echo == 1) lcd_putc("*");
output_high(pin_e2);
delay_ms(10);
output_low(pin_e2);
delay_ms(90);
}
else
{
output_high(pin_e2);
delay_ms(100);
output_low(pin_e2);
}
while(tecla == cusco_tecla());
delay_ms(10);
}
}
// FIM DAS ROTINAS DE TECLADO PARA CUSCOPIC
//*******************************************************************************


long AD(int channel)
{
long aux;
switch(channel)
{
case 0 : input(PIN_A0); break;
case 1 : input(PIN_A1); break;
case 2 : input(PIN_A2); break;
case 3 : input(PIN_A3); break;
case 4 : input(PIN_A5); break;
default: return(0);
}
enable_interrupts( GLOBAL );
setup_adc( ADC_CLOCK_INTERNAL );
setup_adc_ports( ALL_ANALOG );
set_adc_channel(channel);
delay_us(100);
aux = read_adc();
setup_adc_ports(NO_ANALOGS);
return(aux);
}

void tempo_sound(int32 t)
{
while(t > 10000)
{
t-= 10000;
delay_ms(100);
}
while(t > 1000)
{
t-= 1000;
delay_ms(10);
}
while(t > 100)
{
t-= 100;
delay_ms(1);
}
while(t > 10)
{
t-= 10;
delay_us(90);
}
}

// gera audio, na frequencia e duração solicitada
#bit SPK = 0x09.2
void sound(long freq, long dur)
{
long P, PR;
int32 duracao;
duracao = (int32)dur * 10;
PR = (long)5000/freq;
output_low(PIN_E2);
while(duracao > 0)
{
duracao --;
P --;
if (!P)
{
SPK = ~SPK;
P = PR;
}
delay_us(85);
}
SPK = 0;
}

void beep()
{
int aux;
for (aux = 0; aux < 100; aux ++)
{
output_high(BUZZER);
delay_us(450);
output_low(BUZZER);
delay_us(450);
}
}

void disp7seg(long x)
{
int M,D,C,U;
M = (x / 1000) % 10;
C = (x % 1000) / 100;
D = (x % 100) / 10;
U = x % 10;
output_b(M | 0x70); delay_us(10); output_high(PIN_B7);
output_b(C | 0xB0); delay_us(10); output_high(PIN_B6);
output_b(D | 0xD0); delay_us(10); output_high(PIN_B5);
output_b(U | 0xE0); delay_us(10); output_high(PIN_B4);
output_b(0xf0); delay_ms(1);
}

void disp7seg_clear()
{
output_b(0x0F); delay_us(100); output_b(0xff); delay_us(100);
}

//==================================================


short FLAG_PULSO_D0 = 0,
FLAG_PULSO_D1 = 0,
FLAG_PULSO_D2 = 0,
FLAG_PULSO_D3 = 0,
FLAG_PULSO_D4 = 0,
FLAG_PULSO_D5 = 0,
FLAG_PULSO_D6 = 0,
FLAG_PULSO_D7 = 0;

#separate
short PULSO(int PINO)
{
if (!input(PIN_D0)) FLAG_PULSO_D0 = 0;
if (!input(PIN_D1)) FLAG_PULSO_D1 = 0;
if (!input(PIN_D2)) FLAG_PULSO_D2 = 0;
if (!input(PIN_D3)) FLAG_PULSO_D3 = 0;
if (!input(PIN_D4)) FLAG_PULSO_D4 = 0;
if (!input(PIN_D5)) FLAG_PULSO_D5 = 0;
if (!input(PIN_D6)) FLAG_PULSO_D6 = 0;
if (!input(PIN_D7)) FLAG_PULSO_D7 = 0;

switch (PINO)
{
case pin_d0 : if (input(PIN_D0) && !FLAG_PULSO_D0)
{
FLAG_PULSO_D0 = 1;
return(1);
}
else
return(0);
case pin_d1 : if (input(PIN_D1) && !FLAG_PULSO_D1)
{
FLAG_PULSO_D1 = 1;
return(1);
}
else
return(0);
case pin_d2 : if (input(PIN_D2) && !FLAG_PULSO_D2)
{
FLAG_PULSO_D2 = 1;
return(1);
}
else
return(0);
case pin_d3 : if (input(PIN_D3) && !FLAG_PULSO_D3)
{
FLAG_PULSO_D3 = 1;
return(1);
}
else
return(0);
case pin_d4 : if (input(PIN_D4) && !FLAG_PULSO_D4)
{
FLAG_PULSO_D4 = 1;
return(1);
}
else
return(0);
case pin_d5 : if (input(PIN_D5) && !FLAG_PULSO_D5)
{
FLAG_PULSO_D5 = 1;
return(1);
}
else
return(0);
case pin_d6 : if (input(PIN_D6) && !FLAG_PULSO_D6)
{
FLAG_PULSO_D6 = 1;
return(1);
}
else
return(0);
case pin_d7 : if (input(PIN_D7) && !FLAG_PULSO_D7)
{
FLAG_PULSO_D7 = 1;
return(1);
}
else
return(0);
}
return(0);
}

int saidas_toogle_cusco = 0;

short toggle(int PINO)
{
output_d(0x00);
delay_us(2);
if (pulso(PIN_D0))
{
saidas_toogle_cusco ^= 0b00000001;
}
if (pulso(PIN_D1))
{
saidas_toogle_cusco ^= 0b00000010;
}
if (pulso(PIN_D2))
{
saidas_toogle_cusco ^= 0b00000100;
}
if (pulso(PIN_D3))
{
saidas_toogle_cusco ^= 0b00001000;
}
if (pulso(PIN_D4))
{
saidas_toogle_cusco ^= 0b00010000;
}
if (pulso(PIN_D5))
{
saidas_toogle_cusco ^= 0b00100000;
}
if (pulso(PIN_D6))
{
saidas_toogle_cusco ^= 0b01000000;
}
if (pulso(PIN_D7))
{
saidas_toogle_cusco ^= 0b10000000;
}
output_d(saidas_toogle_cusco);
delay_ms(1);
switch(PINO)
{
case PIN_D0 : return((saidas_toogle_cusco & 0b00000001) > 0);
case PIN_D1 : return((saidas_toogle_cusco & 0b00000010) > 0);
case PIN_D2 : return((saidas_toogle_cusco & 0b00000100) > 0);
case PIN_D3 : return((saidas_toogle_cusco & 0b00001000) > 0);
case PIN_D4 : return((saidas_toogle_cusco & 0b00010000) > 0);
case PIN_D5 : return((saidas_toogle_cusco & 0b00100000) > 0);
case PIN_D6 : return((saidas_toogle_cusco & 0b01000000) > 0);
case PIN_D7 : return((saidas_toogle_cusco & 0b10000000) > 0);
}
return(0);
}

//======================================= pwm =========================

#define PWM_250HZ_CLK4 setup_timer_2(T2_DIV_BY_16, 250, 1) //
#define PWM_500HZ_CLK4 setup_timer_2(T2_DIV_BY_16, 125, 1) //
#define PWM_1KHZ_CLK4 setup_timer_2(T2_DIV_BY_4, 250, 1) //
#define PWM_1K25HZ_CLK4 setup_timer_2(T2_DIV_BY_16, 50, 1) //
#define PWM_2KHZ_CLK4 setup_timer_2(T2_DIV_BY_4, 125, 1) //
#define PWM_2K5HZ_CLK4 setup_timer_2(T2_DIV_BY_4, 100, 1) //
#define PWM_4KHZ_CLK4 setup_timer_2(T2_DIV_BY_1, 250, 1) //
#define PWM_5KHZ_CLK4 setup_timer_2(T2_DIV_BY_1, 200, 1) //
#define PWM_8KHZ_CLK4 setup_timer_2(T2_DIV_BY_1, 125, 1) //
#define PWM_10KHZ_CLK4 setup_timer_2(T2_DIV_BY_1, 100, 1) //
#define PWM_20KHZ_CLK4 setup_timer_2(T2_DIV_BY_1, 50, 1) //
#define PWM_25KHZ_CLK4 setup_timer_2(T2_DIV_BY_1, 40, 1) //
#define PWM_100KHZ_CLK4 setup_timer_2(T2_DIV_BY_1, 10, 1) //

#define PWM_500HZ_CLK8 setup_timer_2(T2_DIV_BY_16, 250, 1) //
#define PWM_1KHZ_CLK8 setup_timer_2(T2_DIV_BY_16, 125, 1) //
#define PWM_2KHZ_CLK8 setup_timer_2(T2_DIV_BY_4, 250, 1) //
#define PWM_2K5HZ_CLK8 setup_timer_2(T2_DIV_BY_16, 50, 1) //
#define PWM_4KHZ_CLK8 setup_timer_2(T2_DIV_BY_4, 125, 1) //
#define PWM_5KHZ_CLK8 setup_timer_2(T2_DIV_BY_4, 100, 1) //
#define PWM_8KHZ_CLK8 setup_timer_2(T2_DIV_BY_1, 250, 1) //
#define PWM_10KHZ_CLK8 setup_timer_2(T2_DIV_BY_1, 200, 1) //
#define PWM_16KHZ_CLK8 setup_timer_2(T2_DIV_BY_1, 125, 1) //
#define PWM_20KHZ_CLK8 setup_timer_2(T2_DIV_BY_1, 100, 1) //
#define PWM_40KHZ_CLK8 setup_timer_2(T2_DIV_BY_1, 50, 1) //
#define PWM_50KHZ_CLK8 setup_timer_2(T2_DIV_BY_1, 40, 1) //
#define PWM_200KHZ_CLK8 setup_timer_2(T2_DIV_BY_1, 10, 1) //

#define PWM_1KHZ_CLK16 setup_timer_2(T2_DIV_BY_16, 250, 1) //
#define PWM_2KHZ_CLK16 setup_timer_2(T2_DIV_BY_16, 125, 1) //
#define PWM_4KHZ_CLK16 setup_timer_2(T2_DIV_BY_4, 250, 1) //
#define PWM_5KHZ_CLK16 setup_timer_2(T2_DIV_BY_16, 50, 1) //
#define PWM_8KHZ_CLK16 setup_timer_2(T2_DIV_BY_4, 125, 1) //
#define PWM_10KHZ_CLK16 setup_timer_2(T2_DIV_BY_4, 100, 1) //
#define PWM_16KHZ_CLK16 setup_timer_2(T2_DIV_BY_1, 250, 1) //
#define PWM_20KHZ_CLK16 setup_timer_2(T2_DIV_BY_1, 200, 1) //
#define PWM_32KHZ_CLK16 setup_timer_2(T2_DIV_BY_1, 125, 1) //
#define PWM_40KHZ_CLK16 setup_timer_2(T2_DIV_BY_1, 100, 1) //
#define PWM_80KHZ_CLK16 setup_timer_2(T2_DIV_BY_1, 50, 1) //
#define PWM_100KHZ_CLK16 setup_timer_2(T2_DIV_BY_1, 40, 1) //
#define PWM_400KHZ_CLK16 setup_timer_2(T2_DIV_BY_1, 10, 1) //


RTC.h(desenvolvida por mim [com algumas funções que achei na internet])



#ifndef PCF8583_SDA
#define PCF8583_SDA PIN_C4
#define PCF8583_SCL PIN_C3
#endif

//#use i2c(master, sda=PCF8583_SDA, scl=PCF8583_SCL)

#ifndef PCF8583_WRITE_ADDRESS
#define PCF8583_WRITE_ADDRESS 0xA2
#define PCF8583_READ_ADDRESS 0xA3
#endif

// Register addresses
#define PCF8583_CTRL_STATUS_REG 0x00
#define PCF8583_100S_REG 0x01
#define PCF8583_SECONDS_REG 0x02
#define PCF8583_MINUTES_REG 0x03
#define PCF8583_HOURS_REG 0x04
#define PCF8583_DATE_REG 0x05
#define PCF8583_MONTHS_REG 0x06
#define PCF8583_TIMER_REG 0x07

#define PCF8583_ALARM_CONTROL_REG 0x08
#define PCF8583_ALARM_100S_REG 0x09
#define PCF8583_ALARM_SECS_REG 0x0A
#define PCF8583_ALARM_MINS_REG 0x0B
#define PCF8583_ALARM_HOURS_REG 0x0C
#define PCF8583_ALARM_DATE_REG 0x0D
#define PCF8583_ALARM_MONTHS_REG 0x0E
#define PCF8583_ALARM_TIMER_REG 0x0F

// Use the first NVRAM address for the year byte.
#define PCF8583_YEAR_REG 0x10


// Commands for the Control/Status register.
#define PCF8583_START_COUNTING 0x00
#define PCF8583_STOP_COUNTING 0x80
#separate
void PCF8583_init(void)
{
disable_interrupts(GLOBAL);
i2c_start();
i2c_write(PCF8583_WRITE_ADDRESS);
i2c_write(PCF8583_CTRL_STATUS_REG);
i2c_write(PCF8583_START_COUNTING);
i2c_stop();
enable_interrupts(GLOBAL);
}
#separate
void PCF8583_stop(void)
{
disable_interrupts(GLOBAL);
i2c_start();
i2c_write(PCF8583_WRITE_ADDRESS);
i2c_write(PCF8583_CTRL_STATUS_REG);
i2c_write(PCF8583_STOP_COUNTING);
i2c_stop();
enable_interrupts(GLOBAL);
}
#separate
int8 bin2bcd(int8 value)
{
char retval;

retval = 0;

while(1)
{
// Get the tens digit by doing multiple subtraction
// of 10 from the binary value.
if(value >= 10)
{
value -= 10;
retval += 0x10;
}
else // Get the ones digit by adding the remainder.
{
retval += value;
break;
}
}

return(retval);
}

//----------------------------------------------
// This function converts an 8 bit BCD value to
// an 8 bit binary value.
// The input range must be from 00 to 99.
#separate
char bcd2bin(char bcd_value)
{
char temp;

temp = bcd_value;

// Shifting the upper digit right by 1 is
// the same as multiplying it 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));

}


#separate
// Converte um numero em bcd para decimal
int8 bcd_to_dec(int8 i8_Valor)
{
// Armazena o valor original
int8 i8_ValorOriginal = 0;

// Guarda o valor original
i8_ValorOriginal = i8_Valor;

// Zerando a parte alta, temos a unidade.
i8_Valor = (i8_Valor & 0x0F);

// Rotacionando 4 bits a direita e multiplicando por 10, para obtermos a dezena.
i8_ValorOriginal = ((i8_ValorOriginal >> 4) * 10);

// Somando a unidade e a dezena, temos o numero convertido.
i8_Valor = (i8_Valor + i8_ValorOriginal);

// Retorna o valor convertido
return(i8_Valor);
}

// =============================================================================

#separate
// Converte um número em decimal para bcd
int8 dec_to_bcd(int8 i8_Valor)
{
// Armazena o valor original
int8 i8_ValorOriginal = 0;

// Guarda o valor original
i8_ValorOriginal = i8_Valor;

// Pegando o numero inteiro da divisao e rotacionando 4 bits a esquerda, temos o valor da dezena.
i8_Valor = ((i8_Valor/10) << 4);

// O resto da divisao e a unidade.
i8_ValorOriginal = (i8_ValorOriginal % 10);

// Somando unidade e dezena, temos o valor convertido.
i8_Valor = (i8_ValorOriginal + i8_Valor);

// Retorna o valor convertido
return(i8_Valor);
}


este é meu código

por favor me ajudem estou realmente desesperado

obrigado +1 vez

Agora segue meu esquema de ligação

como não possuo nenhum software para fazer isso:confused:

eu fiz no paint ^_^

espero q possam entender^_^

Obrigado +1 vez

:D

Link para o comentário
Compartilhar em outros sites

Uma coisa, vi a ligação do pino A0, agora pergunto, voce está mandando a seguinte sequencia antes de ler / escrever no RTC?

101000(A0)(R/W), ou seja se voce vai ler, antes de tudo envie esse byte:

10100011

se vais escrever use esse:

10100010

acho que é esse seu problema, voce esta desprezando o valor posto em A0!

abs.

Link para o comentário
Compartilhar em outros sites

Uma coisa, vi a ligação do pino A0, agora pergunto, voce está mandando a seguinte sequencia antes de ler / escrever no RTC?

101000(A0)(R/W), ou seja se voce vai ler, antes de tudo envie esse byte:

10100011

se vais escrever use esse:

10100010

acho que é esse seu problema, voce esta desprezando o valor posto em A0!

abs.

meu endereçamento esta correto

o pino A0 recebe 1 (Vdd) e eu mando o endereço A2 e A3

se eu trocar isso eu só recebo -1 nem mais a data q eu seto n recebo

e quanto ao capacitor que você tinha comentado antes

tb n deu certo

de acordo com meu datasshet é assim mesmo

do jeito q eu tinha posto da entrada de clock para o Vdd

se você souber de + alguma coisa por favor me ajude eu estou desesperado

obrigado d novo

Link para o comentário
Compartilhar em outros sites

Bom li o datasheet e acho que vai ficar mais fácil de ajudar.

o problema creio que esteja na inicialização do RTC, voce configurou o registrador status/control do RTC? se não configure - o de modo que ele fique 00000000, creio que voce estaja setando o flag de parada de contagem e isso está travando - o!

vou continuar vendo aqui e posto mais coisas!

abs.

Link para o comentário
Compartilhar em outros sites

Eu setei o registrador de status em 0 sim

esta na biblioteca RTC.h

se quiser olha é uma das primeiras linhas e na função PFC8583_init

eu realmente não faço a minima ideia do problema

+ alguem que entede bem do assunto pode por favor me ajudar

eu n sei o q esta acontecedo e gostaria muito de uma ajuda

PLXXX

Link para o comentário
Compartilhar em outros sites

já sim

se você der uma olhadinha no codigo vai ver no programa principal

um pcf8583_stop que é uma funcao do RTC.h parando a contagem do relógio

agora me surgiu +1 problema

eu tenho outro pic que faz praticamente a mesma coisa

só que já estava pronto e eu tinha que fazer um programa e modificar aquele

mas eu nao mexi em absolutamente nada no antigo e nem aquele + comunica com o RTC

acho q esse negócio nao gostou d mim :(

sabe o q pode ter acontecido com o outro?

e o meu porque n funciona??

aff acho q isso n é pra mim...

Obrigado +1 vez

Link para o comentário
Compartilhar em outros sites

Ja tentou substituir o RTC?

EDIT.: bom, o que posso sugerir é que voce faça um novo codigo, mas apenas para leitura ou seja,

um codigo somente para inicialização do RTC, e fique lendo os valores de h:m:s pra ver se ele incrementa, se não incrementar substitua o RTC, pois pode estar com defeito!

abs.

Link para o comentário
Compartilhar em outros sites

já tentei com DEZ RTCs diferentes todos apresentam o mesmo problema

ou os 10 estão com problema ou sei lá

e o oscilador, já testei com 3 diferentese todos apresentam o mesmo problema

realmente eu nsao faço a minima ideia do que possa estar acontecedo

pois se vocês olharem o codigo esta certo (ou parece estar)

e as ligacoes tb (já fiz e desfiz elas umas 20 vezes) mas n tem jeito desse troço funcionar

se tiverem + alguma opiniao por favor postem ai

e +1 vez obrigado

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

e o oscilador, já testei com 3 diferentese todos apresentam o mesmo problema

Quero saber se está oscilando e se mediu a frequência.

Se não tiver, pode colocar todos os RTCs do mundo que não vai resolver.

Este oscilador nada mais é do que o cristal de 32768 + capacitor ao pino VCC.

Link para o comentário
Compartilhar em outros sites

estou fazendo por partes, no momento estou tentando testar com o rtc mas não consigo fazer ele contar as horas. eu até consigo atualizar a hora, mas ele só mostra o numero q eu digitei e -1

Perai, dando uma lida no seu topico, deixa eu perguntar, quando voce diz não conta as horas, ele não incrementa somenta as horas , ou não incrementa nada, segundos e minutos?

porque se ele so não incrementar as horas provavelmente esta certo, voce devara mante - lo em teste por uma hora para ver se a contagem incrementou, creio que o problema aqui seja a interpretação do funcionamento do RTC!

abs.

Link para o comentário
Compartilhar em outros sites

Quero saber se está oscilando e se mediu a frequência.

Se não tiver, pode colocar todos os RTCs do mundo que não vai resolver.

Este oscilador nada mais é do que o cristal de 32768 + capacitor ao pino VCC.

cara acho q o problema pode estar aqui

eu n so mtu bom em eletronica, você poderia me dizer como eu faço isso?:mellow:

pode ser q ele n esteja oscilando certo, eu estou usando um oscilador de 32768 como você falou, ele vai do pino 1 para o 2 e tem um capacitor q sai do pino 1 e vai para o 8 é isso? tem + alguma coisa q tenho q fazer?

e respondendo a pergunto do felipe, ele está totalmente parado

nao incrementa centesimos de segundos, segundos, minutos, hrs nada

ele só mostra a hr q eu setar e -1 alternadamente, e eu n esqueci de atualizar o lcd nao se preocupe, n sou programador de ontem é como se ele mostrasse isso no display:

digamos q eu sete a hr 10:15:35 (hh:mm:ss)

ele me mostra

10:15:35

-1:-1:-1

10:15:35

-1:-1:-1

10:15:35

-1:-1:-1

entenderam agora o que está acontecendo?

espero q alguem consiga me ajudar pois eu n sei + o q fazer

+1 vez obrigao

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

Pois é. Este é o primeiro passo quando se quer analisar um circuito que depende de clock: Verificar se ele existe... tanto que desde o post 11 eu fiz esta pergunta.

Se não tem um frequêncímetro, não há o que fazer, apenas troque o cristal e o capacitor.... aliás, que capacitor está usando?

Estes cristais estão na maioria dos brinquedos chineses, relógios digitais, etc....

Link para o comentário
Compartilhar em outros sites

Pois é. Este é o primeiro passo quando se quer analisar um circuito que depende de clock: Verificar se ele existe... tanto que desde o post 11 eu fiz esta pergunta.

Se não tem um frequêncímetro, não há o que fazer, apenas troque o cristal e o capacitor.... aliás, que capacitor está usando?

Estes cristais estão na maioria dos brinquedos chineses, relógios digitais, etc....

o frequencimetro que você fala é um osciloscópio??

pois aqui na empresa temos 1

o capacitor é um de poliester de 100nanoF por 400 (nao sei o q é esse 400 mas tá escrito nele como eu disse nao sou bom ele eletronica)

e eu já olhei com 3 cristais diferentes

só n testei com outro capacitor

obrigado +1 vez vocês estão ajudando bastante :D

Link para o comentário
Compartilhar em outros sites

o frequencimetro que você fala é um osciloscópio??

pois aqui na empresa temos 1

o capacitor é um de poliester de 100nanoF por 400 (nao sei o q é esse 400 mas tá escrito nele como eu disse nao sou bom ele eletronica)

e eu já olhei com 3 cristais diferentes

só n testei com outro capacitor

obrigado +1 vez vocês estão ajudando bastante :D

Olá Amigo,

Deve estar ai o problema, o capacitor está com valor muito alto, só pra testar tira o capacitor do circuito, que deve funcionar, o correto é usar um de 33pF.

Tive esse mesmo problema com o cristal num pic, eu jurava que estava usando um capacitor de 33pF, mas na verdade era de 33nF, perdi 2 dias nessa brincadeira.

Abs.

Link para o comentário
Compartilhar em outros sites

Olá Amigo,

Deve estar ai o problema, o capacitor está com valor muito alto, só pra testar tira o capacitor do circuito, que deve funcionar, o correto é usar um de 33pF.

Tive esse mesmo problema com o cristal num pic, eu jurava que estava usando um capacitor de 33pF, mas na verdade era de 33nF, perdi 2 dias nessa brincadeira.

Abs.

Não amigo, o cristal ao qual nos referimos é o do RTC, provalvelmente o capacitor usado esteja incorreto não gerando a base de tempo do RTC

abs.

Link para o comentário
Compartilhar em outros sites

é provavel mas eu testei com outro mas acho que usei um mais alto dessa vez

usauhsuah

vou refazer o teste com um mais baixo

obrigado pela ajuda por inquanto MTU obrigado

Edit: continua nao dando certo... e agora ele me mostra -91 em vez de -1

eu estou achando que deva ter algum problema com a i2c, nao sei

essa é a primeira vez q faço um projeto assim

acabei de me formar no senai e ainda n sei mtu bem essas coisas mas é com o tempo quu se aprende hehe

obrigado d novo

EDIT2: FUNCIONOUUUUUUUU

DEU CERTO

só que eu tive que tirar o cpacitor e funcionou mas ele ainda me mostra a hr e -91... mas já é alguma coisa

ele fica assim agora:

digamos q eu sete a hr 10:35:57(hh:mm:ss)

ele me mostra

10:35:57

-91:-91:-91

10:35:58

-91:-91:-91

10:35:59

-91:-91:-91

10:36:00

-91:-91:-91

o que pode estar causando o erro e fazer ele mostrar o -91??

ajudem ae tá quase pronto

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

Amigo, não viu o valor do capacitor (que no caso é um trimmer) no datasheet?

20090904112753.gif

O problema não foi o pouco conhecimento, e sim a falta de atenção.

Desculpe se estou sendo chato, mas é para seu bem...

Uma vírgula no datasheet pode fazer diferença, portanto procure ler tudo, principalmente porque ainda é principiante.

100nF em 32KHz é um curto circuito e é 4000 vezes acima do máximo recomendado (25pF).

tenho certeza que se você fizer o programa de acordo com o ''timming'' e registros do datasheet, não terá erros.

Link para o comentário
Compartilhar em outros sites

nossa é verdade eu n tinha olhado essa parte do datasheet mesmo

eu só peguei um exemplo q eu tenho pronto aqui e coloquei um igual

então me explica uma coisa

porque se eu tirar o capacitor ele funciona, mas adianta a contagem??

e onde eu vou achar um capacitor estão pequeno??

agora estamos chegando a algum lugar

obrigado +1 vez vocês ajudaram MTUU

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

Porque é um trimer, e o mínimo é quase 0pF, ou seja o mesmo que sem capacitor (ou não conhece trimer?)

http://www.reidosom.com.br/capacitoresvariaveis.htm

O trimer é justamente para calibrar a frequencia do oscilador o mais próximo possível de 32768Hz.

Verifique também se está setando corretamente o RTC para este cristal.

Está tudo no datasheet.

Link para o comentário
Compartilhar em outros sites

isso eu acho q estou fazendo

eu n sabia o que era um trimmer hhehe

tem esse detalhe

mas agora acho que vai funcionar legal

já consegui o capacitor de 22pF (tendo em vista que o minimo é 5 e p maximo é 25)

assim que eu tiver um tempo eu vou fazer o teste

obrigado pela ajuda,

e você saberia o porque ele fica alternado entre a hr e -91?

Link para o comentário
Compartilhar em outros sites

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades 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

×
×
  • Criar novo...