本次来测试一下STM32C031的SPI接口使用。使用SPI接口oled,驱动oled显示。
OLED使用如下端口:
OLED-D0-->PA7 MOSI
OLED-D1-->PA5 SCK
OLED-CS-->PB0 CS
OLED-RES-->PA9 复位脚
OLED-DC-->PC7 dc控制脚

使用扩展板连接OLED,实物如下:

下面打开STM32CubeMX。在原来的基础工程上,额外使能SPI1模式,以及IO端口初始化。

SPI的参数设置。

设置完成后GENERATE CODE生成代码工程,然后移植OLED驱动。
下面是基于SPI发送数据写oled寄存器。
void ssd1306_Reset(void)
{
// CS = High (not selected)
HAL_GPIO_WritePin(SSD1306_CS_Port, SSD1306_CS_Pin, GPIO_PIN_SET);
// Reset the OLED
HAL_GPIO_WritePin(SSD1306_Reset_Port, SSD1306_Reset_Pin, GPIO_PIN_RESET);
ssd1306_mdelay(10);
HAL_GPIO_WritePin(SSD1306_Reset_Port, SSD1306_Reset_Pin, GPIO_PIN_SET);
ssd1306_mdelay(10);
}
// Send a byte to the command register
void ssd1306_WriteCommand(uint8_t byte)
{
HAL_GPIO_WritePin(SSD1306_CS_Port, SSD1306_CS_Pin, GPIO_PIN_RESET); // select OLED
HAL_GPIO_WritePin(SSD1306_DC_Port, SSD1306_DC_Pin, GPIO_PIN_RESET); // command
HAL_SPI_Transmit(&SSD1306_SPI_PORT, (uint8_t *) &byte, 1, HAL_MAX_DELAY);
HAL_GPIO_WritePin(SSD1306_CS_Port, SSD1306_CS_Pin, GPIO_PIN_SET); // un-select OLED
}
// Send data
void ssd1306_WriteData(uint8_t* buffer, size_t buff_size)
{
HAL_GPIO_WritePin(SSD1306_CS_Port, SSD1306_CS_Pin, GPIO_PIN_RESET); // select OLED
HAL_GPIO_WritePin(SSD1306_DC_Port, SSD1306_DC_Pin, GPIO_PIN_SET); // data
HAL_SPI_Transmit(&SSD1306_SPI_PORT, buffer, buff_size, HAL_MAX_DELAY);
HAL_GPIO_WritePin(SSD1306_CS_Port, SSD1306_CS_Pin, GPIO_PIN_SET); // un-select OLED
}
// Initialize the oled screen
void ssd1306_Init(void)
{
// Reset OLED
ssd1306_Reset();
// Wait for the screen to boot
ssd1306_mdelay(100);
// Init OLED
ssd1306_SetDisplayOn(0); //display off
ssd1306_WriteCommand(0x20); //Set Memory Addressing Mode
ssd1306_WriteCommand(0x00); // 00b,Horizontal Addressing Mode; 01b,Vertical Addressing Mode;
// 10b,Page Addressing Mode (RESET); 11b,Invalid
ssd1306_WriteCommand(0xB0); //Set Page Start Address for Page Addressing Mode,0-7
#ifdef SSD1306_MIRROR_VERT
ssd1306_WriteCommand(0xC0); // Mirror vertically
#else
ssd1306_WriteCommand(0xC8); //Set COM Output Scan Direction
#endif
ssd1306_WriteCommand(0x00); //---set low column address
ssd1306_WriteCommand(0x10); //---set high column address
ssd1306_WriteCommand(0x40); //--set start line address - CHECK
ssd1306_SetContrast(0xFF);
#ifdef SSD1306_MIRROR_HORIZ
ssd1306_WriteCommand(0xA0); // Mirror horizontally
#else
ssd1306_WriteCommand(0xA1); //--set segment re-map 0 to 127 - CHECK
#endif
#ifdef SSD1306_INVERSE_COLOR
ssd1306_WriteCommand(0xA7); //--set inverse color
#else
ssd1306_WriteCommand(0xA6); //--set normal color
#endif
// Set multiplex ratio.
#if (SSD1306_HEIGHT == 128)
// Found in the Luma Python lib for SH1106.
ssd1306_WriteCommand(0xFF);
#else
ssd1306_WriteCommand(0xA8); //--set multiplex ratio(1 to 64) - CHECK
#endif
#if (SSD1306_HEIGHT == 32)
ssd1306_WriteCommand(0x1F); //
#elif (SSD1306_HEIGHT == 64)
ssd1306_WriteCommand(0x3F); //
#elif (SSD1306_HEIGHT == 128)
ssd1306_WriteCommand(0x3F); // Seems to work for 128px high displays too.
#else
#error "Only 32, 64, or 128 lines of height are supported!"
#endif
ssd1306_WriteCommand(0xA4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
ssd1306_WriteCommand(0xD3); //-set display offset - CHECK
ssd1306_WriteCommand(0x00); //-not offset
ssd1306_WriteCommand(0xD5); //--set display clock divide ratio/oscillator frequency
ssd1306_WriteCommand(0xF0); //--set divide ratio
ssd1306_WriteCommand(0xD9); //--set pre-charge period
ssd1306_WriteCommand(0x22); //
ssd1306_WriteCommand(0xDA); //--set com pins hardware configuration - CHECK
#if (SSD1306_HEIGHT == 32)
ssd1306_WriteCommand(0x02);
#elif (SSD1306_HEIGHT == 64)
ssd1306_WriteCommand(0x12);
#elif (SSD1306_HEIGHT == 128)
ssd1306_WriteCommand(0x12);
#else
#error "Only 32, 64, or 128 lines of height are supported!"
#endif
ssd1306_WriteCommand(0xDB); //--set vcomh
ssd1306_WriteCommand(0x20); //0x20,0.77xVcc
ssd1306_WriteCommand(0x8D); //--set DC-DC enable
ssd1306_WriteCommand(0x14); //
ssd1306_SetDisplayOn(1); //--turn on SSD1306 panel
// Clear screen
ssd1306_Fill(Black);
// Flush buffer to screen
ssd1306_UpdateScreen();
// Set default values for screen object
SSD1306.CurrentX = 0;
SSD1306.CurrentY = 0;
SSD1306.Initialized = 1;
}
下面测试oled显示字符效果:
在main中编写oled显示代码如下:

实际效果如下:
