split up a 16 number

Go To Last Post
14 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi you all

I use a calculation in my program (with decimal numbers) but the value that is calculated is offcourse decimal and bigger than 8bits.
Is there a easy way to convert this in hex and split it into two 8 bit registers.

for example:
.equ Time=300/0.05
so time is 6000 dec

I use the attiny24 and do the programming in assembly.

Can anyone give me an idea how to do this?
Thanks,
Patrick

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Do you mean you want 6,000 (0x1770) actually as 0x6000 so it can be split 0x60 and 0x00 for display? If so you are looking for binary to BCD conversion routines - many solutions posted here previously almost all will include "BCD"

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the response

I will use BCD in the search I will probably find an answer there, about the conversion.

What I mean is that decimal 6000 must be convert into hex 1770 and than split up into:
TimeLow=70
TimeHigh=17
to fill the counter

Patrick

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I use the attiny24 and do the programming in assembly.
Then what is the problem? Surely you know what registers your 16 bit number is held in, just move those registers to whatever registers you want.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Do you mean this?

.equ Time=300/0.05 

ldi r16, low(Time)
ldi r17, high(Time)
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Visovian wrote:
Do you mean this?

.equ Time=300/0.05 

ldi r16, low(Time)
ldi r17, high(Time)

Yes that is what I mean!
It looks so simple, if I understand well the 8 low bits of the caculation are placed in r16, and the 8 high bits are placed in r17.

Thank you

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
.equ Time=300/0.05

ldi r16, low(Time)
ldi r17, high(Time) 

This works fine if 300/0.05 is a constant value that never change.
I got the impression that this was a calculated value that might change, not a constant.
In that case you need another approach.

OTOH if that calculation was made in your code you would automatically get ie 6000 divided into 2 hexadecimal bytes (since that's what micro's need to work with).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

I still got a error of a invalid number.
I do something wrong with the calculation but I can not figure out what.
I'm looking at the code for a while now but with no result can anyone give me a clue again?

thanks, Patrick

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It is rather hard to find a fault
when you do not tell us what the code should do
and where it behaves bad.

I only noticed:
In folowing part you should place
"rjmp RESET" immediately after ".org $00"
to jump over reset vectors and included files.

.cseg									;code segment
.org	$00

;----------------------------------------------------
;* afhandeling interrupt routines (zie at24def.inc) *
;----------------------------------------------------

	rjmp	reset						;Reset Handler
	rjmp	reset						;IRQ0 Handler
	rjmp	reset						;PCINT0 Handler
	rjmp	reset						;PCINT1 Handler
	rjmp	reset						;Watchdog Interrupt Handler
	rjmp	reset						;Timer1 Capture Handler
	rjmp	timer1int					;Timer1 Compare A Handler
	rjmp	reset						;Timer1 Compare B Handler
	rjmp	reset						;Timer1 Overflow Handler
	rjmp	reset						;Timer0 Compare A Handler
	rjmp	reset						;Timer0 Compare B Handler
	rjmp	reset						;Timer0 Overflow Handler
	rjmp	reset						;Analog Comparator Handler
	rjmp	reset						;ADC Conversion Handler
	rjmp	reset						;EEPROM Ready Handler 
	rjmp	reset						;USI Start Handler
	rjmp	reset						;USI Overflow Handler

;** Include files met code **
.include "interrupt.asm"				;include the interrupt assembly file
;etc

;DIRECTIVEN		NAME	DEFINITION 
;#define			relay	PortA,PA6 


RESET:									;Main program start
;*** stack pointer set up ***
			ldi		temp0,low(RAMEND)
			out		SPL,temp0			;Set Stack Pointer to bottom of RAM

Edit:
But now I see that it jumps to RESET either.
Do not mind.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi

The code is made to read 2 switches and depending on the state of the switch it put output high and low.

But my problem is that if I run (assemble) the program I get a error (Invalid number).
I think this error is caused by a calculation and after the calculation I split the number up into 2 registers to fill a timer in the interrupt.

But I don't see what I'm doing wrong.
Has it something to do with the result of the calculation is a decimal number and it should be a hex number? And if this is the problem how can I solve it?
Or do I do something else wrong?

Patrick

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

I have found the problem but I still find it strange
the next part of code is not working

...
.def	temp0		=r16				;Gen.purpose
.def	TimeoutL	=r23				;
.def	TimeoutH	=r24			
...
;*** calculations for the setting ***
;*** 1 pulse = 50msec. so 1sec = 20 pulses
;*** calculation Tp = time(sec) / 0.05
;*** Maximum time is 3276sec (FFFF)

.equ	OnTime	=300/0.05					;calculate the on time
.equ	OffTime	=120/0.05				;calculate the off time
...
SwitchLoadOn:	sbi		portA,PA0			;Set output 0 high
				ldi		temp0,low(OnTime)	
				ldi		TimeoutL,temp0	;load timeoutL with the low 8 bits of the timer
				ldi		temp0,high(OnTime)
				ldi		TimeoutH,temp0	;load timeoutH with the hihg 8 bits of the timer

and this is working fine


SwitchLoadOn:	sbi		portA,PA0			;Set output 0 high
				ldi		TimeoutL,low(OnTime)	;load timeoutL with the low 8 bits of the timer
				ldi		TimeoutH,high(OnTime)	;load timeoutH with the hihg 8 bits of the timer

it goes wrong when I fill temp0 with low(OnTime) and than read the content of temp0 into TimeoutL and so on
Why is this not working and if I read low(OnTime) direct into TimeoutL it is working fine.

I think I do exatly the same only with 1 instruction less. Can anyone explain?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MOV not LDI!!

you want MOV what is in r16 to r23

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
  ldi      TimeoutH,high(OnTime)
  ldi      TimeoutL,low(OnTime)   
           ;load timeoutL with the low 8 bits of the timer            
           ;load timeoutH with the high 8 bits of the timer 

As long as TimeroutL and TimeroutH are in r16-r31 this is all you need.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

WrightFlyer wrote:
MOV not LDI!!

you want MOV what is in r16 to r23

Yep you are right!!!
thanks