Página 1 de 1

PIC16F688 - dificuldade na porta C

MensagemEnviado: 03 Out 2011 19:12
por pardal
Olá pessoal, estou iniciando com C e estou fazendo um DIMMER com o PIC16F688, já consegui aprender algo sobre ADC, interrupção por mudança de estado entre outros. Já programai vários PICs mas sempre em assembler, mas esse vai ter muito calculo e achei uma boa oportunidade para aprender um pouco de C.

Usei a interrupção por mudança de estado para gerar o sincronismo com a rede, até aí sem problema, para ir aos poucos e verificar o funcionamento do PIC apenas criei uma rotina para gerar um pulso com um determinado atraso e um determinado comprimento, no código a seguir tem a configuração de uns conversores AD para futuras aplicações:

#include <16F688.h>
#device adc=8

#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOBROWNOUT //No brownout reset

#use delay(int=8000000)
#define LED1 PIN_A5
#define DELAY 1

#int_RA
void RA_isr(void)
{
delay_ms(DELAY);
output_high(LED1);
delay_ms(DELAY);
output_low(LED1);
}



void main()
{

setup_adc_ports(sAN4|sAN5|sAN6); // configura ADCs
setup_adc(ADC_CLOCK_DIV_2);
setup_comparator(NC_NC_NC_NC);
enable_interrupts(INT_RA);
enable_interrupts(GLOBAL);
setup_oscillator(OSC_8MHZ);

}


Esse código funciona bem, no osciloscópio da para conferir, a cada mudança de estado do pino RA0 o pino RA5 aguarda o tempo DELAY gera um pulso posítivo de tempo também DELAY e volta a zero.

Só que preciso que a saída seja no pino RC3, aí vem a bagunça, testei vários pinos da porta C e todos apresentam a mesma característica, ou seja, ao invés de gerar um pulso a cada semiciclo positivo ele gera um trem de pulsos com níveis baixos e altos determinados pelo delay, e no semiciclo negativo ele simplesmente não gera nenhum pulso, a unica mudança no código foi:

de #define LED1 PIN_A5
para #define LED1 PIN_C3

alguém pode me dar uma luz?

MensagemEnviado: 03 Out 2011 19:40
por vtrx
Ja deu uma lida na página 42 do DataSheet e 43 -4.3.4 ?

MensagemEnviado: 03 Out 2011 21:53
por pardal
Tenho que admitir que meu inglês não é lá essas coisas, mas já havia lido, verifiquei o código asm gerado e lá aparece as instruções para ajustar o ANSI eo CMCON0 e parece estar tudo certo, pois foi o que eu entendi no datasheet a não ser que, como disse acima meu inglês té me dando uma pernada.

Para ter uma idéia se a rotina da interrupção fica assim:

output_high(PIN_C3);
delay_us(DELAY);
output_low(PIN_C3);
delay_us(DELAY);

não funciona, se eu fizer:

output_high(PIN_A2);
delay_us(DELAY);
output_low(PIN_A2);
delay_us(DELAY);

aí funciona, e se eu fizer:

output_high(PIN_A2);
delay_us(DELAY);
output_low(PIN_A2);
delay_us(DELAY);
output_high(PIN_C3);
delay_us(DELAY);
output_low(PIN_C3);
delay_us(DELAY);

Funciona os dois, é claro que primeiro o pulso em A2 e depois em C3.

Veja estou usando os pinos A2 e C3 mas testei e notei que qualquer pino de A, menos A3 que só funciona como MCLR ou como entrada funciona e qualquer pino de C não funciona.

MensagemEnviado: 05 Out 2011 21:45
por pardal
Olá VTRX, verifiquei novamente o data sheet mas não consegui achar algo que me ajudasse, tem alguma outra dica?

Tô apanhando bastante, criei uma solução temporária que é enviar uma sequência de no pino RA3, o MCLR que programei como uso geral (apenas entrada pois esse pino, como consta no data sheet, é somente I e não I/O, mesmo assim com a sequência abaixo isso faz com que o pini RC3 funcione de maneira adequada.

output_high(RA3);
output_low(RA3);

Mas acho que deve haver uma solução e não esse artificio (para não falar gambiarra) que usei.

Alguém mais poderia dar uma dica?

MensagemEnviado: 05 Out 2011 22:23
por vtrx
Pardal,porque não programa este micro em ASM?
Usar CCS vai confundir mais.
Se eu fosse voce,programaria em C (C30),apenas para a linha 24 pra cima.
Citei o DataSheet,pois voc epode notar que tem pinos da PORTC que tem outras funções,tipo,RC3 pode ser I/O ou Entrada analógica,eu não sei como o CCS configura isto.
Agurade alguem que use o CCS.

MensagemEnviado: 06 Out 2011 00:06
por pardal
VTRX, de qualquer forma valeu pela força.

Mas como disse dei uma boa vasculhada no código assembler gerado e parece estar tudo certo.

Eu gosto muito do assembler e sempre usei ele, mas nesse caso o projeto vai caminhar para um ponto onde vou precisar alguns cálculos mais complexos, com seno, quadrado entre outros.

Por isso achei boa oportunidade para aprender o C e que seria mais fácil com relação aos cálculos.

MensagemEnviado: 06 Out 2011 10:26
por vtrx
Só uma observção,não adianta olhar o ASM gerado pelo compilador C pois é dependente da implementação do programador do compilador.
Aguarde alguem que use o CCS.

MensagemEnviado: 06 Out 2011 15:39
por ze
oi. veja um dimmer que fiz com pic10f há alguns anos. simulação=ok. tenho o.hex e .dsn se desejar
Código: Selecionar todos
//programa dimmer com pic10f200
//16/04/08
//V0.0 - simulação no MPLAB OK
//V0.1 - simulação no Proteus

#include <pic.h>

#define sobe GP0
#define desce GP1
#define triac GP2
#define zeroc GP3

#define ligado 1
#define desligado 0

__CONFIG(PROTECT & WDTDIS & MCLRDIS);

void delay(unsigned char dl)
{
while(dl--); //alguns uSegs
}

//******************************************************

void main (void)
{
unsigned char a=120; //valor de teste ~ metade da potência
OPTION=0b00000100; ///pullup, prescaler timer0=1:32
TRIS=0b1011; //só GP2=saída=dispara triac
GPIO=0xff;

for (;;)
{
while(!zeroc); //aguarda passagem por zero

TMR0=a-20; //de neg. p pos. alguns triacs disparam antes (ou depois!)
while(TMR0);//aguarda por alguns mSeg

triac=ligado; //pulso...
delay(30);
triac=desligado; //...no gate

while(zeroc); //aguarda passagem por zero
   
TMR0=a;
while(TMR0); //aguarda por alguns mSeg

triac=ligado;
delay(30);
triac=desligado;

if (!sobe) a++; //ângulo de disparo
if (!desce) a--;

if (a<25) a=25; //limite mínimo
if (a>240) a=240; //máximo

   
}

}

hitech-c~=mikroc~=sdcc
abç