基于纳芯微NSSinePad-NS800RT5039设计的多传感器舵机控制系统
该项目使用了NS800RT5039,实现了多传感器舵机控制系统的设计,它的主要功能为:采集显示温度、压力、角度等信息,可实现舵机的转动以及自动回转等功能。
标签
纳芯微
NS800RT5039
NSSinePad
Bymyself
更新2025-12-02
41
KiCad文件
全屏

一、任务介绍

本项目设计了一个基于NSSinePad-NS800RT5039评估板的多传感器舵机控制系统。通过结合多个传感器和控制模块,系统能够精确地控制舵机,执行基本动作,同时获取温度、绝压和磁场数据。该项目的目标是实现一个完整的多传感器数据采集与控制系统,展示如何通过有效的硬件选择和软件编程,使得系统能在实际环境中运行。

二、项目描述(项目的整体介绍)

该项目采用NSSinePad-NS800RT5039评估板作为主控平台,结合PWM模块、定时器模块、IIC模块、GPIO等,成功实现了一个多功能舵机控制系统。该系统通过PWM模块来控制一个360°舵机的转动,通过IIC总线读取温度传感器和绝压传感器的数值,并通过ADC模块读取磁性传感器的两路数据。TFT显示屏则用于实时显示传感器数据及舵机状态。此设计方案通过现有器件的使用巧妙的模拟了一个需要实时采集和处理多通道传感器数据的应用场景,NS800RT5039具备良好的扩展性和实时响应能力。

三、芯片选型 / 简短的硬件介绍

本项目以 NSSinePad-NS800RT5039评估板 作为核心控制单元,构建了一个集舵机控制、环境感知与显示反馈为一体的多传感器系统。

核心控制单元——NSSinePad-NS800RT5039

该评估板是基于 NS800 系列微控制器开发的高性能平台,内部集成了ARM Cortex-M内核(主频260MHz),具备丰富的外设接口与优秀的低功耗特性。我们使用以下的功能模块:

  • PWM模块:用于精确输出脉宽信号控制舵机转角或转速,频率可稳定在 50 Hz,脉宽分辨率高,可实现连续旋转舵机的闭环控制。
  • I²C模块:I²C通道接口(公用),连接温度与压力传感器,支持多从设备寻址与中断响应,通信速率选择100kHz。
  • ADC模块:12 位精度,采样速率高,负责采集磁性传感器的模拟输出,通过模拟数据进行磁场角度解析。
  • GPIO模拟SPI接口:用于驱动 TFT 显示屏,通过软件模拟 SPI 时序以节省硬件资源,灵活性高,便于调整时钟与控制信号。
  • 定时器与中断管理模块:确保各子系统同步运行,为舵机控制、数据采集与显示刷新提供精确的时间基准。

传感器与执行器模块

温度传感器 NST461-DQNR

该传感器采用 I²C 接口输出数字信号,内置温度补偿与校准电路,测量范围宽、精度高(±0.2°C)。在本系统中用于监测环境温度或设备工作状态,为显示界面与控制逻辑提供实时数据。

绝压传感器 NSPAD1N200DR04

同样通过 I²C 通信读取数据,具备宽量程与高线性度特性(典型范围 0–200 kPa)。其信号经主控解析后可实时显示或用于环境调节与保护判断。

磁性传感器MT6521

MT652x是新一代基于水平霍尔及聚磁片(IMC)技术原理的磁性角度和位置检测传感器芯片。该芯片内部包含了两对互成90°放置的水平霍尔阵列及聚磁片,能够根据不同的型号配置来实现对XY,XZ以及YZ平面的磁场变化检测,并输出正弦、余弦两路电压信号,再经后续专用电路的放大、补偿和计算后得到角度值(α) 。MT652x的OUT输出管脚提供可编程选择的模拟输出、PWM和SENT输出。本次使用的是MT6521,输出双通道模拟信号,通过 ADC 模块采样,可测量磁场方向或角度位置。该数据在舵机反馈控制与位置检测中起到关键作用。

360°舵机

接收来自 PWM 模块的控制信号(1–2 ms 脉宽),可实现全角度旋转,用于验证控制算法和系统响应性能。

TFT 显示屏

采用 SPI 时序通讯,用于显示温度、压力、舵机角度等关键数据。通过 GPIO 模拟 SPI 实现灵活通信控制,并具备复位与数据/命令分离控制引脚,显示效果清晰稳定。

四、方案框图 + 设计思路

硬件连接示意图:


0

当活动开始的时候看到这些经典的器件就让我会想起第6季的场景,有很多器件的功能都是相似的,不过这次的特色是多了一个互控,那么这些器件就非常适合我们本次项目的实现了,底层控制的开发实时性会有很大提升,这次非常遗憾没有全部都用上,不过对于我们连接这些新器件已经是足够了,环境信息的采集和显示,运动器件的反馈控制,都是非常不错的设想。

五、原理图、PCB设计

原理图:


0

如图所示,原理图包含了所有传感器关键元件和其连接方式,包括传感器连接、以及主控板的接口电路。我们选择了温度传感器、绝压传感器以及磁性传感器,它们通过IIC和ADC接口与主控平台NSSinePad-NS800RT5039进行连接。在电源方面,系统使用了3.3V的稳压模块,为所有传感器和控制电路提供稳定的电压供应。但是我们这里需要注意,实际的效果磁传感器需要5V供电才能工作,大家如果参考请注意修改,同时要注意由于磁传感器改用5V供电后其输出最高电压输出为5V,这个时候我们要将输出电压进行分压,毕竟单片机系统的供电电压是3.3V。

PCB图:


0

PCB设计图主要考虑的是合理布局和走线优化。主要是接口和传感器的位置分布。还是要注意磁传感器需要5V供电,我们合理时间限制只能通过割线飞线的方式进行,建议重新画一下。

实物图如下:


0

六、软件流程图 + 调试软件说明 + 关键代码说明

这里我们主要介绍一下实现的软件功能和基本的传感器驱动等方面。基本软件流程图如下:


0

这里涉及涉及到的传感器一共有三个,其中第一个就是温度传感器,咱们主要采集的是本地温度数据:

void NST461_Send_Data(uint8_t REG,uint8_t data)
{
i2c1_Senddate((NST461_I2C_ADDR << 1),REG,&data,1);
}

void NST461_Read_Data(uint8_t REG,uint8_t *data)
{
i2c1_Readdate((NST461_I2C_ADDR << 1),REG,data,1);
}

void NST461_Init(void)
{
NST461_Read_Data(NST461_REG_ID,&NST461.ID);
NST461_Read_Data(NST461_REG_CONVER_R,&NST461.ConRate);


}

void NST461_Read_TempData(uint8_t TempType)
{
uint8_t TempRegH = 0;
uint8_t TempRegL = 0;

uint8_t TempH = 0;
uint8_t TempL = 0;
uint16_t datat = 0;

if(TempType == NST461_TEMP_LOCAl)
{
TempRegH = NST461_REG_LOCAlTEMP_H;
TempRegL = NST461_REG_LOCAlTEMP_L;
}
else
{
TempRegH = NST461_REG_REMOTETEMP_H;
TempRegL = NST461_REG_REMOTETEMP_L;
}

NST461_Read_Data(TempRegH,&TempH);
NST461_Read_Data(TempRegL,&TempL);

datat = TempH;
datat = (datat<<4) | (TempL>>4);


datat = datat*10/16;//扩大十倍的温度(整数)

if(TempType == NST461_TEMP_LOCAl)
{
NST461.LocalTEMP = datat;
}
else
{
NST461.RemoteTEMP = datat;
}
}

压力传感器可以直接读取:

void NSPAD1N200DR04_Write_Byte(uint8_t REG,uint8_t data)
{
i2c1_Senddate((NSPAD1N_I2C_ADDR << 1),REG,&data,1);
}

void NSPAD1N200DR04_Read_Byte(uint8_t REG,uint8_t *data)
{
i2c1_Readdate((NSPAD1N_I2C_ADDR << 1),REG,data,1);
}

