Ir ao conteúdo

Posts recomendados

Postado

Olá galera, criei este topico com o intuito de me ajudar e ajudar outras pessoas com o mesmo problema. Estou inciando em PICs e sei q tem muita gente que também está. E não vou fica criando um monte de topico pedindo ajuda.

Eu ainda não sei nada, só fiz um programa até hoje, foi um pisca led, gostaria muito de aprender varios outros programas como, por exemplo, fazer um led acender com uma tensão e conforme essa tensão muda outro led acende, mas não faço a minima ideia de como fazer isso e muitos outros programas, que por sinal já procurei muuuuuito na net mas infelizmente e não achei coisa alguma.

Então ai vai o meu pedido... Galera que é profissa em PIC ou em em outros microprocessadores postem ai programas (Linguagem C ou Assembly), pode ser qualquer programa desde um pisca led até programas super complicado q envolvam LCDs e tudo mais, pra nós que estamos começando termos uma ideia de como é.

E quem tiver alguma duvida posta também, porque pode ser q sua duvida esclareça a minha.

Vou dar minha contribuição, este foi o meu primeiro circuito:

#include <16F877A.h>
#use delay(clock=4000000)
#fuses NOPUT,NOPROTECT,NOBROWNOUT,XT

#define LED PIN_B1

main(){

int tempo=100;
while (true){
output_high(LED);
delay_ms(tempo);
output_low(LED);
delay_ms(tempo);
}
}

agradeço a todos que ajudarem.

abs.

Postado

Vou postar aqui um projetinho bem legal, uma especie de disjuntor eletrônico com transformador de corrente, aqui o codigo fonte:

;Firmware de controle da placa sensor de corrente
;detecta sobrecarga e desativa o rele em caso positivo.
;autor: Felipe Neves


#INCLUDE <P12F675.INC>
RADIX DEC
__CONFIG _BODEN_ON & _CP_OFF & _WDT_OFF & _MCLRE_ON & _PWRTE_ON & _INTRC_OSC_NOCLKOUT
;==========================================================================
;VARIAVEIS

CBLOCK 0X20
C1
C2
ADCONV
W_TEMP
STAT_TEMP
FLAG
ENDC
;==========================================================================
;DEFINIÇOES DE I/O

#DEFINE CAD GPIO,0
#DEFINE NORM GPIO,4
#DEFINE OVER GPIO,5
#DEFINE RELE GPIO,2
;==========================================================================
;DEFINIÇOES DE REGISTRADORES
#DEFINE FLAGOK FLAG,0
;==========================================================================

ORG 0X00
GOTO START

ORG 0X04
BTFSC PIR1,ADIF
GOTO AD_ISR
GOTO END_ISR

AD_ISR:
MOVWF W_TEMP
SWAPF W_TEMP,F ;SALVA CONTEXTO
MOVF STATUS,W
MOVWF STAT_TEMP
SWAPF STAT_TEMP,F
BCF PIR1,ADIF
BCF STATUS,C ;limpa o carry

MOVF ADRESH,W ;pega o resultado da conversao AD
SUBLW .98 ;compara valor, é maior que 5A?
BTFSC STATUS,C
GOTO END_ISR ;nao, rede normal sai da int
BCF RELE ;sim, sobrecarga!
BSF OVER ;acende led de sobrecarga
BCF NORM ;e desliga tudo!
GOTO $ ;so retorna manualmente

END_ISR:
SWAPF STAT_TEMP,W ;recupera contextos
MOVWF STATUS
SWAPF W_TEMP,W
BSF ADCON0,GO ;faz uma nova conversao
BSF FLAGOK
RETFIE ;retorna
;=========================================================================
START:
NOP
BANKSEL GPIO
CLRF GPIO
BANKSEL CMCON
MOVLW 07H
MOVWF CMCON
BANKSEL ANSEL
MOVLW 021H
MOVWF ANSEL
BANKSEL TRISIO
MOVLW 01H
MOVWF TRISIO
BANKSEL ADCON0
CLRF ADCON0
BSF ADCON0,ADON
BANKSEL OPTION_REG
CLRF OPTION_REG
BANKSEL INTCON
MOVLW 040H
MOVWF INTCON
BANKSEL PIE1
BSF PIE1,ADIE
BANKSEL INTCON
BSF INTCON,GIE
BCF STATUS,RP0

