IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> HAL库实现基于STM32+RN8302B的电压采集 -> 正文阅读

[嵌入式]HAL库实现基于STM32+RN8302B的电压采集

一、硬件电路

这里以C相电压采集为例,来快速了解RN8302B的使用

\\I_{R40}=220V/220k=1mA \\U_{R43}=1mA*250\Omega =250mV \\U_{R46}=U_{R43}=250mV \\(U_{R46}-U_{R52})/20k=(U_{R52}-U_{R57})/10k \\ \because U_{R52}=0 \\ \therefore V_{CP}=U_{R57}=-U_{R46}/2=-125mV

?

?二、 配置工作

1、准备好printf工程,参考之前的教程

STM32CubeIDE实现printf重定向输出到串口_飞由于度的博客-CSDN博客STM32CubeIDE之printf重定向及串口https://blog.csdn.net/qq_35629563/article/details/126665838

2、配置RN8302B通信引脚

①SPI引脚

?

具体原因:

1)

2)?

?CPOL表示SCK空闲时间的状态,从时序图里可以看出CPOL=LOW

CPHA表示在第一边沿还是第二边沿进行数据交换,从时序图里可以看出CPOL=2 Edge

?②控制引脚

将PB12配置为GPIO_Output模式,PC6配置为GPIO_Input模式

?③呼吸灯

这里我是用的是PC1作为呼吸灯,其实不论使用哪个引脚控制的呼吸灯,只需将其重命名为LED1即可

3、引脚重命名

然后右击引脚分别重命名(注意顺序:先左击配置模式,再右击重命名)

?

最终结果

?

生成代码

?

三、代码编写

1、rn8302b.h

#ifndef _SPI_H_
#define _SPI_H_

#include "main.h"
#include "stdio.h"

//---------------------- RN8302计量寄存器地址定义---------------------------------------------------//
#define UC_CMD      0x0009//4//C相电压有效值
#define UC_BYTE     4

#define SYSSR_CMD   0x018A//系统状态寄存器
#define SYSSR_BYTE  2

#define DeviceID_CMD   0x018f//RN8302B Device ID
#define DeviceID_BYTE  3

#define SPI_CS_HIGH() 	HAL_GPIO_WritePin( RN_NSS_GPIO_Port , RN_NSS_Pin, GPIO_PIN_SET )
#define SPI_CS_LOW() 	HAL_GPIO_WritePin( RN_NSS_GPIO_Port , RN_NSS_Pin, GPIO_PIN_RESET )


void ReadAmmeterData(void);

#endif

2、rn8302b.c

/****************SPI 采用端口模拟**********************************/
#include "rn8302b.h"
#include "spi.h"


/*****************SPI 写单字节**************************/
void Write_SPI_OneByte(uint8_t TxData)
{
	uint8_t Rxdata;
	HAL_SPI_TransmitReceive(&hspi2,&TxData,&Rxdata,1, 1000);
	return ;
}
/*****************SPI 读单字节**************************/
uint8_t Read_SPI_OneByte(void)
{
	uint8_t Rxdata;
	uint8_t TxData=0;
	HAL_SPI_TransmitReceive(&hspi2,&TxData,&Rxdata,1, 1000);
	return Rxdata;
}
/************************* READ_RN8302*************************************************/
uint32_t READ_SPI(uint16_t Address,uint8_t Data_len)
{
	uint8_t i, DTemp,CheckSumR;
	uint32_t drData;

	SPI_CS_LOW();    // 开启SPI传输

	DTemp = (uint8_t)(Address&0x00FF);//ADDR[7:0]
	CheckSumR = DTemp;
	Write_SPI_OneByte(DTemp);
	DTemp = (((uint8_t)(Address >> 4)) & 0xf0) ;//CMD=R/W+AD[10:8]+BL[1:0]+2’h0(MSB+LSB)
	CheckSumR += DTemp;
	Write_SPI_OneByte(DTemp);

	HAL_Delay(5);
	drData = 0x00000000;//Read 24bit

	for(i=0;i<Data_len;i++)//先发高字节,后发低字节
	{
		DTemp = Read_SPI_OneByte();
		drData = drData<<8;
		drData += DTemp;
		CheckSumR += DTemp;
	}

	CheckSumR = ~CheckSumR;//校验和算法: ADDR+CMD+DATA 单字节求和取反。

	if (CheckSumR != Read_SPI_OneByte())//比较校验和
	{
		drData = 0xFFFFFFFF;
	}

	SPI_CS_HIGH();	  //关闭SPI传输
	HAL_Delay(2);
	return drData;
}
/**************************Write RN8302******************************/
void Write_SPI(uint16_t Address, uint32_t dwData,uint8_t Date_len)
{
	uint8_t i,CheckSumR, DTemp;

	SPI_CS_LOW();	 //开启SPI传输

	DTemp = (uint8_t)(Address&0x00FF);//
	CheckSumR = DTemp;
	Write_SPI_OneByte(DTemp);//写地址
	DTemp = (((uint8_t)(Address >> 4)) & 0xf0)+0x80 ;
	CheckSumR += DTemp;
	Write_SPI_OneByte(DTemp);//写命令


	for (i =0 ;i < Date_len;i++)//先发高字节,后发低字节
	{
		DTemp = (uint8_t)(dwData>>(Date_len-1-i)*8);
		Write_SPI_OneByte(DTemp);//写命令
		CheckSumR += DTemp;
	}

	CheckSumR = ~CheckSumR;//校验和算法: ADDR+CMD+DATA 单字节求和取反。

	Write_SPI_OneByte(CheckSumR);//写命令

	SPI_CS_HIGH();	    //结束传输
	HAL_Delay(2);
}

void ReadAmmeterData(void)
{
	uint32_t temp = 0;

	temp = READ_SPI(DeviceID_CMD,DeviceID_BYTE);//芯片ID//supposed to be 0x00830200(hex)
	printf("Device_ID=%x(hex)\r\n",(int)temp);
	if(temp != 0x00830200) //读ID
	{
		printf("===================== \r\n");
		printf("Device_ID!=0x00830200 \r\n");
		printf("===================== \r\n");
		return;
	}

	temp = READ_SPI(SYSSR_CMD,SYSSR_BYTE);//系统状态
	printf("SYSSR=%x(hex)\r\n",(int)temp);
	HAL_Delay(1000);
	
	temp = READ_SPI(UC_CMD,UC_BYTE);//读取电压有效值
	printf(" UC 寄存器有效值=%8X\r\n",(int)temp);
	printf(" UC 引脚处有效值=%8.2f\r\n",(float)(temp/167772));
	printf(" UC 端口处有效值=%8.2f\r\n",(float)(temp/167772*1.76));
}

3、main.c

USER CODE BEGIN Includes下添加以下代码

#include <stdio.h>
#include <string.h>

#include "rn8302b.h"

uint8_t t=0;

USER CODE BEGIN 3下添加以下代码

	  ReadAmmeterData();
	  HAL_Delay(3000);
	  HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
	  printf("%d\r\n",++t);

四、实验结果

全部代码与RN8302B的手册

https://download.csdn.net/download/qq_35629563/86512618icon-default.png?t=M85Bhttps://download.csdn.net/download/qq_35629563/86512618?

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-09-13 11:33:13  更:2022-09-13 11:34:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 17:29:16-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计