一、STM32的0.96寸OLED顯示屏顯示數據
1.了解SPI(串行外設接口)
定義:
SPI(Serial Peripheral Interface)就是串行外圍設備接口。
SPI,是一種高速的,全雙工,同步的通信總線,並且在芯片的管腳上只占用四根線,節約了芯片的管腳。SPI 是一個環形總線結構,由 ss(cs)、sck、sdi、sdo 構成,時序主要是在 sck 的控制下,兩個雙向移位寄存器進行數據交換。
上升沿發送、下降沿接收、高位先發送。
上升沿到來的時候,sdo 上的電平將被發送到從設備的寄存器中。
下降沿到來的時候,sdi 上的電平將被接收到主設備的寄存器中。
連接方式:

SS( Slave Select):從設備選擇信號線,常稱為片選信號線。
SCK (Serial Clock):時鍾信號線,用於通訊數據同步。
MOSI (Master Output, Slave Input):主設備輸出/從設備輸入引腳。
MISO(Master Input,,Slave Output):主設備輸入/從設備輸出引腳。
通訊過程:

2.使用0.96寸OLED顯示數據
2.1工具
軟件:keil
硬件:stm32
2.2下載廠家程序並燒錄到開發板里面運行結果

二、STM32通過IIC接口實現溫濕度(AHT20)的采集
1.IIC總線協議
1.1什么是I2C協議
I2C 通訊協議(Inter-Integrated Circuit)是由 Phiilps 公司開發的,由於它引腳少,硬件實現簡單,可擴展性強,不需要 USART、CAN 等通訊協議的外部收發設備,現在被廣泛地使用在系統內多個集成電路(IC)間的通訊。
1.2I2C 協議的物理層和協議層
①物理層
I2C是一個支持設備的總線。可連接多個 I2C 通訊設備,支持多個通訊主機及多個通訊從機。對於I2C 總線,只使用兩條總線線路,一條雙向串行數據線(SDA) ,一條串行時鍾線(SCL)。
I2C 通訊設備常用連接方式(引用野火資料中的圖)
②協議層
主要是定義了通訊的起始和停止信號、數據有效性、響應、仲裁、時鍾同步和地址廣播等。

1.3I2C的兩種方式——硬件I2C和軟件I2C
①硬件I2C
直接利用 STM32 芯片中的硬件 I2C 外設。
硬件I2C的使用
只要配置好對應的寄存器,外設就會產生標准串口協議的時序。在初始化好 I2C 外設后,只需要把某寄存器位置 1,此時外設就會控制對應的 SCL 及 SDA 線自動產生 I2C 起始信號,不需要內核直接控制引腳的電平。
②軟件I2C
直接使用 CPU 內核按照 I2C 協議的要求控制 GPIO 輸出高低電平,從而模擬I2C。
軟件I2C的使用
需要在控制產生 I2C 的起始信號時,控制作為 SCL 線的 GPIO 引腳輸出高電平,然后控制作為 SDA 線的 GPIO 引腳在此期間完成由高電平至低電平的切換,最后再控制SCL 線切換為低電平,這樣就輸出了一個標准的 I2C 起始信號。
③兩者的差別
硬件 I2C 直接使用外設來控制引腳,可以減輕 CPU 的負擔。不過使用硬件I2C 時必須使用某些固定的引腳作為 SCL 和 SDA,軟件模擬 I2C 則可以使用任意 GPIO 引腳,相對比較靈活。對於硬件I2C用法比較復雜,軟件I2C的流程更清楚一些。如果要詳細了解I2C的協議,使用軟件I2C可能更好的理解這個過程。在使用I2C過程,硬件I2C可能通信更加快,更加穩定。
2.實現AHT20采集程序
從野火給的代碼源文件中找到自己的需要的

代碼:
void read_AHT20_once(void)
{
delay_ms(10);
reset_AHT20();//重置AHT20芯片
delay_ms(10);
init_AHT20();//初始化AHT20芯片
delay_ms(10);
startMeasure_AHT20();//開始測試AHT20芯片
delay_ms(80);
read_AHT20();//讀取AHT20采集的到的數據
delay_ms(5);
}
void read_AHT20(void)
{
uint8_t i;
for(i=0; i<6; i++)
{
readByte[i]=0;
}
I2C_Start();//I2C啟動
I2C_WriteByte(0x71);//I2C寫數據
ack_status = Receive_ACK();//收到的應答信息
readByte[0]= I2C_ReadByte();//I2C讀取數據
Send_ACK();//發送應答信息
readByte[1]= I2C_ReadByte();
Send_ACK();
readByte[2]= I2C_ReadByte();
Send_ACK();
readByte[3]= I2C_ReadByte();
Send_ACK();
readByte[4]= I2C_ReadByte();
Send_ACK();
readByte[5]= I2C_ReadByte();
SendNot_Ack();
//Send_ACK();
I2C_Stop();//I2C停止函數
//判斷讀取到的第一個字節是不是0x08,0x08是該芯片讀取流程中規定的,如果讀取過程沒有問題,就對讀到的數據進行相應的處理
if( (readByte[0] & 0x68) == 0x08 )
{
H1 = readByte[1];
H1 = (H1<<8) | readByte[2];
H1 = (H1<<8) | readByte[3];
H1 = H1>>4;
H1 = (H1*1000)/1024/1024;
T1 = readByte[3];
T1 = T1 & 0x0000000F;
T1 = (T1<<8) | readByte[4];
T1 = (T1<<8) | readByte[5];
T1 = (T1*2000)/1024/1024 - 500;
AHT20_OutData[0] = (H1>>8) & 0x000000FF;
AHT20_OutData[1] = H1 & 0x000000FF;
AHT20_OutData[2] = (T1>>8) & 0x000000FF;
AHT20_OutData[3] = T1 & 0x000000FF;
}
else
{
AHT20_OutData[0] = 0xFF;
AHT20_OutData[1] = 0xFF;
AHT20_OutData[2] = 0xFF;
AHT20_OutData[3] = 0xFF;
printf("讀取失敗!!!");
}
printf("\r\n");
//根據AHT20芯片中,溫度和濕度的計算公式,得到最終的結果,通過串口顯示
printf("溫度:%d%d.%d",T1/100,(T1/10)%10,T1%10);
printf("濕度:%d%d.%d",H1/100,(H1/10)%10,H1%10);
printf("\r\n");
}
結果顯示:

