• Comunicados

    • Gabriel Torres

      Seja um moderador do Clube do Hardware!   12-02-2016

      Prezados membros do Clube do Hardware, Está aberto o processo de seleção de novos moderadores para diversos setores ou áreas do Clube do Hardware. Os requisitos são:   Pelo menos 500 posts e um ano de cadastro; Boa frequência de participação; Ser respeitoso, cordial e educado com os demais membros; Ter bom nível de português; Ter razoável conhecimento da área em que pretende atuar; Saber trabalhar em equipe (com os moderadores, coordenadores e administradores).   Os interessados deverão enviar uma mensagem privada para o usuário @Equipe Clube do Hardware com o título "Candidato a moderador". A mensagem deverá conter respostas às perguntas abaixo:   Qual o seu nome completo? Qual sua data de nascimento? Qual sua formação/profissão? Já atuou como moderador em algo outro fórum, se sim, qual? De forma sucinta, explique o porquê de querer ser moderador do fórum e conte-nos um pouco sobre você.   OBS: Não se trata de função remunerada. Todos que fazem parte do staff são voluntários.
    • DiF

      Poste seus códigos corretamente!   21-05-2016

      Prezados membros do Fórum do Clube do Hardware, O Fórum oferece um recurso chamado CODE, onde o ícone no painel do editor é  <>     O uso deste recurso é  imprescindível para uma melhor leitura, manter a organização, diferenciar de texto comum e principalmente evitar que os compiladores e IDEs acusem erro ao colar um código copiado daqui. Portanto convido-lhes para ler as instruções de como usar este recurso CODE neste tópico:  
Philippe Henrique

Multiplexação ou Transistor?

12 posts neste tópico

bom... estou realizando uma programação com pic16f628a em assembly. segue abaixo o circuito elétrico no proteus funcionando perfeitamente.

Screenshot_1.png.3d9237e0402feea3e79574c68746e43d.png

 

como podem ver tenho um botão que irá incrementar o display multiplexado, e o outro botão de decremento. o botão iniciar começa a contagem deste display, sendo que o tempo definido no display deixará o pino da luz aceso por este tempo especificado. o pino na luz desligará no resto do tempo do display.

 

incremento máximo do display = 59

exemplo:

tempo definido no display pelo usuário: 30

luz ficará ligado: 30 segundos

luz ficará desligada por 59 - 30 = 29 segundos

 

meu problema:

estou tendo um problema na prática. a multiplexação não está ocorrendo. na prática utilizei o transistor bc547, não sei se tem algum problema, mas era o que eu tinha.

o transistor só fica saturado, e não entra em corte como era pra acontecer. alguém sabe o que está acontecendo?

 

código:

 

;===================================================================*
;=== pic16f628a = clock 4 mhz
;=== 1 ciclo de máquina = 1us
;=== projeto jardineiro eletrônico 2.0
;=== autor: philippe henrique / samuel zoia / italo esqueci / thiago esqueci
;===================================================================*
;===|arquivos incluídos|=======*

	#include	

;===================================================================*
;===|fuse bits|================*

	__config	_intosc_osc_noclkout & _mclre_on & _pwrte_on & _wdt_off & _boren_off & _cp_off & _lvp_off

;===|oscilador interno sem saída clock out
;===|master clear on
;===|power up timer on
;===|wtd off

;===================================================================*
;===|entradas|=================*
	#define		bt_inc		portb,rb0
	#define		bt_dec		portb,rb1
	#define		bt_start	portb,rb2

;===================================================================*
;===|saidas|===================*
	#define		one		porta,ra1
	#define		two		porta,ra0
	#define		three	porta,ra7
	#define		four	porta,ra6

	#define		uni		portb,rb7
	#define 	dez		portb,rb6
	#define		luz		portb,rb5


;===================================================================*
;===|paginação de memória|=====*
	#define		bank0	bcf		status,rp0		;bank0 = bcf status,rp0
	#define		bank1	bsf		status,rp0		;bank1 = bsf status,rp0

;===================================================================*
;===|variáveis|================*
	cblock		h'20'
	unidade
	dezena
	flags					; bit0 = altera tmr0
	valor_unidade			; para gaurdar o valor de [unidade]
	valor_dezena			; para guardar o valor de [dezena]
	resto_unidade
	resto_dezena
	w_temp
	status_temp
	d1
	d2
	aux_tmr0
	aux_tmr1
	repetir
	endc

;===================================================================*
;===|valores fixos|================*
	tmr0_start		equ		.0			; constante [tmr0_start] = .100
	tmr0_valor		equ		.5
	tmr1_valor		equ		.2				; constante [tmr1_valor] = .2
	tmr1_start_l	equ		h'dc'			; constante [tmr1_start_l] = h'dc'
	tmr1_start_h	equ		h'0b'			; constante [tmr1_start_h] = h'0b'


;===================================================================*
;===|vetor de reset|===========*
	org		h'00'
	goto	inicio

;===================================================================*	
;===|vetor de interrupção|=====*
	org		h'04'
	goto	interrupt

;===================================================================*
;===|inicio do programa|=======*

inicio	
	bank1					; registradores do banco 1 de memória
	movlw	h'86'			; (work) = h'85'
	movwf	option_reg		; desativa os pull-ups internos / prescaler do (tmr0) 1:64
	bsf		pie1,tmr1ie		; ativa a interrupção por overflow do (tmr1)

	movlw	b'00000000'		; (work) = b'1100 0000'
	movwf	trisa			; 
	movlw	b'00000111'		; (work) = b'1100 0000'
	movwf	trisb			;

	bank0					; registradores do banco 0 de memória
	movlw	h'07'			; w = h'07'
	movwf	cmcon			; desativa os comp. virtuais
	movlw	h'e0'			; w = h'e0'
	movwf	intcon			; int. global on / tmr0 overflow on / int. de perifericos on
	movlw	h'30'			; w = h'30'
	movwf	t1con			; prescaler 1:8

	movlw	b'00000000'		; (work) = b'0000 0000'
	movwf	porta			;
	movlw	b'00000000'		; (work) = b'0000 0000'
	movwf	portb			;

	movlw	tmr0_start		; constante definida no início do programa
	movwf	tmr0			; (tmr0) inicia com o valor de da constante [tmr0_start]

	movlw	tmr0_valor		; constante definida no início do programa
	movwf	aux_tmr0		; (tmr1h) inicia com o valor da constante [tmr1_start_h]

	movlw	tmr1_valor		; constante definida no início do programa
	movwf	aux_tmr1		; [aux_tmr1] inicia com o valor da constante [tmr1_valor]

	movlw	tmr1_start_h	; constante definida no início do programa
	movwf	tmr1h			; (tmr1h) inicia com o valor da constante [tmr1_start_h]
	movlw	tmr1_start_l	; constante definida no início do programa
	movwf	tmr1l			; (tmr1l) inicia com o valor da constante [tmr1_start_l]

	clrf	unidade			; zera todos os bits de [unidade]
	clrf	dezena			; zera todos os bits de [dezena]
	clrf	valor_unidade	; zera todos os bits de [valor_unidade]
	clrf	valor_dezena	; zera todos os bits de [valor_dezena]
	clrf	resto_unidade	; zera todos os bits de [resto_unidade]
	clrf	resto_dezena	; zera todos os bits de [resto_dezena]
	clrf	flags			; limpa todas as flags de controle
			
;=====================================================================*
;===|main|=====================*
	
teste
	call	delay			; chama delay de 2ms
	btfsc	bt_inc			; bt_int = 1?
	call	inc				; sim/ executa incremento
	btfsc	bt_dec			; bt_dec = 1?
	call	dec				; sim/ executa decremento
	btfss	bt_start		; bt_start = 1?
	goto	teste			; não/ retorna para teste
	bsf		t1con,tmr1on	; sim/ seta bit (tmr1on) = liga o tmr1
	call	guarda_valor	; rotina que salva o valor definido pelo usuário
	call	operacao		; rotina que pega o resto do tempo
	goto 	start			; desvia para start

guarda_valor
	movf	unidade,w		; move [unidade] para (work)
	movwf	valor_unidade	; move (work) para [valor_unidade)
	movf	dezena,w		; move [dezena] para (work)
	movwf	valor_dezena	; move (work) para [valor_dezena]
	return

operacao
	movf	valor_unidade,w	; w = [valor_unidade]
	sublw	.9				; operação sub. w = 9 - [valor_unidade]
	movwf	resto_unidade	; guarda o resultado em [resto_unidade]

	movf	valor_dezena,w	; w = [valor_dezena]
	sublw	.5				; operação sub. w = 5 - [valor_dezena]
	movwf	resto_dezena	; guarda o resultado em [resto_dezena]
	return

inc
	incf	unidade			; incrementa unidade
	movf	unidade,w		; move [unidade] para (work)
	xorlw	.10				; operação xor entre literal 10 e (work)
	skpz					; pula se flag (z) do reg. (status) for 1
	return					; retorna
;mais dez
	clrf	unidade			; limpa [unidade]
	incf	dezena			; incrementa [dezena]
	movf	dezena,w		; move [dezena] para (work)
	xorlw	.6				; operação xor entre literal 6 e (work)
	skpz					; pula se flag (z) do reg. (status) for 1
	return					; retorna
	clrf	unidade			; limpa [unidade]
	clrf	dezena			; limpa [dezena]
	return					; retorna

dec
	decf	unidade			; decrementa [unidade]
	movf	unidade,w		; move [unidade] para (work)
	xorlw	.255			; operação xor entre literal .255 e (work)
	skpz					; pula se flag (z) do reg. (status) for 1
	return					; retorna
; menos dez
	movlw	.9				; (work) = .9
	movwf	unidade			; move (work) para [unidade]
	decf	dezena			; decrementa [dezena]
	movf	dezena,w		; move [dezena] para (work)
	xorlw	.255			; operação xor entre literal .255 e (work)
	skpz					; pula se flag (z) do reg. (status) for 1
	goto	fim_tmr1		; vai para fim_tmr1
	movlw	.5				; move literal .5 para (work)
	movwf	dezena			; move (work) para [dezena]
	movlw	.9				; move literal .9 para (work)
	movwf	unidade			; move (work) para [unidade]
	bcf		t1con,tmr1on	; seta bit (tmr1on) = liga o (tmr1)
	return					; retorna

start
	btfss	t1con,tmr1on	; tmr1on = 1?
	goto	teste			; não/ sai do loop start
	goto	start			; sim/ repete o loop start

;=====================================================================*
;===|interrupção|==============*

interrupt
	movwf	w_temp
	swapf	status,w
	bank0
	movwf	status_temp

	btfss	pir1,tmr1if		; tmr1if = 0?
	goto	int_tmr0		; não/ desvia para int. tmr0
	goto	int_tmr1		; sim/ desvia para int. tmr1
	

;===|interrupção tmr1|==============*
int_tmr1
	bcf		pir1,tmr1if
	decfsz	aux_tmr1
	goto	fim_tmr1
	movlw	tmr1_valor
	movwf	aux_tmr1
	btfsc	flags,1			; testa bit 1 flags
	goto	desliga
	goto	liga

liga
	bsf		luz
	btfss	flags,3
	call	recupera_valor
	bsf		flags,3
	decf	unidade			; decrementa [unidade]
	movf	unidade,w		; move [unidade] para (work)
	xorlw	.255			; operação xor entre literal .255 e (work)
	skpz					; pula se flag (z) do reg. (status) for 1
	goto	fim_tmr1		; vai para fim_tmr1
; menos dez
	movlw	.9				; (work) = .9
	movwf	unidade			; move (work) para [unidade]
	decf	dezena			; decrementa [dezena]
	movf	dezena,w		; move [dezena] para (work)
	xorlw	.255			; operação xor entre literal .255 e (work)
	skpz					; pula se flag (z) do reg. (status) for 1
	goto	fim_tmr1		; vai para fim_tmr1
	clrf	unidade			; limpa [unidade]
	clrf	dezena			; limpa [dezena]
	bsf		flags,1
	bcf		flags,2
	;bcf		t1con,tmr1on	; seta bit (tmr1on) = liga o (tmr1)
	goto	fim_tmr1		; vai para fim_tmr1

desliga
	bcf		luz
	btfss	flags,2
	call	recupera_resto
	bsf		flags,2
	decf	unidade			; decrementa [unidade]
	movf	unidade,w		; move [unidade] para (work)
	xorlw	.255			; operação xor entre literal .255 e (work)
	skpz					; pula se flag (z) do reg. (status) for 1
	goto	fim_tmr1		; vai para fim_tmr1
; menos dez
	movlw	.9				; (work) = .9
	movwf	unidade			; move (work) para [unidade]
	decf	dezena			; decrementa [dezena]
	movf	dezena,w		; move [dezena] para (work)
	xorlw	.255			; operação xor entre literal .255 e (work)
	skpz					; pula se flag (z) do reg. (status) for 1
	goto	fim_tmr1		; vai para fim_tmr1
	clrf	unidade			; limpa [unidade]
	clrf	dezena			; limpa [dezena]
	bcf		flags,1
	bcf		flags,3
	;bcf		t1con,tmr1on	; seta bit (tmr1on) = liga o (tmr1)
	goto	fim_tmr1		; vai para fim_tmr1

recupera_resto
	movf	resto_unidade,w
	movwf	unidade
	movf	resto_dezena,w
	movwf	dezena
	return

recupera_valor
	movf	valor_unidade,w
	movwf	unidade
	movf	valor_dezena,w
	movwf	dezena
	return
	
	

;===|interrupção tmr0|==============*
int_tmr0
	bcf		intcon,t0if
	decfsz	aux_tmr0
	goto	fim_tmr0
	movlw	tmr0_valor
	movwf	aux_tmr0
	btfss	flags,0			; flag altera = 1?
	goto	mult1			; não/
	goto	mult2			; sim/

mult1
	bsf		flags,0
	;call	zero			; limpa display
	bsf 	one
	bsf 	two
	bsf 	three
	bsf		four
	movf	unidade,w
	call	tabela
	bcf		dez
	bsf		uni
	goto	fim_tmr0
	
mult2
	bcf		flags,0
	;call	zero			; limpa display
	bsf 	one
	bsf 	two
	bsf 	three
	bsf		four
	movf	dezena,w
	call	tabela
	bcf		uni
	bsf		dez
	goto	fim_tmr0

;===|fim int_tmr0|==============*
fim_tmr0
	movlw	tmr0_start
	movwf	tmr0			;tmr0 inicia em 100
	goto	fim_int

;===|fim int_tmr1|==============*
fim_tmr1
	movlw	tmr1_start_h
	movwf	tmr1h
	movlw	tmr1_start_l
	movwf	tmr1l
	goto	fim_int

fim_int
	swapf	status_temp,w
	movwf	status
	swapf	w_temp,f
	swapf	w_temp,w	
	retfie
	

tabela	
	addwf	pcl				; soma o que está em (work) com pcl
	goto	zero
	goto	um
	goto	dois
	goto	tres
	goto	quatro
	goto	cinco
	goto	seis
	goto	sete
	goto	oito
	goto	nove

zero
	bcf		one
	bcf		two
	bcf		three
	bcf		four
	return

um
	bsf		one
	bcf		two
	bcf		three
	bcf		four
	return

dois
	bcf		one
	bsf		two
	bcf		three
	bcf		four
	return

tres
	bsf		one
	bsf		two
	bcf		three
	bcf		four
	return

quatro
	bcf		one
	bcf		two
	bsf		three
	bcf		four
	return

cinco
	bsf		one
	bcf		two
	bsf		three
	bcf		four
	return

seis
	bcf		one
	bsf		two
	bsf		three
	bcf		four
	return

sete
	bsf		one
	bsf		two
	bsf		three
	bcf		four
	return

oito
	bcf		one
	bcf		two
	bcf		three
	bsf		four
	return

nove
	bsf		one
	bcf		two
	bcf		three
	bsf		four
	return




delay
	movlw	.99
	movwf	d2
delay_d1
	movlw	.200
	movwf	d1
delay_loop
	goto	$+1
	goto	$+1
	goto	$+1
	nop

	decfsz	d1
	goto	delay_loop
	decfsz	d2
	goto	delay_d1
	return

;====================================================================*	
;===|fim|======================*

end

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

se na simulação funciona e na prática não, procure problema de montagem e afins. P. ex . transistores invertidos ou em curto.

ahhh. sorry não analisar seu código com a profundidade que você merece

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Isadora Ferraz Ok, vou fazer mais algumas verificações. Mas já verifiquei a maior parte da montagem, vi que o problema está na área dos 2 transistores, o resto do código tá rodando perfeitamente na prática. 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Uma microanálise preliminar (e óbvia) seria verificar com osciloscópio se os pinos uni e dez estão operantes e se alternando. Aí você verifica blocos da interrupção deles. Talvez uma interrupt esteja zoando outra, Sorry de novo... só analisei a superfície do seu assembly.

Compartilhar este post


Link para o post
Compartilhar em outros sites

No osciloscópio a multiplexação na saída do PIC ocorre normalmente. Uma coisa que acontece. é que quando retiro o resistor de 1k da base e coloco as saídas da multiplexação direto no coletor do transistor, ele funciona. Mas o display fica com o brilho bem baixo :/

já testei outros resistores também 

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Isadora Ferraz Consegui resolver colocando os pinos que realiza a multiplexação na base do transistor, e o resistor no emissor. Não entendi bem porque funcionou assim, na simulação deste modo n funciona. Mas na prática sim. Por enquanto vou deixar desse jeito. Obrigado pelas respostas :D

 

Screenshot_2.png

Compartilhar este post


Link para o post
Compartilhar em outros sites

#7   Postado (editado)

Se puder,posta uma imagem o video funcionando pra gente ver"

 

 

8 horas atrás, Isadora Ferraz disse:

Uma microanálise preliminar (e óbvia) seria verificar com osciloscópio se os pinos uni e dez estão operantes e se alternando. Aí você verifica blocos da interrupção deles. Talvez uma interrupt esteja zoando outra, Sorry de novo... só analisei a superfície do seu assembly.

Alguma noticia do Paulo?

ele gostaria de explicar este circuito.

Editado por vtrx

Compartilhar este post


Link para o post
Compartilhar em outros sites

@vtrx Tenho este vídeo quando tava acontecendo o problema. Infelizmente não tenho o vídeo de como está agora porque deixei o projeto no meu curso. Amanha gravo outro.

 

Não tá nesse vídeo, mas agora o problema é que a intensidade do display está muito baixa, amanha posso mostrar.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Vi o video algumas vezes pra tentar achar o valor dos resistores que ligaste nos sinais abcdefg. Não consegui. Coloque 1k em cada e volte como estava.

 

Do jeito que colocou foi um resistor comum pra cada display e configurado como seguidor de emissor. Isto pode diminuir a corrente IC pois o transistor não satura. @vtrx ... Paulão @aphawk pode corroborar se achar que deve.

2 pessoas curtiram isso

Compartilhar este post


Link para o post
Compartilhar em outros sites

#10   Postado (editado)

@Isadora Ferraz ,

 

Opa , lí que você passou por problemas semelhantes ao meu.... fico feliz em ver que já está de volta, ativa no Fórum !

Vida longa e próspera !

 

@vtrx ,

 

Caramba, deu um sinal de vida !!!! 

Faz tempo ein meu amigo !

 

@Philippe Henrique ,

 

Da maneira que você ligou, com os resistores no emissor, faz com que a corrente de coletor seja bem pequena, e assim o transistor trabalha fazendo o corte de maneira mais rápida. Mas não é a maneira correta, a correta é a que está em seu post inicial.

 

Existe um problema : com o resistor de base de 1K, o transistor trabalha tão saturado que demora mais tempo para  ocorrer o corte. O correto seria você estimar qual a corrente que cada segmento vai consumir ( devido aos resistores limitadores ligados no 74hc4511 ), multiplicar por sete para ter uma ideia da  corrente total que irá passar pelo transistor, e dividir pelo ganho médio do transistor, assim você tem a corrente de base necessária no transistor, e pode dimensionar corretamente o resistor ligado na base, fazendo o transistor trabalhar bem no início da saturação, onde ele ainda é rápido.

 

Uma maneira de corrigir isso por software é esta : assim que você desligar o transistor, espere algumas dezenas de microsegundos, antes de acionar o outro transistor !

 

Faz algum tempo eu escreví um artigo onde explico esse problema e apresento as maneiras corretas de cálculo e também como resolver por software.

 

Veja aqui :

 

Paulo

Editado por aphawk
1 pessoa curtiu isso

Compartilhar este post


Link para o post
Compartilhar em outros sites
9 horas atrás, aphawk disse:

assim que você desligar o transistor, espere algumas dezenas de microsegundos, antes de acionar o outro transistor !

exatamente o que eu dia dizer mas fiquei com preguiça kk. Adicionemos algo: apague os segmentos, desligue o transistor,espere, coloque o novo dado nos segmentos, ligue o outro transistor

 

Se você não se importar, permita-me observar que, se refizer a montagem,  pode colocar o dado direto na saída do mc. Não precisa ser bit a bit.

Em 17/05/2017 às 17:59, Philippe Henrique disse:

zero bcf one

bcf two

bcf three

bcf four

return

um

bsf one

bcf two

bcf three

bcf four

return

 

Algo como

movf contagem,w
movwf porta

fica mais eficiente

 

Não agora, nem hoje e talvez nem amanhã mas num futuro próximo você deve perceber que nem precisa do 4511 ... e muito menos do ,,, assembly

sucessos

1 pessoa curtiu isso

Compartilhar este post


Link para o post
Compartilhar em outros sites

@aphawk Muito obrigado pela resposta. Vou realizar o cálculo do resistor de base de acordo com o que disse, assim que eu fizer e testar eu volto pra dizer se funcionou, valeu!!

@Isadora Ferraz Muito obrigado novamente. Vou alterar essa parte do código, fica bem mais fácil.

 

4 horas atrás, Isadora Ferraz disse:

Não agora, nem hoje e talvez nem amanhã mas num futuro próximo você deve perceber que nem precisa do 4511 ... e muito menos do ,,, assembly

 

Estou montando em assembly pois o meu curso exige. Assim que termina-lo vou buscar conhecimentos em C, tanto que já tenho um arduino.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!


Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.


Entrar agora