概述
STM32与SSD1351的接线如下:
PC9 – CS :片选低电平有效
PC8–DC :数据/命令控制
PC7–RST :控制器和驱动器的电源复位RES
PB15–SDA :SPI2_MOSI
PB13–SCL : SPI2_SCK
字模取模方式:阴码 逐行式 顺向
图片取模:16位真彩色 高位在前
/*ssd1351.h*/
#ifndef __ssd1351_H
#define __ssd1351_H
#include "stm32f10x.h"
/* 宏定义 --------------------------------------------------------------------*/
#define Black 0x0000 //黑色(不亮)
#define Navy 0x000F //深蓝色
#define Dgreen 0x03E0 //深绿色
#define Dcyan 0x03EF //深青色
#define Maroon 0x7800 //深红色
#define Purple 0x780F //紫色
#define Olive 0x7BE0 //橄榄绿
#define Lgray 0xC618 //灰白色
#define Dgray 0x7BEF //深灰色
#define Blue 0x001F //蓝色
#define Green 0x07E0 //绿色
#define Cyan 0x07FF //青色
#define Red 0xF800 //红色
#define Magenta 0xF81F //品红
#define Yellow 0xFFE0 //黄色
#define White 0xFFFF //白色
#define Max_Column 0x7f // 128-1
#define Max_Row 0x7f // 128-1
//PC7 LCD_RST 控制器和驱动器的电源复位
#define OLED_RES_GPIO_PORT (GPIOC) //RES#引脚
#define OLED_RES_GPIO_PINS (GPIO_Pin_7)
//PC8 LCD_DC 数据/命令控制
#define OLED_DC_GPIO_PORT (GPIOC) //D/C#引脚
#define OLED_DC_GPIO_PINS (GPIO_Pin_8)
//PC9 LCD_CS 片选 低电平有效
#define OLED_CS_GPIO_PORT (GPIOC) //CS#引脚
#define OLED_CS_GPIO_PINS (GPIO_Pin_9)
#define OLED_RES_Set() GPIO_SetBits(OLED_RES_GPIO_PORT, OLED_RES_GPIO_PINS)
#define OLED_RES_Clr() GPIO_ResetBits(OLED_RES_GPIO_PORT,OLED_RES_GPIO_PINS)
#define OLED_DC_Set() GPIO_SetBits(OLED_DC_GPIO_PORT, OLED_DC_GPIO_PINS)
#define OLED_DC_Clr() GPIO_ResetBits(OLED_DC_GPIO_PORT, OLED_DC_GPIO_PINS)
#define SPI_NSS_HIGH() GPIO_SetBits(OLED_CS_GPIO_PORT, OLED_CS_GPIO_PINS)
#define SPI_NSS_LOW() GPIO_ResetBits(OLED_CS_GPIO_PORT, OLED_CS_GPIO_PINS)
/* 函数声明-------------------------------------------------------------------*/
void OLED_GPIO_Init(void);//IO口初始化
void SPI2_Init(void);//SPI初始化
u8 SPI_RW_Byte(u8 data);//使用SPI0读写1Byte
void Fill_RAM(int Colour_RGB);//填充全屏(刷屏)
void Clear_Screen(unsigned char Var_Row);//指定某一行清屏(一共8行:0~7)
//指定坐标画一个字符(逐行式),字符大小固定为8*16
void Display_Char(unsigned char x, unsigned char y, unsigned char Var_Char, int Colour_RGB);
//显示字符串
void Display_String(unsigned char x, unsigned char y, unsigned char *chr, int Colour_RGB);
//指定坐标画一个字符(逐行式),字符大小固定为16*16
void Display_Chinese16x16(unsigned char x, unsigned char y, unsigned char Var_Char, int Colour_RGB);
//指定坐标画一个字符(逐行式),字符大小固定为12*12
void Display_Chinese12x12(unsigned char x, unsigned char y, unsigned char Var_Char, int Colour_RGB);
//显示数字
void Display_Num(unsigned char x,unsigned char y,int Var_Num, unsigned char Num_Len, int Colour_RGB);
//显示图片
void Display_Pattern(unsigned char *Pattern_Data, unsigned char Start_x, unsigned char End_x, unsigned char Start_y, unsigned char End_y);
//画点
void Draw_Point(const unsigned char x, const unsigned char y, int Colour_RGB);
//画圆圈
void Display_Circle(const u8 x,const u8 y,const u8 r, int Colour_RGB);
//灰阶表设置
void Set_Gray_Scale_Table(void);
//OLED显示初始化
void OLED_Init(void);
#endif
/*ssd1351.c*/
#include "font.h"
/****************************************************
函数名:OLED_GPIO_Init
形参:
返回值:
函数功能:OLED的信号引脚初始化
****************************************************/
void OLED_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //定义结构体
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE); //使能GPIOC时钟
GPIO_InitStructure.GPIO_Pin = OLED_RES_GPIO_PINS | OLED_DC_GPIO_PINS | OLED_CS_GPIO_PINS; //初始化用于控制OLED的相关引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure); //初始化
GPIO_SetBits(GPIOC, OLED_RES_GPIO_PINS | OLED_DC_GPIO_PINS | OLED_CS_GPIO_PINS); //将RES、DC、CS引脚拉高
}
/****************************************************
函数名:SPI2_Init
形参:
返回值:
函数功能:初始化SPI2
****************************************************/
void SPI2_Init(void)
{
/* 定义spi与GPIO配置参数结构体 */
SPI_InitTypeDef SPI_InitStruct;
GPIO_InitTypeDef GPIO_InitStructure;
/* 打开SPI2的端口时钟、AFIO与外设时钟 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15 | GPIO_Pin_13; //初始化PB13(CLK)与PB15(MOSI)
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOB, &GPIO_InitStructure);
SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //全双工
SPI_InitStruct.SPI_Mode = SPI_Mode_Master; //SPI主模式
SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; //8位数据结构
SPI_InitStruct.SPI_CPOL = SPI_CPOL_High; //时钟极性高
SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge; //第二个时钟沿有效
SPI_InitStruct.SPI_NSS = SPI_NSS_Soft; //NSS引脚软件控制
SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;//定义波特率预分频的值:波特率预分频值为256 SPI_BaudRatePrescaler_64
SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB; //高位先发送
SPI_InitStruct.SPI_CRCPolynomial = 7; //CRC校验7
SPI_Init(SPI2, &SPI_InitStruct); //初始化
SPI_Cmd(SPI2, ENABLE); //使能SPI2
}
/****************************************************
函数名:SPI_RW_Byte
形参: data:发送的数据
返回值: temp:读取的数据
函数功能:使用SPI0读写1Byte
****************************************************/
u8 SPI_RW_Byte(u8 data)
{
u8 temp=0; //定义变量读取数据
/* 等待发送缓存器空 */
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);//检查指定的SPI标志位设置与否:发送缓存空标志位
/* 发送数据 */
SPI_I2S_SendData(SPI2, data);
// /* 等待接收缓存器非空 */
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
/* 接收一字节数据 */
temp = SPI_I2S_ReceiveData(SPI2);
return temp;
}
/**
* @函数名 Delay
* @功 能 延迟
* @参 数 data:延迟data
* @返回值 无
*/
static void Delay(uint32_t data)
{
while(data--);
}
/****************************************************
函数名:Write_Command
形参: Cmd:发送的命令
返回值:
函数功能:往OLED发送命令
****************************************************/
void Write_Command(unsigned char Cmd)
{
SPI_NSS_LOW(); //片选拉低,选通器件
OLED_DC_Clr(); //DC拉低,发送命令
SPI_RW_Byte(Cmd); //发送数据
OLED_DC_Set(); //DC拉高,空闲时为高电平
SPI_NSS_HIGH(); //片选拉高,关闭器件
}
/****************************************************
函数名:Write_Data
形参: Data:发送的数据
返回值:
函数功能:往OLED发送数据
****************************************************/
void Write_Data(unsigned char Data)
{
SPI_NSS_LOW(); //片选拉低,选通器件
OLED_DC_Set(); //DC拉高,发送数据
SPI_RW_Byte(Data); //发送数据
OLED_DC_Clr();
SPI_NSS_HIGH(); //片选拉高,关闭器件
}
/****************************************************
函数名:Set_Column_Address
形参: Clo_Start:列起始地址;Clo_End:列结束地址 0-127
返回值:
函数功能:设置列地址
****************************************************/
void Set_Column_Address(unsigned char Clo_Start, unsigned char Clo_End)
{
Write_Command(0x15); // 设置列地址
Write_Data(Clo_Start); // 列起始地址
Write_Data(Clo_End); // 列结束地址
}
/****************************************************
函数名:Set_Row_Address
形参: Row_Start:行起始地址;Row_End:行结束地址
返回值:
函数功能:设置行地址
****************************************************/
void Set_Row_Address(unsigned char Row_Start, unsigned char Row_End)
{
Write_Command(0x75); // 设置行地址
Write_Data(Row_Start); // 行起始地址
Write_Data(Row_End); // 行结束地址
}
/****************************************************
函数名:Set_Write_RAM
形参:
返回值:
函数功能:使能MCU写RAM
****************************************************/
void Set_Write_RAM()
{
Write_Command(0x5C); //使能MCU写RAM
}
/****************************************************
函数名:Set_Read_RAM
形参:
返回值:
函数功能:使能MCU读RAM
****************************************************/
void Set_Read_RAM()
{
Write_Command(0x5D); //使能MCU读RAM
}
/****************************************************
函数名:Fill_RAM
形参: Colour_RGB:填充颜色:RRRRRGGGGGGBBBBB
返回值:
函数功能:填充全屏(刷屏)
****************************************************/
void Fill_RAM(int Colour_RGB)
{
unsigned char i,j; //定义变量
Set_Column_Address(0x00,0x7F); //设置列地址0~127
Set_Row_Address(0x00,0x7F); //设置行地址0~127
Set_Write_RAM(); //使能MCU写RAM
for(i=0; i<128; i++) //填充128列*128行
{
for(j=0; j<128; j++)
{
Write_Data(Colour_RGB >> 8); //写入填充颜色高字节
Write_Data(Colour_RGB); //写入填充颜色低字节
}
}
}
/****************************************************
函数名:Clear_Screen
形参: Var_Row:第Var_Row行
返回值:
函数功能:指定某一行清屏(一共8行:0~7)
****************************************************/
void Clear_Screen(unsigned char Var_Row)
{
unsigned int i;
Set_Column_Address(0x00, 0x7F); //设置列地址0~127
Set_Row_Address(Var_Row*16, (Var_Row*16 + 15)); //设置行地址
Set_Write_RAM(); //使能MCU写RAM
for(i = 0; i < 2048; i++) //把这一行清屏,点数量 = 16*128 = 2048
{
Write_Data(0x00);
Write_Data(0x00);
}
}
/****************************************************
函数名:Draw_Point
形参: x:列起始地址;y:行起始地址;Colour_RGB:填充颜色:RRRRRGGGGGGBBBBB
返回值:
函数功能:画点
****************************************************/
void Draw_Point(const unsigned char x, const unsigned char y, int Colour_RGB)
{
Write_Command(0x15); // 设置列地址
Write_Data(x);
Write_Command(0x75); // 设置行地址
Write_Data(y);
Set_Write_RAM(); //使能MCU写RAM
Write_Data(Colour_RGB >> 8); //写入填充颜色高字节
Write_Data(Colour_RGB); //写入填充颜色低字节
}
/****************************************************
函数名:Display_Char
形参: x:列起始地址;y:行起始地址;Var_Char:写入的字符;Colour_RGB:填充颜色:RRRRRGGGGGGBBBBB
返回值:
函数功能:指定坐标画一个字符(逐行式),字符大小固定为8*16
****************************************************/
void Display_Char(unsigned char x, unsigned char y, unsigned char Var_Char, int Colour_RGB)
{
unsigned char i, j; //定义变量
unsigned char Var_Temp, x_Temp; //定义变量
x_Temp = x; //获取x起始坐标
for (i = 0; i < 16; i++)
{
Var_Temp = ACSII_Font[Var_Char - 0x20][i]; //获取字符在数组的偏移量
for ( j = 0; j < 8; j++)
{
if (Var_Temp & 0x80) //先画最高位的点,为1则画对应的颜色
Draw_Point(x, y, Colour_RGB);
//else
//Draw_Point(x, y, 0x0000); //为0则黑色(都不亮),可作为背景色
Var_Temp <<= 1; //移位,准备画下一个点
x++; //x坐标加1
if((x - x_Temp) == 8)
{
x = x_Temp; //x坐标回到起始位置
y++; //y坐标加1
break; //退出当前循环
}
}
}
}
/****************************************************
函数名:Display_String
形参: x:列起始地址;y:行起始地址;*chr:显示的字符串;Colour_RGB:填充颜色:RRRRRGGGGGGBBBBB
返回值:
函数功能:显示字符串
****************************************************/
void Display_String(unsigned char x, unsigned char y, unsigned char *chr, int Colour_RGB)
{
unsigned char i = 0; //定义变量
while(chr[i] != '