LOOP:
BSF ADCON0,GO ;Inicia a conversao ao ligar o equipamento
BSF OVER ;liga led de sobrecarga ate o termino da conversao
BCF RELE ;e mantem Rele desativado
BTFSS FLAGOK ;rede ok?
GOTO $-1 ;converte de novo
BSF RELE ;sim, então liga rele
BCF OVER
BSF NORM ;liga led de rede normal
GOTO $ ;AGUARDA A INTERRUPÇAO

END
;=========================================================================================================================================================================


esquema abaixo

abs.

post-416586-13884952608719_thumb.jpg

Postado

eai felipe, cara deixa eu ver se entendi... esse esquema detecta sobre carga.

mas como assim em caso positivo desativa rele?

Galéra, alguem posta mais algum esquema ai.

valeu.

abs.

Postado

funciona assim, ao ligar o circuito ele fecha o contato, alimentando sua rede e o circuito, e fica constante mente monitorando a corrente consumida, em caso de sobrecarga , ele desativa o circuito, e so pode ser religado interrompendo sua alimentação e religando o circuito!

a vantagen, é que ele pode detectar e interromper curtos muito mais rápido que um disjuntor comum!

é muito utili em bancadas, na verdade fiz ele, pra poder fazer experiencias que envolvam a rede eletrica com mais segurança!

EDIT: esse circuito foi montado e testado em todas as condiçoes, incluindo quando as duas fases são postas em curto, e apresentou o funcionamento esperado!

abs.

Postado

Vou postar um simples de fácil entendimento, detector três niveis de agua com PIC12f629 (8 pinos). para uso em picinas,na pia para indicar transbordamento,pode até em vez de led colocar relês, para desligar automaticamente bombas de agua(por exemplo você põe uma piscina pra enche para seus filhos,com uma bomba de agua que liga no 110,quando enche até um certo nivel elá automaticamente para de enche) com muito pequenas modificações.

PIN_A0 //led 1

PIN_A1 // led2

PIN_A2 // led 3

PIN_A3 // detector 1

PIN_A4 // detector 2

PIN_A5 // detector 3


#include <12F629.h>

#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOMCLR //Master Clear pin used for I/O

#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_A3,rcv=PIN_A2,bits=8)

void main()
{
while(1){
if(input(pin_a3)==1) // parte nivel 1
{
output_high(pin_a0);
}
else{
output_low(pin_a0);
}


if(input(pin_a4)==1)// parte nivel 2
{
output_high(pin_a1);
}
else{
output_low(pin_a1);
}

if(input(pin_a5)==1)// parte nivel 3
{
output_high(pin_a2);
}
else{
output_low(pin_a2);
}
}

}

falou, fação um circuitinho de proteção ao pic para não danifica-lo.

PS:> gostei da iniciativa do topico.

desculpe por postar respostas erradas nos topicos.

Postado

Mais uma contribuição, espero que ajude :D

código exemplo de uso da interface SPI do PIC, muito util para interfacear com varios circuitos integrados suportados pelo protocolo, no exemplo abaixo temos um conversor D/A de 12bits, onde o AD do PIC converte um sinal pra digital e o MCP4921 faz o contrario transformando ele em analógico de novo, a linearidade foi testada e ficou muito boa

aqui o codigo:




;etapa teste de conversor D/A
;Autor: Felipe Neves
;Captura uma amplitude do A/D e poe na saida


LIST P = PIC16F877A
#INCLUDE "P16F877A.INC"
RADIX DEC

__CONFIG _CP_OFF & _CPD_OFF & _DEBUG_ON & _LVP_OFF & _WRT_OFF & _BODEN_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC


;VARIAVEIS

CBLOCK 0X20
C1
C2
C3
C4 ;CONTADORES DE DELAY
ADRESUL ;ARMAZENA CONVERSÃO A/D
BUFFER ;BUFFER DA SPI
ENDC
;CONSTANTES:

SPISETUP1 EQU 20H
SPISTATUS EQU B'11000000'
ADSET0 EQU 80H
ADSET1 EQU B'00001110'
BYTECTR EQU B'00110000' ; BYTE DE COMANDO DO MCP4921


;DEFINIÇÃO DE I/O
#DEFINE BANK1 BSF STATUS,RP0
#DEFINE CAD PORTA,0
#DEFINE SCK PORTC,3
#DEFINE SDO PORTC,5
#DEFINE CS PORTD,3
#DEFINE LDAC PORTD,1


ORG 0X0000
NOP
GOTO SETUP



