本帖最后由 jinglixixi 于 2022-6-14 22:24 编辑
先前介绍了串行数码管模块的显示驱动,它比较适用于工控环境下。若在一般情况下,则使用OLED屏显示会较为合适。 当然,这里所说的OLED屏是I2C接口的显示屏,若使用SPI接口的显示屏,则会太消耗引脚资源。 相较于串行数码管模块的驱动,I2C接口的OLED屏其使用的引脚更少,显示的信息则更丰富,其显示效果如图1所示。 图1 显示效 果 该显示屏使用如图2所示,其引脚连接关系为: CLK---P1.10 DIN---P1.11 图2 使用接口 对所用引脚的配置函数为: void oled_gpio_init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIO1, &GPIO_InitStruct);
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIO1, &GPIO_InitStruct);
}
定义引脚输出高低电平输出的语句为: #define OLED_SCLK_Clr() GPIO_ResetBits(GPIO1, GPIO_Pin_10) #define OLED_SCLK_Set() GPIO_SetBits(GPIO1, GPIO_Pin_10) #define OLED_SDIN_Clr() GPIO_ResetBits(GPIO1, GPIO_Pin_11) #define OLED_SDIN_Set() GPIO_SetBits(GPIO1, GPIO_Pin_11) 以GPIO口模拟I2C发送字节数据的函数如下: void Write_IIC_Byte(unsigned char IIC_Byte)
{
unsigned char i;
unsigned char m,da;
da=IIC_Byte;
OLED_SCLK_Clr();
for(i=0;i<8;i++)
{
m=da;
m=m&0x80;
if(m==0x80)
{
OLED_SDIN_Set();
}
else
OLED_SDIN_Clr();
Delayus(2);
da=da<<1;
OLED_SCLK_Set();
Delayus(2);
OLED_SCLK_Clr();
Delayus(2);
}
}
实现屏幕清除的函数为: void OLED_Clear(void)
{
uint8_t i,n;
for(i=0;i<8;i++)
{
OLED_WR_Byte(0xb0+i,OLED_CMD);
OLED_WR_Byte(0x00,OLED_CMD);
OLED_WR_Byte(0x10,OLED_CMD);
for(n=0;n<128;n++) OLED_WR_Byte(0,OLED_DATA);
}
}
实现字符串显示的函数为: void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t Char_Size)
{
unsigned char j=0;
while (chr[j]!='\0')
{
OLED_ShowChar(x,y,chr[j],Char_Size);
x+=8;
if(x>120)
{
x=0;
y+=2;
}
j++;
}
}
实现图1所示显示效果的主程序如下: int main(void)
{
Hardware_init();
oled_gpio_init();
OLED_Init();
OLED_Clear();
OLED_ShowString(20,0,"LKS32MC081",16);
OLED_ShowString(20,2,"OLED TEST",16);
while (1);
}
对于电机控制来讲,它离不开对外界的感知,从而来进行调控。因此,对各种传感器的使用也是十分普遍的。 就传感器的工作原理来讲,可将其分为3类,即数字式、脉冲类及模拟类。 对于模拟类的传感器,它要配合ADC数据采集来使用;对脉冲类传感器,则主要是依托MCU片内的相应定时/计数器;而对于数字式传感器来讲,它之需要GPIO口和延时函数就可实现数据的检测。 这里以数字式光照强度传感器为例来进行介绍,其传感器的型号为BH1750,是一款I2C接口的器件。 该器件所用的接口如图3所示,其引脚连接关系为: CLK---P0.4 DIN---P0.14 图3 使用接口 由于光照强度传感器涉及数据的读写,因此在工作时要进行工作模式的转换,其模式的设置函数为: void IIC_INPUT_MODE_SET()
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIO0, &GPIO_InitStruct);
}
void IIC_OUTPUT_MODE_SET()
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIO0, &GPIO_InitStruct);
}
图4 光照状态 图5 遮挡状态 读取与显示光照强度的函数为: void Get_Sunlight_Value()
{
int dis_data=0;
float temp;
char i=0;
unsigned int sd;
Single_Write_BH1750(0x01);
Single_Write_BH1750(0x10);
delay(180);
Multiple_Read_BH1750();
for(i=0;i<3;i++) dis_data=BUF[0];
dis_data=(dis_data<<8)+BUF[1];
temp=(float)dis_data/1.2;
sd=temp;
if(sd<54612) OLED_ShowNum(0,6,sd,5,16);
}
实现所示检测效果的主程序如下: int main(void)
{
u16 i;
Hardware_init();
GPIO_LED(ALL_OFF);
oled_gpio_init();
OLED_Init();
OLED_Clear();
OLED_ShowString(20,0,"LKS32MC081",16);
OLED_ShowString(20,2,"OLED TEST",16);
for(i=0;i<100;i++) delay(0xFFFF);
OLED_ShowString(20,2,"BH1750 TEST",16);
BH1750_Init();
for(i=0;i<100;i++) delay(0xFFFF);
OLED_ShowString(0,4,"Sunlight=",16);
OLED_ShowString(48,6,"lx",16);
while(1)
{
Get_Sunlight_Value();
for(i=0;i<100;i++) delay(0xFFFF);
}
}
将光照强度的检测与计时和电机控制功能相结合,就可以完成一个光控的电动窗帘。
|