Sida 1 av 2

AND/OR [ASM]

Postat: 6 maj 2007, 13:04:54
av Korken
Hej alla glada!

Sitter här och försöker få vanliga bitwise operationer att fungera men lyckas inte.

Om jag vill göra som i C typ "unsigned char wee |= 0x80" hur gör man det?
Jag hittade i Atmels Blad att man nog skulle använda "and/or" men lyckas inte få det att fungera.
Skulle någon kunna tänka sig att göra ett litet snabbt exempel på hur man ska göra?

Tack ska ni ha!

//Emil

Postat: 6 maj 2007, 13:39:32
av Icecap
ORI wee,0x80

Postat: 6 maj 2007, 13:44:54
av Korken
Så det ska fungera så?

Gahh, då borde min kod fungera. Men de gör den inte.
Tillbaks till felsökningen igen då. :)

Tack ska du ha!

//Emil

Postat: 6 maj 2007, 15:22:07
av Micke_s
Är det bara en bit som du ska sätta så finns det kommandon för detta också.

Postat: 6 maj 2007, 15:44:28
av Korken
Jo, jag vet.
Sbi/cbi, men jag kombinerar 2 tal med and/or och sedan skickar jag det till en grafisk LCD för x/y position och Z adress.
Jag lyckas initiera den men inte att skriva data till den.
Så jag sitter och felsöker koden nu. :)

//Emil

Postat: 6 maj 2007, 18:12:11
av sodjan
> Så jag sitter och felsöker koden nu...

*Vilken* kod ??

Varför inte bara visa några rader som "inte fungerar" så
får du sannolikt betydligt bättre och snabbare hjälp.
Dåliga frågor ger nästan alltid dåliga svar, och i detta fall
har du i princip inte fått någon hjälp alls, du visste ju
redan att det var AND och OR instruktionerna du skulle
använda. Så upp med koden "på bordet" så får vi se!

Postat: 6 maj 2007, 18:33:18
av Korken
Jag var osäker på hur de fungerade det var därför jag frågade.

Om du vill se koden så får du vänta lite.
Skriver om lite mer än halva för stunden.

Men jag lägger upp den när jag kommit så långt.

Tack för att du är intresserad. :)

//Emil

Postat: 6 maj 2007, 18:39:19
av sodjan
Intresserad och instresserad... :-)
Jag ville bara komma med ett förslag så att du får bättre och snabbare hjälp.
Sen om *jag* kommer att kolla just AVR kod, tja... :-)

Postat: 6 maj 2007, 18:48:56
av Korken
Hehe.

Jag gillar att försöka knäcka problemen själv så brukar fråga lite kryptiskt så jag inte får hela svaret men nu har jag slagit med detta i en vecka och börjar bli trött.

Så jag tar och lägger upp koden.

Problemet är att den inte vill fylla LCDn med tecken.
Init:en fungerar men inte resten.

Koden är väldigt enkelt skriven (tror jag, nybörjare på ASM fortfarande) så den är inte speciellt välkommenterad men undras det något säg till så förklarar jag.

Kod: Markera allt

.include "C:\Program\Atmel\AVR Tools\AvrAssembler2\Appnotes\m168def.inc"

;************************************
;Variables
;- Register names
;- Constant names and values
;************************************
.def tmp 					= r16
.def tmp2					= r17
.def inst					= r20
.def data					= r21
.def x_pos					= r22
.def y_pos					= r23
.def low_delay				= r24
.def high_delay				= r25

.equ LED_PORT 				= PORTB
.equ LED_DDR 				= DDRB
.equ LCD_DATA_PORT 			= PORTD
.equ LCD_DATA_PIN 			= PIND
.equ LCD_DATA_DDR 			= DDRD
.equ LCD_CONTROL_PORT 		= PORTC
.equ LCD_CONTROL_PIN 		= PINC
.equ LCD_CONTROL_DDR 		= DDRC
.equ LCD_RS		 			= 0
.equ LCD_RW 				= 1
.equ LCD_ENABLE 			= 2
.equ LCD_CS1	 			= 3
.equ LCD_CS2 				= 4
.equ LCD_RESET				= 5
.equ LED_PIN				= 0

.equ DISPLAY_ON				= 0b00111111
.equ DISPLAY_OFF			= 0b00111110
.equ DISPLAY_LINE			= 0b11000000
.equ ADDRESS_X				= 0b01000000
.equ ADDRESS_Y				= 0b10111000
;------------------------------------


;************************************
;RESET
;- Jump to main after RESET
;************************************
.org 0x0000
	rjmp main
;------------------------------------


;************************************
;Main function
;- Sets up the Stack
;- Calls the LCD startup function
;************************************
main:
	ldi tmp, low(RAMEND)			;Set up the stack
	out SPL, tmp					;
	ldi tmp, high(RAMEND)			;
	out SPH, tmp					;
	
	rcall LCD_Init					;Call the Init function
	rcall LCD_Fill_Screen			;Fill the LCD with pixels

loop:
	rjmp loop
;------------------------------------


;************************************
;s_delay function
;- Just about 2.5 µs of delay
;************************************
s_delay:
	ldi tmp, 13

