日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于STM32F103将采集的温度-湿度值通过串口输出,用OLED屏显示自己的学号和姓名以及显示AHT20的温度和湿度,滑动显示长字符

發布時間:2023/12/16 编程问答 50 豆豆

文章目錄

  • 一、實驗內容及實驗器材
    • (一)、實驗內容
    • (二)、實驗器材
  • 二、基于STM32F103將采集的溫度-濕度值通過串口輸出
    • (一)、I2C總線通信協議
    • (二)、串口輸出采集的溫度-濕度值
  • 三、用OLED屏顯示自己的學號和姓名以及顯示AHT20的溫度和濕度,滑動顯示長字符
    • SPI協議
    • (一)、用OLED屏顯示自己的學號和姓名
    • (二)、用OLED屏顯示AHT20的溫度和濕度
    • (三)、用OLED屏滑動顯示長字符
  • 四、總結
  • 五、參考文獻

一、實驗內容及實驗器材

(一)、實驗內容

  • 學習I2C總線通信協議,使用STM32F103完成基于I2C協議的AHT20溫濕度傳感器的數據采集,并將采集的溫度-濕度值通過串口輸出。具體任務: 1)解釋什么是“軟件I2C”和“硬件I2C”? (閱讀野火配套教材的第23章“I2C–讀寫EEPROM”原理章節) 2)閱讀AHT20數據手冊,編程實現:每隔2秒鐘采集一次溫濕度數據,并通過串口發送到上位機(win10)。
  • 理解OLED屏顯和漢字點陣編碼原理,使用STM32F103的SPI或IIC接口實現以下功能: 1)顯示自己的學號和姓名; 2)顯示AHT20的溫度和濕度; 3)上下或左右的滑動顯示長字符,比如“Hello,歡迎來到重慶交通大學物聯網205實訓室!”或者一段歌詞或詩詞(最好使用硬件刷屏模式)。
  • (二)、實驗器材

  • 硬件工具:
    STM32F103 開發板
    AHT20 芯片(溫濕度數據采集)
    AHT20 芯片的具體信息及參考代碼參考官網介紹,鏈接:
  • http://www.aosong.com/class-36.html

    USB 轉 TTL 模塊
    杜邦線若干
    PC 機(Win10)
    0.96寸OLED顯示屏模塊
    2. 軟件工具:
    keil 5 MDK
    串口調試助手
    燒錄軟件 mcuisp

    二、基于STM32F103將采集的溫度-濕度值通過串口輸出

    (一)、I2C總線通信協議

    1、I2C 協議簡介
    I2C 通訊協議 (Inter - Integrated Circuit) 是由 Phiilps公司開發的,由于它引腳少,硬件實現簡單, 可擴展性強,不需要 USART、CAN 等通訊協議的外部收發設備,現在被廣泛地使用在系統內多個集成電路 (IC) 間的通訊。
    2、I2C 物理層

    (1) 它是一個支持設備的總線。“總線”指多個設備共用的信號線。在一個 I2C 通訊總線中,可 連接多個 I2C通訊設備,支持多個通訊主機及多個通訊從機。
    (2) 一個 I2C 總線只使用兩條總線線路,一條雙向串行數據線 (SDA) ,一條串行時鐘線(SCL)。 數據線即用來表示數據,時鐘線用于數據收發同步。
    (3)每個連接到總線的設備都有一個獨立的地址,主機可以利用這個地址進行不同設備之間的 訪問。
    (4) 總線通過上拉電阻接到電源。當 I2C設備空閑時,會輸出高阻態,而當所有設備都空閑,都輸出高阻態時,由上拉電阻把總線拉成高電平。
    (5)多個主機同時使用總線時,為了防止數據沖突,會利用仲裁方式決定由哪個設備占用總線。
    (6) 具有三種傳輸模式:標準模式傳輸速率為100kbit/s ,快速模式為400kbit/s ,高速模式下可達3.4Mbit/s,但目前大多 I 2C 設備尚不支持高速模式。
    (7) 連接到相同總線的 IC 數量受到總線的最大電容 400pF 限制。
    3、協議層
    I2C的協議定義了通訊的起始和停止信號、數據有效性、響應、仲裁、時鐘同步和地址廣播等環節。
    4、I2C的兩種方式——硬件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可能通信更加快,更加穩定。

    (二)、串口輸出采集的溫度-濕度值

    1 .代碼編寫
    在野火提供的示例代碼中,打開一個只包含固件庫的空項目。向工程中添加相關代碼,添加代碼的具體內容請參考下面鏈接:

    https://blog.csdn.net/hhhhhh277523/article/details/111397514

    具體的工程項目包下載 鏈接:https://pan.baidu.com/s/1-uYzWATsvkOYRmazolQAzA
    提取碼:4xva

    2 .部分代碼分析
    AHT20 芯片的初始化

    //初始化AHT20 void AHT20_Init(void) { IIC_Init();IIC_Start();IIC_Send_Byte(0x70);IIC_Wait_Ack();IIC_Send_Byte(0xa8);//0xA8進入NOR工作模式IIC_Wait_Ack();IIC_Send_Byte(0x00);IIC_Wait_Ack();IIC_Send_Byte(0x00);IIC_Wait_Ack();IIC_Stop();delay_ms(10);//延時10ms左右IIC_Start();IIC_Send_Byte(0x70);IIC_Wait_Ack();IIC_Send_Byte(0xbe);//0xBE初始化命令,AHT20的初始化命令是0xBE, AHT10的初始化命令是0xE1IIC_Wait_Ack();IIC_Send_Byte(0x08);//相關寄存器bit[3]置1,為校準輸出IIC_Wait_Ack();IIC_Send_Byte(0x00);IIC_Wait_Ack();IIC_Stop();delay_ms(10);//延時10ms左右 }

    AHT20 芯片讀取并保存數據

    //沒有CRC校驗,直接讀取AHT20的溫度和濕度數據 void AHT20_Read_CTdata(u32 *ct) {volatile u8 Byte_1th=0,Byte_2th=0,Byte_3th=0;volatile u8 Byte_4th=0,Byte_5th=0,Byte_6th=0;u32 RetuData = 0;u16 cnt = 0,flag;AHT20_SendAC();//向AHT20發送AC命令delay_ms(80); //大約延時80mswhile(((AHT20_Read_Status()&0x80)==0x80))//直到狀態bit[7]為0,表示為空閑狀態,若為1,表示忙狀態{delay_ms(1);if(cnt++>=100) break;}IIC_Start();IIC_Send_Byte(0x71);flag=IIC_Wait_Ack();Byte_1th = IIC_Read_Byte(flag);//狀態字Byte_2th = IIC_Read_Byte(flag);//濕度,發送ACK(繼續發送)Byte_3th = IIC_Read_Byte(flag);//濕度Byte_4th = IIC_Read_Byte(flag);//濕度/溫度Byte_5th = IIC_Read_Byte(flag);//溫度Byte_6th = IIC_Read_Byte(!flag);//溫度,發送NACK(停止發送) IIC_Stop();//保存得到的數據到RetuData中RetuData = (RetuData|Byte_2th)<<8; RetuData = (RetuData|Byte_3th)<<8;RetuData = (RetuData|Byte_4th);RetuData =RetuData >>4;ct[0] = RetuData;//濕度RetuData = 0;RetuData = (RetuData|Byte_4th)<<8;RetuData = (RetuData|Byte_5th)<<8;RetuData = (RetuData|Byte_6th);RetuData = RetuData&0x0fffff;ct[1] =RetuData; //溫度 }

    main.c 函數

    #include "led.h" #include "usart.h" #include "temhum.h"int main(void) { u32 CT_data[2]={0};volatile float hum=0,tem=0; delay_init(); //延時函數初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設置NVIC中斷分組2:2位搶占優先級,2位響應優先級uart_init(115200); //串口初始化為115200LED_Init(); //LED端口初始化temphum_init(); //ATH20初始化 while(1){AHT20_Read_CTdata(CT_data); //不經過CRC校驗,直接讀取AHT20的溫度和濕度數據 hum = CT_data[0]*100*10/1024/1024; //計算得到濕度值(放大了10倍)tem = CT_data[1]*200*10/1024/1024-500;//計算得到溫度值(放大了10倍)printf("濕度:%.1f%%\r\n",(hum/10));printf("溫度:%.1f度\r\n",(tem/10));printf("\r\n");//延時2s,LED閃爍提示串口發送狀態LED=0;delay_ms(1000);LED=1;delay_ms(1000);} }

    3 .編譯調試后生成hex文件,然后燒錄進STM32,具體燒錄過程請參考:

    https://blog.csdn.net/lengyuefeng212/article/details/104178386

    4 .串口結果顯示
    打開串口助手,實驗結果如下:

    如圖所示,用手握住傳感器即可看到其溫度得到了明顯升高,環境濕度改變后同樣濕度也有了變化。

    三、用OLED屏顯示自己的學號和姓名以及顯示AHT20的溫度和濕度,滑動顯示長字符

    SPI協議

    1、簡介
    SPI協議是由摩托羅拉公司提出的通訊協議(SerialPeripheralInterface),即串行外圍設備接口,是 一種高速全雙工的通信總線。它被廣泛地使用在 ADC、LCD 等設備與 MCU 間,要求通訊速率 較高的場合。

    2、SPI物理層
    SPI通訊使用3條總線及片選線,3條總線分別為SCK、MOSI、MISO,片選線為SS,它們的作 用介紹如下:
    (1) SS*(*SlaveSelect):從設備選擇信號線,常稱為片選信號線,也稱為NSS、CS,以下用NSS 表示。當有多個 SPI 從設備與 SPI 主機相連時,設備的其它信號線 SCK、MOSI 及 MISO 同時并聯到相同的SPI總線上,即無論有多少個從設備,都共同只使用這3條總線;而每 個從設備都有獨立的這一條NSS信號線,本信號線獨占主機的一個引腳,即有多少個從設 備,就有多少條片選信號線。I2C協議中通過設備地址來尋址、選中總線上的某個設備并與 其進行通訊;而SPI協議中沒有設備地址,它使用NSS信號線來尋址,當主機要選擇從設 備時,把該從設備的NSS信號線設置為低電平,該從設備即被選中,即片選有效,接著主 機開始與被選中的從設備進行SPI通訊。所以SPI通訊以NSS線置低電平為開始信號,以 NSS線被拉高作為結束信號。
    (2) SCK(SerialClock):時鐘信號線,用于通訊數據同步。它由通訊主機產生,決定了通訊的速 率,不同的設備支持的最高時鐘頻率不一樣,如STM32的SPI時鐘頻率最大為fpclk/2,兩 個設備之間通訊時,通訊速率受限于低速設備。
    (3) MOSI(MasterOutput,SlaveInput):主設備輸出/從設備輸入引腳。主機的數據從這條信號線 輸出,從機由這條信號線讀入主機發送的數據,即這條線上數據的方向為主機到從機。
    (4) MISO(MasterInput,,SlaveOutput):主設備輸入/從設備輸出引腳。主機從這條信線讀入數據, 從機的數據由這條信號線輸出到主機,即在這條線上數據的方向為從機到主機。
    3、協議層
    與I2C的類似,SPI協議定義了通訊的起始和停止信號、數據有效性、時鐘同步等環節。

    這是一個主機的通訊時序。NSS、SCK、MOSI 信號都由主機控制產生,而 MISO 的信號由從機 產生,主機通過該信號線讀取從機的數據。MOSI與MISO的信號只在NSS為低電平的時候才有 效,在SCK的每個時鐘周期MOSI和MISO傳輸一位數據。
    4、STM32的SPI特性及架構
    STM32的SPI外設可用作通訊的主機及從機,支持最高的SCK時鐘頻率為fpclk/2(STM32F103型 號的芯片默認f:sub:pclk1為72MHz,fpclk2 為36MHz),完全支持SPI協議的4種模式,數據幀長 度可設置為8位或16位,可設置數據MSB先行或LSB先行。它還支持雙線全雙工(前面小節說 明的都是這種模式)、雙線單向以及單線模式。其中雙線單向模式可以同時使用MOSI及MISO數 據線向一個方向傳輸數據,可以加快一倍的傳輸速度。而單線模式則可以減少硬件接線,當然這 樣速率會受到影響。

    (一)、用OLED屏顯示自己的學號和姓名

    1.漢字點陣字模
    利用取模軟件將需要顯示的文字用十六進制表示出來,需要用到的取模軟件:PCtoLCD2002
    打開PCtoLCD2002,軟件初始設置如下:

    在文字輸入區輸入目標文字,點擊生成字模,得到字模碼組

    注:將文字進行了“左旋90度”、“垂直翻轉”,這樣在 OLED 屏上顯示的文字才是正向的,這是因為 OLED 豎屏顯示的原因。

    2.演示程序
    需要下載 0.96 寸 OLED 顯示屏廠家給出的 Demo 程序。

    程序下載鏈接:
    http://www.lcdwiki.com/res/Program/OLED/0.96inch/SPI_SSD1306_MSP096X_V1.0/0.96inch_SPI_OLED_Module_SSD1306_MSP096X_V1.0.zip

    3.修改代碼
    下載資料包之后打開其中的“0.96inch_SPI_OLED_Module_SSD1306_MSP096X_V1.0\1-Demo\Demo_STM32\0.96inch_OLED_Demo_STM32F103RCT6_Software_4-wire_SPI”。

    注意:我用的開發板是 STM32F103C8T6 芯片,所以這里我用的是這個文件里的代碼,如果不一樣,請選擇與自己平臺相同的實例文件。

    1)添加字模
    打開上面下載的工程文件“0.96inch_OLED_Demo_STM32F103RCT6_Software_4-wire_SPI\PROJECT\OLED.uvprojx”,打開 gui.c 下的 oledfont.h 頭文件,將 cfont16[] 數組內的內容修改成自己的中文文字點陣即可。

    2)修改顯示函數
    將 test.c 里 void TEST_MainPage(void) 函數中的語句注釋掉,添加自己的執行語句。

    //主界面顯示測試 void TEST_MainPage(void) { //GUI_ShowString(28,0,"OLED TEST",16,1);//GUI_ShowString(12,16,"0.96\" SSD1306",16,1);//GUI_ShowString(40,32,"64X128",16,1);//GUI_ShowString(4,48,"www.lcdwiki.com",16,1);GUI_ShowCHinese(45,18,16,"劉慢慢",1);GUI_ShowString(18,40,"63190703xxxx",16,1);delay_ms(1500); delay_ms(1500); }

    函數說明:
    ① GUI_ShowString() 函數各參數分別對應: X 坐標、Y 坐標、字符串(ASCLL碼中的)、bit(表示字符顯示格式,這里我用的 16 ,和漢字一樣高)、顯示樣式(1:白字黑底;0:黑字白底)。
    ② GUI_ShowChinese()
    函數各參數分別對應: X 坐標、Y 坐標、漢字點陣大小(這里使用的是 16×16 的,參數應該是16)、要顯示的漢字、顯示樣式(1:白字黑底;0:黑字白底)。

    3)修改主函數
    將 main.c 代碼中的 while 函數里除 TEST_MainPage(); 語句以外的語句全注釋掉,如下:

    4 .編譯調試后生成hex文件,然后燒錄進STM32,具體燒錄過程請參考:

    https://blog.csdn.net/lengyuefeng212/article/details/104178386

    5 .STM32F103 開發板與 OLED 模塊連接

    6 .運行結果如下:

    (二)、用OLED屏顯示AHT20的溫度和濕度

    1 .添加字模
    跟上述方法一樣,獲取需要顯示的字的字模后,向 gui.c 下的 oledfont.h 頭文件里的 cfont16[] 數組內的添加中文文字點陣即可。我這里添加了“當、前、溫、濕、度”這 5 個字的點陣。
    2 .修改代碼
    1)移植 AHT20 溫濕度采集代碼
    從上文使用的工程文件里面移植下面 4 個文件:
    bsp_i2c.h、bsp_i2c.c、
    sys.h(移植后更改了名稱為 AHT20_sys.h,不然會重名)、
    sys.c(移植后更改了名稱為 AHT20_sys.c,不然會重名);
    并將bsp_i2c.c文件中的串口發送改為 OLED 顯示 void Show_OLED(void) 即可。
    具體移植過程和修改可以參考這篇博客:

    https://blog.csdn.net/ssj925319/article/details/111588662?spm=1001.2014.3001.5506

    void Show_OLED(void) {GUI_ShowCHinese(28,10,16,"當前溫濕度",1);GUI_ShowCHinese(20,32,16,"溫度:",1);GUI_ShowString(60,32,strTemp1,16,1);GUI_ShowString(68,32,strTemp2,16,1);GUI_ShowString(76,32,".",16,1);GUI_ShowString(84,32,strTemp3,16,1);GUI_ShowCHinese(92,32,16,"℃",1);GUI_ShowCHinese(20,48,16,"濕度:",1);GUI_ShowString(60,48,strHumi1,16,1);GUI_ShowString(68,48,strHumi2,16,1);GUI_ShowString(76,48,".",16,1);GUI_ShowString(84,48,strHumi3,16,1);GUI_ShowCHinese(92,48,16,"%",1); }

    2)修改主函數
    將 main.c 代碼中不用的函數注釋掉,再修改代碼,之后的結果如下:

    #include "bsp_i2c.h" //注意添加頭文件 int main(void) { delay_init(); //延時函數初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設置NVIC中斷分組2:2位搶占優先級,2位響應優先級OLED_Init(); //初始化OLEDIIC_Init(); //初始化IICOLED_Clear(0); //清屏(全黑)while(1) {read_AHT20_once(); //讀取溫度并顯示OLED_Clear(0); //清屏(全黑) delay_ms(1500);}

    要注意添加頭文件,調用溫濕度讀取并顯示函數。
    3 .編譯調試后生成hex文件,然后燒錄進STM32,具體燒錄過程請參考:

    https://blog.csdn.net/lengyuefeng212/article/details/104178386

    4 .STM32F103 開發板與 OLED 模塊連接

    5 .運行結果如下:

    用手握住傳感器即可看到其溫度得到了明顯升高,環境濕度改變后同樣濕度也有了變化。

    (三)、用OLED屏滑動顯示長字符

    1 .添加字模
    跟上述方法一樣,獲取字模后,向 gui.c 下的 oledfont.h 頭文件里的 cfont16[] 數組內的添加中文文字點陣即可。
    這里我添加的是“生活不易慢慢嘆氣”

    2 .修改代碼
    1)修改顯示函數
    同上,在 test.c 里 void TEST_MainPage(void) 函數中不用的語句注釋掉,添加自己的想要顯示的字符,如下:

    2)修改主函數
    將 main.c 代碼中的 while 函數注釋掉,再添加如下代碼:

    //從左到右滑動( OLED 屏的滾屏命令)OLED_WR_Byte(0x2E,OLED_CMD); //關閉滾動OLED_WR_Byte(0x27,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); //虛擬字節TEST_MainPage();OLED_WR_Byte(0x2F,OLED_CMD); //開啟滾動


    3 .編譯調試后生成hex文件,然后燒錄進STM32,具體燒錄過程請參考:

    https://blog.csdn.net/lengyuefeng212/article/details/104178386

    4 .STM32F103 開發板與 OLED 模塊連接

    5 .運行結果如下:

    四、總結

    在本次實驗中我學習了I2C總線通信協議和SPI 協議,使用STM32F103完成了基于I2C協議的AHT20溫濕度傳感器的數據采集,并將采集的溫度-濕度值成功通過串口輸出。同時理解了OLED屏顯和漢字點陣編碼原理,學會了如何使用STM32F103的SPI接口實現顯示學號和姓名,顯示AHT20的溫度、濕度,以及滑動顯示長字符。這些我之前未曾接觸過,本次實驗受益良多。

    五、參考文獻

    https://blog.csdn.net/qq_47538417/article/details/121547952
    https://blog.csdn.net/m0_58892312/article/details/121410862
    https://blog.csdn.net/ssj925319/article/details/111588662
    https://blog.csdn.net/qq_43279579/article/details/111678857
    《STM32 HAL庫開發實戰指南——基于野火霸天虎開發板》.pdf

    總結

    以上是生活随笔為你收集整理的基于STM32F103将采集的温度-湿度值通过串口输出,用OLED屏显示自己的学号和姓名以及显示AHT20的温度和湿度,滑动显示长字符的全部內容,希望文章能夠幫你解決所遇到的問題。

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