i2c multitarefa + interrupçao

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

i2c multitarefa + interrupçao

Mensagempor cristian » 25 Set 2009 21:50

galera estou fazendo um gerador de ticket funciona assim


recebo os pulsos provieniente de uma placa a parte nao posso mudar
estes pulsos tem duraçao de 100ms
estou usando o ccp para capturar a borda de descida deste pulso e dai ligo o timer1 q mede a duraçao se for dentro dos padroes ele salva o pulso

ao salvar os pulsos ele exibe em 2 display de 7segmentos o valor do pulso

e espera ser pressionado o botao para imprimir o ticket

na impressao tenho q ler um memoria 24c256 q contem o numero de tickets
e ler um DS1307 para imprimir a data e hora

depois q imprimir vou salvar uns 20bytes na memoria (24c)

mas durante a impressao posso receber mais pulsos este tem q ser armazenados para assim q imprimir o anterior ele exibir no display o novo valor dos pulsos e esperar a impressao

o que esta ocorrendo é que nesse le e escreve de memoria e relogio ocorrem erros de leitura e escrita ja estou a muito tempo nisso e nao consigo resolver

tenho pra mim q é a interrup do timer 0 q sempre ocorre q esta atrapalhando estes perifericos mas nao posso desativar ela pois o display pode apagar

estava pesando estou usando 2 recusos para medir este pulso se usar a interrupçao extenar é melhor ???

o que sera q esta havendo com esta leitura e escrita errada de memoria e rtc

na interrupçao do timer 0 tem varias coisas pra ele testar e mudar sera que isso demora e acabo perdendo dados do i2c nao tem como o i2c ser automatico por interrupçao assim como é o usart ??

segue o codigo do timer 0

//----------------------------------------------------- ------------------------TIMER 0
#int_TIMER0
void TIMER0_isr(void)
{
static int tm1,TM2,tm3,tm4,tm5,tm6,tm7;
TM1++;

//----------------------------------------------------------------DISPLAY
IF(MEDIR_TEMPO)
{RESET_TIMER++;
if(RESET_TIMER==200)
{
MEDIR_TEMPO=0;
setup_timer_1 ( T1_DISABLED );
setup_ccp1(CCP_CAPTURE_FE);//borda subida
}
}
if(tm1==attdisplay)
{
tm1=0;
switch (PonteiroDisplay) //Alterna Display
{
case 0:
output_low(U);
Display=DEZ;
output_D(mask(display));
output_high(D);
break;
case 1:
output_low(D);
Display=UNI;
output_D(mask(display));
output_high(U);
break;
default:
PonteiroDisplay=0;
break;
}//switch (PonteiroDisplay).
if(++PonteiroDisplay >=2)PonteiroDisplay=0;
//output_D(mask(display));
}//----------------------------------------------------------------PISCA LED 1
if(piscaled1)
{
if(!tm2--)
{
tm2=flash;
led_s=!led_s;
output_bit( led1, led_s);
}
}else
{
output_high(led1);
}
//----------------------------------------------------------------PISCA LED 2
if(piscaled2)
{
if(!tm5--)
{
tm5=flash2;
led2_s=!led2_s;
output_bit( led2, led2_s);
}
}

//---------------------------------------------------------------0,5TIMER
if(timer_pulso)
{
if(pulsos)
{
if(!timer_500ms--)
{
timer_pulso=0;
trat_pulso=1;

}
}
}
//---------------------------------------------------------------1 seg TIMER
if(timer_1seg)
{
if(!tm6--)
{
timer_1seg=0;
tm6==248;
modo=1;//para botao B
}
}
//---------------------------------------------------------------TIMER botao H
if(hab_botaoH)
{
if(!tm7--)
{
if(!tmp_30--)
{
tmp_30=30;
hab_botaoH=0;
flash=125; //indica botaoH bloqueado
}
tm7==0;
}
}
//----------------------------------------------------incrementa contador
if(off_rele)
{
tm4++;
if(tm4==15)// 250MS
{
tm4=0;
off_rele=0;
output_low(rele1);
}
}

if(incr_contador)
{
//rele armar e desarmar
tm3++;


//---------------------------------SINAL SONORO
if(tm3==tempo_att)// 250MS
{
tm3=0;
if(beep)
{
output_high(rele1);
off_rele=1;
}
//-----------------------------------------------INCREMENTA DISPLAY
uni+=1;
if (uni>9)
{dez+=1;
uni=0;
if(dez>9)
{

uni=0;
dez=0;
//falta colocar acima de 99 pisca display
OUTPUT_low(PONTO);
}
}
if(!--NumPulsos)
{
tm3=0;
incr_contador=0;
display_pronto=1;
//output_low(rele1);
//write_EXT_eeprom(10,2);

}
}
}
//-----------------------------------------------------------------------------
}//timer 0

