Thanks a lot Richard.
The fog lifts somehow a little bit....
I'll give it a try with y 18F 👍
Thanks a lot Richard.
The fog lifts somehow a little bit....
I'll give it a try with y 18F 👍
Last edited by flotulopex; - 20th November 2023 at 09:36.
Roger
is this more clear ?
draws a 7x5 chr A and 14x10 A in a 72x40 window located @ x=0y=0 after clearing screen [ outside of window is just random noise ]
here's a pic on a 128x64 screen , there is no telling how it line up for your screen
#CONFIG __config _INTRC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOD_ON & _IESO_ON & _FCMEN_ON
#ENDCONFIG
define OSC 8
OSCCON = 110000 'Internal RC set to 8MHZ
'ANSEL = 000000 'Select analog inputs Channels 0 to 7 (AN2 + AN4 selected)
'ANSELH = 000000 'Select analog inputs Channels 8 to 11
'TRISB = 000000 'Set Input/Output (4 to 7)
'PORTB = 000000 'Ports High/Low (4 to 7)
' ====== VARIABLES ================================================== ===============================
I2CDevice var byte
SDA VAR PORTB.6 ' I2C Data
SCL VAR PORTB.4 ' I2C Clock
LCD_DATA VAR BYTE
COM VAR BYTE ' COMMAND
I VAR BYTE
J VAR BYTE
X VAR BYTE 'LCD POSITION X(0 TO 127)
Y VAR BYTE 'LCD POSITION Y(0 TO 7)
' ====== INITIALIZE VARIABLES ================================================== ====================
I2CDevice = $78
'======= SSD1306 I2C OLED initialization ================================================== =========
COM = $AE : GOSUB SEND_COMMAND ' turn off oled panel
COM = $D5 : GOSUB SEND_COMMAND ' set display clock divide ratio/oscillator frequency
COM = $80 : GOSUB SEND_COMMAND ' set divide ratio
COM = $A8 : GOSUB SEND_COMMAND ' set multiplex ratio
COM = $3F : GOSUB SEND_COMMAND ' 1/40 duty
COM = $D3 : GOSUB SEND_COMMAND ' set display offset
COM = $0 : GOSUB SEND_COMMAND
COM = $20 : GOSUB SEND_COMMAND
COM = $0 : GOSUB SEND_COMMAND
COM = $AD : GOSUB SEND_COMMAND ' Internal IREF Setting
COM = $30 : GOSUB SEND_COMMAND ' --
COM = $8D : GOSUB SEND_COMMAND ' set Charge Pump enable/disable
COM = $14 : GOSUB SEND_COMMAND ' set(0x10) disable
COM = $40 : GOSUB SEND_COMMAND ' set start line address
COM = $A6 : GOSUB SEND_COMMAND ' set normal display
COM = $A4 : GOSUB SEND_COMMAND ' Disable Entire Display On
COM = $A1 : GOSUB SEND_COMMAND ' set segment re-map 128 to 0
COM = $C8 : GOSUB SEND_COMMAND ' Set COM Output Scan Direction 64 to 0
COM = $DA : GOSUB SEND_COMMAND ' set com pins hardware configuration
COM = $12 : GOSUB SEND_COMMAND '
COM = $81 : GOSUB SEND_COMMAND ' set contrast control register
COM = $7F : GOSUB SEND_COMMAND '
COM = $D9 : GOSUB SEND_COMMAND ' set pre-charge period
COM = $22 : GOSUB SEND_COMMAND '
COM = $DB : GOSUB SEND_COMMAND ' set vcomh
COM = $40 : GOSUB SEND_COMMAND '
COM = $AF : GOSUB SEND_COMMAND ' turn on oled panel
' ====== PROGRAM ================================================== =================================
GOSUB CLEAR_LCD
MAIN:
;7x5 "A"
X = 15 : Y = 0 : GOSUB SET_7
I2CWrite SDA,SCL,I2CDevice,[$40,$fc,$12,$12,$12,$fc]
;14x10 "A"
X = 15 : Y = 2 : GOSUB SET_14
I2CWrite SDA,SCL,I2CDevice,[$40,$f0,$f8,12,12,14,14,12,12,$f8,$f0_
,$ff,$ff,6,6,6,6,6,6,$ff,$ff]
PAUSE 1000
GOTO MAIN
END
' ====== CLEAR LCD ================================================== ===============================
CLEAR_LCD:
COM = $21 : GOSUB SEND_COMMAND
COM = 0 : GOSUB SEND_COMMAND
COM = 71 : GOSUB SEND_COMMAND
COM = $22 : GOSUB SEND_COMMAND
COM = 0 : GOSUB SEND_COMMAND
COM = 4 : GOSUB SEND_COMMAND
LCD_DATA = $00
FOR J = 0 TO 4
FOR I = 0 TO 71
I2CWrite SDA,SCL,I2CDevice,[$40,LCD_DATA]
NEXT I
NEXT J
RETURN
' ====== SEND COMMAND ================================================== ============================
SEND_COMMAND:
I2CWrite SDA,SCL,I2CDevice,[0,COM]
RETURN
'======= SET_XY ================================================== ==================================
SET_7: '7x5
COM = $21 : GOSUB SEND_COMMAND
COM = X : GOSUB SEND_COMMAND
COM = x+4 : GOSUB SEND_COMMAND
COM = $22 : GOSUB SEND_COMMAND
COM = Y : GOSUB SEND_COMMAND
COM = y : GOSUB SEND_COMMAND
RETURN
SET_14: ;14x10
COM = $21 : GOSUB SEND_COMMAND
COM = X : GOSUB SEND_COMMAND
COM = x+9 : GOSUB SEND_COMMAND
COM = $22 : GOSUB SEND_COMMAND
COM = Y : GOSUB SEND_COMMAND
COM = y+1 : GOSUB SEND_COMMAND
RETURN
Last edited by richard; - 22nd November 2023 at 02:14.
Warning I'm not a teacher
Thanks a lot Richard.
I'll give it a try asap![]()
Roger
Voilą.
As no caracter would display, I changed the fill caracter in the CLEAR routine to make someting visible.
Code:' ====== CLEAR LCD ================================================================================= CLEAR_LCD: COM = $21 : GOSUB SEND_COMMAND ' set column address COM = 0 : GOSUB SEND_COMMAND ' column start address COM = 71 : GOSUB SEND_COMMAND ' column end address COM = $22 : GOSUB SEND_COMMAND ' set page address COM = 0 : GOSUB SEND_COMMAND ' page start address COM = 4 : GOSUB SEND_COMMAND ' page end address FOR J = 0 TO 4 FOR I = 0 TO 71 I2CWrite SDA,SCL,I2CDevice,[$40,$FF] NEXT I NEXT J RETURN
Roger
BTW, the number of pixels displayed is 50x20
![]()
Roger
are you using my exact code ?
there are many changes from your orig code including swapping over the scl/sda pins to suit my dev board
i doubt the pullup resistors are needed most modules have then already installed
change
COM = $40 : GOSUB SEND_COMMAND ' set start line address
to
COM = $67 : GOSUB SEND_COMMAND ' set start line address
it looks like display is mapped onto last 5 pages of ram array
Warning I'm not a teacher
Absolutely!Are you using my exact code ?
With this "untouched" code, I get this display:
Then, with the new value of $67, here is what I get:
![]()
Roger
Hi Richard, & all others in the post.
I've just started out with my OLED display, writing in PIC assembler so I'm presently reading the fine-print on the SSD1306 datasheet to ensure I leave no bits un-turned. I'm cross-referencing my program to others I've found, albeit none in assembler, as such I joined the forum to maybe smooth any glitches I stumble across as this discussion seems rather detailed.
Although the datasheet shows an approximate Initialise flowchart, I've noticed a few differences (in order) between some of the subroutines I've found:
An interesting one within the datasheet informs the Set-Charge-Pump command (8Dh) should be followed by the Display On (AFh) command, has yours been okay as such in your Richard?
Your 'set lower column address' & 'set higher column address', should these variables not be preceded with the actual 'Set Column Address' command, 21h?
Also, the 'Internal IREF Setting' command ($AD) , where in the datasheet is that command listed, I can find ample references to the Iref current & the calcs etc but can'f find the actual command.
If your sequence has proved okay, I'll use its order as a reference to set mine up, although I'll set Segment-0 as column-0 just to get it up & running then make changes as required.
Albeit writes to my CGRAM showed a blank display, as such I've yet to find if it's either my I2C timing (I'm bit banging), (OR) my actual programming sequence, hence firstly confirming the Initialise sequence.
This is my sequence;
0AEh ; Set Display OFF. AE h = display OFF, while AF= display ON.
0D5h ; Set Display Clock Divide Ratio/ Oscillator Frequency.
80h ; (value)
0A8h ; Set Multiplex Ratio.
3Fh ; (value)
40h ; Set Display Start Line (row) 0 - 63 (40h 7Fh). [as I'm using the 64x32 display]
20h ; Set Memory Addressing Mode;
00h ; Three choices, I use the Horizontal mode.
21h ; Set Column Address;
00h ; Column start address (0 for me)
3Fh ; Column end address (63 for me) [as I'm using the 64x32 display]
22h ; Set Page Address;
00h ; PAGE start address (0 for me).
03h ; PAGE end address (3 for me). [as I'm using the 64x32 display]
81h ; Set Contrast Control.
0CFh ; (value)
0D9h ; Set Pre-charge period.
0F1h ; (value)
0DBh ; Set VCOMH Deselect Level.
40h ; (value)
0A4h ; Entire display on. A4h= Display as per RAM content. A5h= Display is ON, **BUT** unafected by changes to RAM content.
0A6h ; Set Normal/Inverse Display. A6h= normal, A7h= inverse.
0x8D ; Set charge pump;
0x14 ; (value) - ON
0AFh ; Turn Display ON.
Mark.
------------
'======= SSD1306 I2C OLED initialization ================================================== =========
COM = $AE : GOSUB SEND_COMMAND ' turn off OLED panel
COM = $D5 : GOSUB SEND_COMMAND ' set display clock divide ratio/oscillator frequency
COM = $F0 : GOSUB SEND_COMMAND ' set divide ratio
COM = $A8 : GOSUB SEND_COMMAND ' set multiplex ratio
COM = $27 : GOSUB SEND_COMMAND ' 1/40 duty
COM = $D3 : GOSUB SEND_COMMAND ' set display offset
COM = $00 : GOSUB SEND_COMMAND
COM = $40 : GOSUB SEND_COMMAND ' set display start line
COM = $8D : GOSUB SEND_COMMAND ' set Charge Pump enable/disable
COM = $14 : GOSUB SEND_COMMAND ' set(0x10) disable
COM = $20 : GOSUB SEND_COMMAND ' Addressing Setting Command Table
COM = $00 : GOSUB SEND_COMMAND ' Page Addressing Mode
COM = $A1 : GOSUB SEND_COMMAND ' set segment re-map: column address 127 is mapped to SEG0
COM = $C8 : GOSUB SEND_COMMAND ' Set COM Output Scan Direction 64 to 0
COM = $DA : GOSUB SEND_COMMAND ' set com pins hardware configuration
COM = $12 : GOSUB SEND_COMMAND ' Sequential COM pin configuration
COM = $AD : GOSUB SEND_COMMAND ' Internal IREF Setting
COM = $30 : GOSUB SEND_COMMAND ' --
COM = $81 : GOSUB SEND_COMMAND ' set contrast control register
COM = $2F : GOSUB SEND_COMMAND ' set contrast value 0..255
COM = $D9 : GOSUB SEND_COMMAND ' set pre-charge period
COM = $22 : GOSUB SEND_COMMAND ' set pre-charge value
COM = $DB : GOSUB SEND_COMMAND ' set vcomh deselect level
COM = $20 : GOSUB SEND_COMMAND ' set vcomh value
COM = $A4 : GOSUB SEND_COMMAND ' Disable Entire Display On
COM = $A6 : GOSUB SEND_COMMAND ' set normal display
COM = $0C : GOSUB SEND_COMMAND ' set lower column address
COM = $11 : GOSUB SEND_COMMAND ' set higher column address
COM = $68 : GOSUB SEND_COMMAND ' set display start line register
COM = $AF : GOSUB SEND_COMMAND ' turn on OLED panel
no , that is setting the offset of the actual display as it is overlaid into the memory mapYour 'set lower column address' & 'set higher column address', should these variables not be preceded with the actual 'Set Column Address' command, 21h?
its probably not a command at all but a data value that followed the contrast command that's become dislodged in space and time.Also, the 'Internal IREF Setting' command ($AD) , where in the datasheet is that command listed, I can find ample references to the Iref current & the calcs etc but can'f find the actual command.
Warning I'm not a teacher
I've just realised I'd wrote your name Richard, instead of Rogers, as it was his initialisation listing I was querying, no worry.
I see one of Roger's later posts shows the two subsequent bytes, as with the subsequent Page Address command ($22) two bytes.
The Internal IREF Setting' command ($AD), appears to be listed on older pdf's for the 72x40 type(?), a command not required on later board as set by a resistor.
I've sorted my glitch out, copying a double-byte send I2C section to create the triple byte I'd overlooked the unwanted I2C_Stop call before sending the 3rd byte, so was never seeing it.
Code:;====== call I2C_Start call I2C_Address movlw 00h ; 00=Command stream. movwf I2C_Command_or_Data call I2C_byte movlw 21h ;Column Address; movwf I2C_Command_or_Data call I2C_byte movlw 00h ; Low column. movwf I2C_Command_or_Data call I2C_byte movlw 3Fh ; High column. movwf I2C_Command_or_Data call I2C_byte call I2C_Stop ; ;====== call I2C_Start call I2C_Address movlw 00h ; 00=Command stream. movwf I2C_Command_or_Data call I2C_byte movlw 22h ;[3] Page Address; movwf I2C_Command_or_Data call I2C_byte movlw 00h ; Start page. movwf I2C_Command_or_Data call I2C_byte movlw 03h ; End page. movwf I2C_Command_or_Data call I2C_byte call I2C_Stop ; I2C_Start ;-- Start -- bcf PORTA,SDA ;START commence, call _nops bcf PORTA,SCK ; START complete. return I2C_Address ;-- Address_byte -- ;= 78h (bit [0] = R/W. Writing, so = 0. bcf PORTA,SDA ;bit 7 call clk_it bsf PORTA,SDA ;bit 6 call clk_it bsf PORTA,SDA ;bit 5 call clk_it bsf PORTA,SDA ;bit 4 call clk_it bsf PORTA,SDA ;bit 3 call clk_it bcf PORTA,SDA ;bit 2 call clk_it bcf PORTA,SDA ;bit 1 call clk_it bcf PORTA,SDA ;bit 0 (R/W bit) call clk_it ; return ; I2C_Ack ;-- Ack -- bsf STATUS,RP0 ;Page 1. bsf TRISA,SDA ;Set as input to release the line bcf STATUS,RP0 ;Page 0. call clk_it bsf STATUS,RP0 ;Page 1. bcf TRISA,SDA ;Set back to output. bcf STATUS,RP0 ;Page 0. return ; I2C_byte ;-- Command or Data byte -- movlw 08h movwf countbits ;count the 8 bits RLF byte_bits btfss I2C_Command_or_Data,7 goto low_bit1 bsf PORTA,SDA goto _clk1 low_bit1 bcf PORTA,SDA _clk1 call clk_it decfsz countbits,same goto _rlf goto I2C_Ack ;return _rlf rlf I2C_Command_or_Data goto byte_bits ; I2C_Stop ;-- Stop -- bcf PORTA,SDA ;Before STOP, ensure its low. call _nops bsf PORTA,SCK ;STOP commence, call _nops bsf PORTA,SDA ; STOP completed. ; call _nops call d50mS return ;I2C over.
Bookmarks