Bom dia Claudio, estou precisando de uma ajuda se possível,.Fiz um programa para controle de uns portões que havia falado com você algum tempo atrás, não sei se posso postar aqui o código, o que preciso agora é gravar o estado dos pinos de saída na eeprom, não sei como fazer, pode me ajudar? Outra coisa, eu só consegui fazer a chave bi-estável com o pic usando a função toggle que inverte o estado da saída quando o chave táctil é apertada! o problema é que se ficar apertada fica ligando e desligando! tem como me ensinar outra forma de fazer? agradeço desde já! segue o código que fiz no CCS:
void main()
{
{
delay_ms(50);
Output_low(S1);
Output_low(S2);
Output_low(S3);
Output_low(S4);
while(TRUE)
{
if(input(e1)==0)
{
Output_toggle(S2);
Output_high(S3);
delay_ms(750);
Output_low(S3);
delay_ms(1800);
}
if(input(e2)==0)
{
Output_toggle(S1);
Output_high(S4);
delay_ms(750);
Output_low(S4);
delay_ms(1500);
}
}
}
}
Olá Sergio!
Tente usar um flag para o interruptor, que impeça de ocorrer múltiplos acionamentos na função 'Toggle'. Na primeira ocorrência o código seta ele e impede de repetir o acionamento. Depois que o interruptor muda de estado, então libera o flag resetando ele. O valor das saídas pode ser gravado na eeprom neste primeiro acionamento. No código pós reset (inicialização dos ports e registradores) você deverá recuperar estes valores da EEprom e colocar nas saídas respectivas.
Veja como talvez poderia ficar o código:
//declare os flags como globais
unsigned int1 flag1=0, flag2=0;
//DECLARA OS DEFINES
#define END_S1 0x00 //escolha a posição da eeprom que vai usar para S1
void main()
{
delay_ms(50);
Output_low(S1);
Output_low(S2);
Output_low(S3);
Output_low(S4);
if(read_eeprom(END_S1))Output_high(S1);else Output_low(S1);//recupera o valor de S1
while(TRUE)
{
if(input(e1)==0 && flag1==0)
{
flag1=1; //trava
Output_toggle(S2);
write_eeprom(END_S1,S1);
Output_high(S3);
delay_ms(750);
Output_low(S3);
delay_ms(1800);
}
if(input(e2)==0 && flag2==0)
{
flag2=1;//trava
Output_toggle(S1);
write_eeprom(END_S1,S1);
Output_high(S4);
delay_ms(750);
Output_low(S4);
delay_ms(1500);
}
//
if(input(e1)==1)flag1=0;//reseta os flags de trava
if(input(e2)==1)flag2=0;
}//while(TRUE)
Boa tarde Claudio, no exemplo que passou ele vai gravar na eeprom somente a saída S1? ou ele vai gravar todas os estados das saidas?
Boa tarde Claudio, testei dessa forma que você mostrou não esta gravando, quando liga s1 ja vai para nivel alto, mesmo se vc desligar ela na chave quando liga volta para nivel alto! o flag funcionou perfeitamente! tenho que colocar outro #define para S2?
Olá Sergio!
No exemplo só está para gravar/recuperar a saída S1. Se houver mais saídas a serem gravadas, poderá colocar mais defines e repetir a forma usada no código.
O anterior foi apenas um exemplo incompleto. Tente algo assim (não testei) :
//declare os flags como globais
unsigned int1 flag1=0, flag2=0;
//DECLARA OS DEFINES
#define END_S1 0x00 //escolha a posição da eeprom que vai usar para S1
#define END_S2 0x01 //escolha a posição da eeprom que vai usar para S1
void main()
{
delay_ms(50);
Output_low(S1);
Output_low(S2);
Output_low(S3);
Output_low(S4);
if(read_eeprom(END_S1))Output_high(S1);else Output_low(S1);//recupera o valor de S1
if(read_eeprom(END_S2))Output_high(S2);else Output_low(S2);//recupera o valor de S2
while(TRUE)
{
if(input(e1)==0 && flag1==0)
{
flag1=1; //trava
Output_toggle(S2);
write_eeprom(END_S2,S2);
Output_high(S3);
delay_ms(750);
Output_low(S3);
delay_ms(1800);
}
if(input(e2)==0 && flag2==0)
{
flag2=1;//trava
Output_toggle(S1);
write_eeprom(END_S1,S1);
Output_high(S4);
delay_ms(750);
Output_low(S4);
delay_ms(1500);
}
//
if(input(e1)==1)flag1=0;//reseta os flags de trava
if(input(e2)==1)flag2=0;
}//while(TRUE)
Note que é uma sugestão. Outro programador talvez faça de forma diferente, salvando talvez o port inteiro em uma posição de memória. Ou talvez usando bits individuais e depois agrupando-os para serem salvos em uma única posição de EEprom.
Bom dia Claudio, obrigado pela resposta! vou tentar esse e te retorno o resultado!
Ola Claudio, desculpe pelo incomodo, testei aqui e não deu certo, ele não grava o estado em que esta S1 e S2, quando desliga a energia.
Quando liga mesmo que antes de cortar a energia estava em nivel logico baixo ele volta sempre em nivel logico alto!
Nem sei como resolver, pode me ajudar? Obrigado
Ola Claudio, desculpe pelo incomodo, testei aqui e não deu certo, ele não grava o estado em que esta S1 e S2, quando desliga a energia.
Quando liga mesmo que antes de cortar a energia estava em nivel logico baixo ele volta sempre em nivel logico alto!
Nem sei como resolver, pode me ajudar? Obrigado
Certo. Realmente não está funcionando porque foi usado os nomes dos pinos padrão do arquivo include (PIN_A0...PIN_A7 e PIN_B0...PIN_B7). Estes apresentam uma 'certa' dificuldade para ler o estado dos pinos de saída. Precisa neste caso, de usar a função bit_teste(). Mas ela não aceita os pinos na forma padrão. Uma possível solução é usar um espelho de S1 e S2 com ajuda de defines, como abaixo:
//ports
#byte porta = 0x05
#byte portb = 0x06
//saída S1 e S2 quando usadas em bit_teste() deverá ser usado _S1 e _S2.
#define _S1 portb,1 // (tem que ser virgula)
#define _S2 portb,2 // (tem que ser virgula)
/* Abaixo já é feito no arquivo include (por isto está comentado)
#define S1 PIN_B1
#define S2 PIN_B2
#define S3 PIN_B3
#define S4 PIN_B4
#define e1 PIN_A1
#define e2 PIN_A2
*/
// /declare os flags como globais
unsigned int1 flag1=0, flag2=0;
//DECLARA OS DEFINES
#define END_S1 0x00 //escolha a posição da eeprom que vai usar para S1
#define END_S2 0x01 //escolha a posição da eeprom que vai usar para S1
void main() {
/* Você já deve ter feito esta inicialização
setup_counters(RTCC_INTERNAL,RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
*/
delay_ms(50);
Output_low(S1);
Output_low(S2);
Output_low(S3);
Output_low(S4);
if(read_eeprom(END_S1))Output_high(S1);else Output_low(S1);//recupera o valor de S1
if(read_eeprom(END_S2))Output_high(S2);else Output_low(S2);//recupera o valor de S2
while(TRUE)
{
if(input(e1)==0 && flag1==0)
{
flag1=1; //trava
Output_toggle(S2);
if(bit_test(_S2))write_eeprom(END_S2,1); else write_eeprom(END_S2,0);//
Output_high(S3);
delay_ms(750);
Output_low(S3);
delay_ms(1800);
}
if(input(e2)==0 && flag2==0)
{
flag2=1;//trava
Output_toggle(S1);
if(bit_test(_S1))write_eeprom(END_S1,1); else write_eeprom(END_S1,0);
Output_high(S4);
delay_ms(750);
Output_low(S4);
delay_ms(1500);
}
//
if(input(e1)==1)flag1=0;//reseta os flags de trava
if(input(e2)==1)flag2=0;
}//while(TRUE)
}//MAIN()
Tente mudar e ver se vai gravar corretamente na EEprom.
Bom dia Claudio, uma coisa que esqueci de mencionar foi que estou usando um pic 12f675. Talvez a configuração não seja essa ou estou errado?
Abraço!
Sim, você está correto. Tem que usar os nomes corretos para os pinos. Estes estão no arquivo ' include ' do pic 12F675.
No cabeçalho onde vc coloca:
#byte porta = 0x05
#byte portb = 0x06
é para definir entradas e saídas? eu usei para configurar o 12f675, o wizard do ccs, onde eu coloquei os nomes dos pinos ! teria que configurar os pinos então manualmente? pode me dar um exemplo?
Desculpe-me pela amolação rs..
Obrigado
Ah e o 12f675 só tem um port certo? por isso da pergunta sobre o cabeçalho no inicio...
#byte porta = 0x05
#byte portb = 0x06
Isto mesmo. Só tem um port. Ele senão me engano é definido como GPIO .
Mas nada impede de você redefinir nomes usando #byte e #bit.
Por exemplo:
#byte gpio = 0x05
ou qualquer outro nome que queira dar: #byte portgpio = 0x05 , #byte Luiz = 0x05 , etc.
#bit S1 = 0x5.1
Redefinindo desta forma você tem acesso direto no bit sem ter de usar funções com input(),bit_teste(),output_low(), etc.
por. ex: testar um bit
if(s1) faça_algo(); else faça_outra();
ao invés de: if(input(s1)) faça_algo(); else faça_outra();
para ligar uma saída:
s1=1;
ao invés de : output_high(s1);
Mas tem que acertar o sentido dos pinos no registrador TRISIO (0x85) fazendo que cada pino seja entrada ou saída de forma fixa na inicialização de seu programa.
Já usando os nomes 'oficiais' do arquivo include <12F675> você tem acesso as funções input(),bit_teste(),output_low(), etc. de forma automática, pois o compilador muda o TRISIO para entrada ou saída sem ter que fazer isto no código. Cada programador escolhe como vai trabalhar.
Se for desta ultima forma terá que redefinir usando o pino do include.
Ex. #define S1 GPIO0 // acho que GPIO0 seja a forma que está no arquivo include, mas é bom abri-lo para certificar.
#define S2 GPIO1 // idem para GPIO1.
Você pode também usar o Wizard e configurar tudo na hora de criar o projeto, como você disse ter feito.