STM32硬件SPI驱动0.96寸的OLED
2017-11-30 22:21
543 查看
1.OLED相关
参见—->51 软件模拟SPI驱动OLED2.硬件SPI
参见—->SPI专题(二)——STM32驱动FLASH(W25Q64)3.驱动程序
驱动程序参照51单片机进行移植,只不过模拟的SPI换成STM32硬件SPI,不用再写时序部分的代码。对于STM32的硬件SPI,我们在驱动FLASH中已有介绍,这里就不再做介绍。OLED引脚部分定义:
#ifndef __OLED_H #define __OLED_H #include "spi.h" #include "stm32f10x.h" #include "stm32f10x_conf.h" #define Max_Column 128 #define Max_Row 64 #define SIZE 16 //显示字体选择 #define RCC_APB2Periph_OLED_PORT RCC_APB2Periph_GPIOA #define OLED_PORT GPIOA #define OLED_CS_PIN GPIO_Pin_2 #define OLED_CS_LOW GPIO_ResetBits(GPIOA,GPIO_Pin_2) #define OLED_CS_HIGH GPIO_SetBits(GPIOA,GPIO_Pin_2) #define OLED_DC_PIN GPIO_Pin_3 #define OLED_DC_LOW GPIO_ResetBits(GPIOA,GPIO_Pin_3) #define OLED_DC_HIGH GPIO_SetBits(GPIOA,GPIO_Pin_3) #define OLED_RST_PIN GPIO_Pin_4 #define OLED_RST_LOW GPIO_ResetBits(GPIOA,GPIO_Pin_4) #define OLED_RST_HIGH GPIO_SetBits(GPIOA,GPIO_Pin_4) #define OLED_CLK_PIN GPIO_Pin_5 #define OLED_DATA_PIN GPIO_Pin_7 void SPI_OLED_Init(void); void OLED_Write_Byte(uint8_t dat); void OLED_Write_Data(uint8_t dat); void OLED_Write_Cmd(uint8_t cmd); void OLED_Set_Pos(u8 x,u8 y); void OLED_Display_On(void); void OLED_Display_Off(void); void OLED_Display_Clear(void); void OLED_Display_Onechar(u8 x,u8 y,u8 str); void OLED_Display_String(u8 x,u8 y,u8 *str); void OLED_Display_Chinese(u8 x,u8 y,u8 no); void OLED_Display_Picture(u8 x0,u8 y0,u8 x1,u8 y1,u8 BMP[]); u32 OLED_Pow(u8 m,u8 n); void OLED_Display_Num(u8 x,u8 y,u32 num,u8 len,u8 size_num); void OLED_Init(void); #endif
连接的时候需要看清楚,一开始我就不小心把SPI的CLK与DO接反了,半天找不到原因,这种问题就太低级了,一定得多细心。
OLED初始化:
void SPI_OLED_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_OLED_PORT, ENABLE ); //片选信号初始化 GPIO_InitStructure.GPIO_Pin = OLED_CS_PIN|OLED_DC_PIN|OLED_RST_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //复用推挽输出 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(OLED_PORT, &GPIO_InitStructure); GPIO_SetBits(OLED_PORT,OLED_CS_PIN|OLED_DC_PIN|OLED_RST_PIN); SPI1_Init(); //初始化SPI SPI1_SetSpeed(SPI_BaudRatePrescaler_16); //设置为18M时钟,高速模式 }
OLED写数据实现:
//硬件SPI发送数据 void OLED_Write_Byte(uint8_t dat) { SPI1_ReadWriteByte(dat); } //写入数据 void OLED_Write_Data(uint8_t dat) { OLED_CS_LOW; OLED_DC_HIGH; OLED_Write_Byte(dat); } //写入命令 void OLED_Write_Cmd(uint8_t cmd) { OLED_CS_LOW; OLED_DC_LOW; OLED_Write_Byte(cmd); }
下面就是OLED的具体实现,开启,初始化,写一个字节,写字符串等,也是在51MCU的基础上修改而成。
//Function:设置显示坐标 //Input:x:横坐标;y:纵坐标 //Output:无 //Return:无 //Others:无 void OLED_Set_Pos(uint8_t x,uint8_t y) { OLED_Write_Cmd(0xb0+y);//列偏移 OLED_Write_Cmd(((x&0xf0)>>4)|0x10);//行高四位地址 OLED_Write_Cmd((x&0x0f)|0X01);//行低四位地址 } //Function:开启OLED显示 //Input:无 //Output:无 //Return:无 //Others:无 void OLED_Display_On(void) { OLED_Write_Cmd(0X8D);//设置DCDC OLED_Write_Cmd(0X14);//打开DCDC OLED_Write_Cmd(0XAF);//打开OLED } //Function:关闭OLED显示 //Input:无 //Output:无 //Return:无 //Others:无 void OLED_Display_Off(void) { OLED_Write_Cmd(0X8D);//设置DCDC OLED_Write_Cmd(0X10);//关闭DCDC OLED_Write_Cmd(0XAE);//关闭OLED } //Function:清屏 //Input:无 //Output:无 //Return:无 //Others:无 void OLED_Display_Clear(void) { u8 page,len; for(page=0;page<8;page++) { OLED_Write_Cmd(0xB0+page);//设置页地址(0--7) OLED_Write_Cmd(0X00);//设置显示位置—列低地址 OLED_Write_Cmd(0X10); //设置显示位置—列高地址 for(len=0;len<128;len++) OLED_Write_Data(0);//写入0;屏熄灭 } } //Function:在指定位置显示一个字符,包括部分字符 //x:0~127;y:0~63;size:选择字体 16/12 //Input:x:横坐标;y:纵坐标;str:显示的字符 //Output:无 //Return:无 //Others:无 void OLED_Display_Onechar(u8 x,u8 y,u8 str) { u8 i=0,ret=0; //ret = str -32; ret = str - ' ';//得到偏移后的值,对ASCLL码进行一个减法.即在二维数组里找它的位置 if(x>Max_Column-1) { x = 0; y = y + 2;//针对16号的字符 } if(SIZE == 16 ) { OLED_Set_Pos(x,y); //16的字体分成两部分写入 for(i=0;i<8;i++) OLED_Write_Data(F8X16[ret*16+i]); OLED_Set_Pos(x,y+1); for(i=0;i<8;i++) OLED_Write_Data(F8X16[ret*16+i+8]); } else{ OLED_Set_Pos(x,y+1); for(i=0;i<6;i++) OLED_Write_Data(F6x8[ret][i]); } } //Function:显示字符串 //Input:x:横坐标;y:纵坐标;str:显示的字符串 //Output:无 //Return:无 //Others:无 void OLED_Display_String(u8 x,u8 y,u8 *str) { u8 i=0; while(str[i]!='\0') { OLED_Display_Onechar(x,y,str[i]); x += 8; if(x>120) { x = 0; y += 2; } i++; } } //Function:显示中文 //Input:x:横坐标;y:纵坐标;no:显示的字的序号 //Output:无 //Return:无 //Others:无 void OLED_Display_Chinese(u8 x,u8 y,u8 no) { u8 ch,addr=0; OLED_Set_Pos(x,y); for(ch=0;ch<16;ch++)//数组行列寻址 { OLED_Write_Data(TEST[2*no][ch]);//汉字是2个字节 addr += 1; } OLED_Set_Pos(x,y+1); for(ch=0;ch<16;ch++) { OLED_Write_Data(TEST[2*no+1][ch]); addr += 1; } } //Function:显示图片 //Input:x0,x1:横坐标;y0,y1:纵坐标;BMP:显示的图片 //注意:y1<8,页寻址模式 //Output:无 //Return:无 //Others:无 void OLED_Display_Picture(u8 x0,u8 y0,u8 x1,u8 y1,u8 BMP[]) { u8 x,y; u32 i=0; if(y1%8==0) y = y1 / 8; else y = y1 /8 + 1; for(y=y0;y<y1;y++) { OLED_Set_Pos(x0,y); for(x=x0;x<x1;x++) { OLED_Write_Data(BMP[i++]); } } } //计算m的n次方 u32 OLED_Pow(u8 m,u8 n) { u32 ret = 1; while(n--) ret *= m; return ret; } //Function:显示数字 //Input:x:横坐标;1:纵坐标;num:显示的数字:len:数字长度;size_num:数字字体 //Output:无 //Return:无 //Others:无 void OLED_Display_Num(u8 x,u8 y,u32 num,u8 len,u8 size_num) { u8 t,temp; u8 enshow = 0; for(t=0;t<len;t++) { temp = (num/OLED_Pow(10,len-t-1))%10;//把显示的数字一位一位取出来 if(enshow==0&&t<(len-1)) { if(temp==0) { OLED_Display_Onechar(x+(size_num/2)*t,y,' '); continue; } else enshow = 1; } OLED_Display_Onechar(x+(size_num/2)*t,y,temp+'0'); } } //初始化SSD1306 //命令设置与开启函数作用重叠...... void OLED_Init(void) { SPI_OLED_Init(); OLED_RST_HIGH; delay_ms(200); OLED_RST_LOW; delay_ms(200); OLED_RST_HIGH; OLED_Write_Cmd(0xAE);//关闭OLED OLED_Write_Cmd(0x00);//设置列低位地址 OLED_Write_Cmd(0x10);//设置列高位地址 OLED_Write_Cmd(0x40);//设置起始行地址及映射RAM显示起始行 (0x00~0x3F) OLED_Write_Cmd(0x81);//对比度设置 OLED_Write_Cmd(0xCF); // Set SEG Output Current Brightness OLED_Write_Cmd(0xA1);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常 OLED_Write_Cmd(0xC8);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常 OLED_Write_Cmd(0xA6);//设置显示方式;bit0:1,反相显示;0,正常显示 OLED_Write_Cmd(0xA8);//设置驱动路数(1 to 64) OLED_Write_Cmd(0x3f);//--1/64 duty OLED_Write_Cmd(0xD3);//-设置显示偏移(0x00~0x3F) OLED_Write_Cmd(0x00);//-not offset OLED_Write_Cmd(0xd5);//--set display clock divide ratio/oscillator frequency OLED_Write_Cmd(0x80);//--set divide ratio, Set Clock as 100 Frames/Sec OLED_Write_Cmd(0xD9);//--set pre-charge period OLED_Write_Cmd(0xF1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock OLED_Write_Cmd(0xDA);//--set com pins hardware configuration OLED_Write_Cmd(0x12); OLED_Write_Cmd(0xDB);//--set vcomh OLED_Write_Cmd(0x40);//Set VCOM Deselect Level OLED_Write_Cmd(0x20);//设置页地址模式(0x00/0x01/0x02) OLED_Write_Cmd(0x02);// OLED_Write_Cmd(0x8D);//--set Charge Pump enable/disable OLED_Write_Cmd(0x14);//--set(0x10) disable OLED_Write_Cmd(0xA4);//禁用显示开启;bit0:1,开启;0,关闭;(白屏/黑屏)(0xa4/0xa5) OLED_Write_Cmd(0xA6);// 不使用反向显示 (0xa6/a7) OLED_Write_Cmd(0xAF);//打开显示 OLED_Write_Cmd(0xAF); /*display ON*/ OLED_Display_Clear(); OLED_Set_Pos(0,0); }
实现效果:
相关文章推荐
- STM32之SPI驱动液晶屏的一个问题
- STM32 SPI驱动TFT LCD
- STM32学习笔记之硬件SPI读写与极性设置
- STM32F4使用硬件SPI驱动ADS8322
- spi子系统之驱动SSD1306 OLED
- stm32 ssD1306 OLED驱动架构
- STM32下SPI模式通过MAX7219驱动8位数码管显示模块
- SPI驱动模型---Oled
- STM32 3个硬件SPI的使用
- STM8S1003 硬件SPI 驱动 SI4432 注意CPOL = 0,CPHA=0
- 基于TQ2440的SPI驱动学习(OLED)
- SPI_OLED驱动
- stm32驱动3.2寸触摸屏(包括IO模拟,SPI硬件接口)
- FPGA驱动OLED动态显示(Verilog代码)——SPI写操作
- 基于STM32的OLED与TFTLCD详解1(IC驱动及FSMC初探)
- 【STM32小案例 02 】实现DHT11,BH1750与0.96寸OLED的动态显示
- stm32 SD卡 SPI驱动以及fatfs移植
- STM8L151 使用硬件SPI驱动W25Q16 Flash
- [stm32] 一个简单的stm32vet6驱动的天马4线SPI-1.77寸LCD彩屏DEMO
- 【STM32小案例 03 】实现DHT11,BH1750,GP2Y与0.96寸OLED的动态显示