s_delay_outer_loop:
	dec tmp
	brne s_delay_outer_loop
ret
;------------------------------------


;************************************
;l_delay function
;- Just about 0.5 s of delay
;************************************
l_delay:
	ldi tmp, 16

l_delay_outer_loop:
	ldi low_delay, low(12145)
	ldi high_delay, high(12145)

l_delay_delay_loop:
	adiw low_delay, 1
	brne l_delay_delay_loop
	dec tmp
	brne l_delay_outer_loop
ret
;------------------------------------


;************************************
;LCD_Init function
;- Sets up the DDRs
;- Initializes the LCD
;************************************
LCD_Init:
	ldi tmp, 0xFF
	out LCD_CONTROL_DDR, tmp			;Set LCD_CONTROL_DDR to output
	out LCD_DATA_DDR, tmp				;Set LCD_DATA_DDR to output
	out LED_DDR, tmp					;Set LED_DDR to output

	cbi LCD_CONTROL_PORT, LCD_RESET		;Put the LCD in RESET
	rcall s_delay						;Delay 2.5µs
	sbi LCD_CONTROL_PORT, LCD_RESET		;Start up the LCD

	cbi LCD_CONTROL_PORT, LCD_CS1		;Aim at the CS1 chip
	sbi LCD_CONTROL_PORT, LCD_CS2		;
	ldi inst, DISPLAY_ON				;Send Display On to the CS1 chip
	rcall LCD_Send_Cmd

	sbi LCD_CONTROL_PORT, LCD_CS1		;Aim at the CS2 chip
	cbi LCD_CONTROL_PORT, LCD_CS2		;
	rcall LCD_Send_Cmd					;Send Display On to the CS2 chip

	sbi LCD_CONTROL_PORT, LCD_CS1		;No CS
	sbi LCD_CONTROL_PORT, LCD_CS2
ret
;------------------------------------


;************************************
;LCD_Wait function
;- Waits for the LCD to be ready for commands
;************************************
LCD_Wait:
	ldi tmp, 0x00			
	out LCD_DATA_DDR, tmp				;Make LCD_DATA_DDR to input
	cbi LCD_CONTROL_PORT, LCD_RS		;RS low
	sbi LCD_CONTROL_PORT, LCD_RW		;RW high

LCD_Wait_loop:
	sbi LCD_CONTROL_PORT, LCD_ENABLE	;Clock Enable
	rcall s_delay						
	cbi LCD_CONTROL_PORT, LCD_ENABLE	
	rcall s_delay						

	sbic LCD_DATA_PORT, 7				;If LCD isn't busy the jump next instruction
	rjmp LCD_Wait_loop
ret
;------------------------------------


;************************************
;LCD_Send_Cmd function
;- Sends a command to the LCD
;- Uses the 'inst' register for the command that's to be sent
;************************************
LCD_Send_Cmd:
	rcall LCD_Wait						;Wait for LCD to be ready for commands

	cbi LCD_CONTROL_PORT, LCD_RS		;RS low
	cbi LCD_CONTROL_PORT, LCD_RW 		;RW low

	ldi tmp, 0xFF
	out LCD_DATA_DDR, tmp				;Make LCD_DATA_DDR to output
	out LCD_DATA_PORT, inst				;Put the command on the datapins

	rcall s_delay						;Clock Enable
	sbi LCD_CONTROL_PORT, LCD_ENABLE
	rcall s_delay
	cbi LCD_CONTROL_PORT, LCD_ENABLE
	rcall s_delay
ret
;------------------------------------


;************************************
;LCD_Send_Data function
;- Sends pixel data to the LCD
;- Uses the 'data' register for the data that's to be sent
;************************************
LCD_Send_Data:
	rcall LCD_Wait						;Wait for LCD to be ready for commands

	sbi LCD_CONTROL_PORT, LCD_RS		;RS high
	cbi LCD_CONTROL_PORT, LCD_RW		;RW low
	
	ldi tmp, 0xFF
	out LCD_DATA_DDR, tmp				;Make LCD_DATA_DDR to output
	out LCD_DATA_PORT, data				;Put the data on the datapins

	rcall s_delay						;Clock Enable
	sbi LCD_CONTROL_PORT, LCD_ENABLE
	rcall s_delay
	cbi LCD_CONTROL_PORT, LCD_ENABLE
	rcall s_delay
ret
;------------------------------------


;************************************
;LCD_Set_Pos function
;- Sets the position on LCD for where to do something
;- Uses the 'x_pos' (0-127) and 'y_pos' (0-7) for positioning
;************************************
LCD_Set_Pos:
	cpi x_pos, 64						;If x_pos is lower than 64 then jump to LCD_Set_Pos_lower
	brlo LCD_Set_Pos_lower				;Else continue
	sbi LCD_CONTROL_PORT, LCD_CS1		;Aim at CS2
	cbi LCD_CONTROL_PORT, LCD_CS2
	mov tmp, x_pos						;Copy x_pos to tmp
	subi tmp, 64						;Remove 64 from tmp
	rjmp LCD_Set_Pos_next				;Jump to LCD_Set_Pos_next

