Ir ao conteúdo

Programação em C para PIC


oiluj

Posts recomendados

Postado

Olá turma, procurando aqui pelo FCH não encontrei nenhum tópico que tratase em ambito geral da Programação em C para PIC!

Sou iniciante nesta área e preciso muito de ajuda, afinal umas das funções do Forum é essa, todos se ajudam e todos saem ganhando... Hehehe

Então resolvi criar este Tópico para que tratacemos disso e os mais experientes nessa área pudessem ajudar os iniciante, como eu!

Dei uma lida em algumas apotilas, e assiste a algumas videoaulas, vou postar eles aqui, e também contribuições de companheiros do Forum:

  1. 1-As video aulas são sobre Programação em C para computadores e estão disponicéis aqui, basta descompactar o arquivo com o winrar e clicar em curso.exe e depois seguir a ordem das videoaulas, com esse curso você aprenderá um pouco sobre a linguagem C ANSI, que é a que quase todos os compiladores para PIC usam, quem me passou esse link foi nosso companheiro shunt

  • 2-Após assistir essa video aula eu dei uma lida nesta apostila, disponivel aqui, ela é bem básica mais ajuda muito a iniciantes!

  • 3- Acabei de receber um excelente contribuição do companheiro test man, ele deu a dica dess blog aqui, dei uma olhada e ache muito interessante!

Agora venho pedir aos mais experientes, nesta area, que postem algum material mais avançado e que considerem bom, para aqueles que como eu querem migrar, ou se aprofundar na linguagem C pa PIC's!

Abraços!

Postado

Primeiramente, peço ao moderador que não una os Post seguidos, pois o primeiro voi apenas uma introdução ao Tópico, e agora venho postar uma Dúvida!

Desde já grato!

Após ler isso aí fui arriscar algumas linhas simples no CCS Compiler, para fazer 8 leds acenderem na sequência dó PORTB, o código ficou assim:


//Programador: Júlio César Souza Silveira Júnior
//Função do Programa: Acender 8 leds em sequência
//Data 12/02/2011
//-------------------------------------------------------------------------//
//-------------------------------------------------------------------------//
#include <16F877A.h>
#include <mudanca.inc>
#fuses XT,NOWDT,NOPROTECT,PUT
#use delay(clock=4000000)
//-------------------------------------------------------------------------//
void main()
{
TrisA(0x00);
TrisB(0x00);
TrisC(0x00);
TrisD(0x00);
TrisE(0x00);
while(true)
{
setbit (rb0);
delay_ms(100);
clearbit (rb0);
delay_ms(100);
setbit (rb1);
delay_ms(100);
clearbit (rb1);
delay_ms(100);
setbit (rb2);
delay_ms(100);
clearbit (rb2);
delay_ms(100);
setbit (rb3);
delay_ms(100);
clearbit (rb3);
delay_ms(100);
setbit (rb4);
delay_ms(100);
clearbit (rb4);
delay_ms(100);
setbit (rb5);
delay_ms(100);
clearbit (rb5);
delay_ms(100);
setbit (rb6);
delay_ms(100);
clearbit (rb6);
delay_ms(100);
setbit (rb7);
delay_ms(100);
clearbit (rb7);
delay_ms(100);
}
}
//-------------------------------------------------------------------------//

Funcionou direitinho, mas agora eu queria tentar fazer esse código de outra forma, tratando a saida como se fosse um Vetor (8x1) e enviando os bits para o PORTB, semelhante ao que se consegue fazer em Basic utilizando a função LookUp!

Alguem sabe qual seria a função que teria essa finalidade, pois olhando em ambas as fontes que tve, e também no Reference Manual do CCS (Que por sinal é muito complicado) eu não encontrei nenhuma função assim!

Valeu galera Abraços!

Postado

output_a (value)

Output an entire byte to a port. The direction register is changed in accordance with the last specified #USE *_IO directive.

Seria isso?

Se for o portB é só usar output_b (value). Ela escreve um valor no portb, por exemplo:


output_b(2)

O portb ficará assim:

MSB 0000 0010 LSB

