知识回顾:

本次实践,我们选用的是STM32F407单片机,它是专为要求高性能、低成本、低功耗的嵌入式应用而设计的;我们所选的型号是子系列STM32F407。

OLED(Organic Light-Emitting Diode),又称为有机电激光显示、有机发光半导体(Organic Electroluminescence Display,OLED)。OLED属于一种电流型的有机发光器件,是通过载流子的注入和复合而致发光的现象,发光强度与注入的电流成正比。OLED在电场的作用下,阳极产生的空穴和阴极产生的电子就会发生移动,分别向空穴传输层和电子传输层注入,迁移到发光层。当二者在发光层相遇时,产生能量激子,从而激发发光分子最终产生可见光。

 IIC oled屏幕驱动原理

处理器和芯片间的通信可以形象的比喻成两个人讲话:1、你说的别人得能听懂:双方约定信号的协议。2、你的语速别人得能接受:双方满足时序要求。

一、IIC总线的信号类型

1、开始信号:处理器让SCL时钟保持高电平,然后让SDA数据信号由高变低就表示一个开始信号。同时IIC总线上的设备检测到这个开始信号它就知道处理器要发送数据了。

2、停止信号:处理器让SCL时钟保持高电平,然后让SDA数据信号由低变高就表示一个停止信号。同时IIC总线上的设备检测到这个停止信号它就知道处理器已经结束了数据传输,我们就可以各忙各个的了,如休眠等。
二、IIC数据传输过程

1、在数据传输时,SDA的数据在SCL为高电平时,必须保持稳定,SCL高电平器件完成数据的传输。在SCL低电平器件,可以任意改变SDA的数据。数据写入过程是从最好为开始,高位在前,低位在后,即MSB。
2、响应信号(ACK):接收器在接收到8位数据后,在第9个时钟周期,拉低SDA电平。即接收数据的IC在接收到8bit数据后,向发送数据的IC发出特定的低电平脉冲,表示已收到数据。CPU向受控单元发出一个信号后,等待受控单元发出一个应答信号,CPU接收到应答信号后,根据实际情况作出是否继续传递信号的判断。若未收到应答信号,由判断为受控单元出现故障。
三、数据写入的过程

首先发送一个开始信号,接着发送从机地址,OLED的从机地址前7位为地址,最后一位表示读(1)或者写(0)。应答ACK信号表示有这个从设备存在。在接收到应答信号后,发送控制位,来区分之后所发送的数据是控制命令还是显示相关的数据。在发送控制位后,等待应答信号。然后发送相应的控制命令或者数据。最后发送停止信号,表示数据传输完成。

软件实现

主函数:

#include "stm32f4xx.h"
#include "oled.h"
#include "bmp.h"
#include "LED.h"
#include "stdio.h"
#include "elevator.h"
#include "stdlib.h"
#define LOW '0'
#define HIGH '9'static uint8_t floor_now='1';
static uint8_t floor_request='0';
static uint8_t floor_end='0';
static int check=0;
void USART1_IRQHandler(void)
{uint8_t data;if(USART_GetFlagStatus(USART1,USART_IT_RXNE)==SET){data = USART_ReceiveData(USART1);if(!(floor_end>=LOW&&floor_end<=HIGH)&&!(floor_request>=LOW&&floor_request<=HIGH))check=1;else{if(floor_end=='0' ){floor_end = data;PFout(9)=0;PFout(10) = 1;          }else  if(floor_request==0&&floor_request>=LOW&&floor_request<=HIGH){floor_request=data;PFout(9)=1;PFout(10) = 0;}USART_ClearITPendingBit(USART1,USART_IT_RXNE);}
}}int main(void)
{LED_Config();OLED_Init();OLED_Clear();USART1_Init(9600);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);printf("当前:%c楼\r\n",floor_now);while(1){if(check==1){    printf("请输入正确楼层\r\n");check=0;}else if(floor_end!='0'){   //floor_end=floor_end-48;if(floor_now!=floor_end){        while(floor_now<floor_end){//显示上升过程floor_now++;printf("上升中---当前:%c楼,目的:%c楼\r\n",floor_now,floor_end);OLED_ShowChar(63,40,floor_now,16);//OLED_Clear();OLED_ShowCHinese(63,2,0);OLED_ShowCHinese(80,2,1);OLED_ShowNum( 46, 2, floor_now, 1, 9);Delay_ms(400);}while(floor_now>floor_end){//显示下降过程printf("下降中---当前:%c楼,目的:%c楼\r\n",floor_now,floor_end);floor_now--;OLED_ShowNum( 46, 2, floor_now, 1, 2);Delay_ms(400);}if(floor_request!='0')floor_end=floor_request;printf("目的%c楼\r\n",floor_end); }}floor_end='0';floor_request='0';}}

运行结果:

oled.c 代码:

#include "oled.h"
#include <stdlib.h>
#include "oledfont.h"  #define  SCL      PBout(8)
#define  SDA_W    PBout(9)
#define  SDA_R    PBin(9)void Delay_us(uint32_t n)
{while(n--){SysTick->CTRL = 0;SysTick->LOAD = (168);SysTick->VAL = 0;SysTick->CTRL = 5;while((SysTick->CTRL & (1<<16)) == 0);SysTick->CTRL = 0;}
}void Delay_ms(uint32_t n)
{while(n--){SysTick->CTRL = 0;SysTick->LOAD = (168000);SysTick->VAL = 0;SysTick->CTRL = 5;while((SysTick->CTRL & (1<<16)) == 0);SysTick->CTRL = 0;}
}//OLED的显存
//存放格式如下.
//[0]0 1 2 3 ... 127
//[1]0 1 2 3 ... 127
//[2]0 1 2 3 ... 127
//[3]0 1 2 3 ... 127
//[4]0 1 2 3 ... 127
/**********************************************
//IIC Start
**********************************************/void Set_SDA_mode(GPIOMode_TypeDef mode)
{GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;GPIO_InitStruct.GPIO_Mode = mode;GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;GPIO_Init(GPIOB,&GPIO_InitStruct);
}void IIC_Start()
{Set_SDA_mode(GPIO_Mode_OUT);SCL   = 1;SDA_W = 1; Delay_us(5);SDA_W = 0;Delay_us(5);SCL = 0;Delay_us(5);
}/**********************************************
//IIC Stop
**********************************************/
void IIC_Stop()
{Set_SDA_mode(GPIO_Mode_OUT);SCL   = 0;SDA_W = 0; Delay_us(5);SCL = 1;Delay_us(5);SDA_W = 1;    Delay_us(5);    }uint8_t IIC_Wait_Ack(void)
{uint8_t ack = 0;Set_SDA_mode(GPIO_Mode_IN);SCL = 1;Delay_us(5);if(SDA_R)ack = 1;elseack = 0;SCL = 0;Delay_us(5);return ack;
}
/**********************************************
// IIC 写一个字节
**********************************************/void Write_IIC_Byte(unsigned char byte)
{uint8_t i = 0;Set_SDA_mode(GPIO_Mode_OUT);SCL   = 0;SDA_W = 0;Delay_us(5);for(i= 0; i<8; i++){if(byte & (1<<(7-i))){SDA_W = 1;}elseSDA_W = 0;Delay_us(5);SCL   = 1;Delay_us(5);SCL   = 0;Delay_us(5);       }   }
/**********************************************
// IIC 写命令
**********************************************/
void Write_IIC_Command(unsigned char IIC_Command)
{IIC_Start();Write_IIC_Byte(0x78);            //Slave address,SA0=0IIC_Wait_Ack(); Write_IIC_Byte(0x00);           //write commandIIC_Wait_Ack();  Write_IIC_Byte(IIC_Command); IIC_Wait_Ack();    IIC_Stop();
}
/**********************************************
// IIC 写内容
**********************************************/
void Write_IIC_Data(unsigned char IIC_Data)
{IIC_Start();Write_IIC_Byte(0x78);          //D/C#=0; R/W#=0IIC_Wait_Ack();   Write_IIC_Byte(0x40);           //write dataIIC_Wait_Ack(); Write_IIC_Byte(IIC_Data);IIC_Wait_Ack();    IIC_Stop();
}
void OLED_WR_Byte(unsigned dat,unsigned cmd)
{if(cmd){Write_IIC_Data(dat);}else {Write_IIC_Command(dat);}}/********************************************
// fill_Picture
********************************************/
void fill_picture(unsigned char fill_Data)
{unsigned char m,n;for(m=0;m<8;m++){OLED_WR_Byte(0xb0+m,0);      //page0-page1OLED_WR_Byte(0x00,0);      //low column start addressOLED_WR_Byte(0x10,0);     //high column start addressfor(n=0;n<128;n++){OLED_WR_Byte(fill_Data,1);}}
}//坐标设置void OLED_Set_Pos(unsigned char x, unsigned char y)
{   OLED_WR_Byte(0xb0+y,OLED_CMD);OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);OLED_WR_Byte((x&0x0f),OLED_CMD);
}
//开启OLED显示
void OLED_Display_On(void)
{OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令OLED_WR_Byte(0X14,OLED_CMD);  //DCDC ONOLED_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 OFFOLED_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 (0x00,OLED_CMD);      //设置显示位置—列低地址OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置—列高地址   for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA); } //更新显示
}
void OLED_On(void)
{  u8 i,n;          for(i=0;i<8;i++)  {  OLED_WR_Byte (0xb0+i,OLED_CMD);    //设置页地址(0~7)OLED_WR_Byte (0x00,OLED_CMD);      //设置显示位置—列低地址OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置—列高地址   for(n=0;n<128;n++)OLED_WR_Byte(1,OLED_DATA); } //更新显示
}
//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//mode:0,反白显示;1,正常显示
//size:选择字体 16/12
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size)
{       unsigned char c=0,i=0;    c=chr-' ';//得到偏移后的值          if(x>Max_Column-1){x=0;y=y+2;}if(Char_Size ==16){OLED_Set_Pos(x,y); for(i=0;i<8;i++)OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);OLED_Set_Pos(x,y+1);for(i=0;i<8;i++)OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);}else {   OLED_Set_Pos(x,y);for(i=0;i<6;i++)OLED_WR_Byte(F6x8[c][i],OLED_DATA);}
}
//m^n函数
u32 oled_pow(u8 m,u8 n)
{u32 result=1;  while(n--)result*=m;    return result;
}
//显示2个数字
//x,y :起点坐标
//len :数字的位数
//size:字体大小
//mode:模式   0,填充模式;1,叠加模式
//num:数值(0~4294967295);
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size2)
{           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+(size2/2)*t,y,' ',size2);continue;}else enshow=1; }OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2); }
}
//显示一个字符号串
void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 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++;}
}
//显示汉字
void OLED_ShowCHinese(u8 x,u8 y,u8 no)
{                   u8 t,adder=0;OLED_Set_Pos(x,y);    for(t=0;t<16;t++){OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);adder+=1;}   OLED_Set_Pos(x,y+1);   for(t=0;t<16;t++){    OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);adder+=1;}
}
/***********功能描述:显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127,y为页的范围0~7*****************/
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_Set_Pos(x0,y);for(x=x0;x<x1;x++){      OLED_WR_Byte(BMP[j++],OLED_DATA);          }}
} //初始化SSD1306
void OLED_Init(void)
{   GPIO_InitTypeDef GPIO_InitStruct;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;GPIO_Init(GPIOB,&GPIO_InitStruct);SCL   = 1;SDA_W = 1;    Delay_ms(200);OLED_WR_Byte(0xAE,OLED_CMD);//--display offOLED_WR_Byte(0x00,OLED_CMD);//---set low column addressOLED_WR_Byte(0x10,OLED_CMD);//---set high column addressOLED_WR_Byte(0x40,OLED_CMD);//--set start line address  OLED_WR_Byte(0xB0,OLED_CMD);//--set page addressOLED_WR_Byte(0x81,OLED_CMD); // contract controlOLED_WR_Byte(0xFF,OLED_CMD);//--128   OLED_WR_Byte(0xA1,OLED_CMD);//set segment remap OLED_WR_Byte(0xA6,OLED_CMD);//--normal / reverseOLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)OLED_WR_Byte(0x3F,OLED_CMD);//--1/32 dutyOLED_WR_Byte(0xC8,OLED_CMD);//Com scan directionOLED_WR_Byte(0xD3,OLED_CMD);//-set display offsetOLED_WR_Byte(0x00,OLED_CMD);//OLED_WR_Byte(0xD5,OLED_CMD);//set osc divisionOLED_WR_Byte(0x80,OLED_CMD);//OLED_WR_Byte(0xD8,OLED_CMD);//set area color mode offOLED_WR_Byte(0x05,OLED_CMD);//OLED_WR_Byte(0xD9,OLED_CMD);//Set Pre-Charge PeriodOLED_WR_Byte(0xF1,OLED_CMD);//OLED_WR_Byte(0xDA,OLED_CMD);//set com pin configuartionOLED_WR_Byte(0x12,OLED_CMD);//OLED_WR_Byte(0xDB,OLED_CMD);//set VcomhOLED_WR_Byte(0x30,OLED_CMD);//OLED_WR_Byte(0x8D,OLED_CMD);//set charge pump enableOLED_WR_Byte(0x14,OLED_CMD);//OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel
}  

 oled.h 代码:

#ifndef __OLED_H
#define __OLED_H                 #include "BitBand.h"
#include "stdlib.h"           #include "stm32f4xx.h"#define OLED_MODE 0
#define SIZE 8
#define XLevelL     0x00
#define XLevelH     0x10
#define Max_Column  128
#define Max_Row     64
#define Brightness  0xFF
#define X_WIDTH     128
#define Y_WIDTH     64
//-----------------OLED IIC端口定义----------------                        #define OLED_SCLK_Clr() GPIO_ResetBits(GPIOD,GPIO_Pin_6)//SDA IIC接口的时钟信号
#define OLED_SCLK_Set() GPIO_SetBits(GPIOD,GPIO_Pin_6)#define OLED_SDIN_Clr() GPIO_ResetBits(GPIOD,GPIO_Pin_7)//SCL IIC接口的数据信号
#define OLED_SDIN_Set() GPIO_SetBits(GPIOD,GPIO_Pin_7)#define OLED_CMD  0   //写命令
#define OLED_DATA 1 //写数据//OLED控制用函数
void OLED_WR_Byte(unsigned dat,unsigned cmd);
void OLED_Display_On(void);
void OLED_Display_Off(void);
void OLED_Init(void);
void OLED_Clear(void);
void OLED_DrawPoint(u8 x,u8 y,u8 t);
void OLED_Fill(u8 x1,u8 y1,u8 x2,u8 y2,u8 dot);
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size);
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size);
void OLED_ShowString(u8 x,u8 y, u8 *p,u8 Char_Size);
void OLED_Set_Pos(unsigned char x, unsigned char y);
void OLED_ShowCHinese(u8 x,u8 y,u8 no);
void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[]);
void Delay_50ms(unsigned int Del_50ms);
void Delay_1ms(unsigned int Del_1ms);
void fill_picture(unsigned char fill_Data);
void Picture(void);
void IIC_Start(void);
void IIC_Stop(void);
void Write_IIC_Command(unsigned char IIC_Command);
void Write_IIC_Data(unsigned char IIC_Data);
void Write_IIC_Byte(unsigned char IIC_Byte);
void Delay_ms(uint32_t n);
void Delay_us(uint32_t n);uint8_t IIC_Wait_Ack(void);
#endif 

