Changes from v2.7.7 to v2.7.8:
[feat]:upgrade patch tool to v3.8 [opt]:opt code generate process display [opt]:opt login logic [opt]:opt ghs support [opt]:add MC03 ghs support问题现象描述:
1.我配置ADC的一组为: 通道 0,1,12,13;当我读取ADC->FIFO时,有缺少的还有重复的channel-ID;
2.使用库函数读取ADC->FIFO时,存放寄存器变量的uint32 regValue的值 与寄存器视图 的值 不一致;
260ea2b5-f576-41cc-bf73-bfe4d0496c46-image.png
19c3b12a-ea72-4958-bca9-48a62739efbd-image.png
下面是我ADC的工具配置信息:
9d72f96a-fcb4-4acd-9c46-75eca83ac482-image.png
411a28e4-f1cb-44a5-9d89-ecb820500d49-image.png
d29bfdeb-d0ad-4dad-8c89-424c46896588-image.png
/* adc_config0 */ const adc_converter_config_t adc_config0={ .clockDivider=0, .startTime=12, .sampleTime=2, .overrunMode=false, .autoOffEnable=false, .waitEnable=false, .trigger=ADC_TRIGGER_SOFTWARE, .align=ADC_ALIGN_RIGHT, .resolution=ADC_RESOLUTION_12BIT, .dmaWaterMark=0, .dmaEnable=false, .sequenceConfig={ .sequenceMode=ADC_CONV_LOOP, .sequenceIntEnable=false, .convIntEnable=false, .readyIntEnable=false, .ovrunIntEnable=false, .sampIntEnable=false, .channels={ ADC_INPUTCHAN_EXT0, ADC_INPUTCHAN_EXT1, ADC_INPUTCHAN_EXT12, ADC_INPUTCHAN_EXT13, }, .totalChannels=4, }, .compareConfig={ .compareEnable=false, .compareAllChannelEnable=false, .compHigh=4095, .compLow=0, .compIntEnable=false, }, }; #define ADC_INST 0U adc_converter_config_t get_adc_config0; uint8_t set_adc_sequence_cnt = 2; uint8_t get_adc_sequence_cnt = 2; void ADC_Init(void) { ADC_DRV_ConfigConverter(ADC_INST,&adc_config0); ADC_DRV_Start(ADC_INST); //get adc sequence length set_adc_sequence_cnt = adc_config0.sequenceConfig.totalChannels; ADC_DRV_GetConverterConfig(ADC_INST, &get_adc_config0); get_adc_sequence_cnt = get_adc_config0.sequenceConfig.totalChannels; } void ADC_Get_Value_10ms(void) { uint32 reg_value = 0; for (uint8_t i = 0; i < set_adc_sequence_cnt; i++) { reg_value = ADC_DRV_ReadSeqtagAndData(ADC_INST); // uint8_t channel_id = reg_value>>16; uint8_t channel_id = (reg_value>>16)&0x1f; uint16_t chan_raw_data = (reg_value&0x0000ffff); if(channel_id == 0)//ADC0_SE0 { uint16 ADC_mV_IntPackVolt = 0; ADC_mV_IntPackVolt = (reg_value&0x0000ffff)*3300/4096; //test code to view the convert result of ADC ADC_mV_IntPackVolt = 1100; } } ADC_DRV_Start(ADC_INST); }您好,这里为尝试can接收多帧报文发送多帧报文是否会丢数据,使用evb板,配置can0,发送32邮箱,接受32邮箱,32个id报文10ms发送一次,同时发送,在没有使用软件缓冲区的时候,mcu发送进busy之后此时如果再接受此id的报文并且发送会丢失最新的一帧
2f3555d6-e5ee-4b9d-b98e-950a3e8c3684-image.png
程序里面记录那个rx通道接收和接收次数+1
f900b7a332fa2b3a53982f810378f2ce.png 7065356775a4f34332c4ca77e40345c6.png
发送的正好是上一帧的数值,差了32
这个是不是没有txfifo,想要接收许多数据的话应该怎么做
使用dma后,好像也不是固定32,
69cdb87369e8d5a98b3ab22ea9c59cfe.png
f0068d63-04d3-4117-b894-90f71b29190d-image.png
问题:
YTM32B1L05, 上下电测试中,会随机的出现ADC输出值异常情况。
故障出现后,不断电,故障会一直保持,断电再上电故障消失。
debug获取DMA目标地址数据发现,出现大量连续的 2048/1023 数值。中间掺杂几个正常的数据。
异常数据.jpg
ADC模块使用简介:
1)先 pTMR 触发 ADC采样0或1通道 DMA搬运,250组数据,再 pTMR 触发 ADC采样3或5通道 DMA搬运 1000组数据。
2)每500ms,执行1次 1)操作。
基本配置
ADC模块配置
/* adc_config0 */
const adc_converter_config_t adc_config0={
.clockDivider=0,
.startTime=48,
.sampleTime=200,
.overrunMode=false,
.autoOffEnable=false,
.waitEnable=false,
.trigger=ADC_TRIGGER_HARDWARE,
.align=ADC_ALIGN_RIGHT,
.resolution=ADC_RESOLUTION_12BIT,
.dmaWaterMark=1,
.dmaEnable=true,
.sequenceConfig={
.sequenceMode=ADC_CONV_LOOP,
.sequenceIntEnable=false,
.convIntEnable=false,
.readyIntEnable=false,
.ovrunIntEnable=false,
.sampIntEnable=false,
.channels={
ADC_INPUTCHAN_EXT3,
ADC_INPUTCHAN_EXT5,
},
.totalChannels=2,
},
.compareConfig={
.compareEnable=false,
.compareAllChannelEnable=false,
};
/* adc_config1 */
const adc_converter_config_t adc_config1={
.clockDivider=0,
.startTime=48,
.sampleTime=200,
.overrunMode=false,
.autoOffEnable=false,
.waitEnable=false,
.trigger=ADC_TRIGGER_HARDWARE,
.align=ADC_ALIGN_RIGHT,
.resolution=ADC_RESOLUTION_12BIT,
.dmaWaterMark=1,
.dmaEnable=true,
.sequenceConfig={
.sequenceMode=ADC_CONV_LOOP,
.sequenceIntEnable=false,
.convIntEnable=false,
.readyIntEnable=false,
.ovrunIntEnable=false,
.sampIntEnable=false,
.channels={
ADC_INPUTCHAN_EXT1,
ADC_INPUTCHAN_EXT0,
},
.totalChannels=2,
},
.compareConfig={
.compareEnable=false,
.compareAllChannelEnable=false,
};
DMA模块配置
dma_loop_transfer_config_t adcTransferConfigLoopConfig = {
.triggerLoopIterationCount=1000,
.srcOffsetEnable=false,
.dstOffsetEnable=true,
.triggerLoopOffset=0,
.transferLoopChnLinkEnable=false,
.transferLoopChnLinkNumber=0,
.triggerLoopChnLinkEnable=false,
.triggerLoopChnLinkNumber=0,
};
dma_transfer_config_t adcTransferConfig = {
.srcAddr=(uint32_t)0,
.destAddr=(uint32_t)0,
.srcOffset=0,
.destOffset=0x02U,
.srcTransferSize=DMA_TRANSFER_SIZE_2B,
.destTransferSize=DMA_TRANSFER_SIZE_2B,
.srcModulo=DMA_MODULO_OFF,
.destModulo=DMA_MODULO_OFF,
.transferLoopByteCount=4,
.srcLastAddrAdjust=4,
.destLastAddrAdjust=-4,
.interruptEnable=true,
.loopTransferConfig=&adcTransferConfigLoopConfig,
};
pTMR 配置
const ptmr_user_channel_config_t ptmr_channel_0={
.periodUnits=pTMR_PERIOD_UNITS_COUNTS,
.period=625,
.chainChannel=false,
.isInterruptEnabled=false,
};
时钟频率
内核&DMA 48M
ADC = 16M
pTMR = 8M
ADC链路配置
ADC链路配置.jpg
ADC链路启动
ADC链路启动.jpg
前言
本文档以YTM32B1Mx为例介绍FLEXCAN收发报文数超过物理邮箱个数时邮箱分配方案、LegacyFIFO用法,同时也适用于YTM32B1Lx系列。
1. YTM32B1Mx FLEXCAN邮箱资源介绍
MC03的FLEXCAN资源:
b2492947-eb3f-4cbc-ac09-81efc9621fed-image.png
MD14的FLEXCAN资源:
50bd0110-d75a-456f-97d4-adf5d8f95717-image.png
ME05的FLEXCAN资源:
79278b7f-a6d4-4f82-8b2d-4bb16639cac9-image.png
以ME05为例,邮箱负载为8字节负载时,CAN0、CAN1、CAN2的邮箱数为64个,CAN3、CAN4、CAN5的邮箱数为32个。
硬件设计时注意优先选用CAN邮箱资源多的CAN通道。
以CAN0为例,
收发报文数量小于等于邮箱数(64)时,为每一条收发报文分配一个邮箱即可; 收发报文数量超过邮箱数时,可通过配置接收FIFO、配置邮箱接收范围ID的方式来实现。下文将通过一个ME05应用实例,介绍使用经典CAN时合理分配邮箱来解决收发报文超过邮箱数问题的方案。
2. 应用实例说明
2.1 需求描述
用户使用CAN0,经典CAN,需要发送的报文ID有40条,需要接收的报文ID包括118条离散ID、1条范围ID(0x600 ~ 0x67F)。如下图:
c837846e-9a1a-47c0-b5e1-0c91dd762a71-image.png
2.2 方案概述
由需求知收发报文总条数远大于CAN0邮箱总数,故接收报文需要用到LegacyFIFO,基本步骤如下:
(1)根据需要接收的报文数,计算LegacyFIFO占用的邮箱数,并配置LegacyFIFO用于接收118条离散ID;
(2)剩下的邮箱中,选择一个邮箱用于接收范围ID(0x600 ~ 0x67F);
(3)剩下的所有邮箱均用做发送邮箱,需要发送报文时滚动轮询发送邮箱的状态,使用空闲邮箱进行发送。
例如,一种邮箱分配参考方案如下:
fc491a8b-64e8-4ed3-8283-0b0542a43ec9-image.png
2.3 功能实现
2.3.1 接收FIFO配置
需接收的离散报文ID共118条,因此LegacyFIFO实际需要占用的邮箱数与配置120条滤波码时占用的邮箱数一致,即占用0~35共36个邮箱,配置LegacyFIFO后剩余28个邮箱(邮箱号为36~63)可用。
76be7871-7939-4a94-b98c-d484666b99e7-image.png
LegacyFIFO配置方式:
(1)配置接收LeacyFIFO,手动添加118个接收离散报文ID到过滤表中。配置完成后启动LeacyFIFO接收。
10092b59-b024-41c0-84fc-820aaccb7259-image.png
(2)通过LeacyFIFO接收到报文时重新调用FLEXCAN_DRV_RxFifo(CAN_INST, &rxFifoMsg)函数启动下一次接收。
ea0e466f-b402-4a8e-96bd-3b4292b339c0-image.png
2.3.2 接收邮箱配置
LegacyFIFO占用了MailBox0~35共36个邮箱,这里配置邮箱36用于接收ID范围为0x600~0x67F的报文。
配置方式:
(1)配置MailBox36的接收ID和掩码值,用于接收0x600~0x67F的范围ID报文。
af97abde-76b8-4859-a0a7-243dcb1c723f-image.png
(2)MailBox36接收到报文时重新调用 FLEXCAN_DRV_Receive(CAN_INST, 36, &rxMsgBuffer);函数启动下一次接收。
416138fe-0d56-4a0f-9ace-9b549548d168-image.png
2.3.3 发送邮箱配置
剩下的MailBox37~63共27个邮箱可用做发送邮箱,需要发送报文时,滚动轮询这27个邮箱的状态,使用空闲邮箱发送即可。
配置方式:
(1)配置27个发送邮箱
954a0ac0-155b-4158-a886-0101f4e8330c-image.png
(2)滚动查询27个发送邮箱的状态,使用空闲邮箱发送报文
52245282-7e59-4a0d-af75-7e45c6be3fd5-image.png
3. 总结
(1)本文档仅提供一个参考方案,收发邮箱的分配应当根据实际的收发报文条数、通讯周期等需求来分配。
(2)本文档中对于所有的离散ID,均使用LeacyFIFO进行接收,实际应用时可以少分配一些发送邮箱,预留出更多的邮箱用于报文接收,例如对一部分周期较长或优先级较低的报文可以使用LeacyFIFO接收,对周期较短或优先级较高的报文,单独配置接收邮箱实现等。
参考文档及demo工程
(1)参考文档
AN_0008_YTM32_FlexCAN_SDK_User_Guide_zh_review.pdf
AN_0019_YTM32_FlexCAN_Introduction_zh_review.pdf
(2)示例demo
Flexcan_MB_example.zip
023d05ee-2dd2-459b-add4-1758c8d74582-image.png
1.3 电机实物图三线为电机的三项,五线为传感器端,不使用建议用绝缘胶带包裹;
a8c25300-f3d2-4353-9425-c08d4563ebcc-image.png
MCU通过跳帽可选5V或3.3V电源域;
原理图
ba11ca4c-4e2b-4c89-adf6-595ae1e054f0-image.png
实物图,此时为5V供电;
b593f6a6-7f21-4705-a616-4b3daf6ec18d-image.png
原理图
94524827-3455-418d-8ab7-d62b8a483de6-image.png
2.2.1 将SJP1-1与SJP1-2用锡短接,将SJP2-1与SJP2-2用锡短接,配置为三项电阻采样;
实物图
94d71e68-bf40-4cc5-874c-ef43d25b688a-image.png
2.2.2 将SJP1-1与SJP1-2用锡短接,将SJP2-1与SJP2-2用锡短接,配置为单电阻母线电流采样;
实物图
dd545584-07b7-4672-9f90-2d56f207f76b-image.png
接线端口
49bbc0b0-cfa2-4373-beb0-f08b1261d994-image.png
注:接线不同导致转向不同;
debug为SWD协议,板上端口为10pin SWD标准防呆端口;
125c72e7-9a34-4770-b988-da3e97b482d4-image.png
此demo为12V系统,直流源供电
a7ca5450-8e39-4222-82e6-da22348584a7-image.png
注:使用直流源供电时,推荐限流5A防止系统因直流源限流不工作;
经过以上步骤后,即可上电调试了;
3 调试 3.1 电机参数测量3.1.1 电阻与电感
测试仪器:LCR
选用LS-RS档,电平选择1V,测电阻时频率选择100Hz,测量电感时选择1KHz,测试之前最好进行开路和短路清零。接线方式为表笔与电机任意两相连接,需测三组(例:黄蓝,黄绿,蓝绿三组);
3f6ab13d-059f-4e99-9211-c30c78439233-image.png
测得结果为线电阻与线电感,进行计算得到相电阻与相电感:
phase resistance = ((R1 + R2 + R3) / 3 ) / 2;
phase inductance = ((L1 + L2 + L3) / 3 ) / 2;
注:此电机为表贴式电机,Lq=Ld;
3.1.2 磁链常数测量
测试仪器:示波器
用示波器一个探头的地与信号分别连接电机任意两相,用绳子或其它工具缠绕电机转子,拉动使其旋转,示波器捕捉反向电动势,选取较为均匀的反向电动势波形;
a2f22800-76ff-47a9-8007-74904949316b-image.png
得到峰峰值Vpp和频率F,计算得到磁链常数:
KFI = Vpp / (4 * π * F * sqrt(3));
3.1.3 极对数测量
有多种方式,这里介绍较为常用的一种方式,将电机任意两相连接直流源的正负,通电,电压自定义(不能过大,通常为1V),电流500mA,然后用手转动转子,可以感觉出来有停顿,几次停顿即为几对极,若停顿感觉不明显可每次500mA递增电流后重复动作;
BUS电压采样分压电路
503c21ca-4e41-420c-b96c-5586162e87b8-image.png
根据原理图可得知可测量最大母线电压为 Vbusmax = VDDmcu * 105 / 5;
3.3.1 电流采样运放电路
4e4a27c2-5428-4675-8d21-16326a4d112c-image.png
3.3.2 shunt电路
076e9d73-9ae7-44d0-9751-07f4f97d51a7-image.png
根据原理图可得知电流增益G = 10KΩ/2KΩ = 5, 采样电阻R = 0.05Ω,计算公式为:
Peak current = (0.5 * Vref / G) / R;
至此需测量参数测量结束,将测得参数填入代码;
4 YTM32B1XXX系列MotorDemo原理图SCH_motor_driver_2025-04-22.pdf
5 MotorDemoFOC算法电流环时间对比c75ba5d5-9a0b-4a1f-9c72-0dd6b73d29c1-image.png
6 YTM32B1XXX系列MotorDemo代码MotorDemo.zip
7 YTM32B1XXX系列MotorDemo调速demo可调速范围为300rpm/min - 1500rpm/min
7.1 CAN总线调速CAN总线接线口实物图:
6a3379f9-e380-454b-995d-fac3350e1216-image.png
通过CAN总线可控制电机转速,停止,复位,观察电机速度
DBC文件为:
MotorCtrl.zip
控制电机demo报文ID为0x201
223447f6-cf0c-487e-b910-8dc67105f1cb-image.png
电机demo发送报文ID为0x200
139c0410-6de6-4fff-94d0-b5e032021470-image.png
注:电机温度与Bus总线电压报文待改板后更新
每次按键调速为100rpm/min
0f593ccf-7ca2-48ad-9a6e-8089589a2fb0-image.png
AN0078_General_Mcu_Motor_Control_Guide_zh.pdf
/*
Copyright 2020-2025 Yuntu Microelectronics Co., Ltd. All rights reserved. SPDX-License-Identifier: BSD-3-Clause @file yt_linker.ld @brief*/
/* MEMORY MAP /
MEMORY
{
IVT (RX) : ORIGIN = 0x0, LENGTH = 0x400
TEXT (RX) : ORIGIN = 0x400, LENGTH = 0x7bc00
DTC (RX) : ORIGIN = 0x7c000, LENGTH = 0x1000
DTC_BACKUP (RX) : ORIGIN = 0x7d000, LENGTH = 0x1000
INF (RX) : ORIGIN = 0x7e000, LENGTH = 0x1000
INF_BACKUP (RX) : ORIGIN = 0x7f000, LENGTH = 0x1000
IVT_RAM (RW) : ORIGIN = 0x1fff8000, LENGTH = 0x400
STACK (RW) : ORIGIN = 0x20007c00, LENGTH = 0x400
RAM (RW) : ORIGIN = 0x1fff8400, LENGTH = 0xf800
}
/ SECTIONS */
SECTIONS
{
.IVT : {
}
上面是项目中的ld檔,修改完后SPI的初始程序(下面所示)会一直在下面循环出不来(修改前是没问题的),请问有可能是什么原因呢?会不会是.bss档没清0呢?请问sample code清0的程序在那呢?
while (spiState->rxCount != (uint16_t)0)
{
/* Read the last word from the RX FIFO */
if (SPI_GetStatusFlag(base, SPI_RX_DATA_FLAG))
{
SPI_DRV_ReadRXBuffer(instance);
}
}
CMake 在嵌入式编程中的地位已经越来越重要。它是一个强大的跨平台自动化构建系统,能够管理大型项目中的软件构建过程。以下是几个方面,说明了CMake在嵌入式领域的重要性和使用情况:
跨平台兼容性:CMake可以生成各种平台上的编译环境,包括Windows、MacOS和各种Unix-like系统。这使得它特别适合于开发可以在多种硬件上运行的嵌入式软件。 灵活性和可扩展性:CMake支持复杂的项目结构,可以轻松地管理多个库和应用程序的依赖关系。这对于嵌入式系统开发尤其重要,因为这些系统往往包含多个模块和组件。 工具链集成:CMake可以与各种编译器和工具链无缝集成,如GCC、Clang等,以及专用的嵌入式开发工具链,如ARM Keil、IAR等。这使得开发者可以更容易地在其选择的环境中编译和测试代码。YCT 支持生成CMAKE-GCC/CMAKE-IAR/CMAKE-KEIL/CMAKE-GHS 代码可重用性:使用CMake可以更容易地在不同项目之间重用代码。通过寻找包和库,CMake允许开发者将常用的功能或库集成到新的嵌入式项目中,而无需重新配置整个构建环境。 YCT生成的CMAKE文件架构YCT生成的cmake文件遵守最新的Modern Cmake的理解:
目标导向:Modern CMake 鼓励使用基于目标(target)的指令来管理构建配置,而不是基于全局的设置。每个目标可以定义自己的编译选项、预处理器定义、链接库等,这使得项目更加模块化和易于管理。 用法要求:在传统 CMake 中,库的依赖关系通常通过全局变量和目录链接来管理。而在 Modern CMake 中,推荐使用 target_link_libraries、target_compile_definitions 和 target_include_directories 等命令为目标设置用法要求。这样,当其他目标链接到库时,它们会自动继承正确的编译器标志、宏定义和包含路径。YCT生成的工程默认是如下的配置:
project 包含:GENERATED_CONFIG_TARGET,GENERATED_SDK_TARGET
用户可以直接在 USER CODE BEGIN 开始,USER CODE END 介绍的中间部分增加自己的配置代码,在这之间生成的代码不会被覆盖掉
# USER CODE BEGIN include # target_include_directories(...) # USER CODE END include # USER CODE BEGIN add_executable # target_sources(${project_elf} PRIVATE ..) # USER CODE END add_executable下面以增加bsp目录为例:
# USER CODE BEGIN include # 增加bsp/inc头文件搜索路径 target_include_directories(${project_elf} PRIVATE "bsp/inc") # USER CODE END include # USER CODE BEGIN add_executable # 增加源文件bsp/bsp.c 作为源代码 target_sources(${project_elf} PRIVATE "bsp/bsp.c") # USER CODE END add_executable 添加一个独立的target文件当源文件比较多的时候,或者想更好的控制代码的编译选项的时候,建议增加一个独立的target方式来实现,还是以bsp代码作为例子。
写一个BSP.cmake 文件放到bsp目录 cmake_minimum_required(VERSION 3.16) set(sources bsp.c ) #增加头文件 set(includes inc) #增加私有头文件 set(priIncludes ) add_library(BSP STATIC ${sources}) target_include_directories(BSP PUBLIC ${includes}) target_include_directories(BSP PRIVATE ${priIncludes}) #添加基础的编译选项,如CPU类型等 configcore(BSP ${CMAKE_SOURCE_DIR}) #增加宏定义,PRVIATA代表只有这个target里的源代码可以识别到这个宏,(不用加-D) target_compile_definitions(BSP PRIVATE BSP ) #对BSP target的代码单独设置优化选项,不影响其他模块 target_compile_options(BSP PRIVATE -O1 ) #如果BSP代码访问到了SDK的头文件,那么需要添加依赖的target target_link_libraries(BSP GENERATED_CONFIG_TARGET GENERATED_SDK_TARGET ) 修改顶层的CMakeLists.txt文件 # USER CODE BEGIN include #包含我们添加的BSP.cmake文件 include(${CMAKE_SOURCE_DIR}/bsp/BSP.cmake) #把BSP target 加入到project里 target_link_libraries(${project_elf} BSP) # USER CODE END include-
Announcements
Announcements regarding our community
-
Discussion & Question
A place to talk about whatever you want or ask a question
-
Blogs
Blog posts from individual members
快速上手云途开发生态
发帖前请查看
帮助改进和优化YT CONFIG TOOL,有机会抽取YTM32B1ME0 EVB哦...