|
|
View previous topic :: View next topic |
Author |
Message |
rudy
Joined: 27 Apr 2008 Posts: 168
|
ssd 1306 initialization problem |
Posted: Tue Oct 27, 2015 6:02 am |
|
|
Hi there.
The SD1306 datasheet is a mess, poor work done by SOLOMON SYSTECH unfortunately. Well, I am trying to initialize the LCD with horizontal addressing mode, but besides tons of changes and attempts, no positive results!!! The only thing I never tried is to first initialize the LCD, and after that, prior to send data, change the memory access to horizontal, I will give a shot moreover at night.
This is my procedure to initialize the LCD, is there anything wrong with this code? I inform that, apparently, everything works well, besides of no change in memory access that remains always as page access.
Any help or clue will be much appreciated.
Regards.
Code: | void lcd_init()
{
restart_wdt();
i2c_start ();
i2c_write(lcd_address); //select the display
i2c_write(lcd_cmd); //we are sending a command
i2c_write(0xAE); //S_DISPLAYOFF
i2c_write(0xD5); //S_SETDISPLAYCLOCKDIV
i2c_write(0x80); //DIV_RATIO
i2c_write(0xA8); //S_SETMULTIPLEX
i2c_write(0x3F); //MULTIPLEX
i2c_write(0xD3); //S_SETDISPLAYOFFSET
i2c_write(0x00); //NO OFFSET
i2c_write(0x7F); //S_SETSTARTLINE
i2c_write(0x8D); //S_CHARGEPUMP
i2c_write(0x14); //INT_VCC
i2c_write(0x20); //Set Memory Addressing Mode
i2c_write(0b00000000); //P=10 - H=00b - V=01
i2c_write(0x21); //COLUM REGISTER
i2c_write(0x00); //START
i2c_write(0X7F); //END
i2c_write(0x22); //PAGE REGISTER
i2c_write(0x02); //START
i2c_write(0X03); //END
i2c_write(0xb0);
i2c_write(0xA1); //S_SEGREMAP
i2c_write(0xC8); //S_COMSCANDEC
i2c_write(0xDA); //S_SETCOMPINS
i2c_write(0x12);
i2c_write(0x81); //S_SETCONTRAST
i2c_write(0xFF);
i2c_write(0xD9); //S_SETPRECHARGE
i2c_write(0xF1);
i2c_write(0xDB); //S_SETVCOMDETECT
i2c_write(0x40);
i2c_write(0xA4); //S_DISPLAYALLON_RESUME
i2c_write(0xA7); //S_NORMALDISPLAY
i2c_write(0xAF); //S_DISPLAYON
i2c_stop();
} |
|
|
|
MikeW
Joined: 15 Sep 2003 Posts: 184 Location: Warrington UK
|
|
Posted: Tue Oct 27, 2015 6:38 am |
|
|
This code works a treat.
just change for your chip, and SDA/SCL pins. no otherr changes are needed.
if it still doesnt work, its a hardware problem such as
pullup resistors etc
http://www.ccsinfo.com/forum/viewtopic.php?t=54453 |
|
|
rudy
Joined: 27 Apr 2008 Posts: 168
|
|
Posted: Tue Oct 27, 2015 6:50 am |
|
|
Mike, Thanks.
Anyway, the logo that I am trying to show only appears in the top of the LCD (PAGE 0), like the page access is always running. It don´t seem to me to be a pull up resistor problem, once that commands like Entire LCD on (at the very end of code) works very fine.
I really don´t know what to do, but there is also an RDA5807 FM radio on the line, I will take it out from SDA and SCL pins, and check how it goes.
Thank you.
Regards. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19545
|
|
Posted: Tue Oct 27, 2015 8:04 am |
|
|
If you just want to write a logo, then the 'draw_window' function in my driver, can do this for you. It just writes a block of memory (from the area defined as 'window_buffer' if you are using the graphic functions I supply), directly to any 'cell' location on the display (0-127 x 0-7). The block it transfers is defined by the 'WINDOW_WIDTH' & 'WINDOW_HEIGHT' defines, so easy to change. It is easy to rewrite.
Don't get confused by the layout of the screen. The pixels run vertically down the columns, and you advance to the next column when you get to the bottom. Switching mode will only help you if you are going to fill an entire row or column, which with a small logo is unlikely to happen. This is why the draw_window function calls the address function when it gets to the end of each column it is sending. |
|
|
rudy
Joined: 27 Apr 2008 Posts: 168
|
|
Posted: Tue Oct 27, 2015 2:24 pm |
|
|
Ttelmah, I disagree with you, a little!
Your code is good, no doubt. It clear my mind trough this mess that is the datasheet, unfortunately, and congratulations to you to find a way in this confusion.
I see that there are three different ways to address the LCD. This three ways, in my understanding, is for avoid you to move large quantities of data every time you need to update the LCD information. The horizontal and vertical memory data access is exactly to do this, depending only of the way you draw your initial image. Once you move the entire LCD initial information, with a little quantity of code, you can access any particular portion of the LCD, making small changes where needed, it is poor mentioned in datasheet, but for sure it does this.
I am sure that, once that I discover how to change this memory access mode, I will be able to do what I need. It is almost what you did in the “draw_window” function, but it is slight different. When finish I will update my approach.
Thank all anyway. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19545
|
|
Posted: Tue Oct 27, 2015 3:08 pm |
|
|
Where I disagree with you is in using horizontal address mode.
Problem is that since the data is organized vertically in the display, you end up writing eight bits vertically, then moving horizontally, across the row, and then going back to continue the next row of the character. I'd suggest that it is much easier to use the vertical mode, and complete each column in turn.
I'd say that horizontal mode only makes sense, when the display is operating rotated the other way.
Then you need to ensure that the limits are turned off after your logo is written, otherwise any subsequent write is going to wrap again.
I'd also split things up. Set the unit up, then change modes.
For instance, this is my 'contrast change' routine:
Code: |
void OLED_contrast(int8 contrast)
//Set the display current
{
i2c_start();
i2c_write(SSDADDR);
i2c_write(COMMAND_ONLY);
i2c_write(S_SETCONTRAST);
i2c_write(contrast);
i2c_stop();
}
|
Just change the mode, set the address, write the data, and set the mode back.
You also don't tell us the definitions for some of the commands you are sending?. 'COMMAND_ONLY' (in your code lcd_cmd), has to be 0, for the successive commands to work right. 0x80, which can also be used, stops the successive initialisations from working properly, when they are burst transmitted. |
|
|
rudy
Joined: 27 Apr 2008 Posts: 168
|
|
Posted: Tue Oct 27, 2015 3:31 pm |
|
|
Kkk (Leffen), ok. (This is a very good discussion, but allow me to disagree again.)
From my point of view, in VERTICAL access mode, you can go through, for example, COL 0 to COL 7 straight, in this case there shall be 64 bits directly. I see that vertical and horizontal depends only of your graphic design, better, how you generate the array of bits (bytes) to be send to LCD, just that.
Anyway, give me some time to deep check this issue, I may be wrong also. The good thing is that for sure this will help lots of people who seek for information about this subject.
Regards. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19545
|
|
Posted: Tue Oct 27, 2015 3:38 pm |
|
|
The display always _outputs_ the data one byte at a time organised vertically (in the standard organisation). You don't get 64 bits across a row, you get 64 (or 128) bytes across the row, each carrying 8 bits vertically.
So you can't send 64 bits sequentially along a row (it'd be lovely if you could). Look carefully at the output diagrams showing how the drive bits are derived from the bytes. The horizontal/vertical modes, change how you increment through the bytes, when sequential ones are sent, not how the bytes are organised on the display. Since the bytes are organised vertically, I prefer to finish each column in turn. |
|
|
rudy
Joined: 27 Apr 2008 Posts: 168
|
|
Posted: Wed Oct 28, 2015 5:10 pm |
|
|
Ttelmah, good day!
Well, I was right!!!!
I also discovered an error in the “MESS” datasheet (How many must have more..). The error is at page 34, concerning with PAGE access, as follows:
Where you read “Set the lower start column address of pointer by command 00h~0Fh.”
You must note that first segment (column) is not 0x00, but 0x01, this is also valid for 0x0F, the end column number is 0x7f or 0x80 (not tested the end column number)
Also, where you read “Set the upper start column address of pointer by command 10h~1Fh” it shall be exactly as above, someone please test all situations and update the forum. I will do it myself, but don't know when.
Regarding with the issue of PAGE, HORIZONTAL and VERTICAL Addressing mode. What I was trying to explain is that I should be able to move 1024 bytes of information in a single shot, if I started by using H or V addressing modes, depending only of the way my image was build. You can use LCDAssistant or FastLCd to do your logos, I use Windows Paint to draw and LCDAssistant to convert bitmap to my array. FastLcd don't work fine.
In my case, after initialization, you can see two lines of code, i2c_write(0x20); and i2c_write(0x00);.
The first, I am accessing register 0x20, that handles the memory access mode, the second, I move 0x00, changing to H memory access mode. Once I did that, I could move the entire 1024 bytes in just one loop, avoiding to move 128 bytes, change page, plus 128bytes and change page again till end of page 7, so my code is very light and fast.
Of course I will need to access other specific parts of the LCD, but now, and only now I will have to deal with PAGE, COLUMNS and so on, just to rebuild small parts of the image.
Try this simple example by yourself and check how it goes.
Hope to that this code helps more peoples.
Code: | #include <16f688.h>
#fuses INTRC_IO, NOWDT, NOPROTECT, NOBROWNOUT, NOMCLR, NOCPD, PUT //304C 342C
#use delay(clock = 4000000, RESTART_WDT)
#use i2c(MASTER, FAST, SDA=PIN_C5, SCL=PIN_C4, FORCE_HW)
// #include <string.h>
//#include <stdlib.h>
#define lcd_cmd 0b00000000 //next byte is a command only
#define lcd_data 0b01000000 //next byte is data
#define lcd_address 0x78 //address for the chip - usually 0x7C or 0x78.
int page = 200;
const int logo[1024] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x78, 0xC8, 0x08, 0x08, 0x08, 0x08, 0x0C, 0x04, 0x04, 0xFC, 0xFC, 0x04, 0x04, 0x04, 0x06,
0x02, 0x02, 0x02, 0x0E, 0xF8, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xF8, 0xF8, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0xF8, 0xF8, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xF8, 0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, 0xF8, 0xF8, 0xF0, 0xC0, 0x80,
0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, 0x00, 0x00, 0x00,
0x80, 0xC0, 0xE0, 0xE0, 0xF8, 0x38, 0x38, 0x18, 0x08, 0x00, 0x00, 0xF8, 0xF8, 0xF8, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0xF8, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00,
0xE0, 0xF0, 0xF8, 0x38, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x38, 0xF8, 0xF8, 0xE0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1F, 0xF0, 0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x09, 0x7F, 0xFC, 0x0C, 0x0C, 0x0C,
0x0C, 0x04, 0x04, 0x04, 0x0F, 0xF8, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x03, 0x07, 0x1F,
0x3E, 0xFC, 0xF0, 0xE0, 0x80, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3C, 0x1E, 0x0F,
0x1F, 0x3F, 0x7D, 0xF0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xC1, 0xC3, 0x87, 0x07, 0x0E, 0x0E, 0x0E, 0x1C, 0x1C, 0x1C, 0x3C, 0xF8, 0xF0, 0xE0, 0x00, 0x00,
0x00, 0x00, 0x80, 0xBF, 0xA0, 0xA0, 0xA0, 0xB0, 0x90, 0x90, 0x90, 0x90, 0x9F, 0x9C, 0x98, 0x88,
0x88, 0x88, 0x88, 0x88, 0x88, 0x8B, 0x8E, 0x80, 0x80, 0x8F, 0x8F, 0x8F, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x83, 0x87, 0x8F, 0x8E, 0x8C, 0x8C, 0x8C,
0x8C, 0x8E, 0x8F, 0x87, 0x87, 0x81, 0x80, 0x80, 0x80, 0x8F, 0x8F, 0x8F, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x81, 0x83, 0x8F, 0x8F, 0x8F, 0x8F, 0x80, 0x80, 0x80, 0x8F, 0x8F, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x81, 0x83, 0x87, 0x8F, 0x8E, 0x8C, 0x80, 0x80, 0x8F, 0x8F, 0x8F, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x8F, 0x8F, 0x8F, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x83, 0x87, 0x8F, 0x8E, 0x8E, 0x8C, 0x8C, 0x8C, 0x8C, 0x8E, 0x8F, 0x87, 0x83, 0x81, 0x00, 0x00,
0x00, 0x00, 0xF2, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x02, 0x02, 0x02, 0xF2, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0xF2, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
0x12, 0x12, 0x02, 0x02, 0x02, 0x02, 0x02, 0xC2, 0x22, 0x12, 0x12, 0x12, 0x12, 0x12, 0x22, 0x42,
0x02, 0x02, 0x12, 0x12, 0x12, 0x12, 0xF2, 0x12, 0x12, 0x12, 0x12, 0x02, 0x02, 0xF2, 0x12, 0x12,
0x12, 0x12, 0x12, 0x12, 0xE2, 0x02, 0x02, 0x02, 0xC2, 0x22, 0x22, 0x12, 0x12, 0x12, 0x12, 0x12,
0x22, 0x22, 0xC2, 0x02, 0x02, 0x02, 0xF2, 0x22, 0x22, 0xC2, 0x02, 0x02, 0x02, 0x02, 0xF2, 0x02,
0x02, 0x02, 0x02, 0xF2, 0xF2, 0x02, 0x02, 0x02, 0x02, 0xC2, 0x22, 0x12, 0x12, 0x12, 0x12, 0x12,
0x22, 0x42, 0x02, 0x02, 0x02, 0xE2, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x62, 0x00, 0x00,
0x00, 0x00, 0x3F, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x00, 0x00, 0x00, 0x3F, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x08,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x02, 0x02,
0x02, 0x02, 0x06, 0x1A, 0x21, 0x00, 0x00, 0x00, 0x0F, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20,
0x10, 0x10, 0x0F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x03, 0x0C, 0x0C, 0x10, 0x3F, 0x00,
0x00, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20,
0x10, 0x08, 0x00, 0x00, 0x00, 0x18, 0x21, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x1C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
void lcd_init()
{
restart_wdt();
i2c_start ();
i2c_write(lcd_address); //select the display
i2c_write(lcd_cmd); //we are sending a command
i2c_write(0xAE); //set LCD off
i2c_write(0xD5); //set LCD clock div
i2c_write(0x80); //set LCD osc frequency
i2c_write(0xA8); //set LCD mux
i2c_write(0x3F); //set LCD mux
i2c_write(0xD3); //set LCD offset
i2c_write(0x00); //set no offset
i2c_write(0x40); //set LCD start line
i2c_write(0x8D); //set LCD charge pump
i2c_write(0x14); //set charge pump vcc
i2c_write(0xA1); //set LCD remap
i2c_write(0xC8); //set scan direction
i2c_write(0xDA); //set com pins
i2c_write(0x12); //set com pins
i2c_write(0x81); //set LCD contrast
i2c_write(0xCF); //set LCD contrast
i2c_write(0xD9); //set LCD pre charge
i2c_write(0xF1); //set LCD pre charge
i2c_write(0xDB); //set vcon detect
i2c_write(0x40); //set vcon detect
i2c_write(0xA4); //set LCD all on = A5
i2c_write(0xA6); //set LCD normal=A6 inverse = A7
i2c_write(0xAF); //set display on=AF off=AE
i2c_write(0x20); //access memory mode
i2c_write(0x00); //switch for H mode
i2c_stop();
}
void lcd_write()
{
long i;
i2c_start ();
i2c_write(lcd_address); //select the display
i2c_write(lcd_data) ;
for (i=0; i<1024; i++)
{
restart_wdt();
i2c_write(logo[i]) ;
}
i2c_stop();
}
void main()
{
lcd_init();
loop:
while(page==190)
{
restart_wdt();
}
while(page==200) //start
{
restart_wdt();
lcd_write();
page=190;
}
goto loop;
} |
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Oct 29, 2015 2:38 am |
|
|
Thanks for sharing your code and putting in all the effort.
Just a few remarks, not related to your issue but will make you a better programmer:
1) Using the goto command is considered bad programming as it soon leads to spaghetti code. The command is in the C-language to make it possible to create special code like exception handlers. I'm not a hardliner against the use of 'goto' as I used to be, but for situations like here it is the wrong solution.
2) Why use a watchdog? In my experience they cause more problems than they solve. Only when no user is present to reset your device it makes sense having a watchdog. In all other cases they cause code clutter and hard to find problems.
3) Code: | while(page==190)
{
restart_wdt();
} | This will loop forever. If that's intentional, then your program can be simplified by a 'while(TRUE){}' which also shows your intention more clearly.
Considering all above, your main routine can be reduced to: Code: | void main()
{
lcd_init();
lcd_write();
while(TRUE){};
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19545
|
|
Posted: Thu Oct 29, 2015 3:38 am |
|
|
What I have to ask (still) is why you were fiddling with the mode?.
To burst transmit 1024 bytes, you only need to set the write address to 0, and write 1024 bytes. Nothing else needed. No mode changes etc..
This is what my OLED_CLS function does. It writes 1024 bytes (assuming the display is 128*64) of either all 1's or all 0's (depending if you have the display inverted), straight to the display. |
|
|
rudy
Joined: 27 Apr 2008 Posts: 168
|
|
Posted: Thu Oct 29, 2015 4:34 am |
|
|
Answering ckielstra!
Thanks, I know this is not the best way, but I learn this way and so now I could not change. For each value of page I write some code to do something different.
I don´t know, it seems more structured to me I guess, that´s why I never changed the way I write. But thank you anyway.
Regarding with WDT, I never had problems with it, and always leave it running to restart CPU if any crash happens.
The code is not finished yet, so there will be more "pages" to hold all the functions needed. Please don´t blame me, everybody says it is wrong, it is not the first time I heard that, but works for me.
Answering Ttelmah.
In fact, I had some trouble to true understand your code, my stupidity only, I am not so skilled C writer.
I had tried the burst transmission you provided, but there is some other functions that is needed to change page address and so on. When you write to more powerful processors, there may be more ram memory. In my case, for 16F688, there is not.
So I trying to enjoy the fact that the pointer is automatically updated when you reach the end of page columns, avoid more codes to do this, that´s why.
I soon discover some problems that I will try to solve moreover with H or V address mode, for example after a power up. Today morning, before I left to work, I turned on the power, and the display only was updated on the first page (PAGE=0).
It seems to me that something still need to be done at the lcd_init() code. As soon as I find out I will update the final code.
Thanks all! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19545
|
|
Posted: Thu Oct 29, 2015 5:07 am |
|
|
The pointer does this all the time. No need to change anything!.
Also look at how I send the initialisation. No need for loads of separate calls, I just write the data straight from a ROM array. |
|
|
rudy
Joined: 27 Apr 2008 Posts: 168
|
|
Posted: Fri Oct 30, 2015 5:52 am |
|
|
Ttelmah, you are right.
Checking your code I could see 0x20 plus 0x00, indicating that your code also pointed to H address mode. Unfortunately, my LCD module stops to answer to this command, it simple just don’t change more for H or V address mode, just remain fixed in 0x02 that is PAGE address.
I cannot wait long time to receive another one, to check if it is a problem in my code or some damage to the module itself, so I moved to work with PAGE address mode only.
I will check if others registers may have something with this issue, like clock, mux and so one. Anyway, moreover I will post my code to share with all.
Regards. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|