void NSPAD1N200DR04_Read_3Byte(uint8_t REG,uint8_t *data)
{
i2c1_Readdate((NSPAD1N_I2C_ADDR << 1),REG,data,3);
}



void NSPAD1N_Read_PData(void)
{
uint8_t number = 50;
uint8_t Reg30[3] = {0};
uint8_t Pdata[3] = {0};
uint32_t PCode = 0;
uint32_t data = 0;
NSPAD1NPada = 0;
NSPAD1N200DR04_Write_Byte(NSPAD1N_REG_CONFIG,0x0A);
for(uint8_t i = 0;i<number;i++)
{
NST_Delay_ms(1);
NSPAD1N200DR04_Read_Byte(NSPAD1N_REG_CONFIG,Reg30);
if(Reg30[0] == 0x02)
{
NSPAD1N200DR04_Read_3Byte(NSPAD1NPada_REG_PDATA,Pdata);
PCode=(Pdata[0]*65536+Pdata[1]*256+Pdata[2]); //PCode = Data0x06*2^16+ Data0x07*2^8+ Data0x08
if (PCode >8388607)
data= PCode-16777216; //Symbol processing
else
data= PCode;
NSPAD1NPada = ((float)data/8388607*231.250)+(-8.125);
break;
}
}
}

磁传感器由于使用的默认模拟输出,通过ADC进行采集,采集到的数据需要进行拟合转化才能得到角度信息:

void Get_ADC(void)
{
/* Convert, wait for completion, and store results */
ADC_forceMultipleSOC(myADC0_BASE, (ADC_FORCE_SOC0 | ADC_FORCE_SOC1));
/* Wait for ADCA to complete, then acknowledge flag */
while(ADC_getInterruptStatus(myADC0_BASE, ADC_INT_NUMBER1) == false)
{
}
ADC_clearInterruptStatus(myADC0_BASE, ADC_INT_NUMBER1);
ADC_forceMultipleSOC(myADC1_BASE, (ADC_FORCE_SOC0 | ADC_FORCE_SOC1));
/* Wait for ADCC to complete, then acknowledge flag */
while(ADC_getInterruptStatus(myADC1_BASE, ADC_INT_NUMBER1) == false)
{
}
ADC_clearInterruptStatus(myADC1_BASE, ADC_INT_NUMBER1);
/* Store results */
myADC0Result0 = ADC_readResult(ADCARESULT, ADC_SOC_NUMBER0);
myADC0Result1 = ADC_readResult(ADCARESULT, ADC_SOC_NUMBER1);
myADC1Result0 = ADC_readResult(ADCCRESULT, ADC_SOC_NUMBER0);
myADC1Result1 = ADC_readResult(ADCCRESULT, ADC_SOC_NUMBER1);
}
void Get_Age(void)
{
Get_ADC();
myAge1 = ((float)myADC0Result1)*55/40960;
myAge2 = ((float)myADC0Result0)*55/40960;

if(myAge1 >=1&&myAge1 <=5)
{
Age = (uint16_t)((5-myAge1)*45);
}
else
{
Age = (uint16_t)(180+(4.8-myAge2)*50);
}

if(Age >= 360)
{
Age = 360;
}
}

最后是按键和显示部分,我们创建了一个状态机:

void control_update_10ms(void) {
if ((g_ms - last) < CTRL_LOOP_DT_MS) return;
last = g_ms;

Get_Age();
// 处理按键边沿与保持
// 按键1:按下正转;松开停止(仅当处于手动正转)
if(key_pressed_edge(&key1)== true) {
g_state = ST_MANUAL_CW;
}
if (key_released_edge(&key1) && g_state == ST_MANUAL_CW) {
g_state = ST_IDLE;
}
// 按键2:按下反转;松开停止(仅当处于手动反转)
if (key_pressed_edge(&key2)) {
g_state = ST_MANUAL_CCW;
}
if (key_released_edge(&key2) && g_state == ST_MANUAL_CCW) {
g_state = ST_IDLE;
}
// 按键3:自动回到初始角度(触发一次,直到到位)
if (key_pressed_edge(&key3)) {
g_state = ST_AUTO_RETURN;
g_pid.first = true; // 重置PID
}
// 按键4:以当前角度重标定初始角度
if (key_pressed_edge(&key4)) {
g_init_angle_deg = Age;
}

switch (g_state) {
case ST_IDLE:
if(Motor_flag == 1)
{
HAL_Motor_Stop();
Motor_flag = 0;
}
break;

case ST_MANUAL_CW:
if(Motor_flag == 0)
{
HAL_Motor_Set(1);
Motor_flag = 1;
}
break;

case ST_MANUAL_CCW:
if(Motor_flag == 0)
{
HAL_Motor_Set(2);
Motor_flag = 1;
}
break;

case ST_AUTO_RETURN: {
if(Motor_flag == 0)
{
if(!(((g_init_angle_deg >= Age) && ((g_init_angle_deg-Age)<=5))||((Age >= g_init_angle_deg) && ((Age-g_init_angle_deg)<=5))))
{
HAL_Motor_Set(2);
Motor_flag = 1;
}
else
{
g_state = ST_IDLE;
}
}
if(Motor_flag == 1)
{
if(((g_init_angle_deg >= Age) && ((g_init_angle_deg-Age)<=5))||((Age >= g_init_angle_deg) && ((Age-g_init_angle_deg)<=5)))
{
Motor_flag = 0;
g_state = ST_IDLE;
HAL_Motor_Stop();
}
}
break;
}
default:
g_state = ST_IDLE;
HAL_Motor_Stop();
break;
}
switch (g_state) {
case ST_IDLE: state_txt = "STOP"; break;
case ST_MANUAL_CW: state_txt = "CW "; break;
case ST_MANUAL_CCW: state_txt = "CCW "; break;
case ST_AUTO_RETURN: state_txt = "AUTO"; break;
default: break;
}

}

通过上面的基本驱动来完成的本次任务的功能目标,直接使用单片机进行开发会有很多细节,我们可能注意不到导致得不到想要的结果,这个时候我们就需要进行一些调试工具的辅助,本次活动提供了十二指逻辑分析仪,可是帮了大忙,我们看一下过程调试时NST461本地温度读取波形:

采集间隔显示:


0

单次采集命令间隔:


0

单次命令波形与解析:

本地温度高位结果获取:


0

本地温度低位结果获取:


0

七、实物演示及说明

传感器是根据结构进行的设计,通过PH2.0接口进行连接,所有的传感器都在正面:

image.png

因为开发板的存在,我们基本上使用杜邦线进行连接:

image.png

可以看到页面的显示内容:
0

可以看到,整体的系统中,我们包括了主控板,传感器板,相应的测试结构,舵机和咱们的显示板,这些器件一同通过杜邦线连接在一起组成了本次项目的最终效果。咱们在页面显示中,可以看到显示了温度、压力、角度、初始角度和状态等信息,七中通过实现数据的变化进行刷新,不然咱们的界面一直在做刷新动作会影响整个系统的实时运行效果。

八、遇到的难点及解决方法

本次项目开发过程中遇到的主要难点是咱们的磁传感器输出与角度之间的一个关系。目前来看,其内部输出的电压是一个adc进行的采集后再进行dac转化的一个输出,实际上应该与内部寄存器数字读取的是一样的,所以采用某种方式读取的数据之间应该是11对应关联的,但是和咱们的角度数据之间并不是提数据手册中0-vdd对应的是0-360度的一个转化,我们需要进行一些拟合,才能得到相对应的数据关系,目前的测试结果看来应该是线性的不过会有重叠。

九、心得体会

本次可以说是进行了一下极限开发相关的数据手册,我们都进行了一定的学习了解,不过在开发的时候还是会遇到这样或那样的问题,我们通过一些辅助工具,例如逻辑分析,仪示波器等等,来帮助我们分析问题从而进行针对性的修改。从设计目标到分步实现,再到发现问题,解决问题,整个就是我们进行一些设计开发的,会遇到的流程。感谢本次活动的成功举办,也感谢纳芯微提供的优良的开发板以及传感器,我们又学习到了一种新的厂牌的芯片。

软硬件
电路图
附件下载
NS800rt5.zip
团队介绍
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号