Ou então:


int vet[0b00000000,0b00000001,0b00000010];
output_b(vet[1]);

Postado

Eu usei isso lá funcionou certinho, agora se não for pedi demais, eu queria saber uma função que tipo eu tenho uma variavel que recebeu o seguinte valor, 0b00000001, eu quero que esse valor vá se alternando da seguinte forma, 0b00000010, 0b00000100, 0b00001000, 0b00010000, 0b00100000, 0b01000000, 0b10000000.

Eu pensei que a função shift_left() faria isso, mas não estou sabendo como usá-la eu acho!

porque escrevi o seguinte:

output_b(leds);
delay_ms(2);
while(true)
{
shift_left(leds,1,rb0);
delay_ms(2);
}
}

Só que desse jeito aí, tá totalmente errado o shift_left, queria saber qual seria a forma certa?

Abraços!

Postado

Um tempo atrás tentei usar essa função, não obtive sucesso, então resolvi contorná-la para chegar ao meu objetivo.

Se alguém souber usá-la, poste um exemplo por favor.

Isto resolve o seu problema?


int array[7]={0b00000010, 0b00000100, 0b00001000, 0b00010000, 0b00100000, 0b01000000, 0b10000000};
int i;

void main()
{
while(true)
{
for(i=0;i!=7;i++)
{
output_b(array[i]);
delay_ms(200);
}
}
}

Postado

Programar em C para PIC é igual a programar para o PC, com limitações de pilha, memoria ram, entre outras, mas o modo de programar é o mesmo. A unica diferença são que para você lidar com os perifericos você tem acessar os registradores do PIC. Para tal acesso cada compilador tem alguma função pronta, e os registradores ja mapeados para alguma variavel. Basicamente se você quiser testar algum algoritmo especifico, você pode muito bem testar no computador, e trocar as funçoes de mudar os pinos, por printf da vida. Isso ajuda bastante o tempo de desenvolvimento.

Agora para o seu problema atual. Existe uma coisa chamada em C chamada bitwise. Basicamente são operações que lidam com uma variavel bit a bit. De uma olhada no google que você vai achar bastante referencia disso.

No caso do seu problema você faria da seguinte forma

int a = 0b00000001;

a <<= 1; //Essa operação é o equivalente à a = a << 1

output_b(a);

Postado

Alguns links que usei em tempos para entender a "matemágica" da coisa:

--

http://forum.imasters.com.br/topic/206127-operadores-bit-a-bit/

--

Abaixo, uso sempre:

http://www.graphics.stanford.edu/~seander/bithacks.html

--

Outro muito bom:

http://blog.bsoares.com.br/tag/cpp

--

Quando aprender e dominar estes operadores, verá que seus códigos já não irão ser mais os mesmos.

Existe relatos sobre alguns bugs que eles podem provocar. Pessoalmente nunca os encontrei. E digo que tem praticamente o mesmo efeito do assembly(dependendo do compilador).

Abraço.

Postado

Shunt, pelo menos na simulação o meu funcionou (mostrou o que eu queria ver)...

Diferença entre o seu e o meu código:

Você a<<1 (a<<1 é diferente de a=a<<1)

Eu a<<aux

No meu código eu não altero o valor de a em nenhum momento, mas altero o valor do aux.

Não sei se estou correto, mas acho que com o seu código o bit não vai "andar" pelo port, vai ficar sempre

MSB 0000 0010 LSB...

Postado
Shunt, pelo menos na simulação ...

test man*~: retirei parte da msg anterior para quem inicia não fazer confusão (nem mesmo eu), assim o tópico fica limpo.

Uma pequena falha de digitação(de novo :wacko:) correção:


int aux = 0;

while(1){
for(aux; aux <= 7; aux ++){
output_b(1 << aux);
delay_ms(200);
}
aux = 0;
}

Seu código é funcional. Ao testar cometi um erro.

Agora os dois produzem o mesmo efeito. Muda-se a estrutura de controle, e uma variável à menos.

Download : Codificado com mikroC 4.15 e arquivo para simulação no Proteus.