LCD_Set_Pos_lower:
	cbi LCD_CONTROL_PORT, LCD_CS1		;Aim at CS1
	sbi LCD_CONTROL_PORT, LCD_CS2
	mov tmp, x_pos						;Copy x_pos to tmp

LCD_Set_Pos_next:
	ldi inst, ADDRESS_X					;Make a a bitwise OR with the ADRESS_X and tmp
	or inst, tmp
	rcall LCD_Send_Cmd					;Send it to the LCD

	ldi inst, ADDRESS_Y					;Make a a bitwise OR with the ADRESS_Y and y_pos
	or inst, y_pos
	rcall LCD_Send_Cmd					;Send it to the LCD

	ldi inst, DISPLAY_LINE				;Set Display Line (Z Adress) to first line on both chips
	sbi LCD_CONTROL_PORT, LCD_CS2
	cbi LCD_CONTROL_PORT, LCD_CS1
	rcall LCD_Send_Cmd					;Send to first chip

	sbi LCD_CONTROL_PORT, LCD_CS1
	cbi LCD_CONTROL_PORT, LCD_CS2
	rcall LCD_Send_Cmd					;Send to second chip

	cpi x_pos, 64						;Then aim at the right chip again so we can write data to it
	brlo LCD_Set_Pos_lower2
	sbi LCD_CONTROL_PORT, LCD_CS1
	cbi LCD_CONTROL_PORT, LCD_CS2
	rjmp LCD_Set_Pos_end

LCD_Set_Pos_lower2:
	cbi LCD_CONTROL_PORT, LCD_CS1
	sbi LCD_CONTROL_PORT, LCD_CS2

LCD_Set_Pos_end:
ret
;------------------------------------


;************************************
;LCD_Fill_Screen function
;- Fills the whole LCD with pixels
;************************************
LCD_Fill_Screen:						
	ldi y_pos, 0x07						;Load y_pos with 7
	ldi data, 0xFF						;Load data with 255

LCD_Fill_Screen_inner:
	ldi x_pos, 0x7F 					;Load x_pos with 127
	
LCD_Fill_Screen_outer:
	rcall LCD_Set_Pos					;Set current position
	rcall LCD_Send_Data					;Send data to that position

	dec x_pos					
	brne LCD_Fill_Screen_outer			;If x_pos != 0 do again

	dec y_pos
	brne LCD_Fill_Screen_inner			;If y_pos != 0 do again
ret
;------------------------------------
//Emil

Postat: 6 maj 2007, 19:00:11
av sodjan
OK, som sagt, jag tänker inte leta efter "felet", men bara ett par sakar...

Är detta verkligen det minsta möjliga test-case som visar problemet ?
Hur fasen klarar du själv av att ha koll på koden utan en enda kommentar !!??

Och, vad är det för LCD ??
(Jag kan gissa med ledning av koden...)

Postat: 6 maj 2007, 19:03:26
av Tekko
Ser nästan ut som en grafisk på den koden.

Postat: 6 maj 2007, 19:19:31
av Korken
sodjan skrev:Är detta verkligen det minsta möjliga test-case som visar problemet ?
Det går fint, det händer bara inget.
sodjan skrev:Hur fasen klarar du själv av att ha koll på koden utan en enda kommentar !!??
Därför att den är så basic (mästadels bara cbi/sbi) så det finns inte så mycket att komentera.
Funderar på att komentera så får väll göra det. :)
sodjan skrev:Och, vad är det för LCD ??
(Jag kan gissa med ledning av koden...)
Hehe, glömde det.
Men det är en grafisk 128x64 KS0108B display.

Kan ta och komentera lite och slänga upp den igen.

//Emil

Edit: Displayen: http://www.fractronics.com/128x64bla.shtml

Postat: 6 maj 2007, 19:37:31
av Korken
Så, har fixat komentarer på den nu.

//Emil

Postat: 6 maj 2007, 20:18:15
av sodjan
Tekko> Ser nästan ut som en grafisk på den koden...

Hm, med tanke på att Korket tidigare *skrev* att den
var grafisk, så var det kanske inte så svårt att gissa... :-)

Det jag såg var att det var dubbla CS-linor, och alltså
en av de grafiska modellerna med dubbla controlers.
Alltså måste man i koden kolla vilken "halva" av modulen
som man ska skriva till och se till att toggla rätt CS-lina...

Jag vet inte om det är i just den logiken som problemet
uppstår, men det var lite pyssligt att få det att fungera när
jag skrev en litet PIC demo till en liknande modul. Man vill
ju "dölja" att det är dubbla controllers för överliggande
(applikations-) nivå.

Jag har kollat lite snabbt och i princip är det samma programlogik
som i mitt PIC exempel. Inget uppenbart (för mig) fel. Så det
är väl bara att debugga. T.ex via ett enklare testprogram...
Är det de två OR i LCD_Set_Pos som inte (verkar) fungera ?

Postat: 6 maj 2007, 20:23:13
av Kaggen
Du har inte blandat ihop ADDRESS_X och ADDRESS_Y, om du jämför de bitar du satt i din kod för dessa och hur det ser ut i databladet?