【正点原子FPGA连载】第十章PS SYSMON测量温度电压实验 摘自【正点原子】DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南
1)实验平台:正点原子MPSoC开发板
2)平台购买地址:https://detail.tmall.com/item.htm?id=692450874670
3)全套实验源码+手册+视频下载地址: http://www.openedv.com/thread-340252-1-1.html
第十章PS SYSMON测量温度电压实验
系统监视器(System Monitors)是MPSOC中用来测量电压和温度的模块,能够将电压和温度信息提供给系统的其它部分,包括平台管理单元(PMU),实时处理单元(RPU)和应用处理单元(APU)。MPSOC中有两个SYSMON模块:PL端SYSMON模块和PS端SYSMON模块。
本章我们将使用PS端SYSMON模块,读取芯片的温度电压等信息。本章包括以下几个部分:
1010.1简介
10.2实验任务
10.3硬件设计
10.4软件设计
10.5下载验证
10.1简介
PS SYSMON模块位于PS端低功耗域内,由VCC_PSAUX和VCC_PSADC供电。PS SYSMON能同时测量两个温度和几个固定的电压节点。AXI互联主机通过PS SYSMON和AMS寄存器组控制PS端SYSMON模块。
MPSOC中PS SYSMON和PL SYSMON模块都属于SYSMONE4结构,结构上存在很多相似处。也有许多不同点,例如采样率,参考电压,编程接口,电源域,温度传感器等。PS SYSMON模块框图如下图所示:

图10.1.1 PS SYSMON模块框图
PS SYSMON监测的内部电压节点位于低功耗域和全功耗域,包含内部和IO缓冲区节点。PS中所有电压测量都是单极的,内部电压节点测量范围是03V或06V。PS内部有两个温度传感器,一个物理位置在RPU附近,另外一个在APU附近。在图10.1.1中,软件通过APB SLAVE接口配置PS SYSMON的寄存器。
PS和PL的SYSMON模块各自独立运行。运行模式包括单通道读模式,默认的序列模式和自动序列器模式,SYSMON通常以默认的序列模式运行。在默认模式下,可以通过CONFIG_REG寄存器将SYSMON配置成自定义序列。
单通道读模式一次只能测量一个通道的传感器信号。在使用单通道模式时,先向CONFIG_REG0寄存器[mux_channel]比特位写入通道序号,再将CONFIG_REG1寄存器[sequence_mode]比特位设置成单通道模式,然后等待EOC(end of conversion)中断,当中断触发时,读取相关测量寄存器。
自动序列器模式下,SYSMON模块可以一次或连续的对打开的通道列表进行顺序访问。模拟输入按照固定顺序进行时间多路复用,并且每次只有一路信号送给ADC输入。读取每个通道的测量值时,最大值和最小值都会被存储。测量值也可以在连续测量结果的平均值。
10.2实验任务
本章的实验任务是通过APB Slave接口,读取PS SYSMON测量的芯片温度、供电电压等信息,并通过串口打印出来。
10.3硬件设计
根据实验任务我们可以画出本次实验的系统框图,如下图所示:

图 10.3.1 系统框图
在图 10.3.1中,CPU作为AXI主机连接到SYSMON模块APB Slave接口,读取SYSMON模块采集的温度和电压数据,然后通过串口打印出来。
本次实验在《Hello World》实验中的最小系统上就可以完成,也就是说不需要额外配置PS端或者添加PL端的外设。
打开《hello_world》工程,另存为本次实验工程《ps_sysmon》,导出硬件设计(Hardware),具体步骤可以参照前面的实验,最后打开Vitis软件。
10.4软件设计
在VITIS软件中新建一个空的应用工程,应用工程名为“ps_sysmon”。然后为应用工程新建一个源文件“main.c”,我们在新建的main.c文件中输入本次实验的代码:
1 #include "xsysmonpsu.h"
2 #include "xparameters.h"
3 #include "xstatus.h"
4 #include "stdio.h"
5 #include "sleep.h"
6
7 #define SYSMON_DEVICE_ID XPAR_XSYSMONPSU_0_DEVICE_ID
8 #define printf xil_printf
9
10 int PS_SYSMON_Test(u16 SysMonDeviceId);
11 static int SysMonPsuFractionToInt(float FloatNum);
12 static XSysMonPsu SysMonInst; //PS SYSMON实例
13
14 int main(void)
15 {
16 xil_printf("Run Sysmon Polled Test\r\n");
17
18 PS_SYSMON_Test(SYSMON_DEVICE_ID);
19
20 return XST_SUCCESS;
21 }
22
23 int PS_SYSMON_Test(u16 SysMonDeviceId)
24 {
25 XSysMonPsu_Config *ConfigPtr;
26 u32 TempRawData; //温度 原始数据
27 u32 VccAuxRawData; //PS 辅助电压 原始数据
28 u32 VccIntRawData; //PS 内核电压 原始数据
29 u32 VCCO_PSIO0RawData; //Bank500电压 原始数据
30 u32 VCCO_PSIO1RawData; //Bank501电压 原始数据
31 float TempData; //温度
32 float VccAuxData; //PS 辅助电压
33 float VccIntData; //PS 内核电压
34 float VCCO_PSIO0Data; //Bank500电压
35 float VCCO_PSIO1Data; //Bank501电压
36 u64 IntrStatus;
37 XSysMonPsu *SysMonInstPtr = &SysMonInst;
38
39 printf("\r\nEntering the SysMon Test. \r\n");
40
41 ConfigPtr = XSysMonPsu_LookupConfig(SysMonDeviceId);
42 if (ConfigPtr == NULL) {
43 return XST_FAILURE;
44 }
45 XSysMonPsu_CfgInitialize(SysMonInstPtr, ConfigPtr,
46 ConfigPtr->BaseAddress);
47
48 XSysMonPsu_SetSequencerMode(SysMonInstPtr,
49 XSM_SEQ_MODE_SAFE, XSYSMON_PS); //设置Sequence Mode为安全模式
50
51 XSysMonPsu_SetAlarmEnables(SysMonInstPtr, //关闭寄存器1中指定信号的警报
52 0x0, XSYSMON_PS);
53
54 XSysMonPsu_SetAvg(SysMonInstPtr,
55 XSM_AVG_16_SAMPLES, XSYSMON_PS); //设置采样16次后计算平均值
56
57 XSysMonPsu_SetSeqAvgEnables(SysMonInstPtr,
58 XSYSMONPSU_SEQ_CH0_TEMP_MASK | //使能Temp_LPD通道平均值测量
59 XSYSMONPSU_SEQ_CH0_SUP1_MASK | //使能VCC_PSINTLP通道平均值测量
60 XSYSMONPSU_SEQ_CH0_SUP3_MASK | //使能VCC_PSAUX通道平均值测量
61 XSYSMONPSU_SEQ_CH0_SUP6_MASK | //使能VCCO_PSIO0通道平均值测量
62 XSYSMONPSU_SEQ_CH2_SUP7_MASK , //使能VCCO_PSIO1通道平均值测量
63 XSYSMON_PS);
64
65 XSysMonPsu_SetSeqChEnables(SysMonInstPtr,
66 XSYSMONPSU_SEQ_CH0_TEMP_MASK | //打开Temp_LPD通道
67 XSYSMONPSU_SEQ_CH0_SUP1_MASK | //打开VCC_PSINTLP通道
68 XSYSMONPSU_SEQ_CH0_SUP3_MASK | //打开VCC_PSAUX通道
69 XSYSMONPSU_SEQ_CH0_SUP6_MASK | //打开VCCO_PSIO0通道
70 XSYSMONPSU_SEQ_CH2_SUP7_MASK , //打开VCCO_PSIO1通道
71 XSYSMON_PS);
72
73 IntrStatus = XSysMonPsu_IntrGetStatus(SysMonInstPtr); //读中断状态寄存器
74 XSysMonPsu_IntrClear(SysMonInstPtr, IntrStatus); //清除中断状态寄存器
75
76 XSysMonPsu_SetSequencerMode(SysMonInstPtr,
77 XSM_SEQ_MODE_CONTINPASS, XSYSMON_PS); //设定Sequence Mode为通道循环模式
78
79 while ((XSysMonPsu_IntrGetStatus(SysMonInstPtr) & ((u64)XSYSMONPSU_ISR_1_EOS_MASK<<
80 32))!= ((u64)XSYSMONPSU_ISR_1_EOS_MASK<< 32));//等待EOS(end of sequence)发生
81
82 while(1)
83 {
84 //从ADC数据寄存器读实时温度值
85 TempRawData = XSysMonPsu_GetAdcData(SysMonInstPtr,
86 XSM_CH_TEMP, XSYSMON_PS); //读Temp_LPD通道数据
87 TempData = XSysMonPsu_RawToTemperature_OnChip(TempRawData);
88 printf("The Current Temperature is %0d.%03d Centigrades.\r\n",
89 (int)(TempData), SysMonPsuFractionToInt(TempData));
90
91 //从ADC数据寄存器读VccInt电压值
92 VccIntRawData = XSysMonPsu_GetAdcData(SysMonInstPtr,
93 XSM_CH_SUPPLY1, XSYSMON_PS); //读VCC_PSINTLP通道数据
94 VccIntData = XSysMonPsu_RawToVoltage(VccIntRawData);
95 printf("The Current VCCINT is %0d.%03d Volts. \r\n",
96 (int)(VccIntData), SysMonPsuFractionToInt(VccIntData));
97
98 //从ADC数据寄存器读VccAux电压值
99 VccAuxRawData = XSysMonPsu_GetAdcData(SysMonInstPtr,
100 XSM_CH_SUPPLY3, XSYSMON_PS); //读VCC_PSAUX通道数据
101 VccAuxData = XSysMonPsu_RawToVoltage(VccAuxRawData);
102 printf("The Current VCCAUX is %0d.%03d Volts. \r\n",
103 (int)(VccAuxData), SysMonPsuFractionToInt(VccAuxData));
104
105 VCCO_PSIO0RawData = XSysMonPsu_GetAdcData(SysMonInstPtr,
106 XSM_CH_SUPPLY6, XSYSMON_PS); //读Bank500电压
107 VCCO_PSIO0Data = XSysMonPsu_VccopsioRawToVoltage(VCCO_PSIO0RawData);
108 printf("The Current VCCO_PSIO0 is %0d.%03d Volts. \r\n",
109 (int)(VCCO_PSIO0Data), SysMonPsuFractionToInt(VCCO_PSIO0Data));
110
111 VCCO_PSIO1RawData = XSysMonPsu_GetAdcData(SysMonInstPtr,
112 XSM_CH_SUPPLY7, XSYSMON_PS); //读Bank501电压
113 VCCO_PSIO1Data = XSysMonPsu_VccopsioRawToVoltage(VCCO_PSIO1RawData);
114 printf("The Current VCCO_PSIO1 is %0d.%03d Volts. \r\n\r\n\r\n",
115 (int)(VCCO_PSIO1Data), SysMonPsuFractionToInt(VCCO_PSIO1Data));
116
117 //延时5s
118 sleep(5);
119 }
120
121 return XST_SUCCESS;
122 }
123
124 //将小数转换成整数
125 int SysMonPsuFractionToInt(float FloatNum)
126 {
127 float Temp;
128
129 Temp = FloatNum;
130 if (FloatNum < 0) {
131 Temp = -(FloatNum);
132 }
133
134 return( ((int)((Temp -(float)((int)Temp)) * (1000.0f))));
135 }
代码第14行至第21行,是程序的主函数,主函数比较简单,先输出打印信息“Run Sysmon Polled Test”,然后调用PS_SYSMON_Test()函数,该函数是在官方函数基础上修改而来。
在PS_SYSMON_Test()函数中,首先对SYSMON进行初始化,如程序第41行至第46行所示。通过调用XSysMonPsu_SetSequencerMode()函数,将SYSMON操作模式设置为默认模式(安全模式)。程序第54行至第55行,设置平均值的采样次数为16次。接下来是使能通道的平均值测量,即测量结果是采样16次后计算的平均值,如第57行至第63行所示,如果不打开通道的平均值测量,则测量结果是最后一次采样值。
程序第92行至第93行中,通过调用XSysMonPsu_GetAdcData()函数,读取Vcc_Int内核电压的原始数据。该函数中,第二个参数XSM_CH_SUPPLY1代表supply1通道,通过查看ug1085手册,supply1通道实际就是VCC_PSINTLP通道,如下图所示:

图10.4.1 PS SYSMON传感器通道
通过查看ug1087手册可知,该通道物理地址为0x00FFA50804,而XSysMonPsu_GetAdcData()函数通过对第二和第三个参数计算,最终获取的就是物理地址为0x00FFA50804的VCC_PSINTLP通道的原始数据。程序第94行中,XSysMonPsu_RawToVoltage()函数对原始数据先乘以3再除以65536,公式详细讲解可参考ug580手册,如图10.4.2所示。其它通道的电压温度测量类似,这里不详细讲解。注意MIO通道电压计算公式和其它通道是不同的。

图10.4.2 电压计算公式
程序第96行调用SysMonPsuFractionToInt()函数,该函数将浮点型数据的小数部分转换成整数,函数定义如第125行至第135行所示。
10.5下载验证
首先我们将下载器与开发板上的JTAG接口连接,下载器另外一端与电脑连接。然后使用USB连接线将USB_UART(开发板PS PORT)接口与电脑连接,用于串口通信。最后连接开发板的电源,给开发板上电。
打开Vitis Terminal终端,设置并连接串口。然后下载本次实验的程序,下载完成后,在下方的VITIS Terminal中可以看到应用程序每隔5秒打印一次芯片温度和电压等信息,如下图所示:

图 10.5.1 串口终端中打印的信息
从图 10.5.1中可以看到,串口终端能够正确打印温度和电压信息,说明本次实验在MPSOC开发板上面下载验证成功。
相关文章:
【正点原子FPGA连载】第十章PS SYSMON测量温度电压实验 摘自【正点原子】DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南
1)实验平台:正点原子MPSoC开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id692450874670 3)全套实验源码手册视频下载地址: http://www.openedv.com/thread-340252-1-1.html 第十章PS SYSMON…...
AcWing《蓝桥杯集训·每日一题》—— 1460 我在哪?
AcWing《蓝桥杯集训每日一题》—— 1460. 我在哪? 文章目录AcWing《蓝桥杯集训每日一题》—— 1460. 我在哪?一、题目二、解题思路三、代码实现本次博客我是通过Notion软件写的,转md文件可能不太美观,大家可以去我的博客中查看&am…...
AcWing《蓝桥杯集训·每日一题》—— 3729 改变数组元素
AcWing《蓝桥杯集训每日一题》—— 3729. 改变数组元素 文章目录AcWing《蓝桥杯集训每日一题》—— 3729. 改变数组元素一、题目二、解题思路三、代码实现本次博客我是通过Notion软件写的,转md文件可能不太美观,大家可以去我的博客中查看:北天…...
如何熟练掌握Python在气象水文中的数据处理及绘图【免费教程】
pythonPython由荷兰数学和计算机科学研究学会的吉多范罗苏姆于1990年代初设计,作为一门叫做ABC语言的替代品。Python提供了高效的高级数据结构,还能简单有效地面向对象编程。Python语法和动态类型,以及解释型语言的本质,使它成为多…...
Leetcode详解JAVA版
目录1. 两数之和14. 最长公共前缀15. 三数之和18. 四数之和19. 删除链表的倒数第 N 个结点21. 合并两个有序链表28. 找出字符串中第一个匹配项的下标36. 有效的数独42. 接雨水43. 字符串相乘45. 跳跃游戏 II53. 最大子数组和54. 螺旋矩阵55. 跳跃游戏62. 不同路径70. 爬楼梯73.…...
LeetCode 83. 删除排序链表中的重复元素
原题链接 难度:easy\color{Green}{easy}easy 题目描述 给定一个已排序的链表的头 headheadhead , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。 示例 1: 输入:head [1,1,2] 输出:…...
RMI简易实现(基于maven)
参考其它rmi(remote method invocation)的代码后,加入了自己思考。整个工程基于maven构建,我觉得maven的模块化可比较直观地演示rmi 目录 项目结构图 模块解读 pom文件 rmi-impl rmi-common-interface rmi-server rmi-cli…...
‘excludeSwitches‘ 的 [‘enable-logging‘] 和[‘enable-automation‘]
selenium 使用 chrome 浏览器的 chromedriver 时,可以加参数, chrome_optionswebdriver.ChromeOptions() chrome_options.add_experimental_option(excludeSwitches,[enable-logging]) chrome_options.add_experimental_option(excludeSwitches,[enable…...
华为OD机试 - 最短木板长度(Python)| 真题+思路+考点+代码+岗位
最短木板长度 题目 小明有 n n n 块木板,第 i i i(1≤ i i...
第一个Python程序-HelloWorld与Python解释器
数据来源 01 第一个Python程序-HelloWorld 1)打开cmd: windows R 打开运行窗口输入cmd 2)进入Python编写页面 输入:python 3)然后输入要写的Python代码然后回车 print("Hello World!!!") print() …...
C++数据类型
目录 一、基本的内置类型 二、typedef声明 三、枚举类型 一、基本的内置类型 C 为程序员提供了种类丰富的内置数据类型和用户自定义的数据类型。下表列出了七种基本的 C 数据类型: 类型关键字布尔型bool字符型char整型int浮点型float双浮点型double无类型void宽…...
华为OD机试 - 考古学家(Python)| 真题+思路+考点+代码+岗位
考古学家 题目 有一个考古学家发现一个石碑 但是很可惜 发现时其已经断成多段 原地发现 N 个断口整齐的石碑碎片 为了破解石碑内容 考古学家希望有程序能帮忙计算复原后的石碑文字组合数 ,你能帮忙吗 备注: 如果存在石碑碎片内容完全相同,则由于碎片间的顺序不影响复原后…...
常用调试golang的bug以及性能问题的实践方法
文章目录如何分析程序运行时间和CPU利用率情况1.shell内置time指令/usr/bin/time指令如何分析golang程序的内存使用情况?1.内存占用情况查看如何分析golang程序的CPU性能情况1.性能分析注意事项2.CPU性能分析A.Web界面查看B.使用pprof工具查看如何分析程序运行时间和…...
什么是溶血症?什么是ABO溶血?溶血检查些什么?
什么是溶血症,什么是ABO溶血?女人是O型血,男人是其他血型的夫妻配对,最担心的是胎儿溶血症。从理论上讲,只要夫妻双方血型不同,母亲一定缺乏胎儿从父亲那里遗传的抗原。当任何人接触到他们缺乏的抗原时&…...
NLP实践——知识图谱问答模型FiD
NLP实践——知识图谱问答模型FiD0. 简介1. 模型结构2. 召回3. 问答4. 结合知识的问答0. 简介 好久没有更新了,今天介绍一个知识图谱问答(KBQA)模型,在此之前我一直在用huggingface的Pipeline中提供的QA模型,非常方便但…...
MyBatis 多表关联查询
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...
《NFL橄榄球》:克利夫兰布朗·橄榄1号位
克利夫兰布朗(英语:Cleveland Browns)是一支职业美式橄榄球球队,位于俄亥俄州克利夫兰。 布朗隶属于美国全国橄榄球联盟(NFL)的北区,主场位于第一能源体育场。球队在1946年与AAFC联盟一同成立,并在1946年到…...
InstructGPT笔记
一、InstructGPT是在GPT3上微调,ChatGPT是在GPT3.5上微调 二、该论文展示了怎么样对语言模型和人类意图之间进行匹配,方法是在人类的反馈上进行微调。 **三、方法简介:**收集很多问题,使用标注工具将问题的答案写出来࿰…...
【uniapp】getOpenerEventChannel().once 接收参数无效的解决方案
uniapp项目开发跨平台应用常会遇到接收参数无效的问题,无法判断是哪里出错了,这里是讲替代的方案,现有三种方案可选。 原因 一般我们是这样处理向另一个页面传参,代码是这样写的 //... let { title, type, rank } args; uni.n…...
ELK分布式日志收集快速入门-(二)kafka进阶-快速安装可视化管理界面-(单节点部署)
目录安装前准备安装中安装成功安装前准备 安装kafka-参考博客 (10条消息) ELK分布式日志收集快速入门-(一)-kafka单体篇_康世行的博客-CSDN博客 安装zk 参考博客 (10条消息) 快速搭建-分布式远程调用框架搭建-dubbozookperspringboot demo 演示_康世行的…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...
4. TypeScript 类型推断与类型组合
一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式,自动确定它们的类型。 这一特性减少了显式类型注解的需要,在保持类型安全的同时简化了代码。通过分析上下文和初始值,TypeSc…...