Tudo que você precisa está aqui:

Matheus, o arquivo precisa de um password para descompactar. Não encontrei. Sabe qual é? Obrigado.

Abs.

Postado

Então, testei ambos os códigos....

Todos os dois realizam o mesmo serviço....

Porém nã sei porque na hora de compilar o arquivo do shunt, dá um aviso, não um erro mas um aviso, falando que a estrutura FOR não tera efeito, porém ao simular o arquivo hex no proteus, ele funcionou perfeitamente....

Enfim com isso tudo cmocluimos uma unica coisa, o mundo da programação é muito amplo uma mesma atividade pode ser feita de várias formas, e todos nós temos informações para trocar um com os outros, e a cada dia aprender mais.... E isso só vai beneficiar todo mundo!

E como disse o amigo shunt com relação ao post do MatheusLPS realmente o arquivo precisa de uma senha e eu também nao consegui encontrar!!!

Abraços, Vamos noite a dentro?

Tô no trampo, então hoje é a noite inteira tentando aprender um pouco mais de C!

Postado

Fala pessoal, o link que passei nao sabia que tinha senha.

Mas tenho a apostila aqui e upei p vocês, está sem senha agora. Contém todos os exemplos prontos.

Compilador_C_Ccs_Y_Simulador_

Para quem já está acostumando a programar, vai achar a apostila simples. Mas tem umas 200 páginas de pura informação. Vale a pena.

[OFF-TOPIC]oiluj, você faz faculdade aí em são joão del rei? Estou no 10º período de Engenharia Elétrica aí na Federal de São João.[/OFF-TOPIC]

Estarei aqui no PC até umas 4 da manhã, dúvidas, só postar.

Falou

Postado

Fala já estou baizando lá cara...

Pra ir aprendedo um pouco da linguagem C eu estou pegando uns programinhas que fiz quando comecei no Basic, e fazendo ele em C, agora estou com o seguinte impasse...

Preciso fazer que o programa aguarde que uma chave seja precionada, pra depois iniciar uum contagem de 0 a 9 e mostre em um dizplay de 7-seg, já fiz tudo, tá contando e mostrando certinho, a unica coisa que não tô conseugindo fazer é o programa aguardar que o botão seja precionado!!

[OFF-TOPIC]Eu estou no 5º periodo, mas devend Deus e o mundo nos calculos, eu Faço Elétrica também!![/OFF-TOPIC]

Falous!

Editando aqui, porque serviço hoje pegando fogo vou ter que sair, que tá movimentado aqui, e amanha viajo cedo...

Mas tem mais uma dúvida não estou conseguindo fazer com que uma chave seja o RA0, tentei usar o #bit chave=porta.0, mas não deu!!

Valeu abraços!!

Postado

Veja isto:


#define botao pin_a0

short botao_press=0;
int cont=0;

-----------------------------
while(true)
{
if(input(botao))//ao apertar o botão, a contagem se inicia (1 /\)
botao_press=1;

if(botao_press==1)
{
output_b(cont);//você vai mandar para um display, apenas exemplo aqui
delay_ms(200);

cont++;
if(cont>9)
{
cont=0;
output_b(cont);//zera o port
botao_press=0;//zera a varia vel para parar de contar
}
}
}

Caraca, o Matheus deve estar rindo à toa!!!!! Já é um engenheiro =D... Parabéns ai cara, é muita luta até chegar ao fim do curso.

Mas tem mais uma dúvida não estou conseguindo fazer com que uma chave seja o RA0, tentei usar o #bit chave=porta.0, mas não deu!!

Valeu abraços!!

Tem que endereçar a porta antes. O PIC que você está usando é 18F ou 16F?

#byte porta=0xf80 //18F

#byte porta=0x05 //16F

Postado

Julio, não sei se é exatamente o que precisa:

Download

É um exemplo simples feito com mikroC.

Ao pressionar um botão ou outro, uma variável é incrementada/decrementada e o valor dela decodificado no display.

Se for usar na pratica, não esqueça os resistores nos pinos do portB para o display, na simulação omiti eles.

