主頁 > 移動端開發 > 專案記錄1——基于STM32的電力表資料采集(一)串口通信采集資料

專案記錄1——基于STM32的電力表資料采集(一)串口通信采集資料

2020-11-09 11:48:08 移動端開發

讀博警告:
本人純屬小白一枚,剛開始接觸學習STM32,本篇微博只是想記錄自己在做專案中程序中遇到的問題以及最后的解決辦法,第一次更博,語言表達能力不好還很亂,望見諒,歡迎大家一起學習交流!

專案描述

要求:

1、監測設備一天的用電量,
2、統計開機、關機時間,計算使用率,
3、有可能的話實作手機端實時監控

預計方案:

STM32單片機通過RS-485串口驅動電力表模塊采集資料,然后再通過TTL串口將資料發送給ZigBee終端,ZigBee終端在接收到資料后通過無線傳輸將資料發送給協調器,ZigBee協調器通過RS232串口通訊將資料發送給上位機,上位機實時顯示資料,另外,還可以開發一款手機APP,上位機將資料保存,發送到手機端,通過手機端對資料進行實時監控,
其中,電力表模塊、STM32模塊、ZigBee終端模塊這三部分組成一個資料采集模塊,放置在機器人上,用于采集資料,ZigBee協調器模塊和上位機構成顯示模塊,用于顯示耗電量、使用效率等資料,
專案系統結構圖如下:
專案系統結構圖

專案實施計劃

通信

單片機與電力表之間通過串口1通訊,上位機與單片機之間通過串口2通訊 ,
串口1、2的初始化程式、中端配置程式如下:

//串口1初始化函式
void usart1_init(u32 bound)
{
  //GPIO埠設定
	GPIO_InitTypeDef GPIO_InitStructure;//創建GPIO的初始化結構體
	USART_InitTypeDef USART_InitStructure;//創建USART的初始化結構體
	
	 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//使能USART1,GPIOA時鐘
  
	//USART1_TX   GPIOA.9
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9 RX	
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//復用推挽輸出
    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
   
  //USART1_RX	  GPIOA.10初始化
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空輸入
    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  

  
   //USART 初始化設定

	USART_InitStructure.USART_BaudRate = bound;//串口波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長為8位資料格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一個停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//無奇偶校驗位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無硬體資料流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收發模式

    USART_Init(USART1, &USART_InitStructure); //初始化串口1
   
    USART_Cmd(USART1, ENABLE);                    //使能串口1 

}
//串口1中斷配置
void usart1_NVIC__init(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;//創建NVIC的初始化結構體
	//Usart1 NVIC 配置
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//搶占優先級3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子優先級3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根據指定的引數初始化VIC暫存器
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//開啟串口接受中斷
  

}
void usart2_init(u32 bound)
{  
	//GPIO埠設定
	GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
 	
 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能GPIOA時鐘
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);//使能USART2時鐘
	
 
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;	//PA2 tx
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//復用推挽
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
   
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA3 Rx
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空輸入
    GPIO_Init(GPIOA, &GPIO_InitStructure);  

	
 //USART2配置
	USART_InitStructure.USART_BaudRate = bound;//波特率設定
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8位資料長度
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一個停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;///奇偶校驗位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無硬體資料流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收發模式

    USART_Init(USART2, &USART_InitStructure); ; //初始化串口
  
    USART_Cmd(USART2, ENABLE);                    //使能串口 
}
//串口2中斷配置
void usart2_NVIC__init(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;
	
	NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; //使能串口2中斷
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占優先級2級
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //從優先級2級
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中斷通道
	NVIC_Init(&NVIC_InitStructure); //根據NVIC_InitStruct中指定的引數初始化外設NVIC暫存器
	
	USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//開啟中?


}

上位機與單片機之間

上位機與單片機之間通過串口2通訊 ,當上位機向單片機發送命令時,單片機接收到命令執行相應操作,比如上位機發送“ I”,單片機就會向電力表發送相應的查電流的代碼,
串口2中斷服務程式如下:
此處千萬要注意,千萬要注意中斷服務程式的名字不能寫錯,否則就不能進中斷,(當時這個Bug找了好久…想哭 悲傷 哭泣 委屈)

//串口2中斷服務函式
void USART2_IRQHandler(void)
{
	 
	if(USART_GetITStatus(USART2, USART_IT_RXNE) == SET)//檢測中斷接收標志位是否置1
		uctemp=USART_ReceiveData(USART2);
		
}

電力表與單片機之間

單片機——>電力表

MODBUS_RTU通訊協議補充

電力表提供了RS485通訊介面,采用MODBUS——RTU通訊規約,
在這里插入圖片描述
例如:主機發送資料幀:讀三相電流值

地址命令起始地址(高位在前)暫存器數(低位在前)校驗碼
01H03H00H,45H00H,06HD4H,1DH

存電流暫存器的起始地址是“00H,45H”(查說明書MODBUS——RTU地址資訊表得,即69),存放三相電流的暫存器一共有六個,所以暫存器數是“00H,06H”,
在這里插入圖片描述
校驗碼是通過專用計算器算的,
所以定義讀取電壓、電流、功率的陣列如下:

	u8 current[8]={0x01,0x03,0x00,0x45,0x00,0x06,0xD4,0x1D};
	u8 voltage[8]={0x01,0x03,0x00,0x39,0x00,0x06,0x15,0xC5};
	u8 power[8]={0x01,0x03,0x00,0x4B,0x00,0x06,0xB5,0xDE};
串口發送指令補充

//發送一個位元組
void sendByte(USART_TypeDef* USARTx,u8 date)
{
	USART_SendData(USARTx, date);
	while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE)==RESET);
}

//發送兩個位元組
void sendTwoByte(USART_TypeDef* USARTx,u16 date)
{
	u8 temp_h,temp_l;
	temp_h =(date&0xff00)>>8;
	temp_l=(date&0xff);
	sendByte(USARTx,temp_h);
	sendByte(USARTx,temp_l);
	
	
}

//發送四個位元組
void sendFourByte(USART_TypeDef* USARTx,u32 date)
{
	u8 temp1,temp2,temp3,temp4;
	temp1 =(date&0xff000000)>>24;
	temp2=(date&0xff0000)>>16;
	temp3=(date&0xff00)>>8;
	temp4=(date&0xff);
	sendByte(USARTx,temp1);
	sendByte(USARTx,temp2);
	sendByte(USARTx,temp3);
	sendByte(USARTx,temp4);
	
	
}
//發送8位陣列
void sendArry(USART_TypeDef* USARTx,u8 *arry,u8 num)
{
	u8 i;
	for(i=0;i<num;i++)
	{
		sendByte(USARTx,arry[i]);
	}
	while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET);
}
//發送字串
void Usart_Sendstr(USART_TypeDef* USARTx,char*str)
{
	u8 i=0;
	do
	{
		sendByte(USARTx,str[i]);
		i++; 
	}
	while(*(str+i)!='\n');
	while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET);
	
}

單片機接收到命令后,通過串口1向電力表發送相應指令,電力表通過串口1回傳資料,進入串口1的中斷服務子程式,把接收到的資料存在接收快取暫存器里面,具體程式如下:

//串口1中斷服務函式
//USART_RX_BUF[17];接識訓沖,最大17個位元組 , USART_RX_STA;接收狀態標記,記錄接收到第幾個位元組
void USART1_IRQHandler(void)
{
	u8 Res;
	
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中斷
		{
			
			Res =USART_ReceiveData(USART1);	//讀取接收到的資料
			USART_RX_BUF[USART_RX_STA] = Res;
			USART_RX_STA++;
			if(USART_RX_STA==17)//回傳的資料一共有17個位元組
			{
				USART_RX_STA=0;
				flag =1;//flag是接收完成標志位
			
			}
		
		}
}

單片機再把回傳的資料發送給上位機,

if(flag)//串口1接收中斷完成
		{	
			
			for(t=3;t<15;t++)//陣列里的第四個位元組開始是電流值
			{
				
				USART_SendData(USART2, USART_RX_BUF[t]);//向串口2發送資料
				while(USART_GetFlagStatus(USART2,USART_FLAG_TC)!=SET);//等待發送結束
			}
			flag=0;
		}

只接A相負載的實驗結果如圖
未完待續,,,,
可見A相的電流值為“32 30 20 C5”,這是一個4個位元組表示的浮點型資料,標準的IEEE-754標準,后續還要對資料進行處理,直接用ASCLL碼表示浮點型,
未完待續,,,,,,

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/207808.html

標籤:其他

上一篇:關于BLINKER+8266-12,EEPROM讀寫不正常

下一篇:docker 檔案存放路徑, 修改埠映射

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more