e do i2c memoria 24c

void write_ext_eeprom(long int address, BYTE data)
{
short int status;
i2c_start();
i2c_write(0xa0);
i2c_write(address>>Cool;
i2c_write(address);
i2c_write(data);
i2c_stop();
i2c_start();
delay_ms(50);
status=i2c_write(0xa0);
while(status==1)
{
i2c_start();
status=i2c_write(0xa0);
}
i2c_stop();
}


BYTE read_ext_eeprom(long int address) {
BYTE data;
i2c_start();
i2c_write(0xa0);
i2c_write(address>>Cool;
i2c_write(address);
i2c_start();
i2c_write(0xa1);
data=i2c_read(0);
i2c_stop();
delay_ms(10);
return(data);
}

rtc

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();
delay_Ms(10);
}

void ds1307_get_time(BYTE &hr, BYTE &min, 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);
min = bcd2bin(i2c_read() & 0x7f);
hr = bcd2bin(i2c_read() & 0x3f);

i2c_stop();
delay_Ms(10);

}


estou usando CCS 4.093
cristian
Word
 
Mensagens: 570
Registrado em: 03 Nov 2006 08:15
Localização: serrinha-ba

Mensagempor Alesandro F Zagui » 26 Set 2009 11:32

Qual pic voce ta usando? Ele nao tem I2C por hw?
Alesandro Freire Zagui
Alesandro F Zagui
Byte
 
Mensagens: 154
Registrado em: 12 Mai 2009 11:03
Localização: Campo Mourao, Pr

Mensagempor cristian » 26 Set 2009 11:33

PIC 16F877A TEM SIM
cristian
Word
 
Mensagens: 570
Registrado em: 03 Nov 2006 08:15
Localização: serrinha-ba

Mensagempor Alesandro F Zagui » 26 Set 2009 11:48

Tenta usar o I2C por HW entao.

Por que voce usa CCP pra capturar a borda de descida, porque nao usa a Interrupcao Externa (PortB0)?
Alesandro Freire Zagui
Alesandro F Zagui
Byte
 
Mensagens: 154
Registrado em: 12 Mai 2009 11:03
Localização: Campo Mourao, Pr

Mensagempor cristian » 26 Set 2009 11:57

JA ESTOU USANDO POR HARDWARE SERA Q NAO

e do i2c memoria 24c

#use i2c(Master,SLOW,sda=PIN_C4,scl=PIN_C3)