Abraço.

Postado

Qual seria a linguagem mais eficiente

Assembly, sem dúvida.

completa

C evoluiu muito, cheio de bibliotecas prontas.

e fácil para se praticar?

Só depende do conhecimento inicial, basic para quem não ou pouco sabe.

Pergunto por que estou "treinando" em BASIC com as apostilas do nosso amigo; o engenheiro Paulo, usando o PSI conforme esse link.

http://forum.clubedohardware.com.br/tutorial-introducao-ao/692629

Agricio

É um bom material, treine bastante com ele. Quando achar que deve, migre para C.

Só uma opinião!

Abs.

Postado

Quanto a eficiência, depende muito da aplicação. Hoje em dia há compiladores em C que possuem alta eficiência e fornecem opções para melhorar isso, aumentando um pouco a complexidade do código. Creio que não se deve pensar em eficiência a nao ser em escala industrial. O grande lance da eficiência era antigamente quando as memórias eram caras e era preciso utilizar o máximo possível, dai havia processadores com comandos assembly que forneciam até seno e cosseno. Mas hoje em dia o assembly está sendo redusido para interfaces com pouco mais de 30~50 comandos, e o C nos oferece uma gama de recursos bem melhor. As memórias estão baratas e é possivel fazer quase tudo que se imagina com um ic.

Eu recomendo o C do CCS. O colega MatheusLPS me deu uma grande dica de observar o include de cada pic, que explica todos os comandos que podem ser usados para gerencias o microcontrolador. Com uma pequena noção das funções e de inglês pode-se fazer muito.

Postado

shunt dei uma olhada no arquivo que me mandou e ele é até superior o que eu estava fazendo, mas deu pra ter uma bos ideia de várias funções excelente, e funcionou perfeitamente...

Olhei também o post do test man e fiz umas mudanças a parte de ambos, ficou assim o código completo:


#include <16F877A.h>
#include <mudanca.inc>
#fuses XT,NOWDT,NOPROTECT,PUT
#use delay(clock=4000000)
#define botao RA0
//-------------------------------------------------------------------------//
void main()
{
int array[10]={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};
int i=0;
short chave=0;
while(true)
{
if(input(botao))
{
chave=1;
If (chave==1)
{
for(i=0;i!=10;i++)
{
output_b(array[i]);
delay_ms(200);
}
}
}
}
}

Eu só não estou entendo direito agora qual é a funçção de se declarar no inicio do programa o Fast_IO(X) e declarar através do TrisX(0x00) quais pinos são entradas e saídas, porque quando coloco o Trisb(0x00), no diplay fica só aparecendo o número 7!

Alguem poderia me elucidar o uso dessas funções, que acho que pensei que funcionavam de uma forma e na realidade funcionam de outra!

Quanto aos posts do Agricio:

A expliacção dos nossos amigos, shunt e edu. foram excelentes, eu particularmente aprendi muito com os tutoriais de nosso amigo aphawk, foi com eles que comecei praticamente a programação de PIC's, fiz as duas partes do tutorial, e depois desenvolvi bastante coisa sozinho, como o projeto de uma estufa, esse para um trabalho na faculdade, e um Cubo de Led's, esse já por Hobbi mesmo... E fiquei muito satisfeito, com a linguagem e os resultados possiveis!

Agora comecei a estudar o C e estou apreendo cada dia mais, mas não pretendo abandonar o Basic por isso! O C como já foi dito é uma excelente linguagem por já existir muitas bibliotecas prontos, o que reduz muito o trabalho do programador! E quanto a compilador, estou usando o CCS Compiler, porém tem muitas pessoas que usam o MikroC, mas você aprendendo o funcionamento da linguagem em geral, consegue programar em praticamente todos os compiladores C!

Quanto a eficiencia, o que disse o companheiro shunt é em parte verdade, mas hoje em dia e para os fins que pelo menos eu preciso, não a necessidade de se programar em assembly, que é uma linguagem muito mais complexa que o C e o Basic!

