这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 【换取手持数字示波器】+利用STM32F103C8T6芯片,0.96寸液晶屏显示

共2条 1/1 1 跳转至

【换取手持数字示波器】+利用STM32F103C8T6芯片,0.96寸液晶屏显示与MPL3115A模块对大气压,海拔和温度的读取

菜鸟
2024-06-12 20:05:33   被打赏 43 分(兑奖)     打赏


简介:利用STM32F103C8T6芯片,0.96寸液晶屏显示与MPL3115A模块对大气压,海拔和温度的读取。

 利用STM32作为主控对MPL3115A模块进行读取,并将显示的大气压值,温度值显示到液晶屏上面。

MPL3115A模块介绍:

20bit压力测量(Pascal);20bit高度测量(米);12bit温度测量;

绝对压力测量范围:20110 kPa

相对测量精度: - + 0.05 kPa

有效分辨率:1.5Pa / 0.3m

工作温度范围:-4085摄氏度;

I2C数字输出接口;

内置32FIFO采样缓冲区;

软件代码流程如下:

/*配置SDA的IO口模式信息*/
void GPIO_Output_I2C_Configuration(GPIO_TypeDef* SDA, u16 GPIO_Pin)
{
    GPIO_InitTypeDef GPIO_Initstructure;
    GPIO_Initstructure.GPIO_Pin = GPIO_Pin;
    GPIO_Initstructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Initstructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(SDA, &GPIO_Initstructure);
}
/*配置SCL的IO口模式信息*/
void GPIO_Input_I2C_Configuration(GPIO_TypeDef* SDA, u16 GPIO_Pin)
{
    GPIO_InitTypeDef GPIO_Initstructure;
    GPIO_Initstructure.GPIO_Pin = GPIO_Pin;
    GPIO_Initstructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(SDA, &GPIO_Initstructure);
}
/*IIC总线启动*/
void I2C_Start ()//I2C开始
{
    GPIO_Output_I2C_Configuration(SCL.GPIOx, SCL.GPIO_Pin); //SCL置输出
    GPIO_Output_I2C_Configuration(SDA.GPIOx, SDA.GPIO_Pin); //SDA置输出
    GPIO_SetBits(SDA.GPIOx, SDA.GPIO_Pin);//SDA=1;
    delay_us(50);                         //此处延时50us                   
    GPIO_SetBits(SCL.GPIOx, SCL.GPIO_Pin);//SCL=1;
    delay_us(50);                         //此处延时50us
    GPIO_ResetBits(SDA.GPIOx, SDA.GPIO_Pin);//SDA=0;
    delay_us(50);                         //此处延时50us
    GPIO_ResetBits(SCL.GPIOx, SCL.GPIO_Pin);//SCL=0;
    delay_us(50);                         //此处延时50us
}

/*IIC总线结束*/
void I2C_Stop () //I2C结束
{
    GPIO_Output_I2C_Configuration(SDA.GPIOx, SDA.GPIO_Pin);  //SDA置输出
    GPIO_ResetBits(SDA.GPIOx, SDA.GPIO_Pin);//SDA=0;
    delay_us(50);                         //此处延时50us
    GPIO_SetBits(SCL.GPIOx, SCL.GPIO_Pin);//SCL=1;
    delay_us(50);                         //此处延时50us
    GPIO_SetBits(SDA.GPIOx, SDA.GPIO_Pin);//SDA=1;
    delay_us(50);                         //此处延时50us
}

/*主机检查从机的响应信号*/
int I2C_Slave_ACK(void)    //  检查从机应答信号,返回0有ACK,返回1无ACK
{
    int ACK;
    u8  s1;
    GPIO_Input_I2C_Configuration(SDA.GPIOx, SDA.GPIO_Pin); //SDA置输入
    GPIO_SetBits(SCL.GPIOx, SCL.GPIO_Pin);//SCL=1;
    delay_us(50);                         //此处延时50us
    s1 = GPIO_ReadInputDataBit(SDA.GPIOx, SDA.GPIO_Pin);
    if (s1)                                  //判断返回的数据类型,确定是否正常
    {
        ACK = 1;
    }
    else
    {
        ACK = 0;
    }
    GPIO_ResetBits(SCL.GPIOx, SCL.GPIO_Pin);//SCL=0;
    delay_us(50);                           //此处延时50us
    return(ACK);                            //返回应答信号
}

/*主机发送IIC总线上一个字节数据*/
void I2C_SendByte(u8 data)   //发送一个字节
{
    u8 i;          //发送8位
    GPIO_Output_I2C_Configuration(SDA.GPIOx, SDA.GPIO_Pin);  //SDA置输出
    for(i = 0; i < 8; i++)                                            
    {
        if((data & 0x80) == 0x80)
        {
            GPIO_SetBits(SDA.GPIOx, SDA.GPIO_Pin);
        }                                                  //SDA=1,写 1
        else
        {
            GPIO_ResetBits(SDA.GPIOx, SDA.GPIO_Pin);
        }                                                  //SDA=0,写 0
        GPIO_SetBits(SCL.GPIOx, SCL.GPIO_Pin);  //SCL=1;
        delay_us(50);                     //在时钟大于4u秒期间写数据
        GPIO_ResetBits(SCL.GPIOx, SCL.GPIO_Pin);//SCL=0;
        delay_us(50);                         //此处延时50us
        data = data << 1;                 //将返回的数据进行移位处理
    }
}

/*主机接收IIC总线上一个字节数据*/
u8 I2C_ReciveByte(void)             //接受一个字节
{
    u8 s1 = 0, temp1 = 0;
    u8 i;
    GPIO_Input_I2C_Configuration(SDA.GPIOx, SDA.GPIO_Pin); //SDA置输入
    for(i = 0; i < 8; i++)
    {
        temp1 = temp1 << 1;
        GPIO_SetBits(SCL.GPIOx, SCL.GPIO_Pin);  //SCL=1;
        delay_us(50);   //在时钟大于4u秒期间读数据
        s1 = GPIO_ReadInputDataBit(SDA.GPIOx, SDA.GPIO_Pin);
        if(s1)                   //读 1
        {
            temp1 = temp1 | 0x01;
        }
        else                     //读 0
        {
            temp1 = temp1 & 0xfe;
        }
        GPIO_ResetBits(SCL.GPIOx, SCL.GPIO_Pin);//SCL=0;
        delay_us(50);                         //此处延时50us
    }
    return(temp1);
}

/*主机向IC总线发送连续读信号*/
void I2C_ack(void)          //  发送连续读信号
{
    GPIO_Output_I2C_Configuration(SDA.GPIOx, SDA.GPIO_Pin);  //SDA置输出;
    GPIO_ResetBits(SDA.GPIOx, SDA.GPIO_Pin);//SDA=0;
    delay_us(50);                         //此处延时50us
    GPIO_ResetBits(SCL.GPIOx, SCL.GPIO_Pin);  //SCL=1;
    delay_us(50);                         //此处延时50us
    GPIO_ResetBits(SCL.GPIOx, SCL.GPIO_Pin);//SCL=0;
}

/*主机向IC总线发送不连续读信号*/
void I2C_nack(void)          //  发送不连续读信号
{
    GPIO_Output_I2C_Configuration(SDA.GPIOx, SDA.GPIO_Pin);  //SDA置输出 ;
    GPIO_SetBits(SDA.GPIOx, SDA.GPIO_Pin);//SDA=1;
    delay_us(50);                         //此处延时50us
    GPIO_SetBits(SCL.GPIOx, SCL.GPIO_Pin);  //SCL=1;
    delay_us(50);                         //此处延时50us
    GPIO_ResetBits(SCL.GPIOx, SCL.GPIO_Pin);//SCL=0;
    delay_us(50);                         //此处延时50us
}

void Write_MPL3115A2(u8 Address, u8 Dat)
{
    I2C_Start();            //启动IIC时序
    I2C_SendByte(MPL3115A2Wcmd);//主机发送MPL3115A2W的发送字节命令
    I2C_Slave_ACK();          //主机等待模块返回应答指令
    I2C_SendByte(Address);//主机发送MPL3115A2W的地址
    I2C_Slave_ACK();            //主机等待模块返回应答指令
    I2C_SendByte(Dat);    //主机发送MPL3115A2W的数据
    I2C_Slave_ACK();            //主机等待模块返回应答指令
    I2C_Stop();            //停止IIC时序
}

u8 MPL3115A2Read(u8 adrr)
{
    char p;
    I2C_Start();   //启动IIC时序
    I2C_SendByte(MPL3115A2Wcmd);//主机发送MPL3115A2W的发送字节命令
    I2C_Slave_ACK();    //主机等待模块返回应答指令
    I2C_SendByte(adrr);  //主机发送MPL3115A2W的发送地址命令信息
    I2C_Slave_ACK();    //主机等待模块返回应答指令
    I2C_Start();        //启动IIC时序
    I2C_SendByte(MPL3115A2Rcmd);
    I2C_Slave_ACK();    //主机等待模块返回应答指令
    p = I2C_ReciveByte();//将模块返回
    
    I2C_nack();            //确定IIC无应答
    I2C_Stop();            //停止IIC时序
    return p;
}
void MPL3115A2_Init(void)
{
	  GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
 
	  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
	
    /************引脚设置******************/
    SDA.GPIOx = GPIOB;
    SDA.GPIO_Pin = GPIO_Pin_13;
    SCL.GPIOx = GPIOB;
    SCL.GPIO_Pin = GPIO_Pin_12;
    /**************************************/
	
    /* Set to Altimeter with an OSR = 1 */
    Write_MPL3115A2(0x26, 0x80);   
    /* Enable Data Flags in PT_DATA_CFG */	
    Write_MPL3115A2(0x13, 0x07);
	  /* Set Active */
    Write_MPL3115A2(0x26, 0xB9);
}
void MPL3115A2_Read(struct MPL3115A2 *p)
{
     static u16 AData;
     static u8  BData, CData, DData;
    u16 pre;
loat Alt_Integer,Alt_Fraction,Tmp_Integer,Tmp_Fraction,Pre_Integer,Pre_Fraction; //临时变量存放气压高度温度的小数和整数部分
/* Set to Altimeter with an OSR = 1 *///高度模式
    Write_MPL3115A2(0x26, 0x80);
    /* Enable Data Flags in PT_DATA_CFG */	
    Write_MPL3115A2(0x13, 0x07);
    Write_MPL3115A2(0x26, 0xB9);
    /* Read STATUS Register */
      while((MPL3115A2Read(0x00) & 0x08) == 0);
     AData = MPL3115A2Read(0x01) << 8 | MPL3115A2Read(0x02);
     BData = MPL3115A2Read(0x03);
     CData = MPL3115A2Read(0x04);
     DData = MPL3115A2Read(0x05);
	
     Alt_Integer = (s16)AData;	
	   Alt_Fraction=0;
	   if (BData & 0x80)
		 {
     Alt_Fraction += FRAC_2d1;
		 }
     if (BData & 0x40)
		 {
    Alt_Fraction += FRAC_2d2;
		 }
     if (BData & 0x20)
		 {
     Alt_Fraction += FRAC_2d3;
		 }
     if (BData & 0x10)
		 {
     Alt_Fraction += FRAC_2d4;
		 }
		 if(Alt_Integer>0)
		 {
		    p->Alt = Alt_Integer + Alt_Fraction/10000;
		 }
		 else
		 {
		    p->Alt = Alt_Integer - Alt_Fraction/10000;
		 }
		 
     Tmp_Integer = (s8)CData;
		 Tmp_Fraction=0;	   
	   if (DData & 0x80)
		 {
     Tmp_Fraction += FRAC_2d1;
		 }
     if (DData & 0x40)
		 {
     Tmp_Fraction += FRAC_2d2;
		 }
     if (DData & 0x20)
		 {
     Tmp_Fraction += FRAC_2d3;
		 }
     if (DData & 0x10)
		 {
     Tmp_Fraction += FRAC_2d4;
		 }
		 if(Tmp_Integer>0)
		 {
		    p->Tmp = Tmp_Integer + Tmp_Fraction/10000;
		 }
		 else
		 {
		    p->Tmp = Tmp_Integer - Tmp_Fraction/10000;
		 }		

		 	    /* Set to Altimeter with an OSR = 1 *///气压模式
    /* Enable Data Flags in PT_DATA_CFG */
		Write_MPL3115A2(0x26, 0x00);		 
    Write_MPL3115A2(0x13, 0x07);
		Write_MPL3115A2(0x26, 0x39);
	   /* Read STATUS Register */
	   while((MPL3115A2Read(0x00) & 0x08) == 0);
     AData = MPL3115A2Read(0x01) << 8 | MPL3115A2Read(0x02);
	   BData = MPL3115A2Read(0x03);
     CData = MPL3115A2Read(0x04);
     DData = MPL3115A2Read(0x05);
		 
		 pre=AData;
		 pre=pre<<2;
		 pre|=BData>>6;
		 Pre_Integer=(float)pre;
		 Pre_Fraction = 0;
		 	   if (BData & 0x20)//第5位
		 {
     Pre_Fraction += FRAC_2d1;
		 }
     if (BData & 0x10)//第4位
		 {
                      Pre_Fraction += FRAC_2d2;
		 }
		 p->pre=(Pre_Integer+Pre_Fraction/10000)/100;
		 
}

模块使用心得:手册中提到读取气压的方式有轮询法和中断法。轮询法就是不使用中断的方法。我这里只是测试模块功能,对精度要求不是很高,所以就选择的该方式。只需要接SDA和SCI,而IN1 IN2只有在中断法中才会使用到,这里就不做过多的介绍。

MPL3115A2有3种工作模式。就绪模式、活动测高模式、活动测压模式。

步骤1:先进入就绪模式,CTRL_REG1寄存器(0x26)写入0x04,即就绪模式;

步骤2:再对该寄存器写入0xB9,进入活动测高模式;

步骤3:将PT_DATA_CDG寄存器(0x13)的值写为0x07。配置工作就完成了。

然后它就可以开始按照iic的工作时序开始工作了。我们需要的数据在0x01 0x02 0x03 这三个寄存器中。0x01和0x02都是以米做单位的,读出来就直接是海拔。

在大多数城市 0x01这个寄存器的值都是0,如果你在青藏高原就当我没说;

0x02的数据就是你城市的海拔,0x03的数据,就可以理解为小数点后的数值了。

2:OLED模块介绍:

2.1OLED 简介:

OLED,即有机发光二极管(Organic Light-Emitting Diode),又称为有机电激光显示(Organic Electroluminesence Display, OELD)。因为具备轻薄、省电等特性,因此从 2003 年开始,这种显示设备在 MP3 播放器上得到了广泛应用,而对于同属数码类产品的 DC 与手机,此前只是在一些展会上展示过采用 OLED 屏幕的工程样品。自 2007 年后,寿命得 到很大提高,具备了许多 LCD 不可比拟的优势。

GND:电源地 VCC2.2V~5.5V SCLD0):CLK 时钟 (高电平 2.2V~5.5VSDA(D1)MOSI 数据(高电平 2.2V~5.5VRST:复位(高电平 2.2V~5.5VD/C:数据/命令(高电平 2.2V~5.5V) 兼容 3.3V 5V 控制芯片的 I/O 电平(无需任何设置,直接兼容)

实物图片

 OLED 屏幕界面.png

2.2:汉字显示方法:

需要使用软件做自己的字库

 取模软件界面.png


//向SSD1106写入一个字节。
//dat:要写入的数据/命令
//cmd:数据/命令标志 0,表示命令;1,表示数据;
void OLED_WR_Byte(u8 dat,u8 cmd)
{	
	u8 i;			  
	if(cmd)
	  OLED_DC_Set();
	else 
	  OLED_DC_Clr();		  
	OLED_CS_Clr();
	for(i=0;i<8;i++)
	{			  
		OLED_SCLK_Clr();
		if(dat&0x80)
		   OLED_SDIN_Set();
		else 
		   OLED_SDIN_Clr();
		OLED_SCLK_Set();
		dat<<=1;   
	}				 		  
	OLED_CS_Set();
	OLED_DC_Set();   	  
} 

void OLED_Set_Pos(u8 x, u8 y) 
{ 
	OLED_WR_Byte(0xb0+y,OLED_CMD);
	OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);
	OLED_WR_Byte((x&0x0f)|0x01,OLED_CMD); 
} 

//开启OLED显示    
void OLED_Display_On(void)
{
	OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
	OLED_WR_Byte(0X14,OLED_CMD);  //DCDC ON
	OLED_WR_Byte(0XAF,OLED_CMD);  //DISPLAY ON
}

//关闭OLED显示     
void OLED_Display_Off(void)
{
	OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
	OLED_WR_Byte(0X10,OLED_CMD);  //DCDC OFF
	OLED_WR_Byte(0XAE,OLED_CMD);  //DISPLAY OFF
}	

//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!	  
void OLED_Clear(void)  
{  
	u8 i,n;		    
	for(i=0;i<8;i++)  
	{  
		OLED_WR_Byte (0xb0+i,OLED_CMD);    //设置页地址(0~7)
		OLED_WR_Byte (0x02,OLED_CMD);      //设置显示位置—列低地址
		OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置—列高地址   
		for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA); 
	} //更新显示
}

//在指定位置显示一个字符 调用OLED_ShowChar(48,6,16,t);
//x0,y0显示起点坐标,x0(范围0~127),y0(范围0~7)*8 
//size:选择字体 16/12 
//chr:字符串ascii码
void OLED_ShowChar(u8 x, u8 y, u8 size, u8 chr)
{      	
	u8 c=0,i=0;	
	c=chr-' ';//得到偏移后的值			
	if(x>X_WIDTH-1){x=0;y=y+2;}
	if(size ==ASCII32x32)
	{
		OLED_Set_Pos(x,y);	
		for(i=0;i<ASCII32x32/4;i++)
		OLED_WR_Byte(ASCII16x32[c*ASCII32x32+i],OLED_DATA);
		OLED_Set_Pos(x,y+1);
		for(i=0;i<ASCII32x32/4;i++)
		OLED_WR_Byte(ASCII16x32[c*ASCII32x32+i+ASCII32x32/4],OLED_DATA);//四列显示完
		OLED_Set_Pos(x,y+2);
		for(i=0;i<ASCII32x32/4;i++)
		OLED_WR_Byte(ASCII16x32[c*ASCII32x32+i+2*ASCII32x32/4],OLED_DATA);
		OLED_Set_Pos(x,y+3);
		for(i=0;i<ASCII32x32/4;i++)
		OLED_WR_Byte(ASCII16x32[c*ASCII32x32+i+3*ASCII32x32/4],OLED_DATA);
	}	
	else if(size ==ASCII24x24)
	{
		OLED_Set_Pos(x,y);	
		for(i=0;i<ASCII24x24/3;i++)
		OLED_WR_Byte(ASCII12x24[c*ASCII24x24+i],OLED_DATA);
		OLED_Set_Pos(x,y+1);
		for(i=0;i<ASCII24x24/3;i++)
		OLED_WR_Byte(ASCII12x24[c*ASCII24x24+i+ASCII24x24/3],OLED_DATA);//三列显示完
		OLED_Set_Pos(x,y+2);
		for(i=0;i<ASCII24x24/3;i++)
		OLED_WR_Byte(ASCII12x24[c*ASCII24x24+i+2*ASCII24x24/3],OLED_DATA);
	}		
	else if(size ==ASCII16x16)
	{
		OLED_Set_Pos(x,y);	
		for(i=0;i<ASCII16x16/2;i++)
		OLED_WR_Byte(ASCII8X16[c*ASCII16x16+i],OLED_DATA);
		OLED_Set_Pos(x,y+1);
		for(i=0;i<ASCII16x16/2;i++)
		OLED_WR_Byte(ASCII8X16[c*ASCII16x16+i+ASCII16x16/2],OLED_DATA);//两列显示完
	}
	else if(size ==ASCII12x8)
	{	
		OLED_Set_Pos(x,y);
		for(i=0;i<ASCII12x8;i++)
		OLED_WR_Byte(ASCII6x8[c*ASCII12x8+i],OLED_DATA);	//一列显示完			
	}
}

//m^n函数
u32 oled_pow(u8 m,u8 n)
{
	u32 result=1;	 
	while(n--)result*=m;    
	return result;
}	

//显示数字 调用OLED_ShowNum(103,6,t,3,16); 		  
//x0,y0显示起点坐标,x0(范围0~127),y0(范围0~7)*8 
//len :数字的位数
//size:选择字体 16/12 
//num:数值(0~65536);	
void OLED_ShowNum(u8 x,u8 y,u16 num,u8 len,u8 size)
{         	
	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_ShowChar(x+(size/2)*t,y,size,' ');
				continue;
			}else enshow=1; 
		}
	 	OLED_ShowChar(x+(size/2)*t,y,size,temp+'0'); 
	}
} 

//显示一个字符号串 调用OLED_ShowString(30,0,"OLED TEST");
//x0,y0:显示起点坐标,x0(范围0~127),y0(范围0~7)*8
//size:选择字体 16/12 
//char:字符串ascii码
void OLED_ShowString(u8 x,u8 y,u8 size,u8 *chr)
{
	u8 j=0;
	while (chr[j]!='\0')
	{		
			OLED_ShowChar(x,y,size,chr[j]);
			if(size==ASCII12x8)
			{
				x+=6;//单个ascii偏移量
			}
			else if(size==ASCII16x16)
			{
				x+=ASCII16x16/2;//单个ascii偏移量
			}
			else if(size==ASCII24x24)
			{
				x+=ASCII24x24/3;//单个ascii偏移量
			}
			else if(size==ASCII32x32)
			{
				x+=ASCII32x32/4;//单个ascii偏移量
			}
 			if(x>X_WIDTH-size){x=0;y+=size/8;}
 			j++;
	}
}
                                                                                 
//显示显示BMP图片 调用OLED_DrawBMP(0,0,128,8,BMP1);最大图片
//x0,y0:显示起点坐标,x0(范围0~127),y0(范围0~7)*8
//x1,y1:显示图片长度和宽度,x1(范围0~127),y1(范围0~7)*8
//BMP[]:图片首地址
void OLED_DrawBMP(u8 x0, u8 y0,u8 x1, u8 y1,u8 BMP[])
{ 	
	 u16 j=0;
	 u8 x,y;
  
  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_WR_Byte(BMP[j++],OLED_DATA);	    	
		}
	}
} 

//-----------------------------------显示中文------------------
u32 *getchinesecodepos(u16 ac)
{   
		u16 min,max,mid,midc;
    min=0;
    max=CHINESECHARNUMBER-1;
    while(1)
    {   if(max-min<2)
        {   if(ChineseCode[min]==ac)
                mid=min;
            else if(ChineseCode[max]==ac)
                mid=max;
            else
                mid=0;
            break;
        }
        mid=(max+min)/2;
        midc=ChineseCode[mid];
        if(midc==ac)
            break;
        else if(midc>ac)
            max=mid-1;
        else
            min=mid+1;
    }
    return (u32*)(ChineseCharDot+mid*CHINESECHARDOTSIZE);
}

void Get_Code(u8* dis_buf,u32* address,u8 leng)
{
	u8 i;
	for(i=0;i<leng/4;i++)  //32为单片机4个字节
	{
		*dis_buf=*address;
		dis_buf++;
		*dis_buf=*address>>8;
		dis_buf++;
		*dis_buf=*address>>16;
		dis_buf++;
		*dis_buf=*address>>24;
		dis_buf++;
		address++;
	}
}

void LCD_Char_CH(u8 x,u8 y,vu8 *str)
{
    u8  i,buffer[CHINESECHARDOTSIZE]={0};
		u16  chinese_ascii;
		u32 *p_address;
		chinese_ascii = *str;
		str++;
		chinese_ascii = chinese_ascii<<8|*str; 		//找到汉字内码	
		p_address=getchinesecodepos(chinese_ascii);										
		Get_Code(buffer,p_address,32);  			// 取字模数据 
		OLED_Set_Pos(x,y);	
		for(i=0;i<CHINESECHARSIZE;i++)
		OLED_WR_Byte(buffer[i],OLED_DATA);
		OLED_Set_Pos(x,y+1);
		for(i=0;i<CHINESECHARSIZE;i++)
		OLED_WR_Byte(buffer[i+CHINESECHARSIZE],OLED_DATA);
}

// * 函数名:LCD_Str_CH diao
// * 描述  :在指定坐标处显示16*16大小汉字字符串
// * 输入  : 	- x: 显示位置横向坐标	 
// *         	- y: 显示位置纵向坐标 
// *			- str: 显示的中文字符串
// * 举例  :	
void LCD_Str_CHinese(u8 x,u8 y,vu8 *str)  
{   
    while(*str != '\0')
    {
        	LCD_Char_CH(x,y,str);      
        	str += 2 ;
        	x += 16 ;	
    }
}
//-----------------------------------------------------------------------------

//初始化SSD1306					    
void OLED_Init(void)
{ 	 	 
 	GPIO_InitTypeDef  GPIO_InitStructure;
 	
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);	 //使能PD端口时钟
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_10;	 
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
 	GPIO_Init(GPIOB, &GPIO_InitStructure);	  //初始化GPIOD3,6
 	GPIO_SetBits(GPIOB,GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);

//    DBGMCU->CR = DBGMCU->CR & ~((uint32_t)1<<5);
//    RCC->APB2ENR = 1 |  (1<<3);  /*AFIO/ GPIOB*/
//    AFIO->MAPR = (AFIO->MAPR & ~((uint32_t)0x7 << 24)) | (2 << 24); /*释放 PA15 PB3 PB4*/

	
  OLED_RST_Set();
	delay_ms(100);
	OLED_RST_Clr();
	delay_ms(100);
	OLED_RST_Set(); 
					  
	OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel
	OLED_WR_Byte(0x02,OLED_CMD);//---set low column address
	OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
	OLED_WR_Byte(0x40,OLED_CMD);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)
	OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register
	OLED_WR_Byte(0xCF,OLED_CMD); // Set SEG Output Current Brightness
	OLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping     0xa0左右反置 0xa1正常
	OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction   0xc0上下反置 0xc8正常
	OLED_WR_Byte(0xA6,OLED_CMD);//--set normal display
	OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
	OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty
	OLED_WR_Byte(0x81,OLED_CMD); //对比度设置
	OLED_WR_Byte(0xfF,OLED_CMD); //1~255;默认0X7F (亮度设置,越大越亮)
	OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset	Shift Mapping RAM Counter (0x00~0x3F)
	OLED_WR_Byte(0x00,OLED_CMD);//-not offset
	OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency
	OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
	OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period
	OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
	OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration
	OLED_WR_Byte(0x12,OLED_CMD);
	OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh
	OLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect Level
	OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
	OLED_WR_Byte(0x02,OLED_CMD);//
	OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable
	OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable
	OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
	OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7) 
	OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel
	
	OLED_WR_Byte(0xAF,OLED_CMD); /*display ON*/ 
	OLED_Clear();
	OLED_Set_Pos(0,0); 	
}


 测试图片如下:

MPL3115图片.png






关键词: 大气压     MPL3115A     STM32F103C8T    

专家
2024-06-19 12:13:46     打赏
2楼

谢谢分享


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]