/********************************************************************************/
/* @file ssd1306.c */
/* @version V1.00 */
/* $author: yuanxihua@21cn.com */
/* $Date: 2018/11/27 23:39p $ */
/* @brief SWM320RBT6 Series SSD1306 Driver Sample Code */
/* */
/* @note */
/* Copyright (C) 2010-2019 PM9GZY Technology Corp. All rights reserved. */
/* */
/********************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "dotcode.h"
/*
_________________________________________________
| SWM320RBT6 SSD1306 |
| |
| PB0 PDN ----> PDN |
| PP9 LRST ----> RST |
| PP8 NSS0 ----> SCS |
| PP7 MISO0 <---- SDC |
| PP6 MOSI0 ----> SDA |
| PP5 SCLK0 ----> SCK |
|_______________________________________________|
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define SSD1306_CMD() GPIO_ClrBit(GPIOP, PIN7)
#define SSD1306_DAT() GPIO_SetBit(GPIOP, PIN7)
#define SSD1306_PON() GPIO_ClrBit(GPIOB, PIN0)
#define SSD1306_OFF() GPIO_SetBit(GPIOB, PIN0)
#define SSD1306_RST() GPIO_ClrBit(GPIOP, PIN9)
#define SSD1306_NST() GPIO_SetBit(GPIOP, PIN9)
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
void SPI0Init(void)
{
SPI_InitStructure SPI_initStruct;
GPIO_Init(GPIOB, PIN0, 1, 0, 0);
GPIO_Init(GPIOP, PIN9, 1, 0, 0);
PORT_Init(PORTP, PIN5 , FUNMUX1_SPI0_SCLK, 0);
PORT_Init(PORTP, PIN6 , FUNMUX0_SPI0_MOSI, 0);
GPIO_Init(GPIOP, PIN7, 1, 0, 0);//FUNMUX1_SPI0_MISO
PORT_Init(PORTP, PIN8, FUNMUX0_SPI0_SSEL, 0);
SPI_initStruct.clkDiv = SPI_CLKDIV_4;//0.04US
// SPI_initStruct.clkDiv = SPI_CLKDIV_8;//0.07US
// SPI_initStruct.clkDiv = SPI_CLKDIV_16;//0.14US
// SPI_initStruct.clkDiv = SPI_CLKDIV_32;//0.26US
// SPI_initStruct.clkDiv = SPI_CLKDIV_64;//0.53S
// SPI_initStruct.clkDiv = SPI_CLKDIV_128;//1.07US
// SPI_initStruct.clkDiv = SPI_CLKDIV_256;//2.14US
// SPI_initStruct.clkDiv = SPI_CLKDIV_512;//4.28US
SPI_initStruct.FrameFormat = SPI_FORMAT_SPI;
SPI_initStruct.SampleEdge = SPI_FIRST_EDGE;
SPI_initStruct.IdleLevel = SPI_LOW_LEVEL;
SPI_initStruct.WordSize = 8;
SPI_initStruct.Master = 1;
SPI_initStruct.RXHFullIEn = 0;
SPI_initStruct.TXEmptyIEn = 0;
SPI_initStruct.TXCompleteIEn = 0;
SPI_Init(SPI0, &SPI_initStruct);
SPI_Open(SPI0);
}
void SSD1306_WriteCMD(uint8_t cmd)
{
SSD1306_CMD();
uint8_t r=SPI_ReadWrite(SPI0,cmd);
}
void SSD1306_WriteDAT(uint8_t dat)
{
SSD1306_DAT();
uint8_t r=SPI_ReadWrite(SPI0,dat);
}
void OLED_Init(void)
{
SPI0Init();
SSD1306_OFF();
osDelay(100);
SSD1306_PON();
SSD1306_RST();
osDelay(100);
SSD1306_NST();
osDelay(200); //这里的延时很重要
SSD1306_WriteCMD(0xAE); //display off
SSD1306_WriteCMD(0x20); //Set Memory Addressing Mode
SSD1306_WriteCMD(0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
SSD1306_WriteCMD(0xb0); //Set Page Start Address for Page Addressing Mode,0-7
SSD1306_WriteCMD(0xc8); //Set COM Output Scan Direction
SSD1306_WriteCMD(0x00); //---set low column address
SSD1306_WriteCMD(0x10); //---set high column address
SSD1306_WriteCMD(0x40); //--set start line address
SSD1306_WriteCMD(0x81); //--set contrast control register
SSD1306_WriteCMD(0xff); //亮度调节 0x00~0xff
SSD1306_WriteCMD(0xa1); //--set segment re-map 0 to 127
SSD1306_WriteCMD(0xa6); //--set normal display
SSD1306_WriteCMD(0xa8); //--set multiplex ratio(1 to 64)
SSD1306_WriteCMD(0x3F); //
SSD1306_WriteCMD(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
SSD1306_WriteCMD(0xd3); //-set display offset
SSD1306_WriteCMD(0x00); //-not offset
SSD1306_WriteCMD(0xd5); //--set display clock divide ratio/oscillator frequency
SSD1306_WriteCMD(0xf0); //--set divide ratio
SSD1306_WriteCMD(0xd9); //--set pre-charge period
SSD1306_WriteCMD(0x22); //
SSD1306_WriteCMD(0xda); //--set com pins hardware configuration
SSD1306_WriteCMD(0x12);
SSD1306_WriteCMD(0xdb); //--set vcomh
SSD1306_WriteCMD(0x20); //0x20,0.77xVcc
SSD1306_WriteCMD(0x8d); //--set DC-DC enable
SSD1306_WriteCMD(0x14); //
SSD1306_WriteCMD(0xaf); //--turn on oled panel
}
void OLED_Origin(unsigned char x, unsigned char y) //设置起始点坐标
{
SSD1306_WriteCMD(0xb0+y);
SSD1306_WriteCMD(((x&0xf0)>>4)|0x10);
SSD1306_WriteCMD((x&0x0f)|0x01);
}
void OLED_Wakeup(void) //将OLED从休眠中唤醒
{
SSD1306_WriteCMD(0X8D); //设置电荷泵
SSD1306_WriteCMD(0X14); //开启电荷泵
SSD1306_WriteCMD(0XAF); //OLED唤醒
}
void OLED_Sleep(void) //让OLED休眠 -- 休眠模式下,OLED功耗不到10uA
{
SSD1306_WriteCMD(0X8D); //设置电荷泵
SSD1306_WriteCMD(0X10); //关闭电荷泵
SSD1306_WriteCMD(0XAE); //OLED休眠
}
void OLED_Fill(uint8_t data) //全屏填充
{
unsigned char m,n;
for(m=0;m<8;m++)
{
SSD1306_WriteCMD(0xb0+m); //page0-page1
SSD1306_WriteCMD(0x00); //low column start address
SSD1306_WriteCMD(0x10); //high column start address
for(n=0;n<128;n++)
{
SSD1306_WriteDAT(data);
}
}
}
//--------------------------------------------------------------
// Prototype : void OLED_ShowChar(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize)
// Calls :
// Parameters : x,y -- 起始点坐标(x:0~127, y:0~7); ch[] -- 要显示的字符串; TextSize -- 字符大小(1:6*8 ; 2:8*16)
// Description : 显示codetab.h中的ASCII字符,有6*8和8*16可选择
//--------------------------------------------------------------
void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize)
{
unsigned char c = 0,i = 0,j = 0;
switch(TextSize)
{
case 1:
{
while(ch[j] != '\0')
{
c = ch[j] - 32;
if(x > 126)
{
x = 0;
y++;
}
OLED_Origin(x,y);
for(i=0;i<6;i++){SSD1306_WriteDAT(F6x8[c][i]);}
x += 6;
j++;
}
}break;
case 2:
{
while(ch[j] != '\0')
{
c = ch[j] - 32;
if(x > 120)
{
x = 0;
y++;
}
OLED_Origin(x,y);
for(i=0;i<8;i++)
SSD1306_WriteDAT(F8X16[c*16+i]);
OLED_Origin(x,y+1);
for(i=0;i<8;i++)
SSD1306_WriteDAT(F8X16[c*16+i+8]);
x += 8;
j++;
}
}break;
}
}
//--------------------------------------------------------------
// Prototype : void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N)
// Calls :
// Parameters : x,y -- 起始点坐标(x:0~127, y:0~7); N:汉字在codetab.h中的索引
// Description : 显示codetab.h中的汉字,16*16点阵
//--------------------------------------------------------------
void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N)
{
unsigned char wm=0;
unsigned int adder=32*N;
OLED_Origin(x,y+0);for(wm=0;wm<16;wm++){SSD1306_WriteDAT(F16x16[adder++]);}
OLED_Origin(x,y+1);for(wm=0;wm<16;wm++){SSD1306_WriteDAT(F16x16[adder++]);}
}
//--------------------------------------------------------------
// Prototype : void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[]);
// Calls :
// Parameters : x0,y0 -- 起始点坐标(x0:0~127, y0:0~7); x1,y1 -- 起点对角线(结束点)的坐标(x1:1~128,y1:1~8)
// Description : 显示BMP位图
//--------------------------------------------------------------
void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[])
{
unsigned int j=0;
unsigned char x,y;
if(y1%8==0){y = y1/8;}else{y = y1/8 + 1;}
for(y=y0;y<y1;y++)
{
OLED_Origin(x0,y);
for(x=x0;x<x1;x++){SSD1306_WriteDAT(BMP[j++]);}
}
}
void OLED_Welcome(void)
{
uint32_t i;
OLED_Init();
{
// OLED_Fill(0xFF);//全屏点亮
// osDelay(100);
OLED_Fill(0x00);//全屏灭
// osDelay(500);
for(i=0;i<4;i++)
{
OLED_ShowCN(32+i*16,0,i);//测试显示中文
}
// osDelay(2000);
OLED_ShowStr(40,3,"PM9GZY",2); //测试8*16字符
OLED_ShowStr(13,5,"yuanxihua@139.com",1); //测试6*8 字符
osDelay(1000);
// OLED_Fill(0);//清屏
// OLED_DrawBMP(0,0,128,8,(unsigned char *)BMP1);//测试BMP位图显示
// osDelay(1000);
}
}
void SSD1306_Test(void)
{
// uint32_t i;
// while(1)
// {
// SSD1306_WriteCMD(0x55);
// SSD1306_WriteDAT(0xAA);
// }
OLED_Init();
OLED_Fill(0xff);
osDelay(100);
}
void OLED_Volute(float *vol)
{
unsigned char buf[20];
OLED_Fill(0x00);//全屏灭
for(int i=0;i<4;i++){OLED_ShowCN(32+i*16,0,i);}//测试显示中文
sprintf((char *)buf,"CH1: %3.10f V",vol[0]);OLED_ShowStr(0,3,buf,1);
sprintf((char *)buf,"CH2: %3.10f V",vol[1]);OLED_ShowStr(0,4,buf,1);
sprintf((char *)buf,"CH3: %3.10f V",vol[2]);OLED_ShowStr(0,5,buf,1);
sprintf((char *)buf,"CH4: %3.10f V",vol[3]);OLED_ShowStr(0,6,buf,1);
}
void OLED_Battery(uint16_t bat)
{
uint16_t x=122-((36*bat)/100);if(x>122){x=122;}if(x<86){x=86;}
char str[10];sprintf(str,"%d%%",bat);
OLED_ShowStr(10,0,(unsigned char*)str,2); //测试8*16字符
OLED_Origin(79 ,0);for(int i=79 ;i<82 ;i++){SSD1306_WriteDAT(0xE0);}
OLED_Origin(79 ,1);for(int i=79 ;i<82 ;i++){SSD1306_WriteDAT(0x07);}
OLED_Origin(82 ,0);for(int i=82 ;i<84 ;i++){SSD1306_WriteDAT(0xff);}
OLED_Origin(82 ,1);for(int i=82 ;i<84 ;i++){SSD1306_WriteDAT(0xff);}
OLED_Origin(84 ,0);for(int i=84 ;i<86 ;i++){SSD1306_WriteDAT(0x03);}
OLED_Origin(84 ,1);for(int i=84 ;i<86 ;i++){SSD1306_WriteDAT(0xC0);}
OLED_Origin(86 ,0);for(int i=86 ;i<123;i++){SSD1306_WriteDAT((i>=x)?0xF3:0x03);}
OLED_Origin(86 ,1);for(int i=86 ;i<123;i++){SSD1306_WriteDAT((i>=x)?0xCF:0xC0);}
OLED_Origin(123,0);for(int i=123;i<125;i++){SSD1306_WriteDAT(0x03);}
OLED_Origin(123,1);for(int i=123;i<125;i++){SSD1306_WriteDAT(0xC0);}
OLED_Origin(125,0);for(int i=125;i<127;i++){SSD1306_WriteDAT(0xff);}
OLED_Origin(125,1);for(int i=125;i<127;i++){SSD1306_WriteDAT(0xff);}
}
void OLED_Digital(unsigned char x, unsigned char y, unsigned char N)
{
unsigned char wm=0;unsigned int adder=64*N;
OLED_Origin(x,y+0);for(wm=0;wm<16;wm++){SSD1306_WriteDAT(F32X32[adder++]);}
OLED_Origin(x,y+1);for(wm=0;wm<16;wm++){SSD1306_WriteDAT(F32X32[adder++]);}
OLED_Origin(x,y+2);for(wm=0;wm<16;wm++){SSD1306_WriteDAT(F32X32[adder++]);}
OLED_Origin(x,y+3);for(wm=0;wm<16;wm++){SSD1306_WriteDAT(F32X32[adder++]);}
}
void OLED_pCHz(uint16_t bat,uint32_t pchz,uint8_t PC)
{
OLED_Fill(0x00);//全屏灭
OLED_Battery(bat);
if(pchz>999){OLED_Digital(20,2, pchz/1000);pchz%=1000;
if(pchz<100){OLED_Digital(40,2, 0);}if(pchz<10){OLED_Digital(60,2, 0);}}
if(pchz>99 ){OLED_Digital(40,2, pchz/100 );pchz%=100;
if(pchz<10 ){OLED_Digital(60,2, 0);}}
if(pchz>9 ){OLED_Digital(60,2, pchz/10 );pchz%=10 ;}
OLED_Digital(80,2, pchz);
if(PC){OLED_ShowStr(108,7,"p",1);OLED_ShowStr(116,6,"C",2);}
else {OLED_ShowStr(108,6,"H",2);OLED_ShowStr(116,7,"z",1);}
}
离线