您尚未登录。

楼主 #1 2020-05-09 21:55:24

缥缈九哥
会员
注册时间: 2020-05-09
已发帖子: 93
积分: 96

基于华芯微特SWM320的SSD1306显示器的驱动开发--缥缈九哥

/********************************************************************************/
/* @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);}	
}

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn