logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[ATmega16][C] konwersja liczby bin na dec

Krzysiek_k1984 14 Cze 2008 00:55 3638 4
REKLAMA
  • #1 5244184
    Krzysiek_k1984
    Poziom 13  
    Witam.

    Nie potrafię poradzić sobie z takim problemem. Chciałem zamienić liczbę BIN na DEC, ale coś mi nie wychodzi. Problem polega na tym, że te bity wysyłane są po magistrali CAN, a dokładniej chodzi o bity DLC w polu sterującym (DLC0 - najmłodszy bit). Zczytuje je i dzięki nim obliczę ile bajtów będzie zawierało następne pole z danymi. Dodatkowym problemem jest fakt, że jeśli na magistrali CAN wystąpi po sobie 5 identycznych bitów to ciąg bitów uzupełniany jest bitem szpikującym o przeciwnej wartości. Nie jest on później brany pod uwagę przez uC. Tak więc jeśli w polu arbitrażu wystąpiły np. 3 bity dominujące ('0'), w polu sterującym bity IDE i r0 też będą dominujące to "kod długości danych" nie będzie 4, ale 5 bitowy. Ten 1 bit nie będzie brany pod uwagę. Napisałem taki program, ale niestety błędnie zamienia on na DEC. Proszę więc o pomoc.

    
    //oblicza długość pola danych z bitów DLC w polu sterującym
    		if(CAN_bit>(14+i && CAN_bit<=(18+i)))//pomija bity IDE i r0
    		{	
    			unsigned char suma_DLC=1;		//wartość z 4 bitów DLC
    			unsigned char bit=3;			//4 bity DLC - od 2^3 od 2^0
    
    			//sprawdza czy bit nie jest bitem szpikującym
    if((ramka_CAN[CAN_bit-1]+ramka_CAN[CAN_bit-2]+ramka_CAN[CAN_bit-3]+ramka_CAN[CAN_bit-4]+ramka_CAN[CAN_bit-5]!=0)	||(ramka_CAN[CAN_bit-1]+ramka_CAN[CAN_bit-2]+ramka_CAN[CAN_bit-3]+ramka_CAN[CAN_bit-4]+ramka_CAN[CAN_bit-5]!=5))
    			{
    				if(ramka_CAN[CAN_bit]==1)	//jeżeli bit recesywny
    				{	
    					char j;				
    					
    					suma_DLC=1;
    					for(j=1;j<=bit;j++)		//potęgowanie liczby 2 w celu
    					suma_DLC=suma_DLC*2;	//obliczenia liczby bajtów danych
    				}
    				bit--;
    			}
    			CAN_data=(suma_DLC*8);			//ilość bitów w polu danych
    		}
    


    ramka_CAN[CAN_bit] - bit jaki znajduje się w danej chwili na magistrali
  • REKLAMA
  • #2 5245606
    Jarkon2
    Poziom 25  
    konwersja liczby bin na dec - może to ci pomoże:
    
    ;****************************************************************************
    ;*
    ;* "bin2BCD16" - 16-bit Binary to BCD conversion
    ;*
    ;* This subroutine converts a 16-bit number (fbinH:fbinL) to a 5-digit 
    ;* packed BCD number represented by 3 bytes (tBCD2:tBCD1:tBCD0).
    ;* MSD of the 5-digit number is placed in the lowermost nibble of tBCD2.
    ;*  
    ;* Number of words	:25
    ;* Number of cycles	:751/768 (Min/Max)
    ;* Low registers used	:3 (tBCD0,tBCD1,tBCD2) 
    ;* High registers used  :4(fbinL,fbinH,cnt16a,tmp16a)	
    ;* Pointers used	:Z
    ;*
    ;****************************************************************************
    
    ;***** Subroutine Register Variables
    
    .equ	AtBCD0	=13		;address of tBCD0
    .equ	AtBCD2	=15		;address of tBCD1
    
    .def	tBCD0	=r13		;BCD value digits 1 and 0
    .def	tBCD1	=r14		;BCD value digits 3 and 2
    .def	tBCD2	=r15		;BCD value digit 4
    .def	fbinL	=r16		;binary value Low byte
    .def	fbinH	=r17		;binary value High byte
    .def	cnt16a	=r18		;loop counter
    .def	tmp16a	=r19		;temporary value
    
    ;***** Code
    
    bin2BCD16:
    	ldi	cnt16a,16	;Init loop counter	
    	clr	tBCD2		;clear result (3 bytes)
    	clr	tBCD1		
    	clr	tBCD0		
    	clr	ZH		;clear ZH (not needed for AT90Sxx0x)
    bBCDx_1:lsl	fbinL		;shift input value
    	rol	fbinH		;through all bytes
    	rol	tBCD0		;
    	rol	tBCD1
    	rol	tBCD2
    	dec	cnt16a		;decrement loop counter
    	brne	bBCDx_2		;if counter not zero
    	ret			;   return
    
    bBCDx_2:ldi	r30,AtBCD2+1	;Z points to result MSB + 1
    bBCDx_3:
    	ld	tmp16a,-Z	;get (Z) with pre-decrement
    ;----------------------------------------------------------------
    ;For AT90Sxx0x, substitute the above line with:
    ;
    ;	dec	ZL
    ;	ld	tmp16a,Z
    ;
    ;----------------------------------------------------------------
    	subi	tmp16a,-$03	;add 0x03
    	sbrc	tmp16a,3	;if bit 3 not clear
    	st	Z,tmp16a	;	store back
    	ld	tmp16a,Z	;get (Z)
    	subi	tmp16a,-$30	;add 0x30
    	sbrc	tmp16a,7	;if bit 7 not clear
    	st	Z,tmp16a	;	store back
    	cpi	ZL,AtBCD0	;done all three?
    	brne	bBCDx_3		;loop again if not
    	rjmp	bBCDx_1		
    ;****************************************************************************
  • REKLAMA
  • Pomocny post
    #3 5252123
    Konto nie istnieje
    Konto nie istnieje  
  • REKLAMA
  • #4 5252429
    Krzysiek_k1984
    Poziom 13  
    Właśnie, że taki przypadek też jest brany pod uwagę ;) Wyśle Ci kod na PW.
  • #5 5254727
    Krzysiek_k1984
    Poziom 13  
    Dzięki Żabek za pomoc ;) Drobne poprawki i teraz powinno śmigać.
REKLAMA