SETUP: BCF STATUS,RP0
CLRF SSPBUF
CLRF PORTA ; GARANTE TODAS AS SAÍDAS EM ZERO
CLRF PORTB
CLRF PORTC
CLRF PORTD
CLRF PORTE
BANK1 ; SELECIONA BANCO 1 DA RAM
MOVLW 0FFH
MOVWF TRISA ; CONFIGURA I/O DO PORTA
MOVLW 0FFH
MOVWF TRISB ; CONFIGURA I/O DO PORTB
MOVLW 10H
MOVWF TRISC ; CONFIGURA I/O DO PORTC
MOVLW 00H
MOVWF TRISD ; CONFIGURA I/O DO PORTD
MOVLW 00H
MOVWF TRISE ; CONFIGURA I/O DO PORTE
MOVLW B'11011111'
MOVWF OPTION_REG ; CONFIGURA OPTIONS
; PULL-UPs DESABILITADOS
; INTER. NA BORDA DE SUBIDA DO RB0
; TIMER0 INCREM. PELO CICLO DE MÁQUINA
; WDT - 1:128
; TIMER - 1:1
MOVLW 00H
MOVWF INTCON ; CONFIGURA INTERRUPÇÕES
; DESABILITADA TODAS AS INTERRUPÇÕES
BANKSEL ADCON1
MOVLW ADSET1
MOVWF ADCON1 ;HABILITA IO ANALOGICO EM RA0
BANKSEL SSPCON
MOVLW SPISETUP1
MOVWF SSPCON ;MODO SPI, COM CLOCK FOSC/4 HABILITADO COM CLOCK padrão EM NIVEL '1'
BANKSEL SSPSTAT
MOVLW SPISTATUS
MOVWF SSPSTAT
BANKSEL ADCON0
MOVLW ADSET0
MOVWF ADCON0 ;HABILITA CONVERSOR A/D COM CLOCK FOSC/32 + LEITUTA AN0
BCF STATUS,RP0
CLRF ADRESUL
CLRF BUFFER
GOTO LOOP

LOOP:
BSF CS ;INITIATES WITH MCP LOCKED
BSF LDAC ;D/A CONVERSION LOCKED TOO
BSF ADCON0,ADON ; TURN ON A/D CONVERTER
LOOP2:
BSF ADCON0,GO ;STARTS THE CONVERSION
BTFSC ADCON0,GO ;A/D VALUE CONVERTED?
GOTO $ - 1 ;NO? WAIT THE END OF CONVERSION
MOVF ADRESH,W
; MOVWF PORTD
MOVWF ADRESUL ;YEP, NOW PUT THE VALUE ON MY REGISTER
CALL SPIWRITE

GOTO LOOP2 ;ALWAYS REDO THIS LOOP

SPIWRITE:
BCF CS ;UNLOCK MCP
NOP ;load and mask CONTROL BYTE ON SSPBUF
SWAPF ADRESUL,W
ANDLW B'00001111'
IORLW BYTECTR
MOVWF SSPBUF
BANKSEL PIR1
BTFSS PIR1,SSPIF ;TRANSMISSION ENDED?
GOTO $ - 1 ;NO, WAIT
BCF PIR1,SSPIF
BANKSEL SSPBUF
MOVF ADRESUL,W
ANDLW B'11110000' ;LOAD A/D CONVERSION TO SSPBUF
MOVWF SSPBUF
BANKSEL PIR1
BTFSS PIR1,SSPIF
GOTO $ - 1
BCF PIR1,SSPIF
BCF STATUS,RP0 ;RETURNS TO BANK0
BCF LDAC ;CONVERT THE SIGNAL TO ANALOG AGAIN
BSF CS ;LOCK MCP
BSF LDAC
RETURN

END

datasheet do conversor D/A:

http://www.alldatasheet.com/view.jsp?Searchword=MCP4921

EDIT: alguns comentarios eu acabei pondo em inglês, pois nem imaginava que iria postar esse codigo, duvidas perguntem!

abs.

Postado

Ai galera, achei um tutorial sobre programação de PICs em linguagem C, me pareceu muito bom, ja aprendi muitas coisas com ele.

olha o link:

http://usuarios.upf.br/~fpassold/PIC/C_PIC.PDF

Felipe você usa assembly não é?

Valeu.

Abs.

ah... ia me esquecendo.

Como eu faço pra quando houver uma variação na tensão ele indicar, por exemplo, quando esta menor q 5V ele acende um led, quando esta com 5V outro.

Postado

Felipe você usa assembly não é?