Enfim eu o aconselharia, a estudar as 2 prates do tutorial do aphawk, depois que terminá-las praticar eu quando você já tiver fera no Basic, comece a estudar o C como estou fazendo!!

Postado

Julio, quanto ao registrador TRIS, ele define que pino será entrada e qual será saída. É claro que nem todos os pinos podem ser saídas ou mesmo entradas (depende do tipo e do fabricante). Exemplo para o 16F628A:

PIC16F628A-pinout.jpg

Repare nas setas. Duplas diz que o pino pode ser bidirecional. Simples não (atente aos pinos de alimentação).

A memória (todos os registradores) é organizada da seguinte forma em pic's de 14 bits:

fig0-9.gif

Se você colocar a palavra TRIS à esquerda da imagem acima, a posição dos bits que configura quem será entrada e saída é representada pela propria imagem.

Quando você coloca valor "1" em algum bit do tris, ele será entrada. E quando escreve "0" ele será saida.

Exemplo: B0, B2, B4 e B7 serão saídas o resto entrada. Configuração:

TRISB = 0b01101010; // ou em Hex

TRISB = 0x6A; // que é o mesmo acima.

O tris informa ao processador quem são entradas ou saidas. O PORTx é quem se comunica com o mundo externo, e é neste que você escreve ou lê, a imagem abaixo explica melhor:

fig3-35.gif

Quanto a diretiva:

#use Fast_IO(Port). É obrigatório o uso desta, pois ela informa ao compilador que o controle da direção dos ports(registro TRIS do port indicado) será executado pelo programa. Gera operações de entrada e saída mais rápidos.

Retirei isto do livro do Fábio Pereira que tenho aqui. Pelo que entendo, ela coloca o controle do tris "nas suas mãos". O pessoal do CCS, pode lhe esclarecer melhor.

Espero que ajude. Abraço.

Postado

Valeu shunt, brigadão deu um grande elucidada no assunto e eu acho que o meu TRIS tava diferente porque ao invés de TRIS = 0x00, eu estava colocando TRIS(0x00) aí já viu neah?!! Mancada minha!!

Agora alguém que possa me ajudar, eu estou tentando fazer um código (Tipo aquele que você me mandou shunt) para que o contator, vá aumentando a medida que eu aperte o botão, ou seja contando a quantidade de vezes que eu aperto o botão, só que não dá certo, tipo aparece o zero que eu mandei aparecer no começo, ai depois eu aperto o botão aparece o 1 como teria que ser, mas depois disso não acontece mais nada, simplesmente eu aperto o botão, solto, aperto de novo e nada mais acontece.

Vou postar o código aqui para que me apontem onde pode estar meu Erro:

void main()
{
int array[9]={0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};
int i;
output_b(0x3f);
while(true)
{
if(input(botao))
{
delay_ms(30);
if(input(botao))
{
output_b(array[i]);
delay_ms(200);
i++;
if (i<9)
{
i=0;
}
}
}
}
}

Postado

Vou postar o código aqui para que me apontem onde pode estar meu Erro:

Creio que o problema seja o escopo das variáveis que declarou. No exemplo do mikroC, elas devem ser globais, e no CCS também ^_^

Tente declarar antes do main. Precisa negar com "!" a entrada: botao (se fez pullup nas entradas):


int array[9]={0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};
int i = 0;

void main()
{
output_b(0x3f);
while(true)
{
if([B]![/B]input(botao))
{
delay_ms(30);
if([B]![/B]input(botao))
{
output_b(array[i]);
delay_ms(200);
i++;
if (i [B]>= 10[/B])
{
i=0;
}
}
}
}
}

Isto aqui pode ser útil (cartão de referência do CCS).

Abraço.

Postado

no CCS é:

SET_TRIS_X(0b00000000);

Olhem no arquivo .h do pic de vocês que vai mostrar todas as funções básicas dele de I/O.

no 16F690 temos algumas como:

INPUT_X()

OUTPUT_X()

output_high()

output_low()

output_toggle()

input()

SET_TRIS_X()

GET_TRIS_X()

PORT_X_PULLUPS()

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

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!