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: SERIN2 Receiving Wrong Data
The sending device has the typical 18F4550 USB setup and it is set to "Define OSC 48". The receiving device is set to "DEFINE OSC 16".
rsocor01 Yesterday, 19:56