Você está na página 1de 7

Recursos Exclusivos do CCS C (compilador C para Microcontrolador PIC)

O Compilador C da CCS (Custom Computer Services) talvez seja um dos mais fceis de ser usado para gerar cdigo c embarcado (ou embutido) para microcontroladores PIC. Talvez, tambm, seja um dos mais odiados por profissionais que o acusam de gerar cdigo grande, lento, frente outros como o HI-tech C, IAR ou Microchip C18, este para linha PIC18. Bem, o fato a CCS tem melhorado seu produto. Ento, resolvi postar aqui alguns recursos que a CCS diz serem exclusivos de seu compilador, conforme menciona a pgina do produto no site da empresa (Features Exclusive to CCS Compiler). Quem sabe depois disso, o compilador CCS deixe, ao menos um pouco, de ser to criticado. Recursos Exclusivos do Compilador C CCS (para PIC) (Exclusive Features to CCS C Compiler)

Constantes strings de comprimento varivel


Examine esta ineficiente estrutura de constantes strings: const char strings[3][15] = { "HELLO", "WORLD", "EXTRALONGERWORD" };
No exemplo acima, foi deixado o comprimento mximo de cada string em 15 caracteres, isto devido string "EXTRALONGERWORD". Mas, um vez que as strings "HELLO" e "WORLD" possuem somente 6 caracteres cada (no devemos esquecer do caractere de terminao null), 9 bytes so perdidos para cada um destas strings. Para amenizar este problema, use o mtodo para constantes strings de comprimento varivel:

const char strings[][*] = { "HELLO", "WORLD", "EXTRALONGERWORD" };


Obs.: Isto possvel devido adio de inteligncia na indexao de tabela de dados constantes. Devido isto, no possvel criar ponteiros para strings constantes de comprimento varivel.

Maior flexibilidade na manipulao de constantes


O compilador adiciona ponteiros para constantes: /* um simples exemplo mostrando a atribuio de ponteiro para constante com o endereo de uma string constante: */ const char version[] = "PRODUCT ID V1.01"; const char *ptr;

ptr = &version[0];

/* Um exemplo mais complexo que cria um estrutura de ponteiros para strings constantes: */ const char *strings[] = { "HELLO", "WORLD", "CONST", "STRINGS" };

/* Acessando os ponteiros para constantes acima: */ const char *ptr; while (i = 0; i < (sizeof(strings) / sizeof(const char *)); i++) { ptr = strings[i]; printf("%s", ptr); }

Em adio, strings constantes podem ser passadas para funes que that are normalmente recebem ponteiros para caracteres:

/* A diretiva a seguir habilita o recurso do compilador para copiar strings constantes dentro da RAM quando estas so passadas como parmetros a uma funo: */ #device PASS_STRINGS=IN_RAM

