日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

基于SPI的OLED温湿度显示

發布時間:2024/3/12 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于SPI的OLED温湿度显示 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文首先會簡單介紹SPI通信協議,然后后面的實驗分為兩個板塊,一個是OLED屏的使用,另一個是在此基礎上,結合上次實驗(結尾會附上鏈接),用OLED屏顯示溫濕度信息。
實驗器材:STM32F103C8T6、0.96寸OLED屏、AHT20溫濕度傳感器、杜邦線若干
實驗環境:Keil μVision5、PCtoLCD2002


文章目錄

  • 一、SPI協議
    • 1. SPI簡介
  • 二、OLED屏的簡單應用
    • 1. OLED原理
    • 2. OLED顯示文字
      • 2.1 部分代碼實現思想
      • 2.2 完整代碼
        • `oled.h`
        • `oled.c`
        • `gui.h`
        • `gui.c`
        • `spi.h`
        • `spi.c`
        • `main.c`
      • 2.3 實驗效果
  • 三、OLED屏的溫濕度顯示
    • 1. 部分代碼實現思想
    • 2. 完整代碼
    • 3. 實驗效果
  • 四、OLED屏的滾動顯示
    • 1. 部分代碼實現思想
    • 2. 完整代碼
    • 3. 實驗效果
  • 五、實驗總結
  • 六、參考資料

一、SPI協議

1. SPI簡介

SPI 是英語Serial Peripheral interface的縮寫,顧名思義就是串行外圍設備接口。是Motorola首先在其MC68HCXX系列處理器上定義的。

SPI,是一種高速的,全雙工,同步的通信總線,并且在芯片的管腳上只占用四根線,節約了芯片的管腳,同時為PCB的布局上節省空間,提供方便,主要應用在 EEPROM,FLASH,實時時鐘,AD轉換器,還有數字信號處理器和數字信號解碼器之間。

SPI內部結構簡明圖

SPI接口一般使用4條線通信:

MISO 主設備數據輸入,從設備數據輸出。

MOSI 主設備數據輸出,從設備數據輸入。

SCLK時鐘信號,由主設備產生。

CS從設備片選信號,由主設備控制。

在stm32f103系列芯片中,引腳對應關系如下

STM32F10x的SPI引腳

這些引腳信息也可以在數據手冊查詢到,這里是一個整理

在STM32中文參考手冊中給出了SPI的框圖

SPI框圖

通常SPI通過4個引腳與外部器件相連:

①硬件上為4根線。
②主機和從機都有一個串行移位寄存器,主機通過向它的SPI串行寄存器寫入一個字節來發起一次傳輸。
③串行移位寄存器通過MOSI信號線將字節傳送給從機,從機也將自己的串行移位寄存器中的內容通過MISO信號線返回給主機。這樣,兩個移位寄存器中的內容就被交換。
④外設的寫操作和讀操作是同步完成的。如果只進行寫操作,主機只需忽略接收到的字節;反之,若主機要讀取從機的一個字節,就必須發送一個空字節來引發從機的傳輸。

GPIO口的配置如下圖

表22 SPI

在STM32中文參考手冊及其他廠商的參考資料、開發手冊介紹的已經非常詳細,介于篇幅限制,本文不在詳細敘述。

二、OLED屏的簡單應用

1. OLED原理

OLED(Organic Light-Emitting Diode),又稱為有機電激光顯示、有機發光半導體(Organic Electroluminescence Display,OLED)。OLED屬于一種電流型的有機發光器件,是通過載流子的注入和復合而致發光的現象,發光強度與注入的電流成正比。OLED在電場的作用下,陽極產生的空穴和陰極產生的電子就會發生移動,分別向空穴傳輸層和電子傳輸層注入,遷移到發光層。當二者在發光層相遇時,產生能量激子,從而激發發光分子最終產生可見光

本次實驗采用7針0.96英寸SPI OLED屏,屏幕如下圖

0.96英寸SPI OLED屏

其中七個引腳的配置如下:

引腳說明

所以根據上述引腳說明,OLED的引腳連接如下表

OLED模塊STM32單片機
VCC5V/3.3V
GNDGND
D0PB13
D1PB15
RESPB12
DCPB10
CSPB11

由于本次實驗采用軟件模擬SPI通信,所以引腳的選擇相對比較自由。

2. OLED顯示文字

2.1 部分代碼實現思想

首先是對引腳的GPIO配置

