Ir ao conteúdo

Converter codigo de mickro C para CCS


rodrigocirilo

Posts recomendados

Postado

Pessoal do CDH me ajudem por favor... eu programo (tento) rsrs em C no CCS, quando era bem iniciante comprei esse codigo no Odesk.com mas o programador fez em mickro C, e agora eu quero fazer algumas alterações, mas para isso tem que ser no CCS e eu nao estou conseguindo programar igual no CCS.

 

ele foi feito para o pic 12F675, mas agora vou usar um 16F676.

 

esse programa lê o canal ADC e de acordo com a leitura ao pressionar o gatilho ele seta em 1 uma determinada porta por um tempo de acordo com o tempo associoado a leitura do canal AD..

 #define Pressure 0#define Trigger gpio.GP1#define Coil    gpio.GP2 //unsigned int dataPressure =0; // Pressure variable(1023 corresponds with 10 v and 0 corresponds with 0v)float SensorOutput = 0.0;char Delay = 0;void init(){ ADC_Init();   //initialize ADC TRISIO = 0b00000011; // Pressure and Trigger are input, coil is output GPIO = 0; // Reset the GPIO ANSEL = 1; CMCON  = 7;              // Turn off the comparators TRISIO1_bit = 1;} unsigned char getDelay(int SensorOutput){    if (SensorOutput>=950) return 100;    if (SensorOutput>=900) return 90;    if (SensorOutput>=850) return 80;    if (SensorOutput>=800) return 70;    if (SensorOutput>=750) return 60;    if (SensorOutput>=700) return 50;    if (SensorOutput>=650) return 40;    if (SensorOutput>=600) return 30;    if (SensorOutput>=550) return 20;    if (SensorOutput>=500) return 10;    if (SensorOutput>=0) return 10;}void main() {     init();     while(1){             Delay = getDelay(ADC_Read(Pressure));             if(Trigger){                Delay_ms(200);// bounce                 Coil = 1;                 VDelay_ms(Delay);                 Coil = 0;                 Delay_ms(3000);             }    }}

Editando:

 

Fiz um esboço no CCS, o tempo (variavel) delay até que obedece quando o ADC está em 10 ou em 100, mas acima disso ele só fica nos 250 ms..

 #include <16F676.h>#device adc=8 #FUSES NOWDT                    //No Watch Dog Timer#FUSES INTRC                    //Internal RC Osc#FUSES NOPROTECT                //Code not protected from reading#FUSES NOBROWNOUT               //No brownout reset#FUSES NOMCLR                   //Master Clear pin used for I/O#FUSES NOCPD                    //No EE protection#FUSES PUT                    //No Power Up Timer//#FUSES BANDGAP_HIGH           #use delay(clock=4000000)  int analog=0;int delay=0;          void main(){    setup_adc_ports(sAN0|VSS_VDD);   setup_adc(ADC_CLOCK_INTERNAL); //  setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);   setup_timer_1(T1_DISABLED);   setup_comparator(NC_NC);   setup_vref(FALSE);   WHILE(true){      set_adc_channel(0);      delay_us(20);      analog=read_adc();      delay_ms(10);        if(analog>=10){ delay=50;}     if(analog>=100){ delay=250;}     if(analog>=200){ delay=500;}                       if(input(PIN_A5))      {             output_high(PIN_C0);        delay_ms(delay);         output_low(PIN_C0);           delay_ms(1000);                           }  }}
Postado

Tente assim:

 

#include <16F676.h>#device adc=10 #FUSES NOWDT                    //No Watch Dog Timer#FUSES INTRC_IO                    //Internal RC Osc#FUSES NOPROTECT                //Code not protected from reading#FUSES NOBROWNOUT               //No brownout reset#FUSES NOMCLR                   //Master Clear pin used for I/O#FUSES NOCPD                    //No EE protection#FUSES PUT                    //No Power Up Timer #use delay(clock=4000000)  int16 analog=0;int16 delay=0; void main(){    setup_adc_ports(sAN0);   setup_adc(ADC_CLOCK_DIV_32);    set_adc_channel(0);   delay_us(20);      WHILE(true)   {               analog=read_adc();      delay_ms(10);            if ((analog >= 10) && (analog < 100))      {          delay=50;      }      else if ((analog >= 100) && (analog <= 200))      {          delay=250;      }      else if ((analog >= 200) && (analog <= 1024))      {          delay=500;      }                  if(input(PIN_A5))      {               output_high(PIN_C0);         delay_ms(delay);         output_low(PIN_C0);           delay_ms(1000);       }    }}
Postado

Ok Matheus obrigado pela resposta, mas na verdade esses 3 foram só um exemplo, na verdade eu queria que fosse igual ao primeiro codigo que está em mickro C, onde terei varios valores. 

 

