This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430G2553 ASM, 1 Second or 1/4 Second

Other Parts Discussed in Thread: MSP430G2553

Hi,

So, knock on wood, me and my partner finished our Traffic Lights program for school this last week. We used assembly code. The knock on wood part is that we did not use a timer as we didn't have time for trial and error to get it right so our second consist of:

sec1		mov		#0004h,R13				;Load 4
sec1_3		mov		#0CDFAh,R12				;Load 1/4 a second
sec1_2		dec		R12					;Decrement by 1
		clrz							;Clear Z Flag for JNZ to work
		cmp		R12,R4					;Did the timer reach 0?
		jnz		sec1_2					;Jump to decrement fast timer
		dec		R13					;Decrement R13 by 1
		clrz							;Clear Z Flag for JNZ to work
		cmp		R13,R4					;Did R13 reach zero
		jnz		sec1_3					;Jump to fast timer Load
		ret							;Return from Stack

This is my partner's updated version to try and work out 1 second and 1.5 second problem we were having. (1/4 is easier to scale up to 1.5 then what we originally had).


He mainly wrote the program and i pointed out mistakes for this one because I mainly wrote or figured out our last project (and this community was a big help here). He was doing quite a few calculations when it came down to a second on the msp430G2553. He emailed me last night the final code version he wrote (he called it a mess), so my question is:
Doing it OUR WAY did he calculate 1/4 a second correctly? Or what would be 1 second so I could technically split it down to 1/4 or 1/2 second? Answering any one question (1/4s, 1/2s, 1s) would get me an answer I would like, but not need as of now. He was wracking his brain with new job and this so I thought I could possibly get him a solid answer.

I would have thought this would simple be a frequency divided (16Mhz) by 16bit (0FFFFh) question, but considering what he has above almost or does = 1 second I would be wrong.

I UNDERSTAND a timer would have been the better way, please don't berate us on this.

  • The CLRZ instruction is not needed because CMP always affects the Z flag; a NOP would have the same effect. Anyway:

    Loop: DEC  R12      ; 1
          CLRZ          ; 1
          CMP  R12, #0  ; 1
          JNZ  Loop     ; 2

    CDFAh * 5 is 263650 cycles; times four is 1054600 cycles.

  • MSP430G2553 has active state frequency of 16 Mhz right (its right on its page listed as one of the piece of info under parametrics www.ti.com/.../msp430g2553 ), so his technically wouldn't work. But we are using calls so that is slowing it down.


    Are you telling me for (this is a main part of our code) this that none of the clrz's in there are not needed, the cmp does its thing and decides if the Z flag should be 1 or 0?


    START		mov.w	#0000h,R4				;decimal 0 register
    			mov.w	#0080h,R8				;If equal or greater to this number Night is active
    											;If less than this number CARS loop goes
    S1			mov.b	#024h,&P1OUT			;Initial Red P1
    			mov.b	#001h,&P2OUT			;Initial Red P2
    			bic.b	#BIT4,&P2OUT			;Walk Signal East/West off
    			bic.b	#BIT3,&P2OUT			;Walk Signal North/South off
    			call	#sec_1p5				;1.5 sec routine
    			clrz							;Clear Z Flag
    
    			mov.b	#21h,&P1OUT				;Green going North
    			mov.b	#03h,&P2OUT				;Turn Left Green
    			mov.w	#000Ch,R5				;12 sec counter
    S2			call	#sec1					;1 sec routine
    			dec		R5						;Decrement by 1
    			cmp		R5,R4					;Compare timer with Register value of 0
    			jnz		S2						;Continue decrementing State 2
    			clrz							;Clear Z Flag
    
    			mov.b	#05h,&P2OUT				;Turn Left Yellow
    			mov.w	#0003h,R5				;3 sec counter
    S3			call	#sec1					;1 sec routine
    			dec		R5						;Decrement by 1
    			cmp		R5,R4					;Compare timer with Register value of 0
    			jnz		S3						;Continue decrementing State 3
    			clrz							;Clear Z Flag
    
    			mov.b	#09h,&P1OUT				;Green going South
    			mov.b	#09h,&P2OUT				;Walk NS
    			mov.w	#000Bh,R5				;10 sec counter
    			mov.b 	&P2IN,R6				;Load R6 with P2 input value
    			cmp		R6,R8					;Does input = less than or greater than
    			jlo 	CARS					;Jump to Cars Loop
    			clrz							;Clear Z Flag
    S4			call	#sec1					;1 sec routine
    			dec		R5						;Decrement by 1
    			cmp		R5,R4					;Compare timer with Register value of 0
    			jnz		S4						;Continue decrementing State 4
    			clrz							;Clear Z Flag
    
    			mov.w	#0008h,R5				;16 sec counter including the 2x 1sec loops
    S5			dec		R5						;Decrement by 1
    			cmp		R5,R4					;Compare timer with Register value of 0
    			jnz		WKNSF					;Jump to Walk North/South Flashing
    			clrz							;Clear Z Flag
    
    			mov.w	#0002h,R5				;4 sec counter including the 2x 1sec loops
    			mov.b	#12h,&P1OUT				;Yellow North/South
    S6			dec		R5						;Decrement by 1
    			cmp		R5,R4					;Compare timer with Register value of 0
    			jnz		WKNSF2					;Jump to Walk North/South Flashing 2
    			clrz							;Clear Z Flag
    
    			mov.w	#0001h,R5				;1.5 sec counter
    			mov.b	#024h,&P1OUT			;Initial Red P1
    			mov.b	#009h,&P2OUT			;Initial Red P2
    S7			call	#sec_1p5				;1.5 sec routine
    			dec		R5						;Decrement by 1
    			cmp		R5,R4					;Compare timer with Register value of 0
    			jnz		S7						;Continue decrementing State 7
    			clrz							;Clear Z Flag
    
    			mov.w	#0008h,R5				;7 sec counter
    			mov.b	#64h,&P1OUT				;Green going East
    			mov.b	#10h,&P2OUT				;Walk E
    S8			call	#sec1					;1 sec routine
    			dec		R5						;Decrement by 1
    			cmp		R5,R4					;Compare timer with Register value of 0
    			jnz		S8						;Continue decrementing State 8
    			clrz							;Clear Z Flag
    
    			mov.w	#0005h,R5				;11 sec counter
    			bis.b	#BIT4,&P2OUT			;Walk E ON
    			call	#sec1					;1 sec routine
    S9			dec		R5						;Decrement by 1
    			cmp		R5,R4					;Compare timer with Register value of 0
    			jnz		WKEF					;Jump to Walk E Flashing
    			clrz							;Clear Z Flag
    
    			mov.w	#0002h,R5				;4 sec counter including 2x 1sec loops
    			mov.b	#0A4h,&P1OUT			;Yellow going East
    S10			dec		R5						;Decrement by 1
    			cmp		R5,R4					;Compare timer with Register value of 0
    			jnz		WKEF2					;Jump to Walk E flashing 2
    			clrz							;Clear Z Flag
    
    			mov.b 	&P2IN,R6				;Load R6 with P2 input value
    			cmp		R6,R8					;Does input = less than or greater than
    			jge		NIGHT					;Greater than sends to Night time operation
                jmp     START					;start the process again aka RESTART
    
    NIGHT		mov.b	#012h,&P1OUT			;Initial Red P1
    			mov.b	#001h,&P2OUT			;Initial Red P2
    			call	#sec1					;1 sec routine
    			mov.b	#00h,&P1OUT				;Initial Red P1
    			mov.b	#00h,&P2OUT				;Initial Red P2
    			call	#sec1					;1 sec routine
    			clrz							;Clear Z Flag
    			clrc							;Clear C Flag
    			clrn							;Clear N Flag
    			mov.b 	&P2IN,R6				;Load R6 with P2 input value
    			cmp		R6,R8					;Does input = less than or greater than
    			jlo		START					;Less than sends to Normal operation
    			jge		NIGHT					;Greater than sends to Night time operation
    			jmp		START					;Restarts main program
                jmp		END						;Program Ends

    We've been doing it in our last 2 projects as well, and I trailed along the side of caution with my partner and we put them in there whenever a cmp was needed.

  • >that none of the clrz's in there are not needed, the cmp does its thing and decides if the Z

    That how it is, a cmp does not only set the Z it also clears the Z flag.

    instructions with x sets flags, the ones with - flags are not affected
    and a few were they are always cleared or always set.

  • In fact, your CMP R12,R4; CMP R13,R4; and all CMP R5,R4; are not necessary too. The DEC R12; DEC R13 and all DEC R5; before them have already clear/set the Z-flag for you.

  • Jared sarff said:
    MSP430G2553 has active state frequency of 16 Mhz right (its right on its page listed as one of the piece of info under parametrics www.ti.com/.../msp430g2553 ), so his technically wouldn't work.

    16MHz is the maximum processor frequency of the MSP430G2553. The actual processor frequency depends on the register settings in the Basic Clock Module.

    If the program doesn't change the Basic Clock Module register, then the program will run with a nominal processor frequency of 1MHz, as set by the power-on reset value in the Basic Clock Module registers.

    Does your code configure the Basic Clock Module to set the processor frequency?

    [The information memory in the MSP430G2553 has the BCSCTL1 and DCOCTL settings for calibrated processor frequencies of 1MHz, 8MHz, 12MHz and 16MHz]

  • I looked through my notes from class and it did not mention the nominal 1 Mhz. My partner is the one who started writing this program to start so he might have known that and never told me though.

    Its good to know, as we did not tinker with the clocks on this project. That means the post from above that mentioned the 1000000ish frequency was correct.

    Thank you. (Already submitted my report, but it may be nice to see the circuit in action again with this info and the small corrections I made to it)

  • "I looked through my notes from class and it did not mention the nominal 1 Mhz. "
    On this MSP, the typical default frequency is ~1.05MHz, bu tit varies by temperature and supply voltage and between different devices. There are calibration constants available for some common frequencies, including 1MHz. Those are taken at production time for 3V and 25°C and are way more precise than the default DCO configuration. To use them, you have to load them from INFOA flash and store them to the proper clock system registers.

    However, timers are way better than counting loops, as they precisely count clock cycles and the CPU can do other things in the meantime (or even go to low-power sleep). With a timer, you can even keep your interval time if the CPU has to do some complex stuff in each interval and you don't know how long it takes. Start the timer when you start the job and when done, the timer has already accounted for the code execution time and tells you how much time remains in this interval (or wakes you when the next action is due).

**Attention** This is a public forum