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

STM32F103ZET6_HAL_CAN

1定义时钟

2定义按键

按键上拉电阻

3开启串口

4打开CAN(具体什么意思上一篇讲了)

5生成代码

/* USER CODE BEGIN Header */
/********************************************************************************* @file           : main.c* @brief          : Main program body******************************************************************************* @attention** Copyright (c) 2024 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "can.h"
#include "usart.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/***       CAN 发送一组数据*  	数据  长度*/
uint8_t can_send_msg(  uint8_t *data, uint8_t len )
{//发的结构体CAN_TxHeaderTypeDef can_tx;can_tx.DLC=len;         // 数据长度代码can_tx.ExtId=0x00;// 扩展标识符can_tx.IDE=CAN_ID_EXT;// 标识符类型为扩展帧                            //标识符的长度can_tx.RTR=CAN_RTR_DATA;// 远程传输请求为数据帧can_tx.StdId=0x12;// 标准标识符                                           //can的ID//can_tx.TransmitGlobalTime=ENABLE;// 使用全局时间    ENABLE开启   DISABLE关闭   时间戳uint32_t as=CAN_TX_MAILBOX0;if(HAL_CAN_AddTxMessage(&hcan,&can_tx,data,&as)==HAL_OK){int as1=HAL_CAN_GetTxMailboxesFreeLevel(&hcan);char aa[28];sprintf(aa,"数据发送成功,邮箱个数为:%d\n",as1);HAL_UART_Transmit(&huart1,(uint8_t*)aa,27,50);}while (HAL_CAN_GetTxMailboxesFreeLevel(&hcan) != 3); /* 等待发送完成,所有邮箱为空 */return 0;
}/***        CAN 接收数据查询//    数据*/
void can_receive_msg(  uint8_t *data )
{//接收的结构体// 声明一个变量来存储接收到的消息的头部信息CAN_RxHeaderTypeDef can_rx;//can_rx.DLC			// 数据长度//can_rx.ExtId				//扩展标识符//can_rx.FilterMatchIndex// 过滤器匹配索引//can_rx.IDE			// 标识符类型为扩展帧//can_rx.RTR			// 远程传输请求为数据帧//can_rx.StdId;			// 标准标识符//can_rx.Timestamp	;	// 时间戳if(HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &can_rx, data)== HAL_OK){char aa[28]={"接收成功\n"};HAL_UART_Transmit(&huart1,(uint8_t*)aa,9,50);}else{char aa[28]={"接收失败\n"};HAL_UART_Transmit(&huart1,(uint8_t*)aa,9,50);}
}
/* USER CODE END 0 *//*** @brief  The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_CAN_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */CAN_FilterTypeDef sFilterConfig;//配置CAN过滤器sFilterConfig.FilterBank = 0;                             /* 过滤器0 */sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;sFilterConfig.FilterIdHigh = 0x0000;                      /* 32位ID */sFilterConfig.FilterIdLow = 0x0000;sFilterConfig.FilterMaskIdHigh = 0x0000;                  /* 32位MASK */sFilterConfig.FilterMaskIdLow = 0x0000;sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;    /* 过滤器0关联到FIFO0 */sFilterConfig.FilterActivation = CAN_FILTER_ENABLE;       /* 激活滤波器0 */sFilterConfig.SlaveStartFilterBank = 14;// 过滤器配置 if ( HAL_CAN_ConfigFilter( &hcan, &sFilterConfig ) != HAL_OK ){return 2;}// 启动CAN外围设备 if ( HAL_CAN_Start( &hcan ) != HAL_OK ){return 3;}/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)== GPIO_PIN_SET){HAL_Delay(20);if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)==HAL_OK){char a[]={"按键按下了\n"};HAL_UART_Transmit(&huart1,(uint8_t*)a,11,50);uint8_t tx_data[8] = {"ABCDEFGH"}; // 消息数据uint8_t rx_data[8]; // 接收数据缓冲区can_send_msg(  tx_data, 8 );if(HAL_CAN_GetRxFifoFillLevel(&hcan ,CAN_RX_FIFO0)){can_receive_msg(  rx_data );}else{char aa[28]={"无数据\n"};HAL_UART_Transmit(&huart1,(uint8_t*)aa,9,50);}HAL_Delay(500);HAL_UART_Transmit(&huart1,rx_data,8,500);}}/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){Error_Handler();}
}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//*** @brief  This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef  USE_FULL_ASSERT
/*** @brief  Reports the name of the source file and the source line number*         where the assert_param error has occurred.* @param  file: pointer to the source file name* @param  line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

6编写过程

1编写接收函数

***        CAN 接收数据查询//    数据*/
void can_receive_msg(  uint8_t *data )
{//接收的结构体// 声明一个变量来存储接收到的消息的头部信息CAN_RxHeaderTypeDef can_rx;//can_rx.DLC			// 数据长度//can_rx.ExtId				//扩展标识符//can_rx.FilterMatchIndex// 过滤器匹配索引//can_rx.IDE			// 标识符类型为扩展帧//can_rx.RTR			// 远程传输请求为数据帧//can_rx.StdId;			// 标准标识符//can_rx.Timestamp	;	// 时间戳if(HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &can_rx, data)== HAL_OK){char aa[28]={"接收成功\n"};HAL_UART_Transmit(&huart1,(uint8_t*)aa,9,50);}else{char aa[28]={"接收失败\n"};HAL_UART_Transmit(&huart1,(uint8_t*)aa,9,50);}
}

2编写发送函数

/***       CAN 发送一组数据*  	数据  长度*/
uint8_t can_send_msg(  uint8_t *data, uint8_t len )
{//发的结构体CAN_TxHeaderTypeDef can_tx;can_tx.DLC=len;         // 数据长度代码can_tx.ExtId=0x00;// 扩展标识符can_tx.IDE=CAN_ID_EXT;// 标识符类型为扩展帧                            //标识符的长度can_tx.RTR=CAN_RTR_DATA;// 远程传输请求为数据帧can_tx.StdId=0x12;// 标准标识符                                           //can的ID//can_tx.TransmitGlobalTime=ENABLE;// 使用全局时间    ENABLE开启   DISABLE关闭   时间戳uint32_t as=CAN_TX_MAILBOX0;if(HAL_CAN_AddTxMessage(&hcan,&can_tx,data,&as)==HAL_OK){int as1=HAL_CAN_GetTxMailboxesFreeLevel(&hcan);char aa[28];sprintf(aa,"数据发送成功,邮箱个数为:%d\n",as1);HAL_UART_Transmit(&huart1,(uint8_t*)aa,27,50);}while (HAL_CAN_GetTxMailboxesFreeLevel(&hcan) != 3); /* 等待发送完成,所有邮箱为空 */return 0;
}

3配置过滤器(不配置不可接收数据

  CAN_FilterTypeDef sFilterConfig;//配置CAN过滤器sFilterConfig.FilterBank = 0;                             /* 过滤器0 */sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;sFilterConfig.FilterIdHigh = 0x0000;                      /* 32位ID */sFilterConfig.FilterIdLow = 0x0000;sFilterConfig.FilterMaskIdHigh = 0x0000;                  /* 32位MASK */sFilterConfig.FilterMaskIdLow = 0x0000;sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;    /* 过滤器0关联到FIFO0 */sFilterConfig.FilterActivation = CAN_FILTER_ENABLE;       /* 激活滤波器0 */sFilterConfig.SlaveStartFilterBank = 14;// 过滤器配置 if ( HAL_CAN_ConfigFilter( &hcan, &sFilterConfig ) != HAL_OK ){return 2;}// 启动CAN外围设备 if ( HAL_CAN_Start( &hcan ) != HAL_OK ){return 3;}

4编写按键实现收发数据

while (1){if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)== GPIO_PIN_SET){HAL_Delay(20);if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)==HAL_OK){char a[]={"按键按下了\n"};HAL_UART_Transmit(&huart1,(uint8_t*)a,11,50);uint8_t tx_data[8] = {"ABCDEFGH"}; // 消息数据uint8_t rx_data[8]; // 接收数据缓冲区can_send_msg(  tx_data, 8 );if(HAL_CAN_GetRxFifoFillLevel(&hcan ,CAN_RX_FIFO0)){can_receive_msg(  rx_data );}else{char aa[28]={"无数据\n"};HAL_UART_Transmit(&huart1,(uint8_t*)aa,9,50);}HAL_Delay(500);HAL_UART_Transmit(&huart1,rx_data,8,500);}}/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}

效果

注意

1过滤器

主页中有免费的CAN资料和项目文件

相关文章:

STM32F103ZET6_HAL_CAN

1定义时钟 2定义按键 按键上拉电阻 3开启串口 4打开CAN(具体什么意思上一篇讲了) 5生成代码 /* USER CODE BEGIN Header */ /********************************************************************************* file : main.c* brief …...

javaWeb项目-ssm+vue网上租车系统功能介绍

本项目源码:java-基于ssmvue的网上租车系统源码说明文档资料资源-CSDN文库 项目关键技术 开发工具:IDEA 、Eclipse 编程语言: Java 数据库: MySQL5.7 框架:ssm、Springboot 前端:Vue、ElementUI 关键技术:springboot、…...

Go模板页面浏览器显示HTML源码问题

<!--* Title: This is a file for ……* Author: JackieZheng* Date: 2024-06-09 17:00:01* LastEditTime: 2024-06-09 17:01:12* LastEditors: Please set LastEditors* Description:* FilePath: \\GoCode\\templates\\index.html --> <!DOCTYPE html> <html …...

弃用Docker Desktop:在WSL2中玩转Docker之Docker Engine 部署与WSL入门

Docker技术概论 在WSL2中玩转Docker之Docker Engine部署 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://bl…...

Mac下载了docker,在终端使用docker命令时用不了

问题&#xff1a;在mac使用docker的时候&#xff0c;拉取docker镜像失败 原因&#xff1a;docker是需要用app使用的 &#xff0c;所以在使用的时候必须打开这个桌面端软件才可以在终端上使用docker命令&#xff01;&#xff01;&#xff01;...

Spring Security——基于MyBatis

目录 项目总结 新建一个项目 pom.xml application.properties配置文件 User实体类 UserMapper映射接口 UserService访问数据库中的用户信息 WebSecurityConfig配置类 MyAuthenticationFailureHandler登录失败后 MyAuthenticationSuccessHandlerw登录成功后 WebSecur…...

Qt——升级系列(Level Four):控件概述、QWidget 核心属性、按钮类控件

目录 控件概述 QWidget 核心属性 核心属性概览 enabled geometry windowTitle windowIcon windowOpacity cursor font toolTip focusPolicy styleSheet 按钮类控件 Push Button Radio Buttion Check Box Tool Button 控件概述 Widget 是 Qt 中的核⼼概念. 英⽂原义是 "…...

品质卓越为你打造App UI 风格

品质卓越为你打造App UI 风格...

ei期刊和sci期刊的区别

ei期刊和sci期刊的区别 ei期刊和sci期刊的区别是什么?Sci和ei都属于国际期刊的一种&#xff0c;但是二者之间存在一些区别&#xff0c;选择期刊投稿时需要注意这些区别。EI期刊刊物的审查周期短&#xff0c;SCI学术期刊的审查期长。难度要求不同&#xff0c;SCI期刊比EI期刊对…...

从零手写实现 nginx-20-placeholder 占位符 $

前言 大家好&#xff0c;我是老马。很高兴遇到你。 我们为 java 开发者实现了 java 版本的 nginx https://github.com/houbb/nginx4j 如果你想知道 servlet 如何处理的&#xff0c;可以参考我的另一个项目&#xff1a; 手写从零实现简易版 tomcat minicat 手写 nginx 系列 …...

leetcode290:单词规律

题目链接&#xff1a;290. 单词规律 - 力扣&#xff08;LeetCode&#xff09; class Solution { public:bool wordPattern(string pattern, string s) {unordered_map<char, string> s2t;unordered_map<string, char> t2s;int len pattern.size();int CountSpace…...

IDEA 2022

介绍 【尚硅谷IDEA安装idea实战教程&#xff08;百万播放&#xff0c;新版来袭&#xff09;】 jetbrains 中文官网 IDEA 官网 IDEA 从 IDEA 2022.1 版本开始支持 JDK 17&#xff0c;也就是说如果想要使用 JDK 17&#xff0c;那么就要下载 IDEA 2022.1 或之后的版本。 公司…...

Vue TypeScript 实战:掌握静态类型编程

title: Vue TypeScript 实战&#xff1a;掌握静态类型编程 date: 2024/6/10 updated: 2024/6/10 excerpt: 这篇文章介绍了如何在TypeScript环境下为Vue.js应用搭建项目结构&#xff0c;包括初始化配置、创建Vue组件、实现状态管理利用Vuex、配置路由以及性能优化的方法&#x…...

Hudi extraMetadata 研究总结

前言 研究总结 Hudi extraMetadata ,记录研究过程。主要目的是通过 extraMetadata 保存 source 表的 commitTime (checkpoint), 来实现增量读Hudi表写Hudi表时,保存增量读状态的事务性,实现类似于流任务中的 exactly-once 背景需求 有个需求:增量读Hudi表关联其他Hudi…...

Vue31-自定义指令:总结

一、自定义函数的陷阱 1-1、自定义函数名 自定义函数名&#xff0c;不能用驼峰式&#xff01;&#xff01;&#xff01; 示例1&#xff1a; 示例2&#xff1a; 1-2、指令回调函数的this 【回顾】&#xff1a; 所有由vue管理的函数&#xff0c;里面的this直接就是vm实例对象。…...

Windows环境如何使用Flutter Version Manager (fvm)

Windows环境如何使用Flutter Version Manager (fvm) Flutter Version Manager (fvm) 是一个用于管理多个 Flutter SDK 版本的命令行工具&#xff0c;它允许开发者在不同项目之间轻松切换 Flutter 版本。这对于需要维护多个使用不同 Flutter 版本的项目的开发人员来说非常有用。…...

优化Elasticsearch搜索性能:查询调优与索引设计

在构建基于 Elasticsearch 的搜索解决方案时&#xff0c;性能优化是关键。本文将深入探讨如何通过查询调优和索引设计来优化 Elasticsearch 的搜索性能&#xff0c;从而提高用户体验和系统效率。 查询调优 优化查询是提高 Elasticsearch 性能的重要方法。以下是一些有效的查询…...

STM32-17-DAC

STM32-01-认识单片机 STM32-02-基础知识 STM32-03-HAL库 STM32-04-时钟树 STM32-05-SYSTEM文件夹 STM32-06-GPIO STM32-07-外部中断 STM32-08-串口 STM32-09-IWDG和WWDG STM32-10-定时器 STM32-11-电容触摸按键 STM32-12-OLED模块 STM32-13-MPU STM32-14-FSMC_LCD STM32-15-DMA…...

一杯咖啡的艺术 | 如何利用数字孪生技术做出完美的意式浓缩咖啡?

若您对数据分析以及人工智能感兴趣&#xff0c;欢迎与我们一起站在全球视野关注人工智能的发展&#xff0c;与Forrester 、德勤、麦肯锡等全球知名企业共探AI如何加速制造进程&#xff0c; 共同参与6月20日由Altair主办的面向工程师的全球线上人工智能会议“AI for Engineers”…...

使用QT制作QQ登录界面

mywidget.cpp #include "mywidget.h"Mywidget::Mywidget(QWidget *parent): QWidget(parent) {/********制作一个QQ登录界面*********************/this->resize(535,415);//设置登录窗口大小this->setFixedSize(535,415);//固定窗口大小this->setWindowTi…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1&#xff1a;修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本&#xff1a;CentOS 7 64位 内核版本&#xff1a;3.10.0 相关命令&#xff1a; uname -rcat /etc/os-rele…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

Mysql8 忘记密码重置,以及问题解决

1.使用免密登录 找到配置MySQL文件&#xff0c;我的文件路径是/etc/mysql/my.cnf&#xff0c;有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...