Could you point to an example of that?Most of the data sheets say that when you write to the TMRxH/L, you must declare the entire TxCON SFR
Could you point to an example of that?Most of the data sheets say that when you write to the TMRxH/L, you must declare the entire TxCON SFR
me tooCould you point to an example of that?
I have never had to do that and can find no mention of that short coming anywhere
anyways here is my take on the 7 seg display
if you have a chip with mssp why waste time and code space when the hardware can do it for you
I cheated a bit and did it in asm for speed and size gains
no nasty pauses , all gone
my displays are common anode so the data is inverted see comments
Code:'**************************************************************** '* Name : 4 bit 7 segment display * '* Author : RICHARD * '* Notice : * '* : * '* Date : 18. 2. 2018 * '* Version : 1.0 * '* Notes : * '* MCU : PIC 16F1825 @32MHZ * '**************************************************************** #CONFIG __config _CONFIG1, _FOSC_INTOSC & _CP_OFF & _WDTE_ON & _PWRTE_ON & _MCLRE_ON & _CLKOUTEN_OFF __config _CONFIG2, _PLLEN_OFF & _LVP_OFF #ENDCONFIG goto overasm asm timer1 = TMR1L seg_val addwf PCL, F retlw 0xc0;0B11000000 0 retlw 0xf9;0B11111001 1 retlw 0xa4;0B10100100 2 retlw 0xb0;0B10110000 3 retlw 0x99;0B10011001 4 retlw 0x92;0B10010010 5 retlw 0x82;0B10000010 6 retlw 0xf8;0B11111000 7 retlw 0x80;0B10000000 8 retlw 0x90;0B10010000 9 endasm overasm: DEFINE OSC 32 ; Use internal clock ANSELC=0 SSP1CON1=$22 SSP1STAT=$40 OSCCON=$f0 INCLUDE "DT_INTS-14.bas" ; Base Interrupt System TRISC = %11101010 LPIN var portc.4 ; Latch DPIN var portc.2 ; Data SDO CPIN var portc.0 ; Clock SCK segment var byte value var word d_index var byte buff var byte[5] tmp var byte d_pointer var byte timer1 var word ext timer1_reload con 1543 ;8mS ASM INT_LIST macro ; IntSource, Label, Type, ResetFlag? INT_Handler TMR1_INT, _DISP, ASM, yes endm INT_CREATE ; Creates the interrupt processor ENDASM @ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts T1CON = $1 d_index=0 ;---[simple counter 0 - to 9999]------------------------------------------------ Main: for value = 0 to 9999 arraywrite buff ,[dec4 value] pause 100 next value value = 0 GOTO Main ;---[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 _buff, FSR0H ;load highbyte MOVE?CB low _buff, FSR0L ;load low byte MOVE?BA _d_index ADDWF FSR0L,F MOVLW 0X30 SUBWF INDF0,W L?CALL seg_val MOVE?AB _segment MOVE?BB _d_index ,_tmp BANKSEL _tmp MOVLW 1 ADDWF _tmp,F BANKSEL _d_pointer CLRF _d_pointer BSF STATUS ,C N_BIT BANKSEL _d_pointer RLF _d_pointer,F BCF STATUS ,C BANKSEL _tmp DECFSZ _tmp,F GOTO N_BIT MOVLW 1 BANKSEL _d_index ADDWF _d_index,F MOVLW 3 ANDWF _d_index,F BANKSEL LATC BCF LATC ,4 BANKSEL PIR1 BCF PIR1,3 BANKSEL _segment 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 ANODE DISPLAY BANKSEL PIR1 BCF PIR1,3 BANKSEL SSP1BUF movwf SSP1BUF BANKSEL PIR1 BTFSs PIR1,3 GOTO $-1 BANKSEL LATC BSF LATC ,4 BANKSEL 0 INT_RETURN endasm
Last edited by richard; - 19th February 2018 at 11:18. Reason: convert to english instead of gibberish
Warning I'm not a teacher
OK, looked through a K50 and 16F1619 Data Sheet for that note or catch phrase indicating a full write to TxCON is recommended after writing to the TMRxH/L registers and cannot find it. It might be for an older processor, or maybe I read it on a forum somewhere and now it's that propagating myth. Sorry.
Hello Richard, thanks for response. Your code is probably for 4 digit 7 segment display where the segments is driven via 74HC595 shift register, and the common anodes via transistors directly from MCU or for multiplexing a bare display whitout driver right?
Look at mi first post, my display is driven by two 74HC595 shift register, one for segments, and the second for digits (like common anodes/cathodes).
To send data I used:
Now I tring to find more elegant way to extract ones, tens, hundreds and thousands like my previous solution:Code:SHIFTOUT DPIN, CPIN, MSBFIRST,[ones,%0001] ;(segment pattern, digit position)
Can you help me with it?Code:setdisp: segment = value//10 gosub look ones=segment ; extract ones segment = value/10 segment = segment//10 gosub look tens=segment ; extract tens segment = value/100 segment = segment//10 gosub look hundreds=segment ; extract hundreds segment = value/1000 gosub look thousands=segment ; extract thousands
wrong , my code is for your circuit but using a different pic chip . I don't have a 12f1840 on hand but I cannot see any reason for it not to work on that chip . if you use the right pins.Your code is probably for 4 digit 7 segment display where the segments is driven via 74HC595 shift register, and the common anodes via transistors directly from MCU or for multiplexing a bare display whitout driver right
your code is for common anode mine common cathode the commented lines can be changed to suit
COMF _segment,W for common Anode becomes MOVF _segment,W
COMF _d_pointer,W for common Anode becomes MOVF _d_pointer,W
ie the current is reversed in the display
Warning I'm not a teacher
here is a 12f1822 version
with full hex [upper and lower case] space and - sign also
note comments for common anode/cathode
Code:'**************************************************************** '* 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 timer1 = TMR1L 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 INCLUDE "DT_INTS-14.bas" ; Base Interrupt System " TRISA = %11111000 @LPORT=LATA LPIN CON 2 ;var LATC.4 ; 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] tmp var byte TM_TMP var byte d_pointer var byte timer1 var word ext timer1_reload con 1543 ;8mS ASM INT_LIST macro ; IntSource, Label, Type, ResetFlag? INT_Handler TMR1_INT, _DISP, ASM, yes endm INT_CREATE ; Creates the interrupt processor ENDASM @ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts T1CON = $1 d_index=0 ;---[simple counter 0 - to ffff]------------------------------------------------ Main: for value = 0 to 65535 arraywrite buff ,[HEX4 value,0] pause 100 next value value = 0 GOTO Main ;---[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 _buff, FSR0H ;load highbyte MOVE?CB low _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 MOVLW 1 ADDWF _tmp,F BANKSEL _d_pointer CLRF _d_pointer BSF STATUS ,C N_BIT BANKSEL _d_pointer RLF _d_pointer,F BCF STATUS ,C BANKSEL _tmp DECFSZ _tmp,F GOTO N_BIT MOVLW 1 BANKSEL _d_index ADDWF _d_index,F MOVLW 3 ANDWF _d_index,F BANKSEL LPORT BCF LPORT ,_LPIN BANKSEL PIR1 BCF PIR1,3 BANKSEL _segment MOVF _segment,W ;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 ;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 0 INT_RETURN endasm
Warning I'm not a teacher
Thanks Richard, that code works, but that is a way more difficult understand to me because ASM and so on.
A few things I've noticed when I tried the code:
- your code is a way shorter in MCU memory like mine, which is good
- multiplex is a bit slower I see some flickers
- if I put in to the "value" variable mumber "1234" the display shows "4321"
of course I changed this line
arraywrite buff ,[HEX4 value,0]
to
arraywrite buff ,[DEC4 value,0]
Anyway, it is a good example how the skilled programmer thinks, and how a beginner thinks.
Last edited by louislouis; - 19th February 2018 at 22:49. Reason: My English is terrible, will we go to Hungarian :-)
the refresh rate is 8mS to speed it up to 4mS change timer1_reload to 33543multiplex is a bit slower I see some flickers
sicif I put in to the "value" variable mumber "1234" the display shows "4321"
the digit scan direction can be reversed easily and would result in even smaller code
the difference with this method is that the mcu can now do other tasks and not spend all its time being just a display controller
Warning I'm not a teacher
digit order reversed,scan 4mS
and I moved the lookup out of the isr into the foreground (reduce isr overhead)
Code:'**************************************************************** '* 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 INCLUDE "DT_INTS-14.bas" ; Base Interrupt System TRISA = %11111000 @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 ASM INT_LIST macro ; IntSource, Label, Type, ResetFlag? INT_Handler TMR1_INT, _DISP, ASM, yes endm INT_CREATE ; Creates the interrupt processor ENDASM @ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts 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 MOVLW 1 ADDWF _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 MOVLW 1 BANKSEL _d_index ADDWF _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 0 INT_RETURN endasm
Last edited by richard; - 19th February 2018 at 23:07.
Warning I'm not a teacher
Bookmarks