当前位置: 首页 > news >正文

杰发科技AC7801——ADC软件触发的简单使用

前言

7801资料读起来不是很好理解,大概率是之前MTK的大佬写的。在此以简单的方式进行描述。我们做一个简单的规则组软件触发Demo。因为规则组通道只有一个数据寄存器,因此还需要用上DMA方式搬运数据到内存

AC7801的ADC简介

7801的ADC是一种 12 逐次逼近型 模拟数字转换器,拥有 12 路外部通道和 2 路内部通道,支持单次、连续、扫描或间断转换多种模式。模拟监控器特性允许应用程序监测输入电压是否超出设定的电压范围。

特性

12 位分辨率
通道输入电压范围: AVSS < Vin < AVDD
最大转换速率: 1Msps
14 路通道: 12 路外部通道, 1 路内部温度传感器( T-Sensor ), 1 路内部带隙基准(Bandgap ),每路通道可单独配置采样时间
转换序列分为 规则组( regular group )和注入组( injection group
        − 规则组:最多可配置 12 个通道
        − 注入组:最多可配置 4 个通道
8 种操作模式 ( 方便起见,称为 mode x x=1~8)
        − 规则组单通道单次转换 (mode1)
        − 规则组单通道连续转换 (mode2)
        − 规则组扫描 + 注入组扫描模式多通道单次转换 (mode3 注入组扫描模式 )
        − 规则组扫描 + 注入组间隔模式多通道单次转换 (mode3 注入组间隔模式 )
        − 规则组扫描 + 自动触发注入组扫描模式多通道单次转换 (mode4)
        − 规则组扫描 + 注入组扫描模式多通道连续转换 (mode5 注入组扫描模式 )
        − 规则组扫描+注入组间隔模式多通道连续转换(mode5 注入组间隔模式 )
        − 规则组扫描 + 自动触发注入组扫描模式多通道连续转换 (mode6)
        − 规则组子组扫描模式转换 (mode7)
        − 注入组子组扫描模式转换 (mode8)
通过内部软件触发或外部硬件触发启动 ADC
模拟监控器功能:
        − 配置为单个或所有通道电压检查
        − 监控通道电压是否低于低阈值或高于高阈值
中断:
        − 规则或注入组转换结束 (EOC End Of Conversion)
        − 注入组转换结束 (IEOC)
        − 模拟监控器事件 (AMO)
DMA 访问,仅用于规则组通道

典型操作流程

ADC 首先上电,然后可以通过内部 SWSTART 或外部触发源触发 ADC ,该触发来源于其它模块。触发后ADC 转换器单元开始工作,并将选择信号发送至输入通道选择器,根据规则或注入组通道序列逐个选择所需的通道。在一个通道完成转换后,转换结果将根据当前转换通道所属的组存储到 RDR 或 IDRx 中,并且产生相应的 EOC IEOC 标志置位。模拟监控器工作时,如果发生相应的事件则会出现相关的状态标志。

使用DMA

由于规则组通道只有一个数据寄存器,因此建议使用 DMA 功能 ,以避免在有多个规则组通道进行转换时,丢失转换结果。DMA 功能专用于规则组通道。只有规则组通道转换结束标志才会产生 DMA 请求。只有产生了 DMA 请求, DMA 才会将转换数据从ADC_RDR 搬运到用户指定的目标位置。

ADC流程

经典的初始化,DMA初始化。

ADC的初始化,185/186两行注释看的一脸懵逼

ADC的回调

DMA的回调

业务代码

旋转电位器查看打印值

由单个ADC改成多个ADC

AC7801的ADC写的注释相对比较完整,但是没说明软件触发从1个怎么改到多个。

使用时候需要注意下图中红框部分有些DISABLE和ABLE的参数,错了大概率就不可能正常采样。黄框部分就是从1个ADC改成3个需要修改的地方。

读取时候,只需要触发一次ADC0即可

具体代码如下:

#include "adc_sample.h"#define Delay5us                      (APB_BUS_FREQ/200000-1)
#define Delay5ms                      (APB_BUS_FREQ/200-1)
#define Delay1s                       (APB_BUS_FREQ-1)uint8_t g_dmaFinish = 0;     // DMA传输完成
uint8_t g_halfDmaFinish = 0; // DMA传输半完成
uint8_t g_dmaTransError = 0; // DMA传输错误
uint32_t g_ADCValueBuffer[DMA_TRANSFER_NUM + 1] = {0};
uint32_t g_timerCnt = 0;
uint16_t g_regularAverageSampleValue = 0; // 规则组采样平均值
uint16_t g_injectAverageSampleValue = 0;  // 注入组采样平均值
uint16_t g_adcInjectValue[4];
uint8_t g_AMOFlag = 0; // 模拟看门狗事件标志
/*
注意:EOC标志写0或读取ADC_RDR都会清除该标志位。
在进行debug时,如果有打开memory窗口或打开ADC寄存器。
该标志会被debug清除。
*/
uint8_t g_EOCFlag = 0;  // 规则组转换结束标志。
uint8_t g_IEOCFlag = 0; // 注入组转换结束标志。void ADC_Callback(void *device, uint32_t wpara, uint32_t lpara)
{if (wpara & ADC_STR_EOC_Msk) // 规则组中断标志{g_EOCFlag = 1;}if (wpara & ADC_STR_AMO_Msk) // 模拟监控中断标志{g_AMOFlag = 1;}
}void ADC_DMACallback(void *device, uint32_t wpara, uint32_t lpara)
{/*wparam为DMA通道状态,状态含义可参考CHANNELx_STATUS寄存器,CHANNELx_STATUS[2] 传输错误CHANNELx_STATUS[1] 半传输完成(相对设置的transferNum,如果半传输中断有使能,transferNum设为6,则DATA_TRANS_NUM为3时产生中断,进入回调)CHANNELx_STATUS[0] 传输完成*/if ((wpara & 0x01) == 0x1){g_dmaFinish = 1;}if ((wpara & 0x02) == 0x2){g_halfDmaFinish = 1;}if ((wpara & 0x04) == 0x4){g_dmaTransError = 1;}
}void ADC_DMAInit(void)
{uint32_t tmpMemStartAddr = (uint32_t)&g_ADCValueBuffer[0];uint32_t tmpMemEndAddr = (uint32_t)&g_ADCValueBuffer[DMA_TRANSFER_NUM + 1]; ///< Setting memory DMA addressDMA_ConfigType tmpDMAConfig;memset(&tmpDMAConfig, 0x00, sizeof(DMA_ConfigType));tmpDMAConfig.memStartAddr = tmpMemStartAddr;             // 设置DMA开始地址tmpDMAConfig.memEndAddr = tmpMemEndAddr;                 // 设置DMA结束地址tmpDMAConfig.periphStartAddr = (uint32_t)(&(ADC0->RDR)); ///< Move ADC DR to memorytmpDMAConfig.channelEn = ENABLE;                         ///< 使能DMAx通道tmpDMAConfig.finishInterruptEn = ENABLE;                 ///< 使能DMA传输完成中断tmpDMAConfig.halfFinishInterruptEn = DISABLE;            ///< 去能DMA半传输完成中断tmpDMAConfig.errorInterruptEn = ENABLE;                  ///< 使能DMA传输错误中断tmpDMAConfig.channelPriority = DMA_PRIORITY_VERY_HIGH;   ///< 设置DMA通道优先级,0~3 :优先级由低到高tmpDMAConfig.circular = ENABLE;                          ///< 使能循环模式,如果只想工作一次,设为0即可。tmpDMAConfig.direction = DMA_READ_FROM_PERIPH;           ///< 0: 从外设读取,1:从存储器读取tmpDMAConfig.MEM2MEM = DISABLE;                          ///< 0:在非存储器与存储器之间传输,1:在存储器与存储器之间传输tmpDMAConfig.memByteMode = DMA_MEM_BYTE_MODE_1TIME;      ///< MEM字分割传输数,0:32-bit,1:16-bit[15:0]; 2:16-bit[23:16][7:0];3:8-bit。详情可参考AC781X芯片手册  表20-2 可编程数据宽度&数据对齐tmpDMAConfig.memIncrement = ENABLE;                      ///< 1:MEM地址增加tmpDMAConfig.periphIncrement = DISABLE;                  ///< 0:外设地址固定tmpDMAConfig.memSize = DMA_MEM_SIZE_32BIT;               ///< 0:8-bit,1:16-bit,2:32-bittmpDMAConfig.periphSize = DMA_PERIPH_SIZE_16BIT;         ///< 0:8-bit,1:16-bit,2:32-bittmpDMAConfig.transferNum = DMA_TRANSFER_NUM;             ///< DMA通道传输长度tmpDMAConfig.periphSelect = DMA_PEPIRH_ADC0;             // 外设选择tmpDMAConfig.callBack = ADC_DMACallback;                 ///< 设置DMA中断回调DMA_Init(DMA0_CHANNEL0, &tmpDMAConfig); ///< ADC 使用DMA1通道,每个模块对应的DMA通道,可参考 AC781X芯片手册 表20-1 DMA请求列表NVIC_EnableIRQ(DMA0_CHANNEL0_IRQn);     ///< 使能DMA1中断请求
}void ADC_init()
{ADC_ConfigType tempAdcConfig;ADC_ConfigType *adcConfig;adcConfig = &tempAdcConfig;// 配置PINMUXGPIO_SetFunc(GPIOA, GPIO_PIN4, GPIO_FUN2);            ///< ADC_IN6 Analog function enableGPIO_SetFunc(GPIOA, GPIO_PIN3, GPIO_FUN2);            ///< ADC_IN7 Analog function enableGPIO_SetFunc(GPIOA, GPIO_PIN2, GPIO_FUN2);            ///< ADC_IN8 Analog function enableadcConfig->clkPsc = ADC_CLK_PRESCALER_1;              ///< Set ADC Clk = 24M/2/(0+1)adcConfig->scanModeEn = ENABLE;                       // 扫描模式adcConfig->continousModeEn = DISABLE;                 // 连续模式adcConfig->regularDiscontinousModeEn = DISABLE;       // 1:打开规则组间断转换模式adcConfig->injectDiscontinousModeEn = DISABLE;        // 1:打开注入组间断转换模式adcConfig->injectAutoModeEn = DISABLE;                // 1:自动注入模式adcConfig->intervalModeEn = DISABLE;                  // 1:注入组为间隔转换模式adcConfig->regularDiscontinousNum = 0;                //adcConfig->EOCInterruptEn = ENABLE;                   // EOC中断使能adcConfig->IEOCInterruptEn = ENABLE;                  // IEOC中断使能adcConfig->interruptEn = ENABLE;                      // 中断使能adcConfig->regularDMAEn = ENABLE;                     // 使能ADC DMAadcConfig->regularTriggerMode = ADC_TRIGGER_INTERNAL; // ADC触发源,内部触发adcConfig->regularSequenceLength = 3;                 // 规则组长度设为3adcConfig->dataAlign = ADC_DATA_ALIGN_RIGHT;          // 右对齐adcConfig->callBack = ADC_Callback;                   // 回调adcConfig->powerMode = ADC_POWER_ON;                  // 上电ADC_Init(ADC0, adcConfig);                            ///< ADC works Mode Config// ADC转换率计算公式: 转换时间= 采样时间+转换时间+同步时间  转换时间= (SPT+12)/ADC模块时钟频率+5/APB时钟频率// 备注:1.同步时间为5个APB CLK。2.ADC时钟频率 = APB时钟频率 /(分频系数+1)// 规则组通道设置ADC_SetRegularGroupChannel(ADC0, ADC_CH_7, ADC_SPT_CLK_7, 0); // 采样&转换时间= (7+12)/24000000 + 5/24000000 = 1usADC_SetRegularGroupChannel(ADC0, ADC_CH_8, ADC_SPT_CLK_7, 1); // 采样&转换时间= (7+12)/24000000 + 5/24000000 = 1usADC_SetRegularGroupChannel(ADC0, ADC_CH_6, ADC_SPT_CLK_7, 2); // 采样&转换时间= (7+12)/24000000 + 5/24000000 = 1us
}void ADC_SampleSoftwareTrigerADC(void)
{ADC_init();ADC_DMAInit(); // ADC DMA初始化while (1){// 每次转换数据清零memset(g_ADCValueBuffer, 0x00, sizeof(g_ADCValueBuffer));ADC_SoftwareStartRegularConvert(ADC0); /// 软件触发规则组采样udelay(8); // 需要采样8个通道,延时8us以保证数据采样完成printf("%d %d %d\r\n", g_ADCValueBuffer[0],g_ADCValueBuffer[1],g_ADCValueBuffer[2]);mdelay(100);}
}

转换率公式

相关文章:

杰发科技AC7801——ADC软件触发的简单使用

前言 7801资料读起来不是很好理解&#xff0c;大概率是之前MTK的大佬写的。在此以简单的方式进行描述。我们做一个简单的规则组软件触发Demo。因为规则组通道只有一个数据寄存器&#xff0c;因此还需要用上DMA方式搬运数据到内存。 AC7801的ADC简介 7801的ADC是一种 12 位 逐…...

佳易王个体诊所门诊电子处方软件试用版下载,佳易王电子处方软件的配方模板功能作用与教程

佳易王个体诊所门诊电子处方软件试用版下载&#xff0c;佳易王电子处方软件的配方模板功能作用与教程 1、软件试用版及教程可以点击下方的官网卡片 2、软件中有一个实用的功能&#xff0c;配方模板功能&#xff0c;在开处方单时候可以一键导入配方&#xff0c;节省时间。 而…...

FFmpeg零基础学习(二)——视频文件信息获取

目录 前言正文一、获取宽高信息1、核心代码2、AVFormatContext3、avformat_alloc_context4、avformat_open_input5、avformat_find_stream_info6、av_dump_format7、av_find_best_stream End、遇到的问题1、Qt Debug模式avformat_alloc_context 无法分配对象&#xff0c;而Rele…...

探索 Vue 中的 bus.$emit:实现组件通信的强大工具

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…...

2017年五一杯数学建模A题公交车排班问题解题全过程文档及程序

2017年五一杯数学建模 A题 公交车排班问题 原题再现 随着徐州市经济的快速发展&#xff0c;公交车系统对于人们的出行扮演着越来越重要的角色。在公交车资源有限的情况下&#xff0c;合理的编排公交车的行车计划成为公交公司亟待解决的问题。以下给出公交车排班问题中的部分名…...

【c++】——类和对象(下) ——内存管理

作者:chlorine 专栏:c专栏 目录 &#x1f4bb; C/C内存分布 &#x1f4bb;C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free ​编辑 &#x1f4bb;C内存管理方式 &#x1f449;new/delete操作内置类型 &#x1f449;new和delete操作自定义类型 &#x1f…...

大数据平台/大数据技术与原理-实验报告--部署全分布模式Hadoop集群

实验名称 部署全分布模式Hadoop集群 实验性质 &#xff08;必修、选修&#xff09; 必修 实验类型&#xff08;验证、设计、创新、综合&#xff09; 综合 实验课时 2 实验日期 2023.10.16-2023.10.20 实验仪器设备以及实验软硬件要求 专业实验室&#xff08;配有cen…...

Android Gradle 升级到7.x及Maven推送问题

7.0以下的Android插件工程使用Maven上传时脚本如下所示。 plugins {id com.android.libraryid kotlin-androidid maven }// 源代码一起打包 task androidSourcesJar(type: Jar) {archiveClassifier.set(sources)from android.sourceSets.main.java.sourceFiles }uploadArchive…...

【实战】K8S Helm部署Redis Cluster Redisinsight

文章目录 前言部署Redis Cluster安装Redis Insight写在最后 前言 在Web服务的开发过程中&#xff0c;Redis一直以来都有着举足轻重的作用。基本上所有的后端服务都会用这个中间件实现具体的业务场景&#xff0c;比如常作为系统缓存、分布式锁&#xff0c;也可以实现排名、定位…...

3.前端--HTML标签-文本图像链接【2023.11.25】

1.HTML常用标签(文本图像链接&#xff09; 文本标签 标题 <h1> - <h6> 段落<p> 我是一个段落标签 </p> 换行 <br /> <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta ht…...

ctfshow刷题web入门--1--ljcsd

文章目录 ctf.show。信息搜集web1web2web3web4web5web6web7web8web9web10web11web12web13web14web15web16web17web18web19web20。爆破。知识1.1 播种随机数生成器-mt_srand。参考web21--重点web22--做不出来web23web24web25web26web27web28。。。命令执行。知识1 绕过正则表达式…...

乘法原理 LeetCode 828. 统计子串中的唯一字符

我们定义了一个函数 countUniqueChars(s) 来统计字符串 s 中的唯一字符&#xff0c;并返回唯一字符的个数。 例如&#xff1a;s "LEETCODE" &#xff0c;则其中 "L", "T","C","O","D" 都是唯一字符&#xff0c;…...

python桌面开发PyQt6库和工具库QTDesigner安装和配置

一、安装PyQt6 二、安装pyqt6-tools 三、安装外部工具 四、创建QTDesigner 1.首先查找designer.exe的路径&#xff08;可以自己在窗口中选择&#xff0c;也可以使用Everything搜索&#xff09; 2.使用Everything搜索后会出现多个designer.exe,选中&#xff0c;OpenPath 3.选择…...

火柴棒等式

枚举 只要在保证等式正确的基础上判断火柴棒有没有用完就可以 因为数比较小&#xff0c;而且我不知道最大的等式中的数是多少&#xff0c;索性就设置为999了 还好对效率要求不大&#xff08;doge&#xff09; 要不然就得自己慢慢改最大数来试了 代码如下&#xff1a; #in…...

给定两个字符串 s 和 t ,找不同

题意&#xff1a; 给定两个字符串 s 和 t &#xff0c;它们只包含小写字母。 字符串 t 由字符串 s 随机重排&#xff0c;然后在随机位置添加一个字母。 请找出在 t 中被添加的字母。 示例 1&#xff1a; 输入&#xff1a;s “abcd”, t “abcde” 输出&#xff1a;“e”…...

从权限跳转看Activity的data android:scheme

在应用申请悬浮窗权限的时候&#xff0c;可以跳转到相应的设置界面&#xff0c;并且自动切换到应用的条目&#xff0c;高亮显示一下&#xff0c; android悬浮窗权限怎么申请 在Android中&#xff0c;要申请悬浮窗权限&#xff0c;需要以下步骤&#xff1a; 在 AndroidManifes…...

C++ Qt QFile用法介绍与代码演示

作者:令狐掌门 技术交流QQ群:675120140 csdn博客:https://mingshiqiang.blog.csdn.net/ 文章目录 打开和关闭文件读取文件写入文件示例代码自定义格式文件解析在Qt 中 QFile 的类用于读写本地文件系统中的文件。它继承自 QIODevice,所以它包含了许多用于数据输入和输出的功…...

Redis面试题:Redis的数据过期策略有哪些?

目录 面试官&#xff1a;Redis的数据过期策略有哪些 ? 惰性删除 定期删除 面试官&#xff1a;Redis的数据过期策略有哪些 ? 候选人&#xff1a; 嗯~&#xff0c;在redis中提供了两种数据过期删除策略 第一种是惰性删除&#xff0c;在设置该key过期时间后&#xff0c;我们…...

1.2.1 C语言结构体初始化方法总结

文章目录 结构体定义通用定义注册事项结构体初始化方法一简述示例方法二简述示例方法三简述示例方法四简述示例方法五简述示例结构体定义 通用定义 常用的结构体定义,有2种形式, 一种是关键字struct 结构体形式,如下...

CentOS 7 安装 Weblogic 14 版本

安装JDK程序 注意&#xff1a;安装weblogic前&#xff0c;先安装JDK&#xff01;&#xff08;要求jdk(1.7以上)&#xff09;&#xff1a; 一、创建用户组weblogic及用户weblogic groupadd weblogic useradd -g weblogic weblogic二、将下载好的jdk及weblogic上传至/home/webl…...

从聊天到办公全能:Kimi AI的隐藏功能大揭秘(含Prompt优化技巧)

从聊天到办公全能&#xff1a;Kimi AI的隐藏功能大揭秘&#xff08;含Prompt优化技巧&#xff09; 在AI工具井喷式发展的今天&#xff0c;Kimi AI凭借其独特的多场景适应能力&#xff0c;正在重新定义"智能助手"的边界。这款最初以聊天功能进入大众视野的工具&#x…...

如何查看对象在数据文件中的分布_DBA_EXTENTS与FILE_ID映射关系

DBA_EXTENTS的FILE_ID对应v$datafile.FILE_ID而非FILE#&#xff0c;需用FILE_ID关联&#xff1b;FILE_ID0表示临时段或undo延迟清理区&#xff0c;应查v$tempfile而非v$datafile&#xff1b;查询必须加OWNER和TABLESPACE_NAME过滤以提升性能。DBA_EXTENTS 里 FILE_ID 和实际数据…...

EcomGPT-中英文-7B电商模型Java八股文实践:面试常见AI集成场景设计与实现

EcomGPT-中英文-7B电商模型Java八股文实践&#xff1a;面试常见AI集成场景设计与实现 最近几年&#xff0c;面试里问“系统设计”的越来越多了&#xff0c;尤其是涉及到AI怎么用。很多朋友背熟了微服务、Redis、消息队列这些八股文&#xff0c;但一被问到“怎么把一个大模型塞…...

基于寒武纪MLU370-X8与LLaMA-Factory的ChatGLM3-6B高效微调实战

1. 环境准备&#xff1a;寒武纪MLU370-X8平台搭建 第一次接触寒武纪MLU加速卡时&#xff0c;我和很多开发者一样遇到了环境配置的难题。MLU370-X8作为国产AI加速卡中的旗舰产品&#xff0c;其24GB显存和8卡并行能力确实令人印象深刻&#xff0c;但配套软件生态与NVIDIA存在差异…...

AI开发-python-langchain框架(--langchain与milvus的结合 )诓

一、 什么是 AI Skills&#xff1a;从工具级到框架级的演化 AI Skills&#xff08;AI 技能&#xff09; 的概念最早在 Claude Code 等前沿 Agent 实践中被强化。最初&#xff0c;Skills 被视为“工具级”的增强&#xff0c;如简单的文件读写或终端操作&#xff0c;方便用户快速…...

hadoop+Spark+django基于大数据技术的网络小说推荐系统(源码+文档+调试+可视化大屏)

前言随着计算机技术的发展和普及&#xff0c;采用信息化管理技术取代人工管理是现在管理的主流方式。一些行业依然还是以人工记录为主&#xff0c;office软件为辅&#xff0c;来完成一些简单的数据录入和查询工作。可面对大量的数据信息就很难实现数据共享&#xff0c;数据的重…...

BlueROV2进阶:解锁Pixhawk飞控的舵机高级配置与实战调参

1. 认识BlueROV2与Pixhawk飞控的舵机控制基础 BlueROV2作为开源水下机器人的代表项目&#xff0c;其核心控制单元Pixhawk飞控的强大之处在于可编程性。很多朋友刚接触时会觉得"不就是让舵机动起来吗"&#xff0c;但真正上手才发现机械爪这类执行机构对运动精度和范围…...

Mac终端玩转OpenSSL:3分钟搞定RSA密钥对生成(附PKCS8格式转换技巧)

Mac终端玩转OpenSSL&#xff1a;3分钟搞定RSA密钥对生成&#xff08;附PKCS8格式转换技巧&#xff09; 在数字安全领域&#xff0c;RSA算法一直是加密通信的基石。对于Mac用户而言&#xff0c;系统自带的OpenSSL工具链让密钥管理变得异常简单。本文将带你用终端快速生成RSA密钥…...

HY-Motion 1.0一键部署:云服务器(阿里云/AWS)3分钟上线Web服务

HY-Motion 1.0一键部署&#xff1a;云服务器&#xff08;阿里云/AWS&#xff09;3分钟上线Web服务 1. 概述&#xff1a;从文字到动画的魔法转换 想象一下&#xff0c;你只需要输入"一个人在跳舞"&#xff0c;电脑就能自动生成一个逼真的3D舞蹈动画。这不是科幻电影…...

Pharma NLP:药品命名实体识别的代码工程实践

“把这几十万份 ADR(不良反应)报告里的药品名、不良事件、剂量信息都提取出来?现在全靠人工,一个人一天顶多 80 份,三年的报告积压在那儿了。” 药品 NER 跟你在 CoNLL-2003 上跑的那个 NER,不是一个物种。 通用 NER 里,"苹果"要么是水果要么是公司,上下文清…...