void write_ext_eeprom(long int address, BYTE data)
{
short int status;
i2c_start();
i2c_write(0xa0);
i2c_write(address>>Cool;
i2c_write(address);
i2c_write(data);
i2c_stop();
i2c_start();
delay_ms(50);
status=i2c_write(0xa0);
while(status==1)
{
i2c_start();
status=i2c_write(0xa0);
}
i2c_stop();
}
o CCP é pra medir a duração do sinal q tem 100Ms

TEM COMO FAZER ISSO PELA INT EXTERNA so que tem momentos onde recebo so um pulso
ou seja sai do alto vai a nivel baixo por 100ms e volta pro alto
cristian
Word
 
Mensagens: 570
Registrado em: 03 Nov 2006 08:15
Localização: serrinha-ba

Mensagempor Alesandro F Zagui » 26 Set 2009 13:18

Talvez eu esteja enganado, mas me parece que essa configuração de I2C é por SW.

Tente configurar os registradores da I2C manualmente.
Alesandro Freire Zagui
Alesandro F Zagui
Byte
 
Mensagens: 154
Registrado em: 12 Mai 2009 11:03
Localização: Campo Mourao, Pr

Mensagempor Sergio38br » 26 Set 2009 14:30

Por que vc esta usando um delay na saida das rotinas de leitura?? Geralmente usa-se isto apenas na gravação..

[ ]`
Sergio
Avatar do usuário
Sergio38br
Word
 
Mensagens: 759
Registrado em: 22 Nov 2007 13:39
Localização: São Paulo - SP

Mensagempor cristian » 26 Set 2009 16:31

estou apelando pra tudo achando q pode ser na leitura o erro

as vezes grava na memoria o valor correto e ler errado
cristian
Word
 
Mensagens: 570
Registrado em: 03 Nov 2006 08:15
Localização: serrinha-ba

Re: i2c multitarefa + interrupçao

Mensagempor Djalma Toledo Rodrigues » 26 Set 2009 20:21

. _
Editado pela última vez por Djalma Toledo Rodrigues em 27 Set 2009 17:05, em um total de 1 vez.
Avatar do usuário
Djalma Toledo Rodrigues
Dword
 
Mensagens: 2334
Registrado em: 03 Ago 2008 13:22

Mensagempor elzirobotelho » 27 Set 2009 16:43

Olá Cristian
Eu tive um problema parecido com ao seu, só consegui solucionar desativando as interrupções enquanto lia ou escrevia no RTC. Pois quando ocorria uma interrupção no meio de uma comunicação I2C, a leitura do RTC não era concluída. e não aparecia nada no display e o programa se "perdia". Após a leitura eu habilitava as interrupções novamente vindo a solucionar o problema.

Sds
Elziro Botelho
elzirobotelho
Bit
 
Mensagens: 31
Registrado em: 22 Fev 2008 23:00
Localização: Santos - SP

Mensagempor cristian » 27 Set 2009 22:18

eu fiz isso mas o cliente ta reclamando q o display de 7 segementos esta piscando

estou pensando em mudar o clock pra 8mhz

nunca usei interrupçao de I2C sera que ajudaria
cristian
Word
 
Mensagens: 570
Registrado em: 03 Nov 2006 08:15
Localização: serrinha-ba

Re: i2c multitarefa + interrupçao

Mensagempor Djalma Toledo Rodrigues » 27 Set 2009 23:34

cristian escreveu:galera .... na impressao tenho q ler um memoria 24c256 q contem o numero de tickets

É o número de Série do Ticket ?

Se sim: Lê ao ligar e vai incrementando no uC

Há possibilidade de Criar Buffer na Ram 3 x 20 Bytes e Salvar na EEprom por Página ?

PIC16F877
Clock ----> 20 MHz
Ram ------> 368 Bytes
.
Avatar do usuário
Djalma Toledo Rodrigues
Dword
 
Mensagens: 2334
Registrado em: 03 Ago 2008 13:22

Re: i2c multitarefa + interrupçao

Mensagempor andre_luis » 29 Set 2009 08:16

Cristian,

Algumas observações importantes, mas que sempre as pessoas apanham nisso :

1 ) Voce está usando o mesmo barramento I2C - ou seja, mesma pinagem - para 2 dispositivos com bus interno de 8 e 16 bits. No datasheet, fica claro que não podemos pendurar dispositivos diferentes. Até o 24C16 isso poderia ser feito.

2 ) Pelo fato do protocolo I2C ser síncrono, voce não precisa se preocupar com a temporização. Essa característica permite usar esses componentes em ambientes multitarefas.

3 ) Por acaso, também usei uma topologia parecida com a sua ( 16F877 + DS1307 + 24C16 ) e por algum motivo, o compilador não aceitava acessar o I2C por HW. Tive que forçar na diretiva do CCS - versão 3.242 - para acessar por SW.

+++
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Mensagempor cristian » 29 Set 2009 11:45

Djalma Toledo Rodrigues
ja faço isso leio varios dados e vou incrementando depois da impressao é q vou salvar todos os dados para evitar q uma falta de energia coloque tudo a perder

mas a hora tenho q ler na hora da impressao

uma das soluçoes seria aumentar o clock


andre_teprom

qual seria uma soluçao viavel ???
fazer i2c por software para separar os dispositivos
cristian
Word
 
Mensagens: 570
Registrado em: 03 Nov 2006 08:15
Localização: serrinha-ba

Mensagempor vtrx » 29 Set 2009 12:34

Voce sabe programar em ASM?provavelmente controlaria eficazmente os tempos e eventos.
Avatar do usuário
vtrx
Dword
 
Mensagens: 2240
Registrado em: 20 Abr 2008 21:01

Próximo

Voltar para PIC

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

cron

x