I'm trying to run a OLED WEX012864GL based on SSD1305 OLED controller with a stm32f3discovery board. I've conntected the board with a 31 pin row with first pin binding on the 3V and the last on the PD9 (this is the top-left pin row of the board). The code is looking like that:
#include "stm32f30x.h"
/*--------- PORT-A ----------------------------*/
#define D1 GPIO_Pin_1
#define D1_PORT GPIOA
#define D2 GPIO_Pin_3
#define D2_PORT GPIOA
#define D4 GPIO_Pin_5
#define D4_PORT GPIOA
#define D5 GPIO_Pin_7
#define D5_PORT GPIOA
/*-------- PORT-B ----------------------------*/
#define D7 GPIO_Pin_1
#define D7_PORT GPIOB
#define RD GPIO_Pin_11 //8080 Mode RD Display-Pin:14 PD3
#define RD_PORT GPIOB
#define DISP GPIO_Pin_15
#define DISP_PORT GPIOB
/*-------- PORT-C ----------------------------*/
#define D0 GPIO_Pin_3
#define D0_PORT GPIOC
#define D6 GPIO_Pin_5
#define D6_PORT GPIOC
/*-------- PORT-E ----------------------------*/
#define CS GPIO_Pin_7 //PORT-D Display-Pin:19 PD6
#define CS_PORT GPIOE
#define RES GPIO_Pin_11 //PORT-B Display-Pin:20 PC10
#define RES_PORT GPIOE
#define WR GPIO_Pin_13 //8080 Mode WR Display-Pin:15 PD2
#define WR_PORT GPIOE
#define D_C GPIO_Pin_15 //PORT-C Display-Pin:18 PC12
#define D_C_PORT GPIOE
/*-------- PORT-F ----------------------------*/
#define D3 GPIO_Pin_4
#define D3_PORT GPIOF
#define GPIO_PINS_PORTA_OUT (D1 | D2 | D4 | D5 )
#define GPIO_PINS_PORTB_OUT (D7 | RD| DISP)
#define GPIO_PINS_PORTC_OUT (D0 | D6 )
#define GPIO_PINS_PORTE_OUT (CS| D_C | RES | WR)
#define GPIO_PINS_PORTF_OUT (D3)
#define GPIO_PINS_PORTA_IN (D1 | D2 | D4 | D5 )
#define GPIO_PINS_PORTB_IN (D7)
#define GPIO_PINS_PORTC_IN (D0 | D6 )
#define GPIO_PINS_PORTF_IN (D3)
#define GET_BIT(cmd,bitps) (BitAction)((((uint8_t)cmd&((uint8_t)1)<<bitps))>>bitps)
#define GET_INPUT_BIT(port,pin,pos) ((uint8_t)(GPIO_ReadOutputDataBit(port,pin)<<pos))
#define MOD_GPIO_WRITE(cmd) GPIO_WriteBit(D0_PORT,D0,GET_BIT(cmd,0)); \
GPIO_WriteBit(D1_PORT,D1,GET_BIT(cmd,1)); \
GPIO_WriteBit(D2_PORT,D2,GET_BIT(cmd,2)); \
GPIO_WriteBit(D3_PORT,D3,GET_BIT(cmd,3)); \
GPIO_WriteBit(D4_PORT,D4,GET_BIT(cmd,4)); \
GPIO_WriteBit(D5_PORT,D5,GET_BIT(cmd,5)); \
GPIO_WriteBit(D6_PORT,D6,GET_BIT(cmd,6)); \
GPIO_WriteBit(D7_PORT,D7,GET_BIT(cmd,7)) \
#define MOD_GPIO_READ() GET_INPUT_BIT(D0_PORT,D0,0)| GET_INPUT_BIT(D1_PORT,D1,1) | GET_INPUT_BIT(D2_PORT,D2,2)| \
GET_INPUT_BIT(D3_PORT,D3,3) | GET_INPUT_BIT(D4_PORT,D4,4) | GET_INPUT_BIT(D5_PORT,D5,5) | \
GET_INPUT_BIT(D6_PORT,D6,6) | GET_INPUT_BIT(D7_PORT,D7,7)
//proto
void Delay(uint32_t nTime);
void TimingDelay_Decrement(void);
static __IO uint32_t TimingDelay;
//Init the used Ports
static void Init_Ports_Write( void ) {
//D7-0 outputs
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_PINS_PORTA_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_PINS_PORTB_OUT;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_PINS_PORTC_OUT;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_PINS_PORTE_OUT;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_PINS_PORTF_OUT;
GPIO_Init(GPIOF, &GPIO_InitStructure);
}
static void Init_Ports_Read( void ) {
//D7-0 inputs
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_Pin = GPIO_PINS_PORTA_IN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_PINS_PORTB_IN;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_PINS_PORTC_IN;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_PINS_PORTF_IN;
GPIO_Init(GPIOF, &GPIO_InitStructure);
}
static void Init_Ports( void ) {
//init the System
SystemInit();
//Takt für IO-Port A & C aktivieren
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC | RCC_AHBPeriph_GPIOD | RCC_AHBPeriph_GPIOE | RCC_AHBPeriph_GPIOF, ENABLE);
if (SysTick_Config(SystemCoreClock / 1000000)) { /* Setup SysTick Timer for 1 µsec interrupts (msec/1000000) */
while (1); /* Capture error */
}
Init_Ports_Write();
GPIO_ResetBits(GPIOA, GPIO_PINS_PORTA_OUT);
GPIO_ResetBits(GPIOB, GPIO_PINS_PORTB_OUT);
GPIO_ResetBits(GPIOC, GPIO_PINS_PORTC_OUT);
GPIO_ResetBits(GPIOE, GPIO_PINS_PORTE_OUT);
GPIO_ResetBits(GPIOF, GPIO_PINS_PORTF_OUT);
//set all neg pins
GPIO_SetBits(RES_PORT, RES);
GPIO_SetBits(CS_PORT, CS);
GPIO_SetBits(WR_PORT, WR);
GPIO_SetBits(RD_PORT, RD);
Delay(500000);
}
static void oled_Command_25664(uint8_t cmd){
//write bit by bit
MOD_GPIO_WRITE(cmd);
GPIO_SetBits(RD_PORT, RD);
GPIO_ResetBits(D_C_PORT, D_C);
GPIO_ResetBits(CS_PORT, CS);
GPIO_ResetBits(WR_PORT, WR);
__nop();__nop();__nop();__nop();__nop();__nop();
GPIO_SetBits(WR_PORT, WR);
__nop();__nop();__nop();__nop();__nop();__nop();
GPIO_SetBits(CS_PORT, CS);
__nop();
}
static void oled_Data_25664(uint8_t data){
MOD_GPIO_WRITE(data);
GPIO_SetBits(RD_PORT, RD);
GPIO_SetBits(D_C_PORT, D_C);
GPIO_ResetBits(CS_PORT, CS);
GPIO_ResetBits(WR_PORT, WR);
__nop();__nop();__nop();__nop();__nop();__nop();
GPIO_SetBits(WR_PORT, WR);
__nop();__nop();__nop();__nop();__nop();__nop();
GPIO_SetBits(CS_PORT, CS);
__nop();
}
static uint8_t oled_Read_Data_25664(){
uint8_t read_data;
//Set the D7-0 as inputs
Init_Ports_Read();
//set WR high
read_data = MOD_GPIO_READ();
GPIO_SetBits(WR_PORT, WR);
GPIO_SetBits(D_C_PORT, D_C);
GPIO_ResetBits(CS_PORT, CS);
GPIO_ResetBits(RD_PORT, RD);
__nop();__nop();__nop();__nop();__nop();__nop();
GPIO_SetBits(RD_PORT, RD);
GPIO_ResetBits(RD_PORT, RD);
__nop();__nop();__nop();__nop();__nop();__nop();
read_data = MOD_GPIO_READ();
//Set the D7-0 as outputs
GPIO_SetBits(RD_PORT, RD);
__nop();__nop();__nop();__nop();__nop();__nop();
GPIO_ResetBits(RD_PORT, RD);
__nop();__nop();__nop();__nop();__nop();__nop();
//read
read_data = MOD_GPIO_READ();
GPIO_SetBits(D_C_PORT, D_C);
GPIO_SetBits(CS_PORT, CS);
Init_Ports_Write();
return read_data;
}
void Delay(uint32_t nTime)
{
TimingDelay = nTime;
while(TimingDelay != 0);
}
/* Decrements the TimingDelay variable.*/
void TimingDelay_Decrement(void)
{
if (TimingDelay != 0x00) TimingDelay--;
}
void SysTick_Handler(void)
{
TimingDelay_Decrement();
}
/**
* @brief Main program.
* @param None
* @retval None
*/
int main(void)
{
/*!< At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
file (startup_stm32f30x.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f30x.c file
*/
Init_Ports();
oled_Command_25664(0xAF);//--turn on oled panel
oled_Command_25664(0xA5);
oled_Read_Data_25664();
while(1)
{
oled_Command_25664(0xA5);
Delay(500000);
oled_Command_25664(0xA4);
Delay(500000);
}
}
When I run the code on the board, a very bizarre result is observed - the display is not working, till I press the reset button and the there the screen light up for short and then back down. What could be the reason for that?
The solution was that the DISP signal should be left high-Z or the port is not initialized. The complete code is looking like that:
#include "stm32f30x.h"
/*--------- PORT-A ----------------------------*/
#define D1 GPIO_Pin_1
#define D1_PORT GPIOA
#define D2 GPIO_Pin_3
#define D2_PORT GPIOA
#define D4 GPIO_Pin_5
#define D4_PORT GPIOA
#define D5 GPIO_Pin_7
#define D5_PORT GPIOA
/*-------- PORT-B ----------------------------*/
#define D7 GPIO_Pin_1
#define D7_PORT GPIOB
#define RD GPIO_Pin_11 //8080 Mode RD Display-Pin:14 PD3
#define RD_PORT GPIOB
#define DISP GPIO_Pin_15
#define DISP_PORT GPIOB
/*-------- PORT-C ----------------------------*/
#define D0 GPIO_Pin_3
#define D0_PORT GPIOC
#define D6 GPIO_Pin_5
#define D6_PORT GPIOC
/*-------- PORT-E ----------------------------*/
#define CS GPIO_Pin_7 //PORT-D Display-Pin:19 PD6
#define CS_PORT GPIOE
#define RES GPIO_Pin_11 //PORT-B Display-Pin:20 PC10
#define RES_PORT GPIOE
#define WR GPIO_Pin_13 //8080 Mode WR Display-Pin:15 PD2
#define WR_PORT GPIOE
#define D_C GPIO_Pin_15 //PORT-C Display-Pin:18 PC12
#define D_C_PORT GPIOE
/*-------- PORT-F ----------------------------*/
#define D3 GPIO_Pin_4
#define D3_PORT GPIOF
#define GPIO_PINS_PORTA_OUT (D1 | D2 | D4 | D5 )
#define GPIO_PINS_PORTB_OUT (D7 | RD )
#define GPIO_PINS_PORTC_OUT (D0 | D6 )
#define GPIO_PINS_PORTE_OUT (CS| D_C | RES | WR)
#define GPIO_PINS_PORTF_OUT (D3)
#define GPIO_PINS_PORTA_IN (D1 | D2 | D4 | D5 )
#define GPIO_PINS_PORTB_IN (D7)
#define GPIO_PINS_PORTC_IN (D0 | D6 )
#define GPIO_PINS_PORTF_IN (D3)
#define GET_BIT(cmd,bitps) (BitAction)((((uint8_t)cmd&((uint8_t)1)<<bitps))>>bitps)
#define GET_INPUT_BIT(port,pin,pos) ((uint8_t)(GPIO_ReadOutputDataBit(port,pin)<<pos))
#define MOD_GPIO_WRITE(cmd) GPIO_WriteBit(D0_PORT,D0,GET_BIT(cmd,0)); \
GPIO_WriteBit(D1_PORT,D1,GET_BIT(cmd,1)); \
GPIO_WriteBit(D2_PORT,D2,GET_BIT(cmd,2)); \
GPIO_WriteBit(D3_PORT,D3,GET_BIT(cmd,3)); \
GPIO_WriteBit(D4_PORT,D4,GET_BIT(cmd,4)); \
GPIO_WriteBit(D5_PORT,D5,GET_BIT(cmd,5)); \
GPIO_WriteBit(D6_PORT,D6,GET_BIT(cmd,6)); \
GPIO_WriteBit(D7_PORT,D7,GET_BIT(cmd,7)) \
#define MOD_GPIO_READ() GET_INPUT_BIT(D0_PORT,D0,0)| GET_INPUT_BIT(D1_PORT,D1,1) | GET_INPUT_BIT(D2_PORT,D2,2)| \
GET_INPUT_BIT(D3_PORT,D3,3) | GET_INPUT_BIT(D4_PORT,D4,4) | GET_INPUT_BIT(D5_PORT,D5,5) | \
GET_INPUT_BIT(D6_PORT,D6,6) | GET_INPUT_BIT(D7_PORT,D7,7)
//proto
void Delay(uint32_t nTime);
void TimingDelay_Decrement(void);
static __IO uint32_t TimingDelay;
//Init the used Ports
static void Init_Ports_Write( void ) {
//D7-0 outputs
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_PINS_PORTA_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_PINS_PORTB_OUT;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_PINS_PORTC_OUT;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_PINS_PORTE_OUT;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_PINS_PORTF_OUT;
GPIO_Init(GPIOF, &GPIO_InitStructure);
}
static void Init_Ports_Read( void ) {
//D7-0 inputs
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_Pin = GPIO_PINS_PORTA_IN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_PINS_PORTB_IN;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_PINS_PORTC_IN;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_PINS_PORTF_IN;
GPIO_Init(GPIOF, &GPIO_InitStructure);
}
static void Init_Ports( void ) {
//init the System
SystemInit();
//Takt für IO-Port A & C aktivieren
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC | RCC_AHBPeriph_GPIOD | RCC_AHBPeriph_GPIOE | RCC_AHBPeriph_GPIOF, ENABLE);
if (SysTick_Config(SystemCoreClock / 1000000)) { /* Setup SysTick Timer for 1 µsec interrupts (msec/1000000) */
while (1); /* Capture error */
}
Init_Ports_Write();
GPIO_ResetBits(GPIOA, GPIO_PINS_PORTA_OUT);
GPIO_ResetBits(GPIOB, GPIO_PINS_PORTB_OUT);
GPIO_ResetBits(GPIOC, GPIO_PINS_PORTC_OUT);
GPIO_ResetBits(GPIOE, GPIO_PINS_PORTE_OUT);
GPIO_ResetBits(GPIOF, GPIO_PINS_PORTF_OUT);
//set all neg pins
GPIO_SetBits(RES_PORT, RES);
GPIO_SetBits(CS_PORT, CS);
GPIO_SetBits(WR_PORT, WR);
GPIO_SetBits(RD_PORT, RD);
Delay(500000);
}
static void oled_Command_25664(uint8_t cmd){
//write bit by bit
MOD_GPIO_WRITE(cmd);
GPIO_SetBits(RD_PORT, RD);
GPIO_ResetBits(D_C_PORT, D_C);
GPIO_ResetBits(CS_PORT, CS);
GPIO_ResetBits(WR_PORT, WR);
__nop();__nop();__nop();__nop();__nop();__nop();
GPIO_SetBits(WR_PORT, WR);
__nop();__nop();__nop();__nop();__nop();__nop();
GPIO_SetBits(CS_PORT, CS);
__nop();
}
static void oled_Data_25664(uint8_t data){
MOD_GPIO_WRITE(data);
GPIO_SetBits(RD_PORT, RD);
GPIO_SetBits(D_C_PORT, D_C);
GPIO_ResetBits(CS_PORT, CS);
GPIO_ResetBits(WR_PORT, WR);
__nop();__nop();__nop();__nop();__nop();__nop();
GPIO_SetBits(WR_PORT, WR);
__nop();__nop();__nop();__nop();__nop();__nop();
GPIO_SetBits(CS_PORT, CS);
__nop();
}
static uint8_t oled_Read_Data_25664(){
uint8_t read_data;
//Set the D7-0 as inputs
Init_Ports_Read();
//set WR high
read_data = MOD_GPIO_READ();
GPIO_SetBits(WR_PORT, WR);
GPIO_SetBits(D_C_PORT, D_C);
GPIO_ResetBits(CS_PORT, CS);
GPIO_ResetBits(RD_PORT, RD);
__nop();__nop();__nop();__nop();__nop();__nop();
GPIO_SetBits(RD_PORT, RD);
GPIO_ResetBits(RD_PORT, RD);
__nop();__nop();__nop();__nop();__nop();__nop();
read_data = MOD_GPIO_READ();
//Set the D7-0 as outputs
GPIO_SetBits(RD_PORT, RD);
__nop();__nop();__nop();__nop();__nop();__nop();
GPIO_ResetBits(RD_PORT, RD);
__nop();__nop();__nop();__nop();__nop();__nop();
//read
read_data = MOD_GPIO_READ();
GPIO_SetBits(D_C_PORT, D_C);
GPIO_SetBits(CS_PORT, CS);
Init_Ports_Write();
return read_data;
}
void Delay(uint32_t nTime)
{
TimingDelay = nTime;
while(TimingDelay != 0);
}
/* Decrements the TimingDelay variable.*/
void TimingDelay_Decrement(void)
{
if (TimingDelay != 0x00) TimingDelay--;
}
void SysTick_Handler(void)
{
TimingDelay_Decrement();
}
/**
* @brief Main program.
* @param None
* @retval None
*/
int main(void)
{
/*!< At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
file (startup_stm32f30x.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f30x.c file
*/
Init_Ports();
oled_Command_25664(0xAF);//--turn on oled panel
oled_Command_25664(0xA4);
oled_Read_Data_25664();
while(1)
{
oled_Command_25664(0xA5);
Delay(500000);
oled_Command_25664(0xA4);
Delay(500000);
}
}