void OLED_Init_GPIO(void) {GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能B端口時鐘GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_15; //GPIOB10,11,12,13,15 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽輸出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHzGPIO_Init(GPIOB, &GPIO_InitStructure); //初始化GPIOB10、11、12、13、15GPIO_SetBits(GPIOB,GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_15); }

然后是對OLED屏的初始化

void OLED_Init(void) {OLED_Init_GPIO(); //初始化GPIOdelay_ms(200);OLED_Reset(); //復位OLED/**************初始化SSD1306*****************/ OLED_WR_Byte(0xAE,OLED_CMD); /*display off*/OLED_WR_Byte(0x00,OLED_CMD); /*set lower column address*/OLED_WR_Byte(0x10,OLED_CMD); /*set higher column address*/OLED_WR_Byte(0x40,OLED_CMD); /*set display start line*/ OLED_WR_Byte(0xB0,OLED_CMD); /*set page address*/OLED_WR_Byte(0x81,OLED_CMD); /*contract control*/ OLED_WR_Byte(0xFF,OLED_CMD); /*128*/OLED_WR_Byte(0xA1,OLED_CMD); /*set segment remap*/ OLED_WR_Byte(0xA6,OLED_CMD); /*normal / reverse*/OLED_WR_Byte(0xA8,OLED_CMD); /*multiplex ratio*/ OLED_WR_Byte(0x3F,OLED_CMD); /*duty = 1/64*/OLED_WR_Byte(0xC8,OLED_CMD); /*Com scan direction*/OLED_WR_Byte(0xD3,OLED_CMD); /*set display offset*/ OLED_WR_Byte(0x00,OLED_CMD);OLED_WR_Byte(0xD5,OLED_CMD); /*set osc division*/ OLED_WR_Byte(0x80,OLED_CMD);OLED_WR_Byte(0xD9,OLED_CMD); /*set pre-charge period*/ OLED_WR_Byte(0XF1,OLED_CMD);OLED_WR_Byte(0xDA,OLED_CMD); /*set COM pins*/ OLED_WR_Byte(0x12,OLED_CMD);OLED_WR_Byte(0xDB,OLED_CMD); /*set vcomh*/ OLED_WR_Byte(0x30,OLED_CMD);OLED_WR_Byte(0x8D,OLED_CMD); /*set charge pump disable*/ OLED_WR_Byte(0x14,OLED_CMD);OLED_WR_Byte(0xAF,OLED_CMD); /*display ON*/ }

一般廠家會給出相應的代碼,我們只需要使用就可以了,具體代碼如何實現請自行查看

本次實驗需要顯示漢字和數字,其中數字已經包含在const unsigned char F6x8[][8]數組中,無需設置。顯示的文字需要通過PCtoLCD2002這款軟件實現,比如愛我中華

在文本框中輸入文字后,在選項中設置格式為C51格式,輸出數制為十六進制數

PCtoLCD2002選項

點擊生成字模按鈕

然后將下面生成的字模復制粘貼到代碼中

注意:不同代碼字模的格式不一定相同,請根據代碼自行更改相應的格式

2.2 完整代碼

其中delay.c和delay.h可以參考筆者之前的博客,由于篇幅限制,參考代碼中刪除了部分注釋代碼

oled.h

#ifndef __OLED_H #define __OLED_H //--------------OLED參數定義--------------------- #define PAGE_SIZE 8 #define XLevelL 0x00 #define XLevelH 0x10 #define YLevel 0xB0 #define Brightness 0xFF #define WIDTH 128 #define HEIGHT 64 //-------------寫命令和數據定義------------------- #define OLED_CMD 0 //寫命令 #define OLED_DATA 1 //寫數據 //-----------------OLED端口定義---------------- #define OLED_CS GPIO_Pin_11 //片選信號 PB11 #define OLED_DC GPIO_Pin_10 //數據/命令控制信號 PB10 #define OLED_RST GPIO_Pin_12 //復位信號 PB12//-----------------OLED端口操作定義---------------- #define OLED_CS_Clr() GPIO_ResetBits(GPIOB,OLED_CS) #define OLED_CS_Set() GPIO_SetBits(GPIOB,OLED_CS)#define OLED_DC_Clr() GPIO_ResetBits(GPIOB,OLED_DC) #define OLED_DC_Set() GPIO_SetBits(GPIOB,OLED_DC)#define OLED_RST_Clr() GPIO_ResetBits(GPIOB,OLED_RST) #define OLED_RST_Set() GPIO_SetBits(GPIOB,OLED_RST)//OLED控制用函數 void OLED_WR_Byte(unsigned dat,unsigned cmd); void OLED_Display_On(void); void OLED_Display_Off(void); void OLED_Set_Pos(unsigned char x, unsigned char y); void OLED_Reset(void); void OLED_Init_GPIO(void); void OLED_Init(void); void OLED_Set_Pixel(unsigned char x, unsigned char y,unsigned char color); void OLED_Display(void); void OLED_Clear(unsigned dat); #endif

oled.c

#include "oled.h" #include "stdlib.h" #include "string.h" #include "delay.h" #include "spi.h" //OLED顯存總共分為8頁 //每頁8行,一行128個像素點 //OLED的顯存 //存放格式如下. //[0]0 1 2 3 ... 127 (0~7)行 //[1]0 1 2 3 ... 127 (8~15)行 //[2]0 1 2 3 ... 127 (16~23)行 //[3]0 1 2 3 ... 127 (24~31)行 //[4]0 1 2 3 ... 127 (32~39)行 //[5]0 1 2 3 ... 127 (40~47)行 //[6]0 1 2 3 ... 127 (48~55)行 //[7]0 1 2 3 ... 127 (56~63)行 //數組每個bit存儲OLED每個像素點的顏色值(1-亮(白色),0-滅(黑色)) //每個數組元素表示1列8個像素點,一共128列 static unsigned char OLED_buffer[1024] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, };/******************************************************************** @name :void OLED_WR_Byte(unsigned dat,unsigned cmd)* @date :2018-08-27* @function :Write a byte of content to the OLED screen* @parameters :dat:Content to be writtencmd:0-write command1-write data* @retvalue :None ********************************************************************/ void OLED_WR_Byte(unsigned dat,unsigned cmd) {if(cmd){OLED_DC_Set();}else{OLED_DC_Clr();}OLED_CS_Clr();SPI_WriteByte(dat);OLED_CS_Set(); }/******************************************************************** @name :void OLED_Set_Pos(unsigned char x, unsigned char y) * @date :2018-08-27* @function :Set coordinates in the OLED screen* @parameters :x:x coordinatesy:y coordinates* @retvalue :None ********************************************************************/ void OLED_Set_Pos(unsigned char x, unsigned char y) {OLED_WR_Byte(YLevel+y/PAGE_SIZE,OLED_CMD);OLED_WR_Byte((((x+2)&0xf0)>>4)|0x10,OLED_CMD);OLED_WR_Byte(((x+2)&0x0f),OLED_CMD); } /******************************************************************** @name :void OLED_Display_On(void) * @date :2018-08-27* @function :Turn on OLED display* @parameters :None* @retvalue :None ********************************************************************/ 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 }/******************************************************************** @name :void OLED_Display_Off(void)* @date :2018-08-27* @function :Turn off OLED display* @parameters :None* @retvalue :None ********************************************************************/ 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 }/******************************************************************** @name :void OLED_Set_Pixel(unsigned char x, unsigned char y,unsigned char color)* @date :2018-08-27* @function :set the value of pixel to RAM* @parameters :x:the x coordinates of pixely:the y coordinates of pixelcolor:the color value of the point1-white0-black* @retvalue :None ********************************************************************/ void OLED_Set_Pixel(unsigned char x, unsigned char y,unsigned char color) {if(color){OLED_buffer[(y/PAGE_SIZE)*WIDTH+x]|= (1<<(y%PAGE_SIZE))&0xff;}else{OLED_buffer[(y/PAGE_SIZE)*WIDTH+x]&= ~((1<<(y%PAGE_SIZE))&0xff);} } /******************************************************************** @name :void OLED_Display(void)* @date :2018-08-27* @function :Display in OLED screen* @parameters :None* @retvalue :None ********************************************************************/ void OLED_Display(void) {u8 i,n; for(i=0;i<PAGE_SIZE;i++) { OLED_WR_Byte (YLevel+i,OLED_CMD); //設置頁地址(0~7)OLED_WR_Byte (XLevelL,OLED_CMD); //設置顯示位置—列低地址OLED_WR_Byte (XLevelH,OLED_CMD); //設置顯示位置—列高地址 for(n=0;n<WIDTH;n++){OLED_WR_Byte(OLED_buffer[i*WIDTH+n],OLED_DATA); }} //更新顯示 }/******************************************************************** @name :void OLED_Clear(unsigned dat) * @date :2018-08-27* @function :clear OLED screen* @parameters :dat:0-Display full black1-Display full white* @retvalue :None ********************************************************************/ void OLED_Clear(unsigned dat) { if(dat){memset(OLED_buffer,0xff,sizeof(OLED_buffer));}else{memset(OLED_buffer,0,sizeof(OLED_buffer));}OLED_Display(); }/******************************************************************** @name :void OLED_Reset(void) * @date :2018-08-27* @function :Reset OLED screen* @parameters :dat:0-Display full black1-Display full white* @retvalue :None ********************************************************************/ void OLED_Reset(void) {OLED_RST_Set();delay_ms(100);OLED_RST_Clr();delay_ms(100);OLED_RST_Set(); } /******************************************************************** @name :void OLED_Init_GPIO(void)* @date :2018-08-27* @function :Reset OLED screen* @parameters :None* @retvalue :None ********************************************************************/ void OLED_Init_GPIO(void) {GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能B端口時鐘GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_15; //GPIOB10,11,12,13,15 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽輸出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHzGPIO_Init(GPIOB, &GPIO_InitStructure); //初始化GPIOB10、11、12、13、15GPIO_SetBits(GPIOB,GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_15); }/******************************************************************** @name :void OLED_Init(void)* @date :2018-08-27* @function :initialise OLED SH1106 control IC* @parameters :None* @retvalue :None ********************************************************************/ void OLED_Init(void) {OLED_Init_GPIO(); //初始化GPIOdelay_ms(200);OLED_Reset(); //復位OLED/**************初始化SSD1306*****************/ OLED_WR_Byte(0xAE,OLED_CMD); /*display off*/OLED_WR_Byte(0x00,OLED_CMD); /*set lower column address*/OLED_WR_Byte(0x10,OLED_CMD); /*set higher column address*/OLED_WR_Byte(0x40,OLED_CMD); /*set display start line*/ OLED_WR_Byte(0xB0,OLED_CMD); /*set page address*/OLED_WR_Byte(0x81,OLED_CMD); /*contract control*/ OLED_WR_Byte(0xFF,OLED_CMD); /*128*/OLED_WR_Byte(0xA1,OLED_CMD); /*set segment remap*/ OLED_WR_Byte(0xA6,OLED_CMD); /*normal / reverse*/OLED_WR_Byte(0xA8,OLED_CMD); /*multiplex ratio*/ OLED_WR_Byte(0x3F,OLED_CMD); /*duty = 1/64*/OLED_WR_Byte(0xC8,OLED_CMD); /*Com scan direction*/OLED_WR_Byte(0xD3,OLED_CMD); /*set display offset*/ OLED_WR_Byte(0x00,OLED_CMD);OLED_WR_Byte(0xD5,OLED_CMD); /*set osc division*/ OLED_WR_Byte(0x80,OLED_CMD);OLED_WR_Byte(0xD9,OLED_CMD); /*set pre-charge period*/ OLED_WR_Byte(0XF1,OLED_CMD);OLED_WR_Byte(0xDA,OLED_CMD); /*set COM pins*/ OLED_WR_Byte(0x12,OLED_CMD);OLED_WR_Byte(0xDB,OLED_CMD); /*set vcomh*/ OLED_WR_Byte(0x30,OLED_CMD);OLED_WR_Byte(0x8D,OLED_CMD); /*set charge pump disable*/ OLED_WR_Byte(0x14,OLED_CMD);OLED_WR_Byte(0xAF,OLED_CMD); /*display ON*/ }

gui.h

#ifndef __GUI_H__ #define __GUI_H__void GUI_DrawPoint(u8 x, u8 y, u8 color); void GUI_Fill(u8 sx,u8 sy,u8 ex,u8 ey,u8 color); void GUI_DrawLine(u8 x1, u8 y1, u8 x2, u8 y2,u8 color); void GUI_DrawRectangle(u8 x1, u8 y1, u8 x2, u8 y2,u8 color); void GUI_FillRectangle(u8 x1, u8 y1, u8 x2, u8 y2,u8 color); void GUI_DrawCircle(u8 xc, u8 yc, u8 color, u8 r); void GUI_FillCircle(u8 xc, u8 yc, u8 color, u8 r); void GUI_DrawTriangel(u8 x0,u8 y0,u8 x1,u8 y1,u8 x2,u8 y2,u8 color); void GUI_FillTriangel(u8 x0,u8 y0,u8 x1,u8 y1,u8 x2,u8 y2,u8 color); void GUI_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size,u8 mode); void GUI_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 Size,u8 mode); void GUI_ShowString(u8 x,u8 y,u8 *chr,u8 Char_Size,u8 mode); void GUI_ShowFont16(u8 x,u8 y,u8 *s,u8 mode); void GUI_ShowFont24(u8 x,u8 y,u8 *s,u8 mode); void GUI_ShowFont32(u8 x,u8 y,u8 *s,u8 mode); void GUI_ShowChinese(u8 x,u8 y,u8 hsize,u8 *str,u8 mode); void GUI_DrawBMP(u8 x,u8 y,u8 width, u8 height, u8 BMP[], u8 mode); #endif

gui.c

#include "oled.h" #include "string.h" #include "oledfont.h" #include "delay.h" #include "gui.h"/******************************************************************** @name :void GUI_DrawPoint(u8 x,u8 y,u8 color)* @date :2018-08-27* @function :draw a point in LCD screen* @parameters :x:the x coordinate of the pointy:the y coordinate of the pointcolor:the color value of the point1-white0-black* @retvalue :None ********************************************************************/ void GUI_DrawPoint(u8 x,u8 y,u8 color) {OLED_Set_Pixel(x,y,color);OLED_Display(); }/******************************************************************** @name :void GUI_Fill(u8 sx,u8 sy,u8 ex,u8 ey,u8 color)* @date :2018-08-27 * @function :fill the specified area* @parameters :sx:the bebinning x coordinate of the specified areasy:the bebinning y coordinate of the specified areaex:the ending x coordinate of the specified areaey:the ending y coordinate of the specified areacolor:the color value of the the specified area1-white0-black* @retvalue :None ********************************************************************/ void GUI_Fill(u8 sx,u8 sy,u8 ex,u8 ey,u8 color) { u8 i,j; u8 width=ex-sx+1; //得到填充的寬度u8 height=ey-sy+1; //高度for(i=0;i<height;i++){for(j=0;j<width;j++){OLED_Set_Pixel(sx+j, sy+i,color);} }OLED_Display(); }/******************************************************************** @name :void GUI_DrawLine(u8 x1, u8 y1, u8 x2, u8 y2,u8 color)* @date :2018-08-27 * @function :Draw a line between two points* @parameters :x1:the bebinning x coordinate of the liney1:the bebinning y coordinate of the linex2:the ending x coordinate of the liney2:the ending y coordinate of the linecolor:the color value of the line1-white0-black* @retvalue :None ********************************************************************/ void GUI_DrawLine(u8 x1, u8 y1, u8 x2, u8 y2,u8 color) {u16 t; int xerr=0,yerr=0,delta_x,delta_y,distance; int incx,incy,uRow,uCol; delta_x=x2-x1; //計算坐標增量 delta_y=y2-y1; uRow=x1; uCol=y1; if(delta_x>0)incx=1; //設置單步方向 else if(delta_x==0)incx=0;//垂直線 else {incx=-1;delta_x=-delta_x;} if(delta_y>0)incy=1; else if(delta_y==0)incy=0;//水平線 else{incy=-1;delta_y=-delta_y;} if( delta_x>delta_y)distance=delta_x; //選取基本增量坐標軸 else distance=delta_y; for(t=0;t<=distance+1;t++ )//畫線輸出 { OLED_Set_Pixel(uRow,uCol,color);xerr+=delta_x ; yerr+=delta_y ; if(xerr>distance) { xerr-=distance; uRow+=incx; } if(yerr>distance) { yerr-=distance; uCol+=incy; } } OLED_Display(); } /****************************************************************************** @name :void GUI_DrawRectangle(u8 x1, u8 y1, u8 x2, u8 y2,u8 color)* @date :2018-08-27 * @function :Draw a rectangle* @parameters :x1:the bebinning x coordinate of the rectangley1:the bebinning y coordinate of the rectanglex2:the ending x coordinate of the rectangley2:the ending y coordinate of the rectanglecolor:the color value of the rectangle1-white0-black * @retvalue :None ******************************************************************************/ void GUI_DrawRectangle(u8 x1, u8 y1, u8 x2, u8 y2,u8 color) {GUI_DrawLine(x1,y1,x2,y1,color);GUI_DrawLine(x1,y1,x1,y2,color);GUI_DrawLine(x1,y2,x2,y2,color);GUI_DrawLine(x2,y1,x2,y2,color); } /****************************************************************************** @name :void GUI_FillRectangle(u8 x1, u8 y1, u8 x2, u8 y2,u8 color)* @date :2018-08-27* @function :Filled a rectangle* @parameters :x1:the bebinning x coordinate of the filled rectangley1:the bebinning y coordinate of the filled rectanglex2:the ending x coordinate of the filled rectangley2:the ending y coordinate of the filled rectanglecolor:the color value of the rectangle1-white0-black * @retvalue :None ******************************************************************************/ void GUI_FillRectangle(u8 x1, u8 y1, u8 x2, u8 y2,u8 color) {GUI_Fill(x1,y1,x2,y2,color); }/****************************************************************************** @name :static void _draw_circle_8(u8 xc, u8 yc, u8 x, u8 y, u8 color)* @date :2018-08-27 * @function :8 symmetry circle drawing algorithm (internal call)* @parameters :xc:the x coordinate of the Circular center yc:the y coordinate of the Circular center x:the x coordinate relative to the Circular center y:the y coordinate relative to the Circular center color:the color value of the rectangle1-white0-black * @retvalue :None ******************************************************************************/ static void _draw_circle_8(u8 xc, u8 yc, u8 x, u8 y, u8 color) {OLED_Set_Pixel(xc + x, yc + y, color);OLED_Set_Pixel(xc - x, yc + y, color);OLED_Set_Pixel(xc + x, yc - y, color);OLED_Set_Pixel(xc - x, yc - y, color);OLED_Set_Pixel(xc + y, yc + x, color);OLED_Set_Pixel(xc - y, yc + x, color);OLED_Set_Pixel(xc + y, yc - x, color);OLED_Set_Pixel(xc - y, yc - x, color); }/****************************************************************************** @name :void GUI_DrawCircle(u8 xc, u8 yc, u8 color, u8 r)* @date :2018-08-27* @function :Draw a circle of specified size at a specified location* @parameters :xc:the x coordinate of the Circular center yc:the y coordinate of the Circular center r:Circular radiuscolor:the color value of the rectangle1-white0-black * @retvalue :None ******************************************************************************/ void GUI_DrawCircle(u8 xc, u8 yc, u8 color, u8 r) {int x = 0, y = r,d;d = 3 - 2 * r;while (x <= y) {_draw_circle_8(xc, yc, x, y, color);if (d < 0) {d = d + 4 * x + 6;}else {d = d + 4 * (x - y) + 10;y--;}x++;}OLED_Display(); }/****************************************************************************** @name :void GUI_FillCircle(u8 xc, u8 yc, u8 color, u8 r)* @date :2018-08-27* @function :Fill a circle of specified size at a specified location* @parameters :xc:the x coordinate of the Circular center yc:the y coordinate of the Circular center r:Circular radiuscolor:the color value of the rectangle1-white0-black * @retvalue :None ******************************************************************************/ void GUI_FillCircle(u8 xc, u8 yc, u8 color, u8 r) {int x = 0, y = r, yi, d;d = 3 - 2 * r;while (x <= y) {for (yi = x; yi <= y; yi++){_draw_circle_8(xc, yc, x, yi, color);}if (d < 0) {d = d + 4 * x + 6;} else {d = d + 4 * (x - y) + 10;y--;}x++;}OLED_Display(); }/*********************************************************************************** @name :void GUI_DrawTriangel(u8 x0,u8 y0,u8 x1,u8 y1,u8 x2,u8 y2,u8 color)* @date :2018-08-27 * @function :Draw a triangle at a specified position* @parameters :x0:the bebinning x coordinate of the triangular edge y0:the bebinning y coordinate of the triangular edge x1:the vertex x coordinate of the triangulary1:the vertex y coordinate of the triangularx2:the ending x coordinate of the triangular edge y2:the ending y coordinate of the triangular edge color:the color value of the rectangle1-white0-black * @retvalue :None ***********************************************************************************/ void GUI_DrawTriangel(u8 x0,u8 y0,u8 x1,u8 y1,u8 x2,u8 y2,u8 color) {GUI_DrawLine(x0,y0,x1,y1,color);GUI_DrawLine(x1,y1,x2,y2,color);GUI_DrawLine(x2,y2,x0,y0,color); }/****************************************************************************** @name :static void _swap(u8 *a, u8 *b)* @date :2018-08-27* @function :Exchange two numbers(internal call)* @parameters :a:the address of the first number b:the address of the second number* @retvalue :None ******************************************************************************/ static void _swap(u8 *a, u8 *b) {u16 tmp;tmp = *a;*a = *b;*b = tmp; }/****************************************************************************** @name :static void _draw_h_line(u8 x0,u8 x1,u8 y,u8 color)* @date :2018-08-27* @function :draw a horizontal line in RAM(internal call)* @parameters :x0:the bebinning x coordinate of the horizontal linex1:the ending x coordinate of the horizontal liney:the y coordinate of the horizontal linecolor:the color value of the rectangle1-white0-black * @retvalue :None ******************************************************************************/ static void _draw_h_line(u8 x0,u8 x1,u8 y,u8 color) {u8 i=0;for(i=x0;i<=x1;i++){OLED_Set_Pixel(i, y, color);} }/****************************************************************************** @name :void GUI_FillTriangel(u8 x0,u8 y0,u8 x1,u8 y1,u8 x2,u8 y2,u8 color)* @date :2018-08-27 * @function :filling a triangle at a specified position* @parameters :x0:the bebinning x coordinate of the triangular edge y0:the bebinning y coordinate of the triangular edge x1:the vertex x coordinate of the triangulary1:the vertex y coordinate of the triangularx2:the ending x coordinate of the triangular edge y2:the ending y coordinate of the triangular edge color:the color value of the rectangle1-white0-black * @retvalue :None ******************************************************************************/ void GUI_FillTriangel(u8 x0,u8 y0,u8 x1,u8 y1,u8 x2,u8 y2,u8 color) {u8 a, b, y, last;int dx01, dy01, dx02, dy02, dx12, dy12;long sa = 0;long sb = 0;if (y0 > y1) {_swap(&y0,&y1); _swap(&x0,&x1);}if (y1 > y2) {_swap(&y2,&y1); _swap(&x2,&x1);}if (y0 > y1) {_swap(&y0,&y1); _swap(&x0,&x1);}if(y0 == y2) { a = b = x0;if(x1 < a){a = x1;}else if(x1 > b){b = x1;}if(x2 < a){a = x2;}else if(x2 > b){b = x2;}_draw_h_line(a,b,y0,color);return;}dx01 = x1 - x0;dy01 = y1 - y0;dx02 = x2 - x0;dy02 = y2 - y0;dx12 = x2 - x1;dy12 = y2 - y1;if(y1 == y2){last = y1; }else{last = y1-1; }for(y=y0; y<=last; y++) {a = x0 + sa / dy01;b = x0 + sb / dy02;sa += dx01;sb += dx02;if(a > b){_swap(&a,&b);}_draw_h_line(a,b,y,color);}sa = dx12 * (y - y1);sb = dx02 * (y - y0);for(; y<=y2; y++) {a = x1 + sa / dy12;b = x0 + sb / dy02;sa += dx12;sb += dx02;if(a > b){_swap(&a,&b);}_draw_h_line(a,b,y,color);}OLED_Display(); }/****************************************************************************** @name :void GUI_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size,u8 mode)* @date :2018-08-27 * @function :Display a single English character* @parameters :x:the bebinning x coordinate of the Character display positiony:the bebinning y coordinate of the Character display positionchr:the ascii code of display character(0~94)Char_Size:the size of display character(8,16)mode:0-white background and black character1-black background and white character* @retvalue :None ******************************************************************************/ void GUI_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size,u8 mode) { unsigned char c=0,i=0,tmp,j=0; c=chr-' ';//得到偏移后的值 if(x>WIDTH-1){x=0;y=y+2;}if(Char_Size ==16){for(i=0;i<16;i++){if(mode){tmp = F8X16[c*16+i];}else{tmp = ~(F8X16[c*16+i]);}for(j=0;j<8;j++){if(tmp&(0x80>>j)){OLED_Set_Pixel(x+j, y+i,1);}else{OLED_Set_Pixel(x+j, y+i,0);}}}}else if(Char_Size==8){ for(i=0;i<8;i++){if(mode){tmp = F6x8[c][i];}else{tmp = ~(F6x8[c][i]);}for(j=0;j<8;j++){if(tmp&(0x80>>j)){OLED_Set_Pixel(x+j, y+i,1);}else{OLED_Set_Pixel(x+j, y+i,0);}}}}else{return;}OLED_Display(); }/****************************************************************************** @name :void GUI_ShowString(u8 x,u8 y,u8 *chr,u8 Char_Size,u8 mode)* @date :2018-08-27 * @function :Display English string* @parameters :x:the bebinning x coordinate of the English stringy:the bebinning y coordinate of the English stringchr:the start address of the English stringChar_Size:the size of display charactermode:0-white background and black character1-black background and white character* @retvalue :None ******************************************************************************/ void GUI_ShowString(u8 x,u8 y,u8 *chr,u8 Char_Size,u8 mode) {unsigned char j=0,csize;if(Char_Size == 16){csize = Char_Size/2;}else if(Char_Size == 8){csize = Char_Size/2+2;}else{return;}while (chr[j]!='\0'){ GUI_ShowChar(x,y,chr[j],Char_Size,mode);x+=csize;if(x>120){x=0;y+=Char_Size;}j++;} }/****************************************************************************** @name :u32 mypow(u8 m,u8 n)* @date :2018-08-27 * @function :get the nth power of m (internal call)* @parameters :m:the multipliern:the power* @retvalue :the nth power of m ******************************************************************************/ static u32 mypow(u8 m,u8 n) {u32 result=1; while(n--)result*=m; return result; }/****************************************************************************** @name :void GUI_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 Size,u8 mode)* @date :2018-08-27 * @function :Display number* @parameters :x:the bebinning x coordinate of the numbery:the bebinning y coordinate of the numbernum:the number(0~4294967295)len:the length of the display numberSize:the size of display numbermode:0-white background and black character1-black background and white character* @retvalue :None ******************************************************************************/ void GUI_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 Size,u8 mode) { u8 t,temp;u8 enshow=0,csize;if(Size == 16){csize = Size/2;}else if(Size == 8){csize = Size/2+2;} else{return;}for(t=0;t<len;t++){temp=(num/mypow(10,len-t-1))%10;if(enshow==0&&t<(len-1)){if(temp==0){GUI_ShowChar(x+csize*t,y,' ',Size,mode);continue;}else enshow=1; }GUI_ShowChar(x+csize*t,y,temp+'0',Size,mode); } } /****************************************************************************** @name :void GUI_ShowFont16(u8 x,u8 y,u8 *s,u8 mode)* @date :2018-08-27 * @function :Display a single 16x16 Chinese character* @parameters :x:the bebinning x coordinate of the Chinese charactery:the bebinning y coordinate of the Chinese characters:the start address of the Chinese charactermode:0-white background and black character1-black background and white character* @retvalue :None ******************************************************************************/ void GUI_ShowFont16(u8 x,u8 y,u8 *s,u8 mode) {u8 i,j,k,tmp;u16 num;num = sizeof(cfont16)/sizeof(typFNT_GB16);for(i=0;i<num;i++){if((cfont16[i].Index[0]==*s)&&(cfont16[i].Index[1]==*(s+1))){for(j=0;j<32;j++){if(mode){tmp = cfont16[i].Msk[j];}else{tmp = ~(cfont16[i].Msk[j]);}for(k=0;k<8;k++){if(tmp&(0x80>>k)){OLED_Set_Pixel(x+(j%2)*8+k, y+j/2,1);}else{OLED_Set_Pixel(x+(j%2)*8+k, y+j/2,0);}}} break;} }OLED_Display(); }/****************************************************************************** @name :void GUI_ShowFont24(u8 x,u8 y,u8 *s,u8 mode)* @date :2018-08-27 * @function :Display a single 24x24 Chinese character* @parameters :x:the bebinning x coordinate of the Chinese charactery:the bebinning y coordinate of the Chinese characters:the start address of the Chinese charactermode:0-white background and black character1-black background and white character* @retvalue :None ******************************************************************************/ void GUI_ShowFont24(u8 x,u8 y,u8 *s,u8 mode) {u8 i,j,k,tmp;u16 num;num = sizeof(cfont24)/sizeof(typFNT_GB24);for(i=0;i<num;i++){if((cfont24[i].Index[0]==*s)&&(cfont24[i].Index[1]==*(s+1))){for(j=0;j<72;j++){if(mode){tmp = cfont24[i].Msk[j];}else{tmp = ~(cfont24[i].Msk[j]);}for(k=0;k<8;k++){if(tmp&(0x80>>k)){OLED_Set_Pixel(x+(j%3)*8+k, y+j/3,1);}else{OLED_Set_Pixel(x+(j%3)*8+k, y+j/3,0);}}} break;} }OLED_Display(); }/****************************************************************************** @name :void GUI_ShowFont32(u8 x,u8 y,u8 *s,u8 mode)* @date :2018-08-27 * @function :Display a single 32x32 Chinese character* @parameters :x:the bebinning x coordinate of the Chinese charactery:the bebinning y coordinate of the Chinese characters:the start address of the Chinese charactermode:0-white background and black character1-black background and white character* @retvalue :None ******************************************************************************/ void GUI_ShowFont32(u8 x,u8 y,u8 *s,u8 mode) {u8 i,j,k,tmp;u16 num;num = sizeof(cfont32)/sizeof(typFNT_GB32);for(i=0;i<num;i++){if((cfont32[i].Index[0]==*s)&&(cfont32[i].Index[1]==*(s+1))){for(j=0;j<128;j++){if(mode){tmp = cfont32[i].Msk[j];}else{tmp = ~(cfont32[i].Msk[j]);}for(k=0;k<8;k++){if(tmp&(0x80>>k)){OLED_Set_Pixel(x+(j%4)*8+k, y+j/4,1);}else{OLED_Set_Pixel(x+(j%4)*8+k, y+j/4,0);}}} break;} }OLED_Display(); }/****************************************************************************** @name :void GUI_ShowCHinese(u8 x,u8 y,u8 hsize,u8 *str,u8 mode)* @date :2018-08-27 * @function :Display Chinese strings* @parameters :x:the bebinning x coordinate of the Chinese stringsy:the bebinning y coordinate of the Chinese stringssize:the size of Chinese stringsstr:the start address of the Chinese stringsmode:0-white background and black character1-black background and white character* @retvalue :None ******************************************************************************/ void GUI_ShowChinese(u8 x,u8 y,u8 hsize,u8 *str,u8 mode) { while(*str!='\0'){if(hsize == 16){GUI_ShowFont16(x,y,str,mode);}else if(hsize == 24){GUI_ShowFont24(x,y,str,mode);}else if(hsize == 32){GUI_ShowFont32(x,y,str,mode);}else{return;}x+=hsize;if(x>WIDTH-hsize){x=0;y+=hsize;}str+=2;} }/****************************************************************************** @name :void GUI_DrawBMP(u8 x,u8 y,u8 width, u8 height, u8 BMP[], u8 mode)* @date :2018-08-27 * @function :Display a BMP monochromatic picture* @parameters :x:the bebinning x coordinate of the BMP monochromatic picturey:the bebinning y coordinate of the BMP monochromatic picturewidth:the width of BMP monochromatic pictureheight:the height of BMP monochromatic pictureBMP:the start address of BMP monochromatic picture arraymode:0-white background and black character1-black background and white character * @retvalue :None ******************************************************************************/ void GUI_DrawBMP(u8 x,u8 y,u8 width, u8 height, u8 BMP[], u8 mode) { u8 i,j,k;u8 tmp;for(i=0;i<height;i++){for(j=0;j<(width+7)/8;j++){if(mode){tmp = BMP[i*((width+7)/8)+j];}else{tmp = ~BMP[i*((width+7)/8)+j];}for(k=0;k<8;k++){if(tmp&(0x80>>k)){OLED_Set_Pixel(x+j*8+k, y+i,1);}else{OLED_Set_Pixel(x+j*8+k, y+i,0);}}}} OLED_Display(); }

spi.h

#ifndef _SPI_H_ #define _SPI_H_ #include "stm32f10x.h"//本測試程序使用的是軟件模擬SPI接口驅動 //SPI的數據引腳定義和時鐘引腳定義都可以任意修改 //修改引腳定義后,需要對應修改oled.c中OLED_Init_GPIO函數里面引腳初始化//--------------SPI總線引腳定義----------------------- #define OLED_MOSI GPIO_Pin_15 //OLED屏SPI寫數據信號 #define OLED_CLK GPIO_Pin_13 //OLED屏SPI時鐘信號//--------------SPI端口操作定義--------------------- #define OLED_MOSI_SET() GPIO_SetBits(GPIOB,OLED_MOSI) #define OLED_MOSI_CLR() GPIO_ResetBits(GPIOB,OLED_MOSI) #define OLED_CLK_SET() GPIO_SetBits(GPIOB,OLED_CLK) #define OLED_CLK_CLR() GPIO_ResetBits(GPIOB,OLED_CLK) //SPI寫數據函數 void SPI_WriteByte(u8 Data); #endif

spi.c

#include "spi.h"/****************************************************************************** @name :void SPI_WriteByte(u8 Data)* @date :2018-08-27 * @function :Write a byte of data using STM32's Software SPI* @parameters :Data:Data to be written* @retvalue :None ******************************************************************************/ void SPI_WriteByte(u8 Data) {unsigned char i=0;for(i=8;i>0;i--){if(Data&0x80) {OLED_MOSI_SET(); //寫數據1}else{OLED_MOSI_CLR(); //寫數據0}OLED_CLK_CLR(); //將時鐘拉低拉高 OLED_CLK_SET(); //發送1bit數據Data<<=1; } }

main.c

#include "stm32f10x.h" #include "delay.h" #include "oled.h" #include "gui.h"int main(void) { DELAY_Init(); //延時函數初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);OLED_Init(); //初始化OLED OLED_Clear(0); while(1) { GUI_ShowCHinese(28,20,16,"***",1);GUI_ShowString(4,48,"******",16,1);delay_ms(1500); delay_ms(1500);} }

其中還需要oledfont.h、bmp.h,分別為存儲字體和圖像的文件

2.3 實驗效果

圖 2.3實驗效果

三、OLED屏的溫濕度顯示

有關OLED屏的資料很多,如果有需要可以在各大廠家或賣家等獲取相關資料,或者也可以在其官方網站下載資料。

1. 部分代碼實現思想

結合上次的實驗基于I2C的溫濕度采集_江南煙濃雨的博客-CSDN博客,通過IIC讀取溫濕度信息后再通過OLED顯示出來,主要功能在主程序中實現。將iic.h中H1和T1設置為全局變量,在調用讀取函數時,H1和T1的值便會保存在H1和T1中,再通過上面的GUI函數實現。

注意:需要將原來的H1和T1設置為全局變量,在頭文件中通過extern聲明為全局變量

實驗電路(引腳接口)請參考本次實驗OLED屏及上次實驗AHT20的引腳接法

2. 完整代碼

main.c

#include "stm32f10x.h" #include "stdio.h" #include "stdlib.h" #include "bmp.h" #include "delay.h" #include "iic.h" #include "oled.h" #include "gui.h"uint32_t H1; //Humility uint32_t T1; //Temperatureint main(void) { DELAY_Init(); //延時函數初始化MyUSART_Init();IIC_Init();NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);OLED_Init(); //初始化OLED OLED_Clear(0); while(1) {read_AHT20_once();GUI_DrawLine(0, 10, WIDTH-1, 10,1);GUI_DrawLine(WIDTH/2-1,11,WIDTH/2-1,HEIGHT-1,1);GUI_DrawLine(WIDTH/2-1,10+(HEIGHT-10)/2-1,WIDTH-1,10+(HEIGHT-10)/2-1,1);GUI_ShowString(0,1,"2021-11-24",8,1);GUI_ShowString(70,1,"Wednesday",8,1);GUI_ShowString(14,HEIGHT-1-10,"Cloudy",8,1);GUI_ShowString(WIDTH/2+1,13,"TEMP",8,1); //顯示溫度GUI_DrawCircle(WIDTH-20, 25, 1,2);GUI_ShowString(WIDTH-15,20,"C",16,1);GUI_ShowNum(WIDTH/2+8,20,T1/10,2,16,1);GUI_ShowString(WIDTH-41,26,".",8,1);GUI_ShowNum(WIDTH-35,20,T1%10,1,16,1);GUI_ShowString(WIDTH/2+1,39,"HUM",8,1); //顯示濕度GUI_ShowNum(WIDTH/2+8,46,H1/10,2,16,1);GUI_ShowString(WIDTH-41,52,".",8,1);GUI_ShowNum(WIDTH-35,46,H1%10,1,16,1);GUI_ShowString(WIDTH-21,46,"%",16,1);GUI_DrawBMP(6,16,51,32, BMP5, 1);delay_ms(2000);} }

3. 實驗效果

在實驗過程中,用手捂住AHT20溫濕度傳感器,使其溫度升高,OLED屏幕上也會隨之而變化

四、OLED屏的滾動顯示

1. 部分代碼實現思想

OLED支持水平滾動、垂直并水平滾動兩種效果。在0.96OLED數據手冊第九章中給出了功能定義

Scrolling Command Table

第一個字節是26h/27h,26h:向右進行水平滾動;27h:向左進行水平滾動
第二個字節是空字節,建議發送00即可
第三個字節設置水平滾動的起始頁地址,頁0 ~頁7。
第四個字節設置滾動步長時間間隔,幀為單位。
第五個字節設置水平滾動的終止頁地址,頁0 ~頁7(終止頁地址必須要比起始頁地址要大)
第六個字節是空字節,建議發送00即可
第七個字節是空字節,建議發送FF即可

注意:設置滾動前,必須先發送2Eh命令停止滾動。

以上內容參考自如何使用OLED實現滾動效果_正點原子的博客-CSDN博客

知道了這些連續字節的含義,接下來就是水平滾動代碼的編寫。(更多資料請參考相關博客或數據手冊)

2. 完整代碼

注意:需要修改或添加oledfont.h的文字內容

main.c

#include "stm32f10x.h" #include "delay.h" #include "oled.h" #include "gui.h"int main(void) { DELAY_Init(); //延時函數初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);OLED_Init(); //初始化OLED OLED_Clear(0); OLED_WR_Byte(0x2E,OLED_CMD); //關閉滾動OLED_WR_Byte(0x26,OLED_CMD); //水平向左或者右滾動 26/27OLED_WR_Byte(0x00,OLED_CMD); //虛擬字節OLED_WR_Byte(0x00,OLED_CMD); //起始頁 0OLED_WR_Byte(0x07,OLED_CMD); //滾動時間間隔OLED_WR_Byte(0x07,OLED_CMD); //終止頁 7OLED_WR_Byte(0x00,OLED_CMD); //虛擬字節OLED_WR_Byte(0xFF,OLED_CMD); GUI_ShowChinese(0,20,16,"你說江南煙濃雨",1);OLED_WR_Byte(0x2F,OLED_CMD);delay_ms(1500); }

3. 實驗效果

五、實驗總結

本次實驗完成了對于OLED屏的一些操作,但是美中不足的是沒有實現硬件IIC和SPI,而是軟件模擬的方式實現了IIC和SPI協議。文中所附代碼大部分可能并沒有用到,請讀者自行斟酌,可以參考相關廠商的代碼進行改進

六、參考資料

SPI(SPI協議)_百度百科 (baidu.com)

OLED_百度百科 (baidu.com)

基于SPI通信方式的OLED顯示_不#曾&輕聽的博客-CSDN博客

如何使用OLED實現滾動效果_正點原子的博客-CSDN博客

0.96inch SPI OLED Module - LCD wiki

基于I2C的溫濕度采集_江南煙濃雨的博客-CSDN博客

STM32中文參考手冊.pdf

STM32F103數據手冊.pdf

0.96OLED顯示屏_驅動芯片手冊.pdf

總結

以上是生活随笔為你收集整理的基于SPI的OLED温湿度显示的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

91九色porn在线资源 | 国产精品69av | 亚洲在线色 | 亚洲乱码在线观看 | 国产美女无遮挡永久免费 | 97成人在线 | 国产群p视频 | 国产日韩精品一区二区 | 成人综合婷婷国产精品久久免费 | 亚洲精品视频在线观看视频 | 91福利视频在线 | 亚洲国内精品视频 | 九九日韩 | 国产小视频免费观看 | 人人插人人艹 | 日韩字幕| 丰满少妇在线观看网站 | 五月天高清欧美mv | 久久专区| 91精品久久久久久久91蜜桃 | 精品久久久久久综合 | 波多野结衣在线播放一区 | 国产在线一卡 | 91丨九色丨蝌蚪丨对白 | 亚洲成a人片在线观看中文 中文字幕在线视频第一页 狠狠色丁香婷婷综合 | 欧美片网站yy | 欧美成人h版在线观看 | 久草资源在线观看 | 亚洲欧美成人在线 | 五月天,com| 日韩中文字幕视频在线观看 | 久久综合影视 | 中文国产在线观看 | 五月婷婷一区二区三区 | 98精品国产自产在线观看 | 正在播放日韩 | 亚洲成人av一区二区 | 欧美日韩国语 | 成人一区二区在线观看 | 波多野结衣一区二区三区中文字幕 | 午夜av大片 | 美女免费视频网站 | av免费网站在线观看 | 日韩av快播电影网 | 国产网站色 | 91探花在线视频 | 九九导航 | avcom在线 | 伊人婷婷| 久久久天堂 | 超碰97人人爱 | 欧美日产一区 | 亚洲精品免费在线观看 | 免费日韩视 | 国产黄色高清 | 福利视频一区二区 | 国产视频一区二区在线观看 | 四虎在线免费视频 | 久久久精品欧美一区二区免费 | 五月婷婷在线综合 | 综合网五月天 | 四虎永久免费在线观看 | 亚洲成人一区 | 偷拍视频一区 | 韩国精品在线观看 | 久久大片网站 | 亚洲精品乱码久久久久久写真 | 中文字幕人成不卡一区 | 在线播放亚洲激情 | 日日麻批40分钟视频免费观看 | 毛片二区| 在线观看黄色大片 | 成人动漫一区二区三区 | www免费黄色| 婷婷在线免费视频 | 亚洲精品国产区 | 国产黄色av | 国内精品久久久久影院一蜜桃 | 婷婷激情网站 | 国产精品久久久久永久免费 | 超碰97中文 | 亚洲成人xxx | 色婷五月天| 国产精品一区一区三区 | 色综合色综合久久综合频道88 | 久久成人国产精品一区二区 | 久久免费福利 | 精品一区在线 | 在线观看成人福利 | 国产精品嫩草影视久久久 | 91污视频在线观看 | 久久国产免费视频 | 国产手机在线观看视频 | 91在线精品秘密一区二区 | 国产中文| 国产只有精品 | 日韩免费av网址 | 在线 精品 国产 | 国产一及片 | 色综合网 | 亚洲三级影院 | 在线免费观看黄色 | 色97在线| 国产色视频| 日日干综合 | 一区二区精品在线 | 四虎国产精 | 在线看片日韩 | 亚洲天天综合 | 丁香综合网| 97碰碰视频 | 欧美日韩久久一区 | 色视频在线免费观看 | 国产精品久久久久aaaa九色 | 超碰久热 | 国产美女免费视频 | 成人免费在线看片 | 国产精品国产精品 | 亚洲欧洲一区二区在线观看 | 成人小视频在线观看免费 | 国产黄在线 | 久久国内精品 | 综合色久 | 激情欧美丁香 | av性网站| 成人观看视频 | 人人艹人人 | 亚洲麻豆精品 | 中文字幕人成乱码在线观看 | 日韩在线精品一区 | 亚洲永久精品在线观看 | 国产精品成人一区二区三区吃奶 | 日日操天天操夜夜操 | 国产一级免费在线 | 国产拍揄自揄精品视频麻豆 | www.com黄 | 免费中文字幕视频 | 日韩中出在线 | 欧美日韩视频精品 | 国产亚洲在 | 国产视频网站在线观看 | 国产精品嫩草影院99网站 | 91精品免费视频 | 九九激情视频 | 97超碰人人网 | 色搞搞| 嫩嫩影院理论片 | 伊人天天综合 | 一区二区亚洲精品 | 久久www免费视频 | 国产精品视频最多的网站 | 亚洲精品国产欧美在线观看 | 91丨九色丨国产在线 | 9797在线看片亚洲精品 | 日韩av一区二区在线影视 | 久久高清 | 91av国产视频 | 色综合www| 亚洲国产视频在线 | 国产一区二区综合 | 人人插人人费 | 亚洲精品动漫在线 | 91av网址| 国内精品久久久久久久久 | 99精品欧美一区二区三区黑人哦 | 97超碰成人在线 | 久久99深爱久久99精品 | 91探花在线视频 | 最近中文字幕免费观看 | 91精品久久久久久粉嫩 | 又黄又刺激的网站 | 午夜精品一区二区三区在线观看 | 久久国产手机看片 | 中文字幕日本电影 | 黄色大片中国 | 狠色在线 | 国产精品乱码高清在线看 | 伊人色综合久久天天 | 久久久香蕉视频 | av片子在线观看 | 蜜臀av麻豆 | 91av影视| 干天天 | 欧美成人一区二区 | 免费网址你懂的 | 国产精品一区二区三区在线免费观看 | 99久久日韩精品免费热麻豆美女 | 午夜免费福利视频 | 97国产情侣爱久久免费观看 | 色综合久久中文字幕综合网 | 天天干,天天射,天天操,天天摸 | 久草视频在线观 | 午夜av在线电影 | 日韩视频免费观看高清完整版在线 | 91爱爱电影 | 国产精品久久久久久久久蜜臀 | 99九九视频 | 午夜久久网站 | 国产精品色在线 | 日韩中文在线视频 | 深爱激情丁香 | 色婷婷视频在线 | 色综合天天干 | 久久综合免费视频 | av在线成人 | 成年人在线观看视频免费 | 日韩av一区二区三区在线观看 | 日韩在线观看中文字幕 | 美女视频久久久 | 午夜在线看 | 91av超碰| 97色在线视频 | 亚洲国产日本 | 福利电影一区二区 | 国产精品第二十页 | 中文日韩在线视频 | 中文字幕av在线播放 | 久久精品国产99 | 在线网址你懂得 | 天天做日日爱夜夜爽 | 色老板在线视频 | 在线观看网站你懂的 | 中文字幕av在线 | 久久精品久久精品久久精品 | 91麻豆网站 | 91精品国产乱码久久 | 国产精品美女久久久久久久 | 色成人亚洲 | 国产一区二区精品91 | 深夜男人影院 | 91传媒91久久久 | 99久久久国产精品美女 | 久久国产一二区 | 中文字幕一区二区三区久久蜜桃 | 中文字幕 影院 | 国产不卡在线 | 亚洲精品乱码久久久久久写真 | 成人啪啪18免费游戏链接 | 国产精品一区二区在线观看免费 | 久久视频在线视频 | 国产精品你懂的在线观看 | 成人午夜黄色影院 | 成人av电影在线 | 日韩精品欧美精品 | 超级碰碰碰免费视频 | 日本一区二区免费在线观看 | 高清免费在线视频 | 不卡精品 | 国内精品久久久久久久久久久 | 国产一级二级视频 | 99久久精品午夜一区二区小说 | 亚洲精品中文在线 | 国产老太婆免费交性大片 | 插插插色综合 | 色婷婷综合久久久 | 一区二区影院 | 国产一区二区免费在线观看 | 激情久久综合 | 欧美精品九九99久久 | 久久综合久久综合这里只有精品 | 国产高清免费在线播放 | 午夜视频在线观看一区二区 | 伊人婷婷色 | 五月婷婷综合在线 | 国产精品免费在线播放 | 五月丁香 | 91在线视频精品 | 午夜在线免费视频 | 综合久久网 | 日韩精品欧美视频 | 天天操天天弄 | 亚洲精品午夜视频 | 亚洲欧美在线观看视频 | 青青河边草免费观看完整版高清 | 亚洲在线高清 | 日本中文字幕网址 | 日韩在线电影观看 | 视频在线一区 | 欧美另类性| 日韩午夜在线观看 | 日日夜夜爱 | 91成人免费视频 | 免费色av | 欧美一区免费观看 | 91精品免费视频 | 中文字幕在线观看91 | 国产综合精品一区二区三区 | 中文字幕在线播放视频 | 最近中文字幕免费大全 | 成人精品国产免费网站 | 亚洲成人av影片 | 2022中文字幕在线观看 | 国产精品久久久久久久久久妇女 | 久久免费成人精品视频 | 国产成人久久久77777 | h视频日本| 国产最顶级的黄色片在线免费观看 | 视频国产在线 | 蜜臀av一区二区 | 在线免费观看黄色小说 | 99视频在线观看视频 | 亚洲精品电影在线 | 精品国产一区二区三区久久久久久 | 色综合久久五月 | 国产污视频在线观看 | 麻豆视频免费在线 | 91av亚洲 | 中文字幕韩在线第一页 | 美女视频黄色免费 | 香蕉久久国产 | 成人免费观看视频网站 | 国产成人久久精品一区二区三区 | 成人国产精品久久久春色 | 国产精品欧美久久久久三级 | 国产一二三在线视频 | 国产一区二三区好的 | 久久久国产视频 | 中文字幕人成不卡一区 | 2017狠狠干| 亚洲jizzjizz日本少妇 | 国产免费观看久久 | 黄色www| 高清视频一区 | 国产尤物一区二区三区 | 亚洲精品男女 | 成人网在线免费视频 | 中文字幕日韩无 | 国产综合精品久久 | 99久热在线精品视频成人一区 | 久久久久成 | 狠狠色丁香久久婷婷综合丁香 | 日韩高清免费电影 | 欧美日韩成人一区 | 日本99热| 日韩伦理一区二区三区av在线 | 久久精品官网 | 99免费精品视频 | 亚洲精品久久久久中文字幕二区 | 色av资源网| 国产69精品久久99的直播节目 | 97精品国产一二三产区 | 欧美91av | 久草在线视频首页 | 国产福利91精品一区二区三区 | 国产一区久久 | 日韩在线免费视频 | av丝袜制服 | 就要色综合 | 欧美午夜精品久久久久 | 91porny九色91啦中文 | 久久久国产高清 | 精品亚洲午夜久久久久91 | 看黄色.com | 国产精品一区专区欧美日韩 | 人人干人人做 | 精品久久九九 | 丝袜美腿av | 在线观看视频你懂得 | 亚洲欧美va | 国产精品av免费观看 | 日韩欧美亚州 | 久久亚洲视频 | 婷婷丁香激情 | 午夜久久久久久久久久久 | 中文字幕黄色av | 五月开心婷婷网 | 狠狠色丁香久久婷婷综合_中 | 色婷婷福利 | 日本精品在线看 | 成人91在线 | 国产69久久久欧美一级 | 黄色免费高清视频 | 91精品在线免费观看视频 | 97精品国自产拍在线观看 | 天天性天天草 | 男女啪啪免费网站 | 午夜视频在线观看一区二区 | 黄av在线 | 日韩欧美在线综合网 | 在线观看香蕉视频 | 天天人人 | 黄在线免费观看 | 999ZYZ玖玖资源站永久 | 麻豆影视在线观看 | 成 人 黄 色视频免费播放 | 狠狠狠色丁香婷婷综合久久88 | 人人干人人干人人干 | 黄色影院在线播放 | 国产午夜激情视频 | www.天天综合 | 国产69精品久久app免费版 | 天天天天天操 | 成人91在线 | 96视频免费在线观看 | 久久久成人精品 | 精品国产一区二区在线 | 97偷拍视频| 精品国产三级 | 国产精品一区二区av | 亚洲免费在线视频 | 中文字幕一区二区三区乱码在线 | 久草网视频在线观看 | 精品国产一区二区在线 | 免费av片在线 | 丝袜一区在线 | 国产最新在线 | 成人久久久久久久久 | 天天干天天搞天天射 | 免费观看一级特黄欧美大片 | 欧美日韩在线观看一区二区 | 久久精品草 | 超级碰碰碰免费视频 | 人人干干人人 | 伊人五月天 | 黄色特一级 | 国产精品99视频 | 怡红院久久 | 又黄又爽又色无遮挡免费 | 日韩av电影手机在线观看 | 深爱激情av | 国色天香在线 | 亚洲一区精品二人人爽久久 | 丁香久久| 天天操天天色综合 | www91在线| 国产伦理久久精品久久久久_ | 91精品视频免费观看 | 日韩av电影中文字幕在线观看 | 欧美激情另类 | av免费看av| 欧美成人在线免费观看 | 日韩在线免费观看视频 | 中文字幕123区 | 亚洲一片黄 | 中文字幕av日韩 | 色婷婷av一区 | 天天做日日爱夜夜爽 | 亚洲无吗天堂 | 国产精品久久久一区二区 | 日韩久久精品一区二区三区 | 一本一道久久a久久精品蜜桃 | 欧美色图一区 | 国产黄色成人av | 九九爱免费视频 | 亚洲欧洲精品一区二区 | 日韩精品免费在线播放 | 日韩欧美网址 | 少妇bbb| adn—256中文在线观看 | 国产一及片 | 天天色天天射综合网 | 狠狠狠狠狠狠狠狠 | 日韩高清免费无专码区 | 99精品国产免费久久久久久下载 | 天天射天天 | 国产福利精品在线观看 | 日韩二区三区在线 | 青春草视频在线播放 | 97色婷婷成人综合在线观看 | 色婷婷电影| www九九热 | 99精品毛片 | 五月婷婷激情 | 在线视频你懂得 | 亚洲精品国产精品久久99热 | 最近的中文字幕大全免费版 | 中文字幕在线日 | 久久久久久久免费 | 精品伦理一区二区三区 | 日韩精品三区四区 | 久久久麻豆 | 久久国产精品久久精品 | 久久国产精品99久久人人澡 | 日本精品久久久久 | 中文字幕在线播放日韩 | 色妞色视频一区二区三区四区 | 黄色大片日本免费大片 | 少妇av片 | 日韩一区二区三区高清在线观看 | a v在线视频 | 一区二区三区免费播放 | 色永久免费视频 | 69精品在线 | www.久草.com | 人人爽人人爽人人爽 | 97精品欧美91久久久久久 | 精品一区二三区 | 成人久久国产 | 国产精品久久久久久久久软件 | 亚州精品视频 | 天天爽网站 | www.国产视频 | 91大神在线观看视频 | 91视频免费看 | 欧美做受高潮1 | 亚洲视频 在线观看 | 97超级碰 | 三级av免费看 | 黄色特一级片 | 国产一区91 | 91中文视频 | 草久草久| 日本久久久久 | 成人a级网站 | 国产精品毛片一区二区在线 | 久草精品视频 | 27xxoo无遮挡动态视频 | 国产一区二区免费在线观看 | 久久国内视频 | 四虎成人精品永久免费av | 久草免费在线 | 中文字幕在线观看视频一区 | 国产一级特黄毛片在线毛片 | 久亚洲精品 | 久久这里精品视频 | 日韩美精品视频 | 91在线亚洲| 免费在线观看中文字幕 | 天天色天天射综合网 | 99精品亚洲 | 欧美综合干 | 五月花激情| 色网址99 | 免费在线一区二区三区 | 808电影免费观看三年 | 久久视频国产精品免费视频在线 | 91av原创| 精品国产一区二区三区久久久蜜臀 | 黄色小说视频网站 | 18久久久久久 | 日本久久久久久科技有限公司 | 在线导航福利 | 亚洲精品国偷自产在线91正片 | 国产亚洲精品久久久网站好莱 | 在线免费观看麻豆 | 欧美一级黄大片 | 99人久久精品视频最新地址 | 久久99久久99免费视频 | 亚洲一级电影在线观看 | 黄色福利 | 97电院网手机版 | 亚洲精品国产成人 | 婷婷在线资源 | 久久观看免费视频 | 天天撸夜夜操 | 天天操狠狠操网站 | 久久久久9999亚洲精品 | 人人爽人人爽 | 久久久久国产精品免费 | 久久久在线 | 国产在线观看不卡 | 99视频在线观看免费 | 一区二区三区免费 | 99爱视频在线观看 | 色大片免费看 | 中文字幕在线观看播放 | 久久久久亚洲国产精品 | 国产美女在线免费观看 | 国产成人精品aaa | 欧美亚洲成人xxx | 久久视频一区二区 | 在线视频日韩精品 | 亚洲成av人片在线观看www | 久久精品福利 | 亚洲一区二区三区四区在线视频 | 国产日韩欧美在线观看视频 | 日韩高清观看 | 波多野结衣在线观看一区二区三区 | 久久久激情视频 | 热久久在线视频 | 亚洲精品黄网站 | 久久国产乱 | 国产精品久久99综合免费观看尤物 | 成人av久久 | 在线激情电影 | 成人性生活大片 | 国产三级午夜理伦三级 | 韩国av一区二区三区在线观看 | 丁香一区二区 | 色婷婷丁香 | 国产婷婷色 | 久久精品视频在线播放 | 2023亚洲精品国偷拍自产在线 | 日韩一区二区三区不卡 | 视频一区亚洲 | 人人干干人人 | 97免费视频在线 | 91精品欧美一区二区三区 | 久久国产亚洲精品 | 奇米网网址 | 丁香花中文字幕 | 91成人免费看 | 日日躁夜夜躁aaaaxxxx | 五月天亚洲婷婷 | 午夜精品99久久免费 | 2021国产在线 | 成人午夜剧场在线观看 | 91精品爽啪蜜夜国产在线播放 | 国产专区视频在线观看 | 欧美一级专区免费大片 | 久色小说 | 天天爽天天碰狠狠添 | 高清av免费看 | 久久久久久久久久久免费av | 日本黄色免费观看 | 尤物九九久久国产精品的分类 | 婷婷丁香狠狠爱 | 99免费观看视频 | 日韩两性视频 | 日本中文在线观看 | 国产精品久久久久久久久久 | 就要干b | 免费av在线| 亚洲欧美乱综合图片区小说区 | 日韩在线观看第一页 | 国产精品高清免费在线观看 | av成人在线电影 | 国产午夜精品一区二区三区在线观看 | 欧美午夜精品久久久久久浪潮 | 久久久国产精品网站 | 亚洲在线免费视频 | 99婷婷狠狠成为人免费视频 | 91最新在线观看 | 中文字幕av在线不卡 | 亚洲一区日韩在线 | 91亚色视频在线观看 | 欧美久久久久久久久久久 | 久久深夜| 日韩精品一区二区三区免费视频观看 | 中文字幕久久精品 | 999视频在线播放 | 九九热在线视频免费观看 | 91av视频在线播放 | 成人毛片在线观看 | 特级a毛片 | 国产一级免费观看 | 最新午夜 | 91在线一区 | 欧美在线视频一区二区 | 最近av在线 | 国产麻豆电影在线观看 | 五月天婷婷免费视频 | 国内精品视频久久 | 久久歪歪| 1区2区3区在线观看 三级动图 | 日韩91精品 | 日韩大片在线免费观看 | 91久久国产自产拍夜夜嗨 | 欧美一二区视频 | 国产精品久久久久久久久软件 | 国产人成看黄久久久久久久久 | 国产精品美女久久久久久久久久久 | 黄色精品一区二区 | 久久综合狠狠综合久久综合88 | 久久无码av一区二区三区电影网 | 亚洲蜜桃在线 | 五月婷婷毛片 | 午夜色站| 中文字幕在线观看网址 | 亚洲一级国产 | 九九在线国产视频 | 国产精品久久久久影院 | 丁香久久久 | 国产vs久久 | 中国一级片在线播放 | 国产一区二区在线免费 | 欧美乱大交 | 97在线观| 黄色三级网站在线观看 | 顶级bbw搡bbbb搡bbbb | 成人免费视频视频在线观看 免费 | 亚洲a资源 | 久久免费高清 | 久久精品欧美一 | 亚洲精品乱码久久久久久按摩 | 中文字幕在线观看视频一区 | 欧美 日韩 视频 | 嫩草伊人久久精品少妇av | 国产在线观看99 | 日韩午夜剧场 | 国产手机在线视频 | 国产成人无码AⅤ片在线观 日韩av不卡在线 | 日韩三级视频在线观看 | 在线电影 一区 | 中文字幕中文字幕在线中文字幕三区 | 99热这里只有精品8 久久综合毛片 | 国产精品对白一区二区三区 | 色视频网址 | 精品少妇一区二区三区在线 | 91视频在线自拍 | av在线最新| 激情深爱五月 | 国产精品青草综合久久久久99 | 日韩av一区二区在线 | 国产自制av | 黄色综合| 亚洲乱码精品久久久 | 精品一二三四在线 | 精品电影一区二区 | 亚洲国产美女精品久久久久∴ | 国产生活一级片 | 91av网站在线观看 | 欧美一级淫片videoshd | 丁香婷婷深情五月亚洲 | 亚洲黄色在线 | 99精品视频在线观看 | 精品专区一区二区 | 成人国产在线 | 在线国产中文字幕 | 99视频在线精品国自产拍免费观看 | 四虎在线免费观看视频 | 日韩免费一区二区三区 | 国产成人精品日本亚洲999 | 成人久久18免费网站图片 | 男女激情麻豆 | 成人亚洲网 | 国产很黄很色的视频 | 精品美女久久久久久免费 | 久久午夜电影 | 久久久 精品| 毛片在线网| 一区二区成人国产精品 | 久久视频国产精品免费视频在线 | 黄色免费大全 | 国产一级二级在线 | 欧美少妇xxx| 日韩一区二区三区在线观看 | 99久久久国产免费 | 91视频大全 | 成人精品视频 | 黄色三级免费 | 美女视频免费一区二区 | 欧美激情va永久在线播放 | 久久在现视频 | 五月天天天操 | 97理论片| 国产精品免费一区二区三区在线观看 | 国产综合久久 | 成人三级黄色 | 亚洲电影av在线 | 99爱精品视频 | 国产一二三区在线观看 | 91免费在线播放 | 久黄色 | 久久国产二区 | 久久不卡免费视频 | 日本不卡一区二区 | 国产99免费| 欧美天堂视频在线 | 久久精品视频免费 | 国产一区精品在线观看 | 在线免费观看欧美日韩 | 久久久观看 | 亚洲 欧美 综合 在线 精品 | 黄色免费看片网站 | 青青草国产成人99久久 | 成人av网站在线播放 | 日韩久久电影 | 国产主播大尺度精品福利免费 | 久久久综合九色合综国产精品 | 欧美性生活小视频 | 91香蕉视频720p | 久久歪歪 | www.色婷婷.com | 精品国产不卡 | 91麻豆文化传媒在线观看 | 97超碰成人在线 | 中文字幕资源在线观看 | 国产亚洲精品成人av久久ww | 久草在线费播放视频 | 在线亚洲精品 | 久久久久在线 | 一级淫片a | av网在线观看 | 久久你懂的 | 黄色毛片电影 | av线上免费看 | 中文字幕国产一区二区 | 国产原厂视频在线观看 | 亚洲国产中文字幕在线 | 日韩伦理一区二区三区av在线 | 91伊人久久大香线蕉蜜芽人口 | 九九视频在线观看视频6 | 91精品资源 | 久99久在线视频 | 在线国产日韩 | 国产午夜精品免费一区二区三区视频 | 97国产电影 | 国产精品资源在线 | 国产精品麻豆99久久久久久 | 国产粉嫩在线 | 国产精品资源网 | 999电影免费在线观看2020 | 福利一区二区三区四区 | 日本久久精品 | 欧美精品第一 | 日本在线观看中文字幕无线观看 | 97爱爱爱 | 麻豆久久精品 | 久久手机免费视频 | 丁香婷婷成人 | 国产91丝袜在线播放动漫 | 色综合久久综合中文综合网 | 久久超碰免费 | 麻豆视频免费版 | 亚洲综合日韩在线 | 黄色一级动作片 | 国产中文字幕亚洲 | 久久综合中文色婷婷 | 国内精品久久久精品电影院 | 亚洲男人天堂a | 天天干天天射天天爽 | 成人av在线看 | 亚洲精品国偷自产在线99热 | 91视频91自拍 | 久草视频网 | 一级片在线| 欧美大jb| 久久激五月天综合精品 | 国产亚洲精品久久久久久 | 久久国产网 | 精品视频免费在线 | 中文字幕婷婷 | 成人精品亚洲 | 亚洲一区二区麻豆 | 欧美一区二区在线看 | 国产精品系列在线观看 | 久久亚洲综合色 | 国产成人在线看 | 91免费视频黄 | 欧美日韩中文字幕在线视频 | 欧美日韩精品在线免费观看 | 国产91学生| 国产精品一区二区久久 | 17婷婷久久www | 午夜视频在线观看一区 | 日韩中文在线电影 | 午夜av一区二区三区 | 欧美成人中文字幕 | 欧美影片| 免费一级日韩欧美性大片 | 日韩视频在线不卡 | 亚洲精品xxx | 国产精品女人久久久 | 国产精品亚州 | 欧美成a人片在线观看久 | 精品国产一二三四区 | 亚洲午夜久久久综合37日本 | 精品久久久久久久久久久久 | 欧美激情奇米色 | av三级av | 成人黄色大片网站 | 久久久麻豆视频 | 成年美女黄网站色大片免费看 | 91精品国自产在线观看 | 视频福利在线观看 | 久久久国产精品一区二区中文 | www..com毛片| 国产精品爽爽久久久久久蜜臀 | av青草 | 黄在线免费观看 | 国产精品久久久久久爽爽爽 | 日日操天天操夜夜操 | 久久九九九九 | 精品久久久久久久久久久久久久久久久久 | 久久久国产一区二区三区 | 天堂av在线网址 | 偷拍区另类综合在线 | 国产免费久久久久 | 亚洲手机天堂 | 午夜精品一区二区三区免费 | 91喷水| 综合激情网 | 四虎在线视频免费观看 | 亚洲天堂自拍视频 | 久久这里只有精品1 | 十八岁免进欧美 | 一区二区影视 | jizz18欧美18 | 成人av影院在线观看 | 久久在线免费视频 | 狠狠色丁香久久综合网 | 午夜 在线| 日韩欧美国产视频 | 97超级碰碰碰视频在线观看 | 日韩免费电影网站 | 天天草视频| 成人羞羞视频在线观看免费 | 国产一级免费播放 | 天天色图 | 午夜精品福利一区二区三区蜜桃 | 综合av在线 | 在线视频黄| 涩涩色亚洲一区 | 国产资源在线视频 | 国产麻豆成人传媒免费观看 | 91麻豆精品一区二区三区 | 在线免费色 | 日韩精品一区二区三区第95 | 激情五月五月婷婷 | 国产自制av| 日日夜夜天天操 | 国产高清亚洲 | 91亚洲国产成人久久精品网站 | 91成人区 | 日本大尺码专区mv | 久久久久久国产精品美女 | 香蕉手机在线 | 欧美一区二区免费在线观看 | 久久久久国产精品厨房 | 伊色综合久久之综合久久 | av在线com| 免费看黄20分钟 | 午夜精品99久久免费 | 国产亚洲视频系列 | 久久女同性恋中文字幕 | 久久极品| 一区视频在线 | 成人免费在线网 | 天天操夜操视频 | 在线中文字幕观看 | 在线激情电影 | 国产视频一区二区在线 | 亚洲欧美日韩一区二区三区在线观看 | 狠狠躁夜夜a产精品视频 | 国产成人中文字幕 | 337p西西人体大胆瓣开下部 | 国产美女在线观看 | 欧美视屏一区二区 | 日韩亚洲在线视频 | 国产精品久久久久久久久久了 | 日韩欧美综合视频 | 在线国产一区二区 | 天堂网一区二区 | 成人在线视 | 西西444www大胆高清视频 | 在线观看免费一级片 | 99久久久久久| 精品国产理论片 | 天天干天天天天 | 日本最新高清不卡中文字幕 | 99久久精品国产系列 | 日本精品一| 国产剧情久久 | 毛片的网址 | 国产精品精品国产婷婷这里av | 亚洲成人动漫在线观看 | 色婷婷综合成人av | 日本中文一区二区 | 高清一区二区三区av | 三级毛片视频 | www夜夜 | 欧美日韩免费在线视频 | 精品1区二区 | 日日色综合 | 国产淫a | 精品视频在线视频 | 久久久精品网 | 亚洲日本韩国一区二区 | 亚洲综合色激情五月 | 国产精品一区在线播放 | 91av电影在线 | 久久精品国产免费看久久精品 | 国产精品一区二区精品视频免费看 | 91豆麻精品91久久久久久 | 99精品福利 | 国产日韩欧美精品在线观看 | 美女在线免费观看视频 | 欧美日韩在线视频观看 | 国产资源av | 韩日电影在线免费看 | 国产专区视频在线 | 婷婷狠狠操 | 91桃色国产在线播放 | 日韩精品免费一区二区 | 91香蕉视频黄 | 91av视频在线观看免费 | 午夜在线日韩 | 天天玩天天干天天操 | 免费看片网站91 | 2019av在线视频 | 天天操天天操一操 | 亚洲精品电影在线 | 在线观看欧美成人 | www.久久免费视频 | 毛片网在线观看 | 男女男视频 | 中国一级特黄毛片大片久久 | 国产成人亚洲在线观看 | 在线观看亚洲精品视频 | 日韩精品一区二区三区高清免费 | 日本护士三级少妇三级999 | 人人操日日干 | 日韩av免费一区二区 | 天天干天天干 | 欧美精品一区在线 | 免费看一级一片 | 99热这里只有精品免费 |