Opto por ser um programador 'hibrido' :D, por isso uso as duas, o que varia de acordo com o projeto, para interfaces graficas com certeza C, mas para aplicações que envolvem velocidade de processamento e controle total do MCU uso assembly, como a maioria dos projetos que desenvolvo são com processamento de sinais, uso mais a segunda opção, o ASM.

Quanto ao teu detector de nivel, voce viu o codigo do amigo angelox? se voce usar a criatividade e modifica lo poderá ter isso que queres!

Qualquer duvidas perguntem, logo logo postarei novos codigos!

abs.

Postado

ae galera ninguem sabe um programa desse tipo, não precisa ser o programa enteiro, só uma explicação que me ensine, o programa eu elaboro qui.

Ah... postem mais programas ai galera.

Agradeço a todos que ajudaram ou que vão ajuda.

Abs.

Postado

Vou te mostrar o caminho para isso, o melhor metodo é o que faz o uso do comparador interno do PIC:

supondo que voce esteja usando o 628A, ficaria assim:

no pino não inversor voce liga seu potenciometro pra variar a tensão, na não inversora voce liga uma rede resistiva de modo que a tensão entre o segundo resistor e o terra seja de 5V ( se a alimentação do circuito for 5V então ligue esse pino direto na alimentação)

no mesmo PIC ligue uma saida num LED e a outra em outro LED.

e como ja disse o codigo do amigo angelox serve e muito bem, basta voce modificar ele!

abs.

Postado

"ae galera ninguem sabe um programa desse tipo, não precisa ser o programa enteiro, só uma explicação que me ensine, o programa eu elaboro qui".

Felipe desculpe por essa mensagem é que quando respondi ainda não tinha aparecido a sua mensagem (acredito q deve ter sido um erro no CDH)

Olha o meu programa, acredito que errei na definição da tensão que deve entrar no PIC e o pino que defini o Vcc porque ainda não sei muito sobre isso de pino de entrada e saida (tenho que ler mais os datasheets). :D

#include <16F628A.h>
#use delay(clock=4000000)
#fuses NOPUT,NOPROTECT,NOBROWNOUT,XT

//Entrada
#define VCC PIN_A0

//Saida
#define LED1 PIN_A1
#define LED2 PIN_A2

void main (){

while (1){
if (input(VCC==5)){ //tensão igual 5V, executa a seguinte função
output_high(LED1);
}
else {
output_low(LED1);
}

if (input(VCC<5)){ //tensão menor que 5V, executa a seguinte
output_high(LED2);
}
else {
output_low(LED2);
}
}
}

por favor corrigam o que estiver errado e não me "esculachem" pelos meus erros pois ainda sou iniciante.^_^

Valeu!!

Abs a todos.

  • Curtir 1
Postado

Poxa realmente tem coisa errada....

vamos la, primeiro começemos pelos fuses:

#fuses NOPUT,NOPROTECT,NOBROWNOUT,XT

Se voce esta usando um 628A com o oscilador interno de 4MHz então deve colocar INTRC_IO, caso contrario não roda...