效果显示:

基于STM32的电梯智能控制系统(软件实现)相关推荐

  1. 基于STM32的电梯楼层控制系统proteus仿真

    硬件设计 仿真图如下所示: 程序设计 #include "main.h" #include "delay.h" #include "led.h&quo ...

  2. 基于 STM32 的语音识别智能家居控制系统的设计(LD3320语音识别芯片+ESP8266 WIFI模块+DHT11温湿度采集+MQ系列 烟雾及可燃气体+蜂鸣器+步进电机模拟窗帘+OLED液晶显示+

    ## **基于 STM32 的语音识别智能家居控制系统的设计(LD3320语音识别芯片+ESP8266 WIFI模块(阿里云 或ONENET或局域网)+DHT11温湿度采集+MQ系列 烟雾及可燃气体+ ...

  3. 基于 STM32 的新型激光测距控制系统的设计

    基于 STM32 的新型激光测距控制系统的设计 基于 STM32 的新型激光测距控制系统的设计 闵小 (陕西理工大学(物理与电信工程学院)电子专业1502班,陕西 汉中 723003) 指导老师:韩团 ...

  4. 基于STM32单片机的智能家居测量系统设计

    当今的家庭生活面临着各种环境和健康问题,周围的生活参数存在潜在的隐患,包括室温.气体中有害物质的浓度等.在新时代,人们越来越关注健康及其相关因素.随着微电子技术的应用,电器的普及,以及单片机和传感器性 ...

  5. 【基于stm32 FreeRtos的智能台灯控制】

    基于stm32 FreeRtos的智能台灯控制 之前做了一个裸机版本的智能台灯,最近刚好复习一下FreeRto的一些基础知识,朋友发给了我一个功能需求刚好用来实践一下,需要的朋友可以自行下载. 完整工 ...

  6. 基于STM32水温炉温温度控制系统电路设计-分享

    (1).主控制器采用STM32单片机 (2).必须要有温度检测装置,采用DS18B20 (3).要有加热装置,采用220V交流电供电 (4).要能够设置报警的温度上限值以及温度加热的下限值 (5).要 ...

  7. 基于STM32单片机的智能停车场车位管理系统设计

    摘  要 通过调查发现,现有的许多公共场所的停车位管理落后,智能化程度不高.为顺应现代自动化狂潮的发展趋势,本项目以STM32单片机为主控芯片,基于RFID智能识别技术,设计了一个具有IC识别的智能停 ...

  8. 基于STM32单片机的智能手环设计(OLED显示)(Proteus仿真+程序+报告)

    编号8 基于STM32单片机的智能手环设计(OLED显示) 功能描述: 由 STM32单片机+按键模拟计步+RTC时钟模块+DS18B20温度传感器模块+心率采集模块+串口模块+OLED显示模块+键盘 ...

  9. 基于STM32单片机的智能加湿器(Proteus仿真+程序)

    标号:11 基于STM32单片机的智能加湿器 功能描述: 11.基于STM32单片机的智能加湿器 本设计由STM32F103单片机最小系统+DHT11温湿度传感器+1602液晶显示模块+声光报警模块+ ...

最新文章

  1. BPM与Portal SSO实施方案v2
  2. 单片机复位后为什么要对sp重新赋值_常见的单片机复位方式及其原理分析
  3. Android 之 Shape (圆角输入框)
  4. Matlab中的logspace函数,matlab之logspace函数
  5. 用汇编写系统服务程序
  6. java获取当前运行代码的类名、方法名、行号
  7. [大学回忆录]桂X大学大二(上)学期总结
  8. 今日恐慌与贪婪指数为31 恐慌程度有所上升
  9. SQL Server数据库是否会引发恶意?
  10. [转]MegCup2015初赛题
  11. PVLAN技术初探-巧用PVLAN优化网络
  12. weblogic 解决线程阻塞
  13. Python 基础课程第五天
  14. C#自学总结_Day2
  15. 使用阿里云code和git管理项目
  16. 数学建模—多元回归分析
  17. 联想y7000笔记本触摸板开启快捷键_联想 拯救者Y7000P 如何关闭触摸板?
  18. Java字符串使用及运算符详解
  19. 【和小冉一起学习c++】踏入c++的大门~第一个c++程序
  20. vba自定义函数,设置加载宏,建立自己的excel函数库,代码库

热门文章

  1. Python有限差分法——向前差分,向后差分和中心差分的Python程序
  2. 计算机电竞学院就业方向,电竞专业主要是学什么的 有前途吗
  3. Python跨文件全局变量
  4. 微信小程序调用本地相册与拍照
  5. 宇宙扛把子(原创勿删)
  6. VirtualBox7.0 虚拟机直接挂载物理硬盘
  7. 第2章第9节:标题设计技巧:制作抖音风格的标题样式 [PowerPoint精美幻灯片实战教程]
  8. TQQ2440第二节:流水灯
  9. 菜谱小程序_云应用程序食谱
  10. 诸神之眼——nmap入门教程