AND/OR [ASM]
AND/OR [ASM]
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
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
> 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!
*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!
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.//Emil
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
;------------------------------------
Senast redigerad av Korken 6 maj 2007, 19:39:06, redigerad totalt 2 gånger.
Det går fint, det händer bara inget.sodjan skrev:Är detta verkligen det minsta möjliga test-case som visar problemet ?
Därför att den är så basic (mästadels bara cbi/sbi) så det finns inte så mycket att komentera.sodjan skrev:Hur fasen klarar du själv av att ha koll på koden utan en enda kommentar !!??
Funderar på att komentera så får väll göra det.

Hehe, glömde det.sodjan skrev:Och, vad är det för LCD ??
(Jag kan gissa med ledning av koden...)
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
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 ?
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 ?