acho que até dá pra fazer assim, mas o codigo vai ficar muito extenso. mas se nao tiver outro jeito...

 

de qualquer forma obrigado pela ajuda... 

Postado

Matheus, outra coisa que vi, por que no seu codigo de exemplo você usou o setup_adc(ADC_CLOCK_DIV_32) por que DIV_ 32 e não internal???

Editando:

aproveitando, compilei e simulei no proteus e o tempo associado e leitura do adc entre 100 e 200 nao funcionou que seriam os 250ms....

Postado

Na verdade, você não precisa de delay. Mas o conversor AD tem um tempo mínimo para executar a conversão. Está no datasheet como título de A/D Acquisition Requirements

Lá ele explica exatamente como calcular o tempo (normalmente 16uS). Nesse caso, você precisa configurar o AD de acordo com o clock do PIC.

Aí lá no CCS, temos as seguintes opções de configuração da velocidade de conversão do AD:

////////////////////////////////////////////////////////////////// ADC// ADC Functions: SETUP_ADC(), SETUP_ADC_PORTS() (aka SETUP_PORT_A),// SET_ADC_CHANNEL(), READ_ADC()// Constants used for SETUP_ADC() are:#define ADC_OFF 0 // ADC Off#define ADC_CLOCK_DIV_2 0x10000#define ADC_CLOCK_DIV_4 0x4000#define ADC_CLOCK_DIV_8 0x0040#define ADC_CLOCK_DIV_16 0x4040#define ADC_CLOCK_DIV_32 0x0080#define ADC_CLOCK_DIV_64 0x4080#define ADC_CLOCK_INTERNAL 0x00c0 // Internal 2-6usAí você escolhe e acordo com o cristal.

 

Falou

Postado

Na verdade, você não precisa de delay. Mas o conversor AD tem um tempo mínimo para executar a conversão. Está no datasheet como título de A/D Acquisition Requirements

Lá ele explica exatamente como calcular o tempo (normalmente 16uS). Nesse caso, você precisa configurar o AD de acordo com o clock do PIC.

Aí lá no CCS, temos as seguintes opções de configuração da velocidade de conversão do AD:

 

////////////////////////////////////////////////////////////////// ADC// ADC Functions: SETUP_ADC(), SETUP_ADC_PORTS() (aka SETUP_PORT_A),// SET_ADC_CHANNEL(), READ_ADC()// Constants used for SETUP_ADC() are:#define ADC_OFF 0 // ADC Off#define ADC_CLOCK_DIV_2 0x10000#define ADC_CLOCK_DIV_4 0x4000#define ADC_CLOCK_DIV_8 0x0040#define ADC_CLOCK_DIV_16 0x4040#define ADC_CLOCK_DIV_32 0x0080#define ADC_CLOCK_DIV_64 0x4080#define ADC_CLOCK_INTERNAL 0x00c0 // Internal 2-6usAí você escolhe e acordo com o cristal.

Falou

Sim mas eu tinha dado o tempo necessario para a conversão:

 

 setup_adc_ports(sAN0);
   setup_adc(ADC_CLOCK_INTERNAL);
   set_adc_channel(0);
   delay_us(20); 
 
 
Ou você fala desse aqui que você adicionou:
 
 analog=read_adc();
      delay_ms(10);
 
 
 
Quanto ao clock do ADC, no caso eu vou usar o oscilador interno do PIC 4Mhz, qual o clock que tenho que usar para conversão AD, não entendi muito bem isso...
 
Também tenho outro projeto onde vou usar um cristal externo de 20Mhz, e lá eu uso 1 canais AD, e configurei como ADC_CLOCK_INTERNAL também.  ja montei na proto e funcionou.... lembrando que lá é um pic 16F876..
 
 
Mas enfim, a parte do codigo eu acabei programando mais um pouco e pelo menos no proteus funcionou.. segue:
 
 #include <16F676.h>#device adc=10 #FUSES NOWDT                    //No Watch Dog Timer#FUSES INTRC_IO                    //Internal RC Osc#FUSES NOPROTECT                //Code not protected from reading#FUSES NOBROWNOUT               //No brownout reset#FUSES NOMCLR                   //Master Clear pin used for I/O#FUSES NOCPD                    //No EE protection#FUSES PUT                    //No Power Up Timer #use delay(clock=4000000)  int16 analog=0;int16 delay=0; void main(){    setup_adc_ports(sAN0);   setup_adc(ADC_CLOCK_INTERNAL);   set_adc_channel(0);   delay_us(20);      WHILE(true)   {               analog=read_adc();      delay_ms(10);            if      (analog >= 950)/* && (analog <= 1023))*/{delay=200;}      else if (analog >= 900)/* && (analog <= 949))*/ {delay=190;}      else if (analog >= 850)/* && (analog <= 899))*/ {delay=180;}       else if (analog >= 800) /*&& (analog <= 849))*/ {delay=170;}      else if (analog >= 750) /*&& (analog <= 799))*/ {delay=160;}      else if (analog >= 700)/* && (analog <= 749))*/ {delay=160;}         else if (analog >= 650)/* && (analog <= 699)) */{delay=160;}      else if (analog >= 600)/* && (analog <= 649))*/ {delay=170;}      else if (analog >= 550)/* && (analog <= 599))*/ {delay=180;}         else if (analog >= 500)/* && (analog <= 549))*/ {delay=190;}                  if(input(PIN_A5))      {               output_high(PIN_C0);         delay_ms(delay);         output_low(PIN_C0);           delay_ms(1000);       }    }}