/* um exemplo do uso deste novo recurso: */ if (stricmp(buffer,"ATDT\r")==0) { //faz alguma coisa } Note que o qualificador const sempre significa que o dado ser colocado na memria de programa e, portanto, este dado "somente leitura". Isto no segue a definio ANSI que estabelece simplesmente que o qualificador const apenas significa ser "somente leitura".

Diretiva #USE I2C()


Experimente a poderosa biblioteca IC (Inter-Integrated Circuit - Circuito Inter-Integrado) includa no compilador. Primeiro, voc pode atribuir suas portas IC diferentes identificadores de stream (fluxo de dados). Atribuindo diferentes identificadores de stream aos canais IC, fica fcil diferenciar no cdigo qual porta est sendo usada. Segundo, a funo i2c_start() pode enviar um sinal de incio (IC start) ou um sinal de reincio (IC restart). O parmetro de reincio para a funo i2c_start() pode ser configurado para um valor "2" para forar um reincio ao invs de um incio. Um valor "1" far um incio

normal. Se o reincio no especificado ou "0", ento o reincio ser feito somente se o compilador encontrou por ltimo um i2c_start() e no um i2c_stop(). /* Isto configura duas portas IC, cada qual com seu identificador de stream diferente. */ #use i2c(sda=PIN_C4, scl=PIN_C3, stream=I2C_HW) #use i2c(sda=PIN_B1, scl=PIN_B2, stream=I2C_SW)

/* A funo seguinte l um byte de dado da EEPROM IC 24LC16 da Microchip, usando a porta identificada como I2C_HW: */ int Read2416(int address) { i2c_start(I2C_HW, 1); //perform a start i2c_write(I2C_HW, 0xA0); i2c_write(I2C_HW, address); i2c_start(I2C_HW, 2); //perform a restart i2c_write(I2C_HW, 0xA1); data=i2c_read(IC2_HW, 0); i2c_stop(I2C_HW); return(data); }

Diretiva #USE SPI()

Algumas das bibliotecas mais poderosas do CCS so as que do suporte comunicao serial com protocolos RS-232 e IC, as quais do ao programador a flexibilidade de usar mltiplas portas RS-232 e IC ao mesmo tempo que estiver usando qualquer conjunto de pinos de I/O de uso geral, sem restringir o uso destes pinos somente aos perifricos. Bibliotecas SPI (Serial Peripheral Interface - Interface Serial para Perifricos) esto includas no CCS e permitem ao usurio o uso de qualquer pino I/O de uso geral, configurao de clock, qualquer nmero de bits de dados, streams, freqncia de clock e mais.

/* O #use SPI configura a porta SPI. Aqui tem-se um configurao simples: */ #use SPI( DO = PIN_B0, DI = PIN_B1, CLK = PIN_B2, baud = 100000, BITS = 8, LSB_FIRST, SAMPLE_RISE, stream = SPI_PORT0 ) /* Lendo um byte de dados, no caso, de uma memria EEPROM 9356 usando o novo stream SPI: */ void Read9356(long address, int data) { output_high(EEPROM_9356_SELECT); SPI_XFER(SPI_PORT0, 0x18);

SPI_XFER(SPI_PORT0, address); data=SPI_XFER(SPI_PORT0, 0); output_low(EEPROM_9356_SELECT); }

Diretiva #USE RS232()


A biblioteca para RS-232 do compilador, inclu as seguintes opes:

Dois parmetros adicionais para #use rs232(): UART1 e UART2. Escolhendo um destes parmetros, os pinos de transmisso e recepo da biblioteca RS-232 do CCS sero automaticamente configurados para os pinos de transmisso e recepo do hardware MSSP do microcontrolador PIC. Um parmetro de timeout (tempo excedido) ser includo, atribuindo funo getc() um timeout de um determinado tempo em milissegundos. Um parmetro de clock permite que se possa configurar o clock do sistema, ao invs de usar o clock especificado pela diretiva #use delay. Quando este parmetro no especificado, ser utilizado o clock especificado na diretiva #use delay. O nmero de stop bits (bits de parada) pode ser definido. O RS-232 pode ser utilizado no modo sncrono master (mestre) ou sncrono slave (escravo). A opo baud rate (taxa de transmisso em bytes por segundo) suporta vrgulas, perodos, e os seguintes prefixos: K, KHZ, MHZ. Por ex., agora so vlidos: BAUD=9.6k, BUAD=115,200, BAUD=115,2k, etc.

Configurao Automtica dos fusveis (#fuses)


O compilador configura automaticamente algumas configuraes de bits (#fuses) baseado no cdigo:

Por padro, a opo (fusvel) NOLVP ser configurada (desligando a programao em baixa tenso - low voltage programming). Por padro, a opo (fusvel) PUT ser configurada (ligando o power-up timer - temporizador do estado de reset que quando ligado, mantm o PIC em reset por cerca de 72ms aps este ter sido ligado). Se no existe a funo restart_wdt() no cdigo, a opo NOWDT ser configurada. Caso exista a funo restart_wdt() no cdigo, ento a opo WDT ser configurada. Os bits de configurao do oscilador sero configurados com base na diretiva #use delay (ver prxima seo). Se o debugger est habilitado na IDE PCW, a opo DEBUG ser configurada.

Com as opes bsicas dos fusveis sendo configurados automaticamente muitos programas no precisaram de utilizar a diretiva #fuses. Este recurso pode ser desabilitado usando a compatibilidade retroativa CCS3 (veja a seo CCS backwards compatibility no site da CCS).

Addressmod: capacidade para criar espaos definidos pelo usurio em qualquer tipo de memria (interna ou externa)
Parte do padro IEEE Embedded C standard (ISO/IEC TR 18037), o qualificador addressmod permite o uso de identificadores personalizados que servem para criao de varveis em qualquer tipo de memria (interna ou externa). O identificador assim criado, pode ser usado com tipo de dados, incluindo estruturas, unies, vetores, e ponteiros. Verifique o exemplo a seguir que usa o addressmod para criar variveis na ram externa:

/* A sintaxe para o addressmod : addressmod (identifier,read,write,start,end) identifier - o nome de seu identificador personalizado read/write - as funes de leitura e escrita para acesso memria externa start/end - a faixa de endereos que este identificador pode acessar */ addressmod(extram, readextram, writeextram, 0, 0xFFFF) /* Cria um vetor extenso; o contedo real deste vetor ser armazenado na memria externa. */ extram largeBuffer[2000]

/* Cria um ponteiro para a memria externa. O ponteiro em si ser armazenado na memria do microcontrolador. */ extram char *extramPtr; /* Alguns exemplos de uso. */ //acesso direto largeBuffer[0] = 5;

//atribuio do endereo ao ponteiro extramPtr = &largeBuffer[0];

//acessando a memria externa indiretamente *extramPtr = 5;

Parmetros Default (padro)

Este recurso foi tomado emprestado da linguagem C++, sendo includo no compilador. Parmetros Default podem ser usados nas funes. Assim, se o parmetro no passado funo, o valor padro deste utilizado.

int mygetc(char *c, int n=100) { /* Esta funo espera n milisegundos por um caractere enviado via comunicao RS232. Se um caractere recebido, este salvo no ponteiro c e retorna TRUE. Se ocorrer um timeout, um FALSE retornado. */ }

//obtm caractere, espera 100ms para timeout mygetc(&c);

//obtm caractere, espera 200ms para timeout mygetc(&c, 200);

Nmero varivel de parmetros

possvel usar funes que possuam nmero varivel de parmetros. Isto mais comumente encontrado em funes tais como as das bibliotecas printf e fprintf.

/* stdarg.h possui as macros e o tipo de dado va_list necessrios para se usar o recurso de nmero varivel de parmetros. */ #include <stdarg.h> /*

Uma funo com nmero varivel de parmetros necessita de duas coisas. Primeiro, necessita das reticncias (...), o qual precisa ser o ltimo parmetro da funo. As reticncias representam a lista de argumentos varivel. Segundo, necessria uma varivel a mais antes das reticncias (...). Usualmente usa-se esta varivel como mtodo para determinar quantas variveis sero passadas no lugar das reticncias. Aqui, uma funo que calcula e retorna a soma de todas as variveis: */ int Sum(int count, ...) { //um ponteiro para a lista de argumentos va_list al;

int x, sum=0;

//inicia a lista de argumentos //count a primeira varivel antes das reticncias va_start(al, count);

while(count--) { //obtm um inteiro da lista x = var_arg(al, int);

sum += x; }

//termina usando a lista va_end(al);

return(sum); }

/* Alguns exemplos usando esta nova funo: */ x=Sum(5, 10, 20, 30, 40, 50); y=Sum(3, a, b, c);

Sobrecarga de funes (overloading)

Tomado emprestado da linguagem C++, este recurso permite ao usurio implementar diversas funes com mesmo nome, porm diferenciando-as em nmero e tipos de parmetros.

/* Aqui tem-se um exemplo de sobrecarga de funes: As duas funes a seguir tm o mesmo nome, mas diferenciam-se quanto ao tipo usado nos parmetros. O compilador determina o tipo de parmetro que est sendo passado e chama a funo apropriada. */

void FindSquareRoot(long *n) { /* Esta funo encontra a raiz quadrada de uma varivel do tipo inteiro longo (do ponteiro), sendo o resultado retornado de volta ao ponteiro. */ }

void FindSquareRoot(float *n) { /* Esta funo encontra a raiz quadrada de uma varivel do tipo inteiro ponto flutuante (do ponteiro), sendo o resultado retornado de volta ao ponteiro. */ }

/* A funo FindSquareRoot chamada. Se a varivel do tipo inteiro longo, a primeira implementao da FindSquareRoot() ser usada. Caso seja do tipo ponto flutuante, a segunda implementao que ser usada. */ FindSquareRoot(&variable);

Decimal de ponto fixo

Uma recurso poderoso do compilador CCS a habilidade de representar decimais usando um novo tipo de dado, o decimal de ponto fixo. Decimal de ponto fixo proporciona representao decimal, mas com a velocidade de um inteiro. Isto proporciona um aumento de velocidade fenomenal em relao a operao com ponto flutuante. Isto realizado atravs do qualificador: _fixed(x), onde o parmetro x o nmero de dgitos aps o ponto decimal que o tipo de dado pode reter.

/* Cria uma varivel de 16bits com uma faixa de 0.00 to 655.35 */ int16 _fixed(2) dollars;

/* Atribuindo 1.23 varivel dollars. Internamente, 123 ser salvo no int16. */ dollars=1.23;

/* Somando 3.00 dollars. Internamente, 300 adicionado ao int16. */ dollars += 3;

/* printf exibir 4.23 */ printf("%w", dollars);

Você também pode gostar