سلام
این کتابخونه glcdKS108 بدونه مورد برای سری قبلی AVR ها بخوبی کار میکنه ولی متاسفانه با سری Xmega عملکرد خوبی نشون نمیده .
مشکل زمانی بروز میکنه که چندتا اینتراپت فعال بشن در این حالت امکان بهم ریختگی بوجود میاد
از روی مطالبی که تو سایت mcselec بود تو کتابخونه glcdKS108.lib هم @genus رو مقدارش رو تا دو برابر اضافه کردام ولی باز هم مشکل وجود داره
توی نسخه 2.0.7.7 این مشکل رو مثل اینکه درست شده
این کتابخونه glcdKS108 بدونه مورد برای سری قبلی AVR ها بخوبی کار میکنه ولی متاسفانه با سری Xmega عملکرد خوبی نشون نمیده .
مشکل زمانی بروز میکنه که چندتا اینتراپت فعال بشن در این حالت امکان بهم ریختگی بوجود میاد
از روی مطالبی که تو سایت mcselec بود تو کتابخونه glcdKS108.lib هم @genus رو مقدارش رو تا دو برابر اضافه کردام ولی باز هم مشکل وجود داره
توی نسخه 2.0.7.7 این مشکل رو مثل اینکه درست شده
کد:
Copyright = Mcs Electronics Www = Http ://Www.mcselec.com Email = Avr@mcselec.com Comment = KS0108 Graphic Display Library for 128 * 64 Libversion = 1.11.9.8 Date = 1 Okt 2003 Statement = No Source Code From The Library May Be Distributed In Any Form Statement = Of Course This Does Not Apply For The Compiled Code When You Have A Bascom -avr License History= special thanks to Bob Gardner who got me a display history=changed timing for higher crystals history=added init_lcd label to support INITLCD command history=added support for CLS with optional clear of line history=added rampz check for > 64KB chips history= R23 is replaced by r11 because r23 might be used in case you use an extended port for control [_GLCD] $EXTERNAL _LPMBYTE _set_display: Clr r20 rcall _SelChip * Cbi _glcd_portm , _glcd_reset ; Reset * Sbi _glcd_portm , _glcd_rd * Cbi _glcd_portm, _glcd_enable Ldi r24,100 ; reset 100 mS Clr R25 * Call _waitms ser r25 * Out _glcd_port_ddr , R25 ; Make Output Port * Sbi _glcd_portm , _glcd_reset ; Reset High _set_display1: Rcall _gRead_Status sbrc r1,4 rjmp _set_display1 rcall _Init_display ser r20 rcall _SelChip _Init_display: _Init_lcd: ldi r24,$3F rcall _gwrite_cmd ldi r24,$C0 rcall _gwrite_cmd ldi r24,$40 rcall _gwrite_cmd ldi r24,$B8 rjmp _gwrite_cmd ; return from there ;ret _selChip: Cpi r20,64 ; check column Brlo _selChip2 ; smaller then 64 _selChip1: * sbi _glcd_portm , _glcd_ce ; select the SECOND chip * cbi _glcd_portm , _glcd_ce2 subi r20,64 ret _selChip2: ; do not confuse labelname with CHIP * sbi _glcd_portm , _glcd_ce2 * cbi _glcd_portm , _glcd_ce ; select the FIRST chip ret _gwrite_cmd: * Cbi _glcd_portm , _glcd_cd ; Command Rjmp _Gwrite_DataMisc ; same code _gwrite_data: * Sbi _glcd_portm , _glcd_cd ; Data _gwrite_datamisc: @genus(5) * Out _glcd_port , R24 ; Write * Cbi _glcd_portm , _glcd_rd ; Write Low * Sbi _glcd_portm , _glcd_enable ; Enable Chip @genus(2) * Cbi _glcd_portm , _glcd_enable ; Disable Chip ;rcall _gRead_Status Ret _gRead_Status: * Cbi _glcd_portm , _glcd_cd ; Status Rcall _gRead_data1 sbrc r1,7 rjmp _gRead_Status Ret _gRead_data: * Sbi _glcd_portm , _glcd_cd ; Data _gRead_data1: clr r25 * Out _glcd_port_ddr, R25 ; read direction Ser r25 * Out _glcd_port , R25 ; read pull ups high @genus(5) * Sbi _glcd_portm , _glcd_rd ; read High * Sbi _glcd_portm , _glcd_enable ; Enable Chip @genus(2) * In r1, _glcd_port_in ; get byte * Cbi _glcd_portm , _glcd_enable ; Disable Chip * Out _glcd_port_ddr, R25 ; write direction ret ;there is no difference between clear text and clear graphics! _clear_graph: _clear_text: clr r20 rcall _selchip rcall _clear_graph3 ser r20 rcall _selchip _clear_graph3: Ldi r16, 0 ; 8 pages _clear_graph2: Ldi r24,64 Rcall _gwrite_cmd ; address 0 Ldi r24,&B10111000 ; page 0 Add r24,r16 Rcall _gwrite_cmd Ldi r17,64 _clear_graph1: CLr r24 rcall _GWrite_data ; write 0 Dec r17 Brne _clear_graph1 ; write 64 times Inc r16 Cpi r16,8 Brne _clear_graph2 ret ;character in r24 ;in order to draw multiple fontsizes the fontdata stores the ;number of bytes and the number of rows. _gwrite_lcdchar: $EXTERNAL _LPMBYTE, _MUL8, _GLOCATE Push r30 ; save registers Push r31 #IF _ROMSIZE>65536 In R1, RAMPZ Push R1 ; save rampz #ENDIF * lds r21,{___lcdrow} ; the row Y push r21 ; save it * lds r7,{___lcdcol} * Lds r30 ,{___fonttable} ; start of font data * Lds r31 ,{___fonttable +1} *#IF _ROMSIZE>65536 ;* Clr r0 ; temp reg ;* lsl R30 ; shift to left ;* Rol r31 ; rotate left with carry ;* Rol R0 ; MSB of address is in R0 LS bit ;* Out RAMPZ, R0 ; set the page * Lds r0,{___fonttable +2} ; load page number for the used font * Out RampZ,r0 ; set page number *#ENDIF call _lpmbyte ; get Y bytes 1 for example mov r18,r0 ; save Y call _lpmbyte ; get X bytes , 8 for an 8*8 font mov r19,r0 ; save X call _lpmbyte ; get blocksize mov r16,r0 ; in accu ; adiw r30,1 ; adjust for words call _lpmbyte ; get true type option subi r24,32 ; chars start at 32 (space) mov r20,r24 call _mul8 ; get offset Add r30,r20 ; add to start of font data Adc r31,r21 #IF _ROMSIZE>65536 rcall _glcd_rampcheck_inc ; check boundery #ENDIF _gwrite_lcdchar_rows: sts {___lcdcol},r7 ; restore column mov r11,r19 ; x bytes (8) _gwrite_lcdchar1: lds r20,{___lcdcol} lds r21,{___lcdrow} rcall _Glocate call _lpmbyte ; get byte mov r24,r0 ;-------- lds r21,{___LCDrev} ; reverse display? tst r21 breq _gwrite_lcdchar3 com r24 ; not 0 so complement _gwrite_lcdchar3: ;-------- rcall _GWrite_data ; write char data lds r21,{___lcdcol} ; increase column inc r21 sts {___lcdcol},r21 ; save column dec r11 ; dec bytes dones brne _gwrite_lcdchar1 ; not ready *lds r21,{___lcdrow} ; inc row inc r21 * sts {___lcdrow},r21 dec r18 ; dec rows brne _gwrite_lcdchar_rows ; for all rows pop r21 ; get original row back * sts {___lcdrow},r21 ; restore #IF _ROMSIZE>65536 Pop R1 ; get rampz back Out RAMPZ,R1 #ENDIF Pop R31 Pop R30 ret #IF _ROMSIZE>65536 _glcd_rampcheck_inc: Brcc _glcd_rampcheck_inc1 ; no boundery In R2,RAMPZ Inc R2 Out RAMPZ,R2 _glcd_rampcheck_inc1: ret _glcd_rampcheck_dec: Brcc _glcd_rampcheck_dec1 ; no boundery In R2,RAMPZ Dec R2 Out RAMPZ,R2 _glcd_rampcheck_dec1: ret #ENDIF [END] [_GLOCATE] ; called with R20 X/column R21 row/Y _glocate: Dec r20 ; adjust Dec r21 ; adjust _setcol: rcall _selChip ldi r24,&B10111000 add r24,r21 ; add X rcall _GWrite_cmd ; page address Ldi r24,64 Add r24,R20 ; add Y rjmp _GWrite_cmd [END] ;r22 - x2 ;r20- x1 ;r21 - y [_CLS_LINE] $EXTERNAL _GLOCATE _Cls_Line: inc r22 push r20 push r21 rcall _glocate ; select right location pop r21 pop r20 _Cls_Line_loop: lds r24,{___LCDrev} ;read value to use from reverse rcall _gwrite_data ; clear inc r20 cpi r20,65 brne _Cls_Line2 push r20 rcall _glocate ; select right location pop r20 _Cls_Line2: cp r20,r22 brlo _Cls_Line_loop Ret [END] [_GPIXEL] $EXTERNAL _DIV8 , _GLOCATE , _ADJUST_PIN ; set or reset a single pixel ; X=R20 , Y=R21 , R25 is on/off _gpixel: Push r0 Push r1 Push r2 Push r3 Push r16 Push r25 Push r20 Mov r16,r21 ; row Ldi R20 , 8 ; 8 Bits In Byte call _Div8 ; r16 contains proper Y/row address now Mov r0, r24 ; save remainder Pop r20 ; get X back Mov r21,r16 ; y data location mov r2,r20 ; save for later mov r3,r21 rcall _setcol ; use the code from locate rcall _gread_data ; return data in r1 rcall _gread_data ; return data in r1 DO NOT REMOVE !!! mov r20,r2 mov r21,r3 rcall _setcol ; use the code from locate Mov r24,r0 ; remainder call _Adjust_pin ; Pop r16 ;param r25 tst r16 breq _gpixel_clear or r1,r24 rjmp _gpixel_set _gpixel_clear: and r1,r25 _gpixel_set: mov r24,r1 rcall _GWrite_data ; write data Pop r16 Pop r3 Pop r2 Pop r1 Pop r0 ret [END] [_getbytefromrom_eprom] $EXTERNAL _READEEPROM, _LPMBYTE ; get a byte from code ROM or from EEPROM ;you could write code to get the data from an external EEPROM _getbytefromrom: Tst R11 ; is it 0 ? Breq _GetByteFromROM1 ; yes get from flash Clr R26 ; point to R0 Clr R27 jmp _ReadEEPROM1 ; get data in r0 _getbytefromrom1: jmp _LpmByte ; returns data in r0 [END] [_showpicture] $EXTERNAL _DIV8 , _MUL8 , _GETBYTEFROMROM_EPROM , _GLOCATE ; RLE encoded. When the data after the byte is AA, it means it is a repeating ; sequence and the byte after it hold the number of repeats ; AB, AC , AF,AA, EE means show AB,AC and AF EE times ; needs more code but needs less picture data! ; show a picture with ShowPic x,y , label ; y+2 holds X, y+1 holds Y , y+0 holds EPROM/ROM flag, Z points to picture data ; The calling code uses for example ; clr r20 ; clr r21 ; st -y,r20 this way it will be referred to with y+4 ; st -y,r21 and y+3 ; ldi zl,low(plaatje * 2) to point to picture data ; ldi zh,high(plaatje * 2) ; in the SED data is stored column after column with 8 rows of data _showpicture: CLR R1 ; repeats CLR R2 ; char to repeat clr r3 ; temp register ld r11,y+ ; 255 means get from EEPROM, 0 means get from flash Call _getbytefromrom ; Get Height Of Picture In Pixels Mov r16,r0 ; Ldi r20,8 Call _Div8 ; divide by 8 St -y,r16 ; y+2 number of rows to do Call _getbytefromrom ; Get Width Of Picture In Pixels st -y,r0 ; number of cols into y+1 st -y,r0 ; number of cols into y+0 ld r16,y+3 ; get Y pos Ldi R20 , 8 Call _div8 ; Correct st y+3,r16 ; save row _showpicture1: ld r20,y+4 ; get X mov r15,r20 ld r21,y+3 ; get Y Rcall _setcol ; set address _showpicture2: ; *** New RLE encoding routine *** cp r1,r3 ; is repeats 0 ? brne _ShowPicture8 ; no Call _getbytefromrom ; Get Next Char mov r2,r0 ; save char mov r24,r0 cpi r24,&HAA ; test for repeat char must always be shown breq _ShowPicture9 ; we need to show AA Call _getbytefromrom ; Is It Rle print mov r24,r0 cpi r24,&HAA ; is it a RLE encoded char? breq _ShowPicture10 ; yes sbiw R30,1 ; no readjust pointer to graphic data #IF _ROMSIZE>65536 rcall _glcd_rampcheck_dec ; check boundery #ENDIF rjmp _ShowPicture11 ; show it _showpicture9: adiw r30,1 ; skip 0 #IF _ROMSIZE>65536 rcall _glcd_rampcheck_inc ; check boundery #ENDIF rjmp _ShowPicture11 _showpicture8: ;we are repeating dec r1 ; adjust repeat counter breq _showpicture2 rjmp _ShowPicture11 ; show it _showpicture10: Call _getbytefromrom ; Get Number Of Repeats Mov r24,r0 Tst r24 ; is it zero? Brne _showpicture15 ; no a real sequenc Sbiw r30,2 ; adjust pointer #IF _ROMSIZE>65536 rcall _glcd_rampcheck_dec ; check boundery #ENDIF Rjmp _showpicture11 ; skip somebytes _showpicture15: mov r1,r0 ; save number of repeats _showpicture11: mov r24,r2 ; *** end of RLE code *** ;-------------- * lds r25,{___LCDrev} ; reverse display? tst r25 breq _showpicture12 com r24 _showpicture12: ;--------------- push r24 mov r20,r15 ldd r21,y+3 Rcall _setcol ; set address pop r24 inc r15 rcall _Gwrite_Data ld r24,y+1 ; get column counter dec r24 st y+1,r24 ; save col counter brne _ShowPicture2 ; for all columns ld r24,y+3 ; next page inc r24 st y+3,r24 ld r24,y+0 ; get num of cols st y+1,r24 ; save for the new row ld r24,y+2 ; get row counter dec r24 st y+2,r24 brne _showpicture1 ; for all rows adiw r28,5 ; adjust soft stack Ret [END]