Postado

Rodrigo, veja essa tabela que consta em todos os datasheets dos PICs com AD:

 

tabala_AD_tempo_16F877.png

 

Ele relaciona o cristal com o divisor do AD.

 

Aquele delay que você colocou não adianta para a conversão. Ajuda, mas não resolve.

 

Se você usar o INTERNAL, vai funcionar, mas você perde precisão da medida.

 

Dê uma olhada no datasheet pela parte chamada A/D Acquisition Requirements.

 

Lá explica os detalhes do motivo pelo qual se deve usar essa configuração.

 

Falou

Postado

Rodrigo,o único trecho que voce deve alterar para 'funcionar' no CCs seria;

long getDelay(int SensorOutput){    if (SensorOutput>=950) return 100;    if (SensorOutput>=900) return 90;    if (SensorOutput>=850) return 80;    if (SensorOutput>=800) return 70;    if (SensorOutput>=750) return 60;    if (SensorOutput>=700) return 50;    if (SensorOutput>=650) return 40;    if (SensorOutput>=600) return 30;    if (SensorOutput>=550) return 20;    if (SensorOutput>=500) return 10;    if (SensorOutput>=0) return 10;}

acho...

Postado

Rodrigo, veja essa tabela que consta em todos os datasheets dos PICs com AD:

 

tabala_AD_tempo_16F877.png

 

Ele relaciona o cristal com o divisor do AD.

 

Aquele delay que você colocou não adianta para a conversão. Ajuda, mas não resolve.

 

Se você usar o INTERNAL, vai funcionar, mas você perde precisão da medida.

 

Dê uma olhada no datasheet pela parte chamada A/D Acquisition Requirements.

 

Lá explica os detalhes do motivo pelo qual se deve usar essa configuração.

 

Falou

 

Ok matheus, vou verificar e fazer uns testes... obrigado..

Rodrigo,o único trecho que voce deve alterar para 'funcionar' no CCs seria;

long getDelay(int SensorOutput){    if (SensorOutput>=950) return 100;    if (SensorOutput>=900) return 90;    if (SensorOutput>=850) return 80;    if (SensorOutput>=800) return 70;    if (SensorOutput>=750) return 60;    if (SensorOutput>=700) return 50;    if (SensorOutput>=650) return 40;    if (SensorOutput>=600) return 30;    if (SensorOutput>=550) return 20;    if (SensorOutput>=500) return 10;    if (SensorOutput>=0) return 10;}

acho...

Sim, mas como seria essa alteração?? 

Postado

Ja esta feita,desde que o problema era no Delay.

No CCS voce deve definir a variavel global usada no Delay como 'LONG'.

Long por estar usando o conversor ADC com 10 bits de resolução certo? e se eu usasse somente 8, qual seria o tipo de variavel....

Postado

Não,se voce não definir LONG o tempo do Delay fica limitado,o que difere o codigo feito no CCS como o Do MikroC,a temporização?

Postado
long getDelay(int SensorOutput){    if (SensorOutput>=950) return 100;    if (SensorOutput>=900) return 90;    if (SensorOutput>=850) return 80;    if (SensorOutput>=800) return 70;    if (SensorOutput>=750) return 60;    if (SensorOutput>=700) return 50;    if (SensorOutput>=650) return 40;    if (SensorOutput>=600) return 30;    if (SensorOutput>=550) return 20;    if (SensorOutput>=500) return 10;    if (SensorOutput>=0) return 10;}

Deixe a função igual a que esta postada aqui em cima,só isso.

Postado

Rodrigo,o CCS aceita essa função!!

voce não queria 'copiar' o código do MikroC para CCS??

A única coisa que não ia funcionar corretamente,alem das configurações iniciais,seria esta função.

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...

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!