PIC: Controlando PIC18F4550 via USB
Projeto de um sistema de comunicação via USB, entre o PIC18F4550 e o programa feito em C#.
Este programa monitoras 8 entradas digitais e 8 entradas analógicas e controla 8 saídas digitais e 2 saídas PWM.
O Firmware foi feito no MikroC PRO PIC. O código é simples, mas para realizar a comunicação USB, você deve configurar os seguintes bits de configuração: Selecione o menu Project > Edit Project
Este programa monitoras 8 entradas digitais e 8 entradas analógicas e controla 8 saídas digitais e 2 saídas PWM.
O Firmware foi feito no MikroC PRO PIC. O código é simples, mas para realizar a comunicação USB, você deve configurar os seguintes bits de configuração: Selecione o menu Project > Edit Project
PLL Prescaler Selection: Caso você queira utilizar um outro valor de cristal, altere este campo
No download, estou incluindo o firmware, e o software junto com o seu código-fonte.
DOWNLOAD:
Projeto: ControladorUSB.rar
#include "built_in.h" #define STX 0x0F unsigned char HidReadBuff[64] absolute 0x500; unsigned char HidWriteBuff[64] absolute 0x540; unsigned char Reserve4thBankForUSB[256] absolute 0x400; enum Comandos {None=0, Analog, DigitalIn, DigitalOut, PWM}; char cmd = None; void interrupt() { Usb_Interrupt_Proc(); } void CheckCommand() { if(cmd == None) { if(HidReadBuff[0] != STX) return; cmd = HIDReadBuff[1]; } } void EntradaAnalogica() { unsigned analogVal; HIDWriteBuff[1] = Analog; analogVal = ADC_get_sample(0); HIDWriteBuff[2] = Hi(analogVal); HIDWriteBuff[3] = Lo(analogVal); analogVal = ADC_get_sample(1); HIDWriteBuff[4] = Hi(analogVal); HIDWriteBuff[5] = Lo(analogVal); analogVal = ADC_get_sample(2); HIDWriteBuff[6] = Hi(analogVal); HIDWriteBuff[7] = Lo(analogVal); analogVal = ADC_get_sample(3); HIDWriteBuff[8] = Hi(analogVal); HIDWriteBuff[9] = Lo(analogVal); analogVal = ADC_get_sample(4); HIDWriteBuff[10] = Hi(analogVal); HIDWriteBuff[11] = Lo(analogVal); analogVal = ADC_get_sample(5); HIDWriteBuff[12] = Hi(analogVal); HIDWriteBuff[13] = Lo(analogVal); analogVal = ADC_get_sample(6); HIDWriteBuff[14] = Hi(analogVal); HIDWriteBuff[15] = Lo(analogVal); analogVal = ADC_get_sample(7); HIDWriteBuff[16] = Hi(analogVal); HIDWriteBuff[17] = Lo(analogVal); while(!HID_Write(&HIDWriteBuff, 64)); } void EntradaDigital() { HidWriteBuff[1] = DigitalIn; HidWriteBuff[2] = PORTD; while(!Hid_Write(&HidWriteBuff, 64)); } void SaidaDigital() { HidWriteBuff[1] = DigitalOut; HidWriteBuff[2] = PORTB; while(!Hid_write(&HidWriteBuff, 64)); } void USB_Recv() { char dataRx = 0; while(1) { HidWriteBuff[0] = STX; EntradaAnalogica(); EntradaDigital(); SaidaDigital(); dataRx = HID_Read(); if(dataRx) { dataRx = 0; CheckCommand(); if(cmd == DigitalOut) //Saídas Digitais { PORTB = PORTB ^ (1 << HidReadBuff[2]); cmd = None; } else if(cmd == PWM) { PWM1_Set_Duty(HidReadBuff[2]); PWM2_Set_Duty(HidReadBuff[3]); cmd = None; } } delay_ms(100); } } void main() { TRISD = 255; TRISB = 0; TRISA = 255; TRISC = 0; PORTB = 0xAA; ADC_Init(); PWM1_Init(4000); PWM2_Init(3000); PWM1_Set_Duty(127); PWM2_Set_Duty(127); PWM1_Start(); PWM2_Start(); HID_Enable(&HidReadBuff, &HidWriteBuff); Usb_Recv(); }
Parabens pelo seu trabalho ,Preciso de uma ajuda na montagem de um projeto ,Me manda um email helbertparanhos_50@hotmail.com sobre um medidor de tensão
ResponderExcluirParabéns pelo Blog, ele é muito bom e bem didático!!
ResponderExcluirPor favor gostaria de sua ajuda!
O meu projeto é bem parecido com este, a diferença é que digito uma tecla pelo teclado e o PIC trata esta função executando algo.No proteus está funcionando perfeitamente.
O meu problema é que quando gravo no PIC e conecto no PC o PC não reconhece a USB do PIC, não carrega nada. Sabe me disser o que está faltando ou o que é?
Boa noite... realmente parabens msm pelo blog!!!
ExcluirPor gentileza gostaria de uma informação, quando simulo no proteus roda perfeitamente, mas quando gravo no pic ele tbm nao reconhece o dispositivo usb, é como se faltasse um driver de instalação... desde ja obrigado
Provavelmente deve ter algo errado com o circuito, talvez o capacitor de regulação de tensão da usb, ou alguma configuração de clock do pic, ou até mesmo problemas com o cristal. Teste algum outro projeto antes, que não envolva a usb, pra verificar que o hardware funciona.
ExcluirOla, estou com um problemam, quando eu simulo no proteus seu .hex ele funciona, o windows reconhce, quando recompilo os arquivos que estao na pasta do firmware, ele não funciona mais, pode me dizer por que isso ocorre? eu recompilo sem modificar nada, porem mesmo assim o windows sequer reconhece que o dipositivo esta conectado, quando retorno ao .hex que vem no .rar ele reconhece.
ResponderExcluirNao sei o q pode estar acontecendo!
ExcluirTem como ver se o .hex da pasta é exatamente igual ao .hex depois de recompilado?
Como faço para ver isso? Estou construindo um inversor de tensao, e gostaria que o computador enviasse alguns valores para o pic, e o pic enviasse algumas variaveis para o pc, voce pode me ajudar com esse projeto? Eu tenho o codigo pra ele funciona com botoes, entao eu gostaria que ele funcionasse a partir do botoes, mas se estivesse conectado ao pc ele apenas recebece do pc.
ExcluirO problema é o caminho do projeto que foi criado originalmente no computador de quem postou, você deve alterar o path do projeto para sua pasta atual ou vc. copia o código e cria um novo projeto e salva em qualquer pasta, depois basta colar o código e compilar que irá funcionar.
ExcluirSegui passo a passo funcionou certinho. Parabéns
ExcluirO cara ignora o que eu disse ae em cima, o problema estava no crack que eu havia usado para o mikroC, agora compila certinho. Sera que tem como voce me dizer como funciona o envio e recebimento de dados via usb?
ResponderExcluirpor exemplo:
HidWriteBuff[1] = DigitalOut;
HidWriteBuff[2] = PORTB;
while(!Hid_write(&HidWriteBuff, 64));
esse buff[1] é o que identifica o dado? e o [2] é oque?
o byte 1 informa ao PC que "tipo" de dado será enviado.
Excluiro byte 2 é o valor do dado a ser enviado.
No caso do exemplo citado por você, o byte 1 informa que o dado representa uma saida digital da PORTB, e o byte 2 é o valor da saída da PORTB.
Cara, entendi essa parte, agora estou com outro problema, eu tenho meu codigo escrito no compilador ccs, e eu nao consegui de jeito nenhum fazer a comunicação usb por la, agora eu tenho dois codigos em dois compiladores diferentes, e eu nao sei migrar o codigo do ccs pro mikroC, principalmente por causa das interrupções que no mikroC é diferente. É muito dificil fazer essa adaptaçao entre os compiladores? Voce poderia me ajudar com isso?
ResponderExcluirhttp://pastebin.com/0c1DP2ya
http://pastebin.com/BWSxvjLm
Ou entao, voce poderia me dizer como eu uso as interrupções da porta B, timer0 e timer2?
Excluirestou tentando implementar aqui, inclusive vi o tutorial no seu site, mas parece que a interrupção não esta sendo acionada =[
http://pastebin.com/5RmRp9Ey <= void main
http://pastebin.com/y07SpU7M <= void interrupt ()
//Achei este erro!!! Tambem é o mesmo erro do TIMER2!!!
Excluirvoid TIMER0_isr(void)
{
//Tem q ser colocado aqui
INTCON.TMR0IF=0; //SEMPRE q houver a interrupção, vc deve limpar a flag, caso
// contrario nao ocorrera a proxima interrupção
cont3++;
if(cont3==5);//SET_ADC_CHANNEL(0);
if(cont3==10)
{
valor = ADC_Read(7);
comando=1;
cont3=0;
// INTCON.TMR0IF=0; //Nao pode ser colocado aqui
}
}
1- Hmm, interessante, segui oque voce disse, e para fazer um teste, habilitei a interrupçao dos pinos B, e escrevi o seguinte cógigo
ResponderExcluir{
if (INTCON.RBIF == 1){
INTCON.RBIF = 0;
if (MODULO == 'B'){
PORTa=255;
MODULO = 'A';
}
else {
PORTa = 0;
MODULO = 'B';
}
}
o problema é que quando eu aperto o botão, ele fica "piscando" as portas A.
2- qual é o comando pra mim setar uma saida do microcontrolador como alta, no ccs eu uso outpu_high(pin_a1), mas no mikroc eu uso oq?
cara, vlw mesmo, voce ta me ajudando pra caramba =D
Pra não ficar postando muita duvida nos comentario desse post, é possivel eu me comunicar com vc de outra forma? talvez email?
ExcluirEmail: microcontrolandos2012@gmail.com
ExcluirOlá, conseguimos funcionar as entradas e saídas digitais e a saída PWM. Porém as entradas analógicas não funcionaram. Vocês têm alguma ideia do que pode ser? Consultei o datasheet do 18F4550 e não encontrei nenhum registrador que possa estar incorretamente configurado. Obrigado
ResponderExcluirPelos nossos testes, o PIC está adquirindo o valor do conversor A/D dentro da rotina EntradaAnalogica() . Porém o programa em C# não atualiza os ProgressBar que apresentam os valores do AD.
ExcluirNão tem como simular o funcionamento do programa com o Proteus no Windows 8 de 64bits?
ResponderExcluirBoa tarde, no meu projeto eu preciso apenas enviar uma string simples para o pic, como eu poderia modificar o programa para fazer isso?
ResponderExcluirObrigado.
Não tem como simular o funcionamento do programa com o Proteus no Windows 8 de 64bits?
ResponderExcluirThiago... acho que deve ter algum problema na configuração dos Fuses Bits, pois o computador reconhece a HID mas não comunica.. diz que aconteceu algum erro e que a comunicação não foi possível ser feita. Eu sempre tenho esse problema quando o MCU não entra em 48MHZ no barramento. Qual o Oscilador você usa neste código?
ResponderExcluirEu alterei seu programa para trabalhar com o Oscilador de 8MHZ e o programa funcionou perfeitamente.
Outro ponto é no cruzamento de Thready... Sempre que dou play, ele me dá erro de cruzamento de Thready já no método de Analógico... Precisa fazer um tratamento de INVOKE nele eu acredito.
Júnior,
ResponderExcluirO que você deve fazer é simplesmente adicionar o código abaixo no evento load do seu form.
#Código
CheckForIllegalCrossThreadCalls = false;
Fiz aqui e funcionou.
Abs!
urgente alguem me ajuda , mesmo q amigo ali em cima eu compilo mesmo projeto e não funciona com hex compilado .. meu mikroc é versão mikroc for pic 5.61. alguem ai sabe versão q funciona?
ResponderExcluirOi
ResponderExcluirQuando eu envio o dado do firmware para o software funciona mas quando envio o dado do software para o firmware nao funciona ou seja o firmware não recebe nada tem ideia do que pode ser.
ResponderExcluirOlá Tiago, tudo bem? Primeiramente obrigado por compartilhar o seu conhecimento!
ResponderExcluirEu abri o source no mikroC, porém ele gera um .hex diferente do que já vem compilado. Eu não alterei nenhuma configuração na IDE, simplesmente abri e mandei compilar. Como sou iniciante com microcontroladores, não estou conseguindo entender o porquê disso. O .hex já gerado rodou direitinho no Proteus, reconheceu o dispositivo e tudo mais! Porém com o que eu gerei por aqui, logicamente deu erro.
Você saberia por que isso está ocorrendo? Será que é alguma configuração específica de compilação? Segue abaixo o link de ambos os arquivos .hex:
https://drive.google.com/file/d/0B7031uB8x8LmTmJNcGxraDN5cW8/view?usp=sharing
https://drive.google.com/file/d/0B7031uB8x8LmY1hoQUk1VGU5NUE/view?usp=sharing
Obrigado e abraços!
Olá, tudo bem!
ExcluirTambém não entendo...fiz o mesmo, baixei o arquivo, abri e mandei compilar e o .hex gerado ta normal...olhando o arquivo que vc gerou, a diferença do tamanho é gigantesca...veja se ha alguma mensagem de erro na hora de compilar, tipo "demo limit".
Abraços.
Não sei se ainda é útil, porém esse erro me aconteceu constantemente e eu demorei a achá-lo, tomem cuidado com os cracks do MikroC, muitos não funcionam, fazem com que seu programa seja compilado de forma errada. Peguem o PicKit e abram o .hex que vocês verão como as posições de mémoria estão vazias...
ExcluirBoa Noite, Estou gostando muito do seu Blog, esta sendo muito Útil para mim, e gostaria de saber se teria como utilizar o PI16F877 neste projeto e o que deveria ser mudado?
ResponderExcluirOlá, não tem como, pois o PIC16F877A não possui USB. O que você poderia fazer é utilizar um PIC com usb ou utilizar a porta serial. Caso utilize a porta serial voce pode conectar através da porta USB utilizando um conversor FTDI.
ExcluirParabéns pelo projeto. Ficou bem simples e fácil de entender. Você poderia me dizer qual biblioteca é essa UsbLibrary.dll que você usou no programa em C#? Estou tentando encontrar alguma documentação sobre ela na internet, mas não consegui. Existe alguma biblioteca nativa no Visual Studio que faça a comunicação USB HID, assim como existe para comunicação serial?
ResponderExcluirQual é o codigo que grava no pic?
ResponderExcluirOlá Qual a versão do Visual studios vc usou?
ResponderExcluirTentei abri-lo no Visual Basic 2010 mas não deu!
Parabens pelo trabalho. Gostei muito do blog
ResponderExcluirCara tem como postar um vídeo explicando o passo a passo ?
ResponderExcluirOlá. Sou iniciante em microcontroladores, se puderem me tirar uma dúvida..no "PLL Prescaller Selection" vc selecionou "No Prescaller".. Neste caso, o cristal que deve se usar nesse projeto é o de 4MHz?
ResponderExcluir