if (input(VCC==5)){ //tensão igual 5V, executa a seguinte função

ta errado, primeiro o 628A não possui conversor A/D ele so le niveis logicos, tipo '0' e '1' se voce colocar 5 ele simplesmente ira ignorar a instrução....

de uma lida no datasheet do PIC e veja o modulo comparador de tensão, e veja como ele pode ser configurado no CCS, abra o arquivo 16f628A.h para ver as opções de comparador!

abs.

Postado

Obrigado mais uma vez felipe vou dar uma olhada no datasheet e nos arquivos dos PIC pra achar algum que tenha conversor A/D mas quanto a intentificação da voltagemesta certa não é ? Se eu fizer esse programa em um PIC que tenha conversor, quando estiver com 5V a função desejada sera executada? E quando estivesse menor que 5V eletambém executaria?

Obrigado.

Abs.

Postado

a resposta : Não

agora vamos ao porque, o conversor analogico / digital do PIC é de 8bits (modelos mais novos trabalham com 10 bits) ou seja, quando voce mandar ele ler a tensão ele vai te re tornar um valor de 0 a 255 ( 0 a 1023 para 10 bits) de acordo com a tensão lida, depois disso voce deve pegar esse valor e fazer uma regra de 3 para converter par um rage de 0 a 5 volts e depois fazer os if / else com os 5 volts. Caso contrario não vai rodar, um dos leds vai ficar sempre aceso e o outro nunca vai ligar!

abs.

Postado

putz cara, vou dar mais uma estudada antes de começar esse programa.

Valeu as dicas.

Acho que estou começando a entender. Achei um PIC que tem comversor A/D e se não me engano o oscilador e externo.

Tentei fazer um codigo mas não deu certo:

#include <16F676.h>
#use delay(clock=4000000)
#fuses NOPUT,NOPROTECT,NOBROWNOUT,XT

//Entrada
#define VCC PIN_A0

//Saida
#define LED1 PIN_C1
#define LED2 PIN_C2

void main (){

while (1){
if (input(VCC==0b1111111111)){
output_high(LED1);
}
else {
output_low(LED1);
}

if (input(VCC<0b11111111111)){
output_high(LED2);
}
else {
output_low(LED2);
}
}
}

não acendeu nada, eu não ponhei INTRC_IO, porque não tem oscilador interno (me corrigam se estiver errado).

Quanto ao codigo binario é ali mesmo que se ponha? O codigo binario pelo menos esta certo?

Pesquisei sobre conversor A/D e foi mais ou menos isso que entendi.

Obrigado.

Até mais

  • Curtir 1
Postado

Pera, pera, pera...

você nem configorou o A/D, como espera que ele leia algo?

primeiro configure o A/D com as funçoes, SETUP_ADC, SETUP_ADC_PORTS, SETUP_ADC_CHANNEL...

depois voce usa o comando read_adc(), para ler o conteudo analógico do porta, ai DEPOIS voce faz o if com o valor da leiutura, exemplo

if (read_adc() = 0b11111111)...

entendeu?

demais uma pesquisada!

abs.

Postado

entendi vou dar mais uma pesquisada .

Obrigado Felipe

Olá, olha defini o que você falou conforme no tutorial que li mas infelizmente não deu certo.


SETUP_ADC_PORTS_A(ALL_ANALOG)
SETUP_ADC(ADC_CLOCK_INTERNAL)
SETUP_ADC_CHANNEL (1)

O codigo esta errado ou pelo menos dessa vez eu acertei?

Eu ponhei esse codigo como #definição. É em definição mesmo que ponha, ou em outro lugar.

Obrigado.

Postado
O codigo esta errado ou pelo menos dessa vez eu acertei?

Eu ponhei esse codigo como #definição. É em definição mesmo que ponha, ou em outro lugar.

Obrigado.

Não pois define serve para nome de portas,comandos,esses setups são comandos,então coloque-os abaixo do Void main() {

entendeu?.....

EX:

void main()
{
SETUP_ADC_PORTS_A(ALL_ANALOG);
SETUP_ADC(ADC_CLOCK_INTERNAL);
SETUP_ADC_CHANNEL (1);
// Resto do seu programa....
}

Corrigam-me se estiver errado.

PS: Vou ler um livro de pic que tenho aqui para conferir os Comandos do AD..

Falows

Postado

Resposta:

Comando SETUP_ADC_PORTS_A(ALL_ANALOG); == Correto

SETUP_ADC(ADC_CLOCK_INTERNAL); == Correto

SETUP_ADC_CHANNEL (1); == Correto.

Resumindo, Todos os comandos postados conferem com os comandos do CCS, ou seja talvez funcione se colocar no lugar certo

Vou dar um exemplo que está no meu livro:


long int valor; // define variavel tipo long int para armazernar valor do A/D
set_adc_channel (1); // Seleciona canal para entrada do A/D
delay_us(10); // Delay minimo nessecario para garantir que o capacitor interno de amostragem possa ser carregado
valor = read_adc(); // efetua conversão A/D

Postado

Pelo amor de Deus, alguem me da uma luz, melhor me da um oloforte, to quebrando a cabeça e não to conseguindo fazer essa @#$@#@$ desse programa. :angry:


#include <16F676.h>
#use delay(clock=4000000)
#fuses INTRC_IO,NOPUT,NOPROTECT,NOBROWNOUT,XT

void main (){

SETUP_PORT_A(ALL_ANALOG);
SETUP_ADC(ADC_CLOCK_INTERNAL);
SET_ADC_CHANNEL(1);

while (1){
if (input(read_adc()==0b1111111111)){
output_high(PIN_C1);
}
else {
output_low(PIN_C1);
}

if (input(read_adc()<0b11111111111)){
output_high(PIN_C2);
}
else {
output_low(PIN_C2);
}
}
}

Por favor me ajudem, o que fiz de erraaaadddoooo?

Abs.

Visitante
Este tópico está impedido de receber 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...