Ir ao conteúdo
  • Cadastre-se

Multiplexação ou Transistor?


Posts recomendados

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

 

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

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.

  • Curtir 1
Link para o comentário
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 

Link para o comentário
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

Link para o comentário
Compartilhar em outros sites

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.

Link para o comentário
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.

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

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.

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

@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

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

  • Membro VIP
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

  • Curtir 2
Link para o comentário
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.

Link para o comentário
Compartilhar em outros sites

  • 2 semanas depois...

Bom atualizando... Eu refiz toda a montagem na protoboard, e o problema não é o mesmo, mas agora é um problema "menos pior" digamos assim. Segue o vídeo.

 

Liguei um jumper no GND, e quando seguro nesse jumper o suposto mau contato para. Não sei onde pode estar esse problema. Alguém já teve esse problema?

Link para o comentário
Compartilhar em outros sites

@Philippe Henrique  

 

Hehehe é legal quando vejo acontecer com os outros coisas estranhas que já aconteceram comigo kkkkkkk !

 

Pegue um  capacitor eletrolítico de 47 uF ( ou 22 ou 100 também serve ) , e um capacitor de 100 nF , e coloque ambos o mais próximo possível dos pinos de VCC e GND do Pic, que isso deve sumir. Veja bem, o mais próximo possível, ok ?

 

Paulo

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

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

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!