Issue about drawing on NHD-0420CW-AY320 in i2c
Hello everyone,
I use an oled display NHD-0420CW-AY320. Datasheet: https://newhavendisplay.com/content/specs/NHD-0420CW-AY3.pdf
common driver US2066. Datasheet: https://newhavendisplay.com/content/app_notes/US2066.pdf
The microcontroller I use in my code is a STM32F107RC.
This display is connected to the I²C bus of the microcontroller.
I do not have to use arduino.
Below the diagram of my display:
we can see that in relation to the datasheet the configuration in i2c mode is correct.
Then I retrieve and adapt a code to run my display, oledDisplay.c:
/* The circuit:
*
* OLED pin 1 (Vss) pin ground
* OLED pin 2 (VDD) pin 3.3V
* OLED pin 3 (REGVDD) to Vss ground
* OLED pin 4 (SA0) to Vss ground (to assign I2C address 0x3D, connect to VDD 3.3V)
* OLED pin 5 and 6 to Vss ground
* OLED pin 7 (SCL) pin SCL (7=D0)
* OLED pin 8 and 9 (SDAin,SDAout) pin SDA (9=D2; 8=D1)
* OLED pin 10 to 15 to Vss ground (14=D7; 13=D6; 12=D5; 11=D4; 10=D3)
* OLED pin 16 (/RES) pin Reset or VDD 3.3V
* OLED pin 17 (BS0) to Vss ground
* OLED pin 18 (BS1) to VDD 5V
* OLED pin 19 (BS2) to Vss ground
* OLED pin 20 (Vss) to Vss ground
*/
/**********************/
/****** includes ******/
/**********************/
#include "oledDisplay.h"
/*********************/
/****** globals ******/
/*********************/
/** @brief Number of display rows */
const uint8_t ROW_N = 4;
/** @brief Number of display columns */
const uint8_t COLUMN_N = 20;
/** @brief pin assigned to the Reset line (optional, can be always high) */
const uint8_t RES = 16;
/** @brief Display I2C Slave address, in 7-bit form: 0x3C if SA0=LOW, 0x3D if SA0=HIGH */
const uint8_t SLAVE2W = 0x3C;
/** @brief Strings to be displayed */
const uint8_t TEXT[4][21] = {"1-Newhaven Display--",
"2-------Test--------",
"3-16/20-Characters--",
"4!@#$%^&*()_+{}[]<>?"};
/** @brief DDRAM address for each line of the display */
uint8_t new_line[4] = {0x80, 0xA0, 0xC0, 0xE0};
/** @brief Display mode: 1/3 lines or 2/4 lines; default 2/4 (0x08) */
uint8_t rows = 0x08;
/** @brief Packet to be transmitted (max 20 bytes) */
uint8_t tx_packet[MAXPACKET]={0};
//uint8_t tx_packet[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
/*********************************/
/****** Function definition ******/
/*********************************/
/**
* @brief subroutine: prepares the transmission of a command
*
* @param[in] commandByte The command to be executed by the display
*/
void command(uint8_t commandByte)
{
i2cBuffer[0] = DATABYTE_COMMAND; // Control Byte; C0_bit=0, D/C_bit=0 -> following Data Byte contains command
i2cBuffer[1] = commandByte;
send_packet(2, i2cBuffer); // Transmits the two bytes
}
/**
* @brief subroutine: prepares the transmission of a byte of data
*
* @param[in] dataByte The character to be displayed
*/
void data(uint8_t dataByte)
{
i2cBuffer[0] = DATABYTE_DATA; // Control Byte; C0_bit=0, D/C_bit=1 -> following Data Byte contains data
i2cBuffer[1] = dataByte;
send_packet(2, i2cBuffer); // Transmits the two bytes
}
/**
* @brief subroutine: send to the display the number of bytes stored in tx_packet
*
* @param[in] byteStored Command or bytes of data stored
* @param[in] *tx_pack Packet to be transmitted
*/
void send_packet(uint8_t byteStored, uint8_t *tx_pack)
{
/* Wire.beginTransmission(SLAVE2W); */ // Begin the transmission via I2C to the display with the given address
/*send start condition and slave address, then send the data and stop condition */
i2cmWrite(SLAVE2W, byteStored, tx_pack);
/* Wire.write(tx_packet[index]); */ // queue bytes for transmission
/* Wire.endTransmission(); */ // Transmits the bytes that were queued
}
/**
* @brief subroutine: displays the four strings, then the same in reverse order
*/
void output(void)
{
uint8_t row = 0; // Row index
uint8_t column = 0; // Column index
command(CLEARDISPLAY); // Clears display (and cursor home)
softDelay(2); // After a clear display, a minimum pause of 1-2 ms is required
for (row=0; row<ROW_N; row++) // One row at a time
{
command(new_line[row]); // moves the cursor to the first column of that line
for (column=0; column<COLUMN_N; column++) // One character at a time
{
data(TEXT[row][column]); // displays the corresponding string
}
}
softDelay(200); // Waits, only for visual effect purpose
for (row=0; row<ROW_N; row++) // One row at a time
{
command(new_line[row]); // moves the cursor to the first column of that line
for (column=0; column<COLUMN_N; column++) // One character at a time
{
data(TEXT[3-row][column]); // displays the correspondig string (in reverse order)
}
}
}
/**
* @brief subroutine: fills the entire display with the character "block"
*/
void blocks(void)
{
uint8_t row = 0; // Row index
uint8_t column = 0; // Column index
command(CLEARDISPLAY); // Clear display (and cursor home)
softDelay(2); // After a clear display, a minimum pause of 1-2 ms is required
for (row=0; row<ROW_N; row++) // One row at a time
{
command(new_line[row]); // moves the cursor to the first column of that line
for (column=0; column<COLUMN_N; column++) // One character at a time
{
data(SEGCONFIGURATION); // displays the character 0xDB (block)
softDelay(50); // Waits, only for visual effect purpose
}
softDelay(200); // Waits, only for visual effect purpose
}
}
/**
* @brief initial setup
*/
void setup(void)
{
softDelay(10); // Waits 10 ms for stabilization purpose
if (ROW_N == 2 || ROW_N == 4)
rows = 0x08; // Display mode: 2/4 lines
else
rows = 0x00; // Display mode: 1/3 lines
command(FUNCTIONBLINK | rows); // Function set: extended command set (RE=1), lines #
command(FUNCTIONSELECTA); // Function selection A
data(0x5C); // enable internal Vdd regulator at 5V I/O mode (def. value) (0x00 for disable, 2.8V I/O)
command(FUNCTIONLINE | rows); // Function set: fundamental command set (RE=0) (exit from extended command set), lines #
command(DISPLAYCTRL); // Display ON/OFF control: display off, cursor off, blink off (default values)
command(FUNCTIONBLINK | rows); // Function set: extended command set (RE=1), lines #
command(OLEDCHARACTERIZ_SD); // OLED characterization: OLED command set enabled (SD=1)
command(DISPLAYSET); // Set display clock divide ratio/oscillator frequency:
command(0x70); // divide ratio=1, frequency=7 (default values)
command(OLEDCHARACTERIZ); // OLED characterization: OLED command set disabled (SD=0) (exit from OLED command set)
if (ROW_N > 2)
command(FUNCTIONSET_N); // Extended function set (RE=1): 5-dot font, B/W inverting disabled (def. val.), 3/4 lines
else
command(FUNCTIONSET); // Extended function set (RE=1): 5-dot font, B/W inverting disabled (def. val.), 1/2 lines
command(ENTRYMODESET_C); // Entry Mode set - COM/SEG direction: COM0->COM31, SEG99->SEG0 (BDC=1, BDS=0)
command(FUNCTIONSELECTB); // Function selection B
data(0x0A); // ROM/CGRAM selection: ROM C, CGROM=250, CGRAM=6 (ROM=10, OPR=10)
command(OLEDCHARACTERIZ_SD); // OLED characterization: OLED command set enabled (SD=1)
command(0xDA); // Set SEG pins hardware configuration:
command(0x10); // alternative odd/even SEG pin, disable SEG left/right remap (default values)
command(FUNCTIONSELECTC); // Function selection C:
command(0x00); // internal VSL, GPIO input disable
command(CONTRASTCONTROL); // Set contrast control:
command(0x7F); // contrast=127 (default value)
command(PHASELENGHT); // Set phase length:
command(0xF1); // phase2=15, phase1=1 (default: 0x78)
command(0xDB); // Set VCOMH deselect level:
command(0x40); // VCOMH deselect level=1 x Vcc (default: 0x20=0,77 x Vcc)
command(OLEDCHARACTERIZ); // OLED characterization: OLED command set disabled (SD=0) (exit from OLED command set)
command(FUNCTIONLINE | rows); // Function set: fundamental command set (RE=0) (exit from extended command set), lines #
command(CLEARDISPLAY); // Clear display
softDelay(2); // After a clear display, a minimum pause of 1-2 ms is required
command(SETDDRAMADDR); // Set DDRAM address 0x00 in address counter (cursor home) (default value)
command(DISPLAYCTRL_D); // Display ON/OFF control: display ON, cursor off, blink off
softDelay(250); // Waits 250 ms for stabilization purpose after display on
if (ROW_N == 2)
new_line[1] = 0xC0; // DDRAM address for each line of the display (only for 2-line mode)
}
/**
* @brief clear display
*/
void clearDisplay(void)
{
command(CLEARDISPLAY); // Clears display (and cursor home)
}
/**
* @brief display on
*/
void displayON(void)
{
command(DISPLAYCTRL_DCB); // Set the display/cursor/blink ON
}
/**
* @brief display off
*/
void displayOFF(void)
{
command(DISPLAYCTRL); // Set the display/cursor/blink OFF
}
/**
* @brief main program
*/
void mainOledDisplay(void)
{
i2cmInit(); // Initialize the I2C master
setup(); // Initial setup
displayON(); // Set the display ON
output(); // Execute subroutine "output"
softDelay(100); // Waits, only for visual effect purpose
blocks(); // Execute subroutine "blocks"
softDelay(100); // Waits, only for visual effect purpose
displayOFF(); // Set the display OFF
gpioSetLedTxd(FALSE);
}
So the mainOledDisplay function will be launched first.
Here is my code, the problem is simply that the display does not work and that I do not find the problem.
Summary of how the code works:
The main function initializes the i2c, then initializes all the commands (I already have test by removing this function call and same result), then we call the function that turns on the display, for all the hexadecimal commands used I refer to to the NHD datasheet so normally.
In the command and data functions I have already tried to use the tx_packet array that I defined as: uint8_t tx_packet [MAXPACKET] = {0}; but it does not work so for the moment I left i2cBuffer (which does not work too) or maybe the problem comes from elsewhere, that's why I need you.
Then the function send_packet which has first parameter the number of byte recorded, here 2 because
- and [1] contain the data. The function has as a second parameter a pointer to the first element of the array i2cBuffer or tx_packet if I have tx_packet.
This function uses a function that can be found in my code i2cMaster.c it is also sent the slave address. However, I think, but I can not use this display correctly. I mean, ok the operation of what I said above may work but it does not advance me to operate the display because I do not even know how to make sure that what I do be displayed.
So I'm blocked for some time on it. Thank you.
Thank you very much for taking the time to read me and thank you in advance. Really sorry for my english ! Thanks a lot !
-
Can you tell me if you are getting an ACK from the display?
0 -
Thank you for your answer, i dont received an ACK from the display.
When i debug my code, I pass through my code and it does not crash, nothing happens.
Here is my header file of my code :
#ifndef OLEDDISPLAY_H_
#define OLEDDISPLAY_H_
/**********************/
/****** includes ******/
/**********************/
#include "../../Common/i2cMaster.h"
#include "../../Common/genPurpose.h"
#include <stm32f10x_i2c.h>
#include <stm32f10x_gpio.h>
#include "../taskManagement.h"
#include "../../Common/constants.h"
#include "../gpio.h"
/********************************/
/***** constants and macros *****/
/********************************/
/*!< @brief Fundamental Command List */
#define CLEARDISPLAY 0x01 /*!< @brief Write "20H" to DDRAM and set DDRAM address to "00H" from AC */
#define RETURNHOME 0x02 /*!< @brief DDRAM address to "00H" from AC and return cursor to its original position if shifted */
/*!< @brief RE=0 Assign cursor & blink moving direction with DDRAM address / Assign display shift with DDRAM address */
#define ENTRYMODESET_LD 0x04 /*!< @brief I/D = "0": cursor/ blink moves to left | S = "0": display shift disable */
#define ENTRYMODESET_LE 0x05 /*!< @brief I/D = "0": cursor/ blink moves to left | S = "1": display shift enable */
#define ENTRYMODESET_RD 0x06 /*!< @brief I/D = "1": cursor/ blink moves to right | S = "0": display shift disable */
#define ENTRYMODESET_RE 0x07 /*!< @brief I/D = "1": cursor/ blink moves to right | S = "1": display shift enable */
/*!< @brief RE=1 Common bi-direction function / Segment bi-direction function */
#define ENTRYMODESET 0x04 /*!< @brief BDC = "0": COM31 -> COM0 | BDS = "0": SEG99 -> SEG0 */
#define ENTRYMODESET_S 0x05 /*!< @brief BDC = "0": COM31 -> COM0 | BDS = "1": SEG0 -> SEG99 */
#define ENTRYMODESET_C 0x06 /*!< @brief BDC = "1": COM0 -> COM31 | BDS = "0": SEG99 -> SEG0 */
#define ENTRYMODESET_CS 0x07 /*!< @brief BDC = "1": COM0 -> COM31 | BDS = "1": SEG0 -> SEG99 */
/*!< @brief RE=0 Set display/cursor/blink ON/OFF */
#define DISPLAYCTRL 0x08 /*!< @brief D = "0": display OFF | C = "0": cursor OFF | B = "0": blink OFF */
#define DISPLAYCTRL_B 0x09 /*!< @brief D = "0": display OFF | C = "0": cursor OFF | B = "1": blink ON */
#define DISPLAYCTRL_C 0x0A /*!< @brief D = "0": display OFF | C = "1": cursor ON | B = "0": blink OFF */
#define DISPLAYCTRL_CB 0x0B /*!< @brief D = "0": display OFF | C = "1": cursor ON | B = "1": blink ON */
#define DISPLAYCTRL_D 0x0C /*!< @brief D = "1": display ON | C = "0": cursor OFF | B = "0": blink OFF */
#define DISPLAYCTRL_DB 0x0D /*!< @brief D = "1": display ON | C = "0": cursor OFF | B = "1": blink ON */
#define DISPLAYCTRL_DC 0x0E /*!< @brief D = "1": display ON | C = "1": cursor ON | B = "0": blink OFF */
#define DISPLAYCTRL_DCB 0x0F /*!< @brief D = "1": display ON | C = "1": cursor ON | B = "1": blink ON */
/*!< @brief RE=1 Assign font width, black/white inverting of cursor, and 4line display mode control bit */
#define FUNCTIONSET 0x08 /*!< @brief FW = "0": 5-dot font width | B/W = "0": black/white inverting of cursor disable | NW = "0": 1-line or 2-line display mode */
#define FUNCTIONSET_N 0x09 /*!< @brief FW = "0": 5-dot font width | B/W = "0": black/white inverting of cursor disable | NW = "1": 3-line or 4-line display mode */
#define FUNCTIONSET_B 0x0A /*!< @brief FW = "0": 5-dot font width | B/W = "1": black/white inverting of cursor enable | NW = "0": 1-line or 2-line display mode */
#define FUNCTIONSET_BN 0x0B /*!< @brief FW = "0": 5-dot font width | B/W = "1": black/white inverting of cursor enable | NW = "1": 3-line or 4-line display mode */
#define FUNCTIONSET_F 0x0C /*!< @brief FW = "1": 6-dot font width | B/W = "0": black/white inverting of cursor disable | NW = "0": 1-line or 2-line display mode */
#define FUNCTIONSET_FN 0x0D /*!< @brief FW = "1": 6-dot font width | B/W = "0": black/white inverting of cursor disable | NW = "1": 3-line or 4-line display mode */
#define FUNCTIONSET_FB 0x0E /*!< @brief FW = "1": 6-dot font width | B/W = "1": black/white inverting of cursor enable | NW = "0": 1-line or 2-line display mode */
#define FUNCTIONSET_FBN 0x0F /*!< @brief FW = "1": 6-dot font width | B/W = "1": black/white inverting of cursor enable | NW = "1": 3-line or 4-line display mode */
/*!< @brief IS=0 RE=0 Set cursor moving and display shift control bit, and the direction, without changing DDRAM data */
#define CURSORSHIFT_L 0x10 /*!< @brief S/C = "0": cursor shift | R/L = "0": shift to left */
#define CURSORSHIFT_R 0x14 /*!< @brief S/C = "0": cursor shift | R/L = "1": shift to right */
#define DISPLAYSHIFT_L 0x18 /*!< @brief S/C = "1": display shift | R/L = "0": shift to left */
#define DISPLAYSHIFT_R 0x1C /*!< @brief S/C = "1": display shift | R/L = "1": shift to right */
/*!< @brief IS=0 RE=1 Double Height (4-Line)/ Display-dot Shift */
#define DOUBLEHEIGHT 0x10 /*!< @brief Assign different doubt height format UD2 = "0" | UD1 = "0" | DH = "0": dot scroll enable */
#define DOUBLEHEIGHT_D 0x11 /*!< @brief Assign different doubt height format UD2 = "0" | UD1 = "0" | DH = "1": display shift enable */
#define DOUBLEHEIGHT_U1 0x14 /*!< @brief Assign different doubt height format UD2 = "0" | UD1 = "1" | DH = "0": dot scroll enable */
#define DOUBLEHEIGHT_U1D 0x15 /*!< @brief Assign different doubt height format UD2 = "0" | UD1 = "1" | DH = "1": display shift enable */
#define DOUBLEHEIGHT_U2 0x18 /*!< @brief Assign different doubt height format UD2 = "1" | UD1 = "0" | DH = "0": dot scroll enable */
#define DOUBLEHEIGHT_U2D 0x19 /*!< @brief Assign different doubt height format UD2 = "1" | UD1 = "0" | DH = "1": display shift enable */
#define DOUBLEHEIGHT_U21 0x1C /*!< @brief Assign different doubt height format UD2 = "1" | UD1 = "1" | DH = "0": dot scroll enable */
#define DOUBLEHEIGHT_U21D 0x1D /*!< @brief Assign different doubt height format UD2 = "1" | UD1 = "1" | DH = "1": display shift enable */
/*!< @brief IS=1 RE=1 Shift Enable DS[4:1]=1111b when DH = 1b Determine the line for display shift */
#define SHIFTDISABLE 0x10 /*!< @brief DS1 = "0": 1st line display shift disable | DS2 = "0" | DS3 = "0" | DS4 = "0" */
#define SHIFTENABLE_4 0x11 /*!< @brief DS1 = "0": 1st line display shift disable | DS2 = "0" | DS3 = "0" | DS4 = "1" */
#define SHIFTENABLE_3 0x12 /*!< @brief DS1 = "0": 1st line display shift disable | DS2 = "0" | DS3 = "1" | DS4 = "0" */
#define SHIFTENABLE_34 0x13 /*!< @brief DS1 = "0": 1st line display shift disable | DS2 = "0" | DS3 = "1" | DS4 = "1" */
#define SHIFTENABLE_2 0x14 /*!< @brief DS1 = "0": 1st line display shift disable | DS2 = "1" | DS3 = "0" | DS4 = "0" */
#define SHIFTENABLE_24 0x15 /*!< @brief DS1 = "0": 1st line display shift disable | DS2 = "1" | DS3 = "0" | DS4 = "1" */
#define SHIFTENABLE_23 0x16 /*!< @brief DS1 = "0": 1st line display shift disable | DS2 = "1" | DS3 = "1" | DS4 = "0" */
#define SHIFTENABLE_234 0x17 /*!< @brief DS1 = "0": 1st line display shift disable | DS2 = "1" | DS3 = "1" | DS4 = "1" */
#define SHIFTENABLE_1 0x18 /*!< @brief DS1 = "1": 1st line display shift enable | DS2 = "0" | DS3 = "0" | DS4 = "0" */
#define SHIFTENABLE_14 0x19 /*!< @brief DS1 = "1": 1st line display shift enable | DS2 = "0" | DS3 = "0" | DS4 = "1" */
#define SHIFTENABLE_13 0x1A /*!< @brief DS1 = "1": 1st line display shift enable | DS2 = "0" | DS3 = "1" | DS4 = "0" */
#define SHIFTENABLE_134 0x1B /*!< @brief DS1 = "1": 1st line display shift enable | DS2 = "0" | DS3 = "1" | DS4 = "1" */
#define SHIFTENABLE_12 0x1C /*!< @brief DS1 = "1": 1st line display shift enable | DS2 = "1" | DS3 = "0" | DS4 = "0" */
#define SHIFTENABLE_124 0x1D /*!< @brief DS1 = "1": 1st line display shift enable | DS2 = "1" | DS3 = "0" | DS4 = "1" */
#define SHIFTENABLE_123 0x1E /*!< @brief DS1 = "1": 1st line display shift enable | DS2 = "1" | DS3 = "1" | DS4 = "0" */
#define SHIFTENABLE 0x1F /*!< @brief DS1 = "1": 1st line display shift enable | DS2 = "1" | DS3 = "1" | DS4 = "1" */
/*!< @brief IS=1 RE=1 Scroll Enable HS[4:1]=1111b when D = 0b Determine the line for horizontal smooth scroll */
#define SCROLLDISABLE 0x10 /*!< @brief HS1 = "0": 1st line dot scroll disable | HS2 = "0" | HS3 = "0" | HS4 = "0" */
#define SCROLLENABLE_4 0x11 /*!< @brief HS1 = "0": 1st line dot scroll disable | HS2 = "0" | HS3 = "0" | HS4 = "1" */
#define SCROLLENABLE_3 0x12 /*!< @brief HS1 = "0": 1st line dot scroll disable | HS2 = "0" | HS3 = "1" | HS4 = "0" */
#define SCROLLENABLE_34 0x13 /*!< @brief HS1 = "0": 1st line dot scroll disable | HS2 = "0" | HS3 = "1" | HS4 = "1" */
#define SCROLLENABLE_2 0x14 /*!< @brief HS1 = "0": 1st line dot scroll disable | HS2 = "1" | HS3 = "0" | HS4 = "0" */
#define SCROLLENABLE_24 0x15 /*!< @brief HS1 = "0": 1st line dot scroll disable | HS2 = "1" | HS3 = "0" | HS4 = "1" */
#define SCROLLENABLE_23 0x16 /*!< @brief HS1 = "0": 1st line dot scroll disable | HS2 = "1" | HS3 = "1" | HS4 = "0" */
#define SCROLLENABLE_234 0x17 /*!< @brief HS1 = "0": 1st line dot scroll disable | HS2 = "1" | HS3 = "1" | HS4 = "1" */
#define SCROLLENABLE_1 0x18 /*!< @brief HS1 = "1": 1st line dot scroll enable | HS2 = "0" | HS3 = "0" | HS4 = "0" */
#define SCROLLENABLE_14 0x19 /*!< @brief HS1 = "1": 1st line dot scroll enable | HS2 = "0" | HS3 = "0" | HS4 = "1" */
#define SCROLLENABLE_13 0x1A /*!< @brief HS1 = "1": 1st line dot scroll enable | HS2 = "0" | HS3 = "1" | HS4 = "0" */
#define SCROLLENABLE_134 0x1B /*!< @brief HS1 = "1": 1st line dot scroll enable | HS2 = "0" | HS3 = "1" | HS4 = "1" */
#define SCROLLENABLE_12 0x1C /*!< @brief HS1 = "1": 1st line dot scroll enable | HS2 = "1" | HS3 = "0" | HS4 = "0" */
#define SCROLLENABLE_124 0x1D /*!< @brief HS1 = "1": 1st line dot scroll enable | HS2 = "1" | HS3 = "0" | HS4 = "1" */
#define SCROLLENABLE_123 0x1E /*!< @brief HS1 = "1": 1st line dot scroll enable | HS2 = "1" | HS3 = "1" | HS4 = "0" */
#define SCROLLENABLE 0x1F /*!< @brief HS1 = "1": 1st line dot scroll enable | HS2 = "1" | HS3 = "1" | HS4 = "1" */
/*!< @brief RE=0 Function Set Numbers of display line, N
* when N = "1": 2-line (NW=0b) / 4-line (NW=1b), when N = "0": 1-line (NW=0b) / 3-line (NW=1b),
* DH = "1/0": Double height font control for 2-line mode enable/ disable, Extension register : IS */
#define FUNCTIONLINE 0x20 /*!< @brief N = "0" | DH = "0" | RE = "0" | IS = "0" */
#define FUNCTIONLINE_I 0x21 /*!< @brief N = "0" | DH = "0" | RE = "0" | IS = "1" */
#define FUNCTIONLINE_D 0x24 /*!< @brief N = "0" | DH = "1" | RE = "0" | IS = "0" */
#define FUNCTIONLINE_DI 0x25 /*!< @brief N = "0" | DH = "1" | RE = "0" | IS = "1" */
#define FUNCTIONLINE_N 0x28 /*!< @brief N = "1" | DH = "0" | RE = "0" | IS = "0" */
#define FUNCTIONLINE_NI 0x29 /*!< @brief N = "1" | DH = "0" | RE = "0" | IS = "1" */
#define FUNCTIONLINE_ND 0x2C /*!< @brief N = "1" | DH = "1" | RE = "0" | IS = "0" */
#define FUNCTIONLINE_NDI 0x2D /*!< @brief N = "1" | DH = "1" | RE = "0" | IS = "1" */
/*!< @brief RE=1 Function Set CGRAM blink enable */
#define FUNCTIONBLINK 0x22 /*!< @brief N = "0" | DH = "0": CGRAM blink disable | RE = "1" | REV = "0": normal display */
#define FUNCTIONBLINK_R 0x23 /*!< @brief N = "0" | DH = "0": CGRAM blink disable | RE = "1" | REV = "1": reverse display */
#define FUNCTIONBLINK_D 0x26 /*!< @brief N = "0" | DH = "1": CGRAM blink enable | RE = "1" | REV = "0": normal display */
#define FUNCTIONBLINK_DR 0x27 /*!< @brief N = "0" | DH = "1": CGRAM blink enable | RE = "1" | REV = "1": reverse display */
#define FUNCTIONBLINK_N 0x2A /*!< @brief N = "1" | DH = "0": CGRAM blink disable | RE = "1" | REV = "0": normal display */
#define FUNCTIONBLINK_NR 0x2B /*!< @brief N = "1" | DH = "0": CGRAM blink disable | RE = "1" | REV = "1": reverse display */
#define FUNCTIONBLINK_ND 0x2E /*!< @brief N = "1" | DH = "1": CGRAM blink enable | RE = "1" | REV = "0": normal display */
#define FUNCTIONBLINK_NDR 0x2F /*!< @brief N = "1" | DH = "1": CGRAM blink enable | RE = "1" | REV = "1": reverse display */
/*!< @brief RE=0 Set address */
#define SETCGRAMADDR 0x40 /*!< @brief Set CGRAM Address */
#define SETDDRAMADDR 0x80 /*!< @brief Set DDRAM Address */
/*!< @brief RE=1 Set Scroll Quantity */
#define SETSCROLLQT 0x80 /*!< @brief Set the quantity of horizontal dot scroll */
/*!< @brief Read Busy Flag and Address/ Part ID */
#define BUSYSTATE 0x80 /*!< @brief BF = "1": busy state */
#define READYSTATE 0x00 /*!< @brief BF = "0": ready state */
/*!< @brief Extended Command Set */
#define FUNCTIONSELECTA 0x71 /*!< @brief Function Selection A */
#define FUNCTIONSELECTB 0x72 /*!< @brief Function Selection B */
#define FUNCTIONSELECTC 0xDC /*!< @brief Function Selection C */
#define OLEDCHARACTERIZ 0x78 /*!< @brief SD=0b: OLED Command set is disabled */
#define OLEDCHARACTERIZ_SD 0x79 /*!< @brief SD=1b: OLED Command set is enabled */
/*!< @brief OLED Command Set */
#define CONTRASTCONTROL 0x81 /*!< @brief Set Contrast Control */
#define DISPLAYSET 0xD5 /*!< @brief Set Display Clock Divide Ratio / Oscillator Frequency */
#define PHASELENGHT 0xD9 /*!< @brief Set Phase Length */
#define SEGCONFIGURATION 0xDB /*!< @brief Set SEG Pins Hardware Configuration */
#define FADEOUTBLINKSET 0x23 /*!< @brief Set Fade Out and Blinking */
/*!< @brief following Data Byte contains command or data */
#define DATABYTE_COMMAND 0x00 /*!< @brief Control Byte; C0_bit=0, D/C_bit=0 -> following Data Byte contains command */
#define DATABYTE_DATA 0x40 /*!< @brief Control Byte; C0_bit=0, D/C_bit=1 -> following Data Byte contains data */
/** @brief Packet to be transmitted (max 20 bytes) */
#define MAXPACKET 20
/*******************/
/***** globals *****/
/*******************/
/** @brief Number of display rows */
extern const uint8_t ROW_N;
/** @brief Number of display columns */
extern const uint8_t COLUMN_N;
/** @brief pin assigned to the Reset line (optional, can be always high) */
extern const uint8_t RES;
/** @brief Display I2C Slave address, in 7-bit form: 0x3C if SA0=LOW, 0x3D if SA0=HIGH */
extern const uint8_t SLAVE2W;
/** @brief Strings to be displayed */
extern const uint8_t TEXT[4][21];
/** @brief DDRAM address for each line of the display */
extern uint8_t new_line[4];
/** @brief Display mode: 1/3 lines or 2/4 lines; default 2/4 (0x08) */
extern uint8_t rows;
/** @brief Packet to be transmitted (max 20 bytes) */
extern uint8_t tx_packet[MAXPACKET];
/***********************************/
/****** Function declarations ******/
/***********************************/
/**
* @brief subroutine: prepares the transmission of a command
*
* @param[in] commandByte The command to be executed by the display
*/
void command(uint8_t commandByte);
/**
* @brief subroutine: prepares the transmission of a byte of data
*
* @param[in] dataByte The character to be displayed
*/
void data(uint8_t dataByte);
/**
* @brief subroutine: send to the display the number of bytes stored in tx_packet
*
* @param[in] byteStored Command or bytes of data stored
* @param[in] *tx_pack Packet to be transmitted
*/
void send_packet(uint8_t byteStored, uint8_t *tx_pack);
/**
* @brief subroutine: displays the four strings, then the same in reverse order
*/
void output(void);
/**
* @brief subroutine: fills the entire display with the character "block"
*/
void blocks(void);
/**
* @brief initial setup
*/
void setup(void);
/**
* @brief clear display
*/
void clearDisplay(void);
/**
* @brief display on
*/
void displayON(void);
/**
* @brief display off
*/
void displayOFF(void);
/**
* @brief main program
*/
void mainOledDisplay(void);
#endif /* OLEDDISPLAY_H_ */Thanks a lot
0 -
Hey Arrgon,
What value pull-up resistors do you have on the SCL and SDA lines?
Has the timing been verified on an oscilloscope?0 -
Thank you very much for helping me !
I already use the i2c for external memory Eeprom so the timing has been checked and works for the external memory.
You can see the value of pull-up resistors for SCL and SDA lines on the picture.
Thank you again0 -
Can you confirm that the I2C slaves do not have conflicting addresses?
Thanks!0 -
Thanks, I found this in my code :
/** @brief Read sectors protection registers op-code */
#define FLASH_OPCODE_SECTOR_READPROTECT 0x3CI don't know if its a conflicting address with the I2C slaves
/** @brief Display I2C Slave address, in 7-bit form: 0x3C if SA0=LOW, 0x3D if SA0=HIGH */
const uint8_t SLAVE2W = 0x3C;Thanks a lot
0 -
To verify please check the datasheet for the I2C devices on your PCB ;)
On the NHD-0420CW-AY3 module there is an address-select line (Pin 4). For troubleshooting purposes you can try to tie the address-select line (Pin 4) HIGH 3.3V. Please note that you will probably have to cut a pin / trace since your schematic shows it tied to GND. Finally, be sure to update the displays I2C Slave address to 0x3D in your software.
Disclaimer: Modified product will void warranty.« Last Edit: March 06, 2018, 08:58:36 AM by Paul_B »0 -
Thanks for your help.
It's finally working, I just changed the slave adress 0x3C by 0x78 and it works, Im so happy !
Bye0 -
Glad to hear you got your display up and running!
0
Please sign in to leave a comment.
Comments
9 comments