I start to play with one of this cheap 4 digit 7 segment display. The display is driven by two 74HC595 which one is for segments and the other is for common cathodes (digits).
Here is the schematic:
I writed a simple code using Darrel's interrupts. Code multiplexing the digits using TMR1 interrupt.
It works OK, but I think that code is not as elegant. It looks rough, because I'm not a skilled programmer.
Can someone explain to me a better way to do this task?
Here is my code:
'**************************************************************** '* Name : 4 bit 7 segment display * '* Author : LouisLouis * '* Notice : Copyright (c) 2018 * '* : All Rights Reserved * '* Date : 18. 2. 2018 * '* Version : 1.0 * '* Notes : * '* MCU : PIC 12F1840 * '**************************************************************** #CONFIG __config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_ON & _FCMEN_ON __config _CONFIG2, _WRT_OFF & _PLLEN_ON & _STVREN_ON & _BORV_19 & _LVP_OFF #ENDCONFIG DEFINE OSC 32 ; Use internal clock OSCCON = 110000 CLKRCON = 0 Include "modedefs.bas" INCLUDE "DT_INTS-14.bas" ; Base Interrupt System INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts TRISA = %0000 ANSELA = 00 OPTION_REG.7=0 ; Enable internal pull-ups LPIN var porta.2 ; Latch DPIN var porta.4 ; Data CPIN var porta.5 ; Clock segment var byte value var word place var byte[4] ones var word tens var word hundreds var word thousands var word ASM INT_LIST macro ; IntSource, Label, Type, ResetFlag? INT_Handler TMR1_INT, _DISP, PBP, yes endm INT_CREATE ; Creates the interrupt processor ENDASM @ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts T1CON = $1 ;---[simple counter 0 - to 9999]------------------------------------------------ Main: for value = 0 to 9999 pause 100 next value value = 0 GOTO Main ;---[TMR1 - interrupt handler]-------------------------------------------------- DISP: T1CON.0 = 0 ; stop timer TMR1H = 111100 TMR1L = 011111 T1CON.0 = 1 ; restart timer ;---[extract ones and show]----------------------------------------------------- ones = value//10 lookup ones, [000000,111001,100100,110000,011001,010010,000010,111000,000000,010000],segment LOW LPIN Shiftout DPIN, CPIN, MSBFIRST,[segment,01] high lpin pause 4 ;---[extract tens and show]----------------------------------------------------- tens = value/10 tens = tens//10 lookup tens, [000000,111001,100100,110000,011001,010010,000010,111000,000000,010000],segment LOW LPIN Shiftout DPIN, CPIN, MSBFIRST,[segment,10] high lpin pause 4 ;---[extract hundreds and show]------------------------------------------------- hundreds = value/100 hundreds = hundreds//10 lookup hundreds, [000000,111001,100100,110000,011001,010010,000010,111000,000000,010000],segment LOW LPIN Shiftout DPIN, CPIN, MSBFIRST,[segment,00] high lpin pause 4 ;---[extract thousands and show]------------------------------------------------ thousands = value/1000 place = 00 lookup thousands, [000000,111001,100100,110000,011001,010010,000010,111000,000000,010000,001000],segment LOW LPIN Shiftout DPIN, CPIN, MSBFIRST,[segment,00] high lpin @ INT_RETURN
it adds unnecessary bloat for this app
'**************************************************************** '* Name : 4 bit 7 segment display * '* Author : RICHARD * '* Notice : * '* : * '* Date : 18. 2. 2018 * '* Version : 1.0 * '* Notes : * '* MCU : PIC 12F1822 @32MHZ * '**************************************************************** #CONFIG __config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_ON & _FCMEN_ON __config _CONFIG2, _WRT_OFF & _PLLEN_ON & _STVREN_ON & _BORV_19 & _LVP_OFF #ENDCONFIG goto overasm ASM seg_val CHK?RP _TM_TMP MOVWF _TM_TMP SUBLW 0x21 btfsc STATUS, C retlw 0 ;" " MOVF _TM_TMP,W SUBLW 0x2f btfsc STATUS, C retlw 64 ;"-" MOVF _TM_TMP,W MOVLW 0X40 SUBWF _TM_TMP,W btfsC STATUS, C GOTO TM_ALPHA MOVF _TM_TMP,W ANDLW 0X0F GOTO TM_LU TM_ALPHA ANDLW 0xdf ;ucase SUBLW 6 btfsS STATUS, C retlw 0 ;ERROR MOVLW 0X37 SUBWF _TM_TMP,W ANDLW 0xdf ;ucase TM_LU BRW retlw 0X3F ;0 retlw 6 retlw 0X5B retlw 0X4F retlw 0X66 retlw 0X6D retlw 0X7D retlw 7 retlw 0X7F retlw 0X67 ;9 retlw 0X77 ;A retlw 0X7C ;b retlw 0X39 ;C retlw 0X5E ;d retlw 0X79 ;E retlw 0X71 ;F endasm overasm: DEFINE OSC 32 ; Use internal clock ANSELA=0 SSP1CON1=$22 SSP1STAT=$40 OSCCON=$70 DEFINE INTHAND _DISP TRISA = %111000 @LPORT=LATA LPIN CON 2 ;var LATa.2 ; Latch DPIN var porta.0 ; Data SDO CPIN var porta.1 ; Clock SCK segment var byte value var word d_index var byte buff var byte[5] seg_buff var byte[4] seg_cnt var byte seg_dat var byte tmp var byte TM_TMP var byte d_pointer var byte timer1_reload con 33543 ;4mS PIR1.0=0 INTCON=$C0 PIE1.0=1 T1CON = $1 d_index=0 ;---[simple counter 0 - to ffff]------------------------------------------------ Main: for value = 0 to 65535 arraywrite buff ,[HEX4 value,0] gosub load_seg pause 100 next value value = 0 GOTO Main load_seg : for seg_cnt=0 to 3 seg_dat= buff[seg_cnt] asm MOVE?BA _seg_dat L?CALL seg_val MOVE?AB _seg_dat endasm seg_buff[seg_cnt]= seg_dat next return ;---[TMR1 - interrupt handler]-------------------------------------------------- DISP: asm MOVE?CT 0, T1CON, TMR1ON ; 1 stop timer MOVLW LOW(_timer1_reload) ; 1 Add TimerReload to the ADDWF TMR1L,F ; 1 value in Timer1 BTFSC STATUS,C ; 1/2 INCF TMR1H,F ; 1 MOVLW HIGH(_timer1_reload) ; 1 ADDWF TMR1H,F ; 1 MOVE?CT 1, T1CON, TMR1ON ; 1 start timer MOVE?CB high _seg_buff, FSR0H ;load highbyte MOVE?CB low _seg_buff, FSR0L ;load low byte MOVE?BA _d_index ADDWF FSR0L,F MOVF INDF0,W ;L?CALL seg_val MOVE?AB _segment MOVE?BB _d_index ,_tmp BANKSEL _tmp INCF _tmp,F MOVLW 16 BANKSEL _d_pointer movwf _d_pointer BcF STATUS ,C N_BIT BANKSEL _d_pointer RRF _d_pointer,F BANKSEL _tmp DECFSZ _tmp,F GOTO N_BIT BANKSEL _d_index INCF _d_index,F MOVLW 3 ANDWF _d_index,F BANKSEL LPORT BCF LPORT ,_LPIN BANKSEL PIR1 BCF PIR1,3 BANKSEL _segment MOVF _segment,W ;COMMENT USED TO INVERT DATA FOR COMMON cathode DISPLAY ;COMF _segment,W ;COMMENT USED TO INVERT DATA FOR COMMON ANODE DISPLAY BANKSEL SSP1BUF movwf SSP1BUF BANKSEL PIR1 BTFSs PIR1,3 GOTO $-1 BANKSEL _d_pointer COMF _d_pointer,W ;COMMENT USED FOR COMMON cathode DISPLAY ;MOVF _d_pointer,W ;COMMENT USED FOR COMMON ANODE DISPLAY BANKSEL PIR1 BCF PIR1,3 BANKSEL SSP1BUF movwf SSP1BUF BANKSEL PIR1 BTFSs PIR1,3 GOTO $-1 BANKSEL LPORT BSF LPORT ,_LPIN BANKSEL PIR1 BCF PIR1 ,0 RETFIE endasm
Main: for value = 0 to 65535 arraywrite buff ,[HEX4 value] gosub load_seg seg_buff[2]=seg_buff[2]|128 ; place a dp in digit 2 pause 100 next value value = 0 GOTO Main
Re: Serin Not Recognizing Qualifier From Another PIC
I don't really use serin so I can't be of much help, but just to educate me: isn't the contents inside the square brackets a qualifier or filter - like the WAIT modifier in serin2?
rocket_troy Today, 03:24Troy