求英飞凌TriCore TC17xx系列DMA转SSC通信示例代码及问题排查
以下代码基于TC1796芯片,实现DMA驱动SSC发送8位数据的功能,适配I2S帧格式(可根据硬件需求调整):
SSC初始化(发送模式)
#include <tc1796.h> void SSC_Init(void) { // 使能SSC模块时钟 SCU_PCON0 |= SCU_PCON0_SSC0_Msk; // 引脚复用配置(需根据硬件原理图调整对应引脚的复用寄存器) // 示例:假设TXD对应P1.0、CLK对应P1.1、FS对应P1.2 // SCU_P1_IOCR0 |= SCU_IOCR_PC0(0x10); // TXD引脚设为SSC0_TXD // SCU_P1_IOCR0 |= SCU_IOCR_PC1(0x10); // CLK引脚设为SSC0_TCK // SCU_P1_IOCR0 |= SCU_IOCR_PC2(0x10); // FS引脚设为SSC0_TFS // 复位SSC控制寄存器 SSC0_CR = 0; // 使能发送帧与发送器 SSC0_CR |= SSC_CR_TFEN | SSC_CR_TEN; // 配置帧格式:8位数据,帧同步领先1位,时钟上升沿发送 SSC0_FRM = SSC_FRM_TFLEN(7) // 发送帧长度:8位(0-7共8个数据位) | SSC_FRM_TFSW(0) // 帧同步宽度1位 | SSC_FRM_TFSD(1); // 帧同步在数据前 // 配置发送时钟:内部分频生成1MHz时钟(系统时钟假设为16MHz) SSC0_CKD = SSC_CKD_TCD(15) // 分频系数16(16/16=1MHz) | SSC_CKD_TCPOL(0); // 时钟上升沿触发数据发送 }
DMA初始化(通道0绑定SSC发送)
uint8_t tx_buf[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; void DMA_Init(void) { // 使能DMAC模块时钟 SCU_PCON0 |= SCU_PCON0_DMAC_Msk; // 配置DMA通道0参数 DMAC_CH0_SRC = (uint32_t)tx_buf; // 源地址:发送缓冲区 DMAC_CH0_DST = (uint32_t)&SSC0_TDR; // 目标地址:SSC发送数据寄存器 DMAC_CH0_BCR = 8; // 传输总字节数:8 DMAC_CH0_CTL = DMAC_CTL_SRC_WIDTH(0) // 源数据宽度:字节(8位) | DMAC_CTL_DST_WIDTH(0) // 目标数据宽度:字节 | DMAC_CTL_SRC_INC(1) // 源地址自动递增 | DMAC_CTL_DST_INC(0) // 目标地址固定(SSC_TDR) | DMAC_CTL_TRIG_SEL(0x12) // 触发源:SSC0发送就绪(TDRE) | DMAC_CTL_EN; // 使能DMA通道 }
启动DMA发送函数
void SSC_DMA_Send(void) { // 重置传输参数(支持重复发送) DMAC_CH0_SRC = (uint32_t)tx_buf; DMAC_CH0_BCR = 8; // 重新使能DMA通道触发传输 DMAC_CH0_CTL |= DMAC_CTL_EN; }
针对你遇到的“加载8字节仅发2字节(第二个为0)”问题,重点检查以下配置:
DMA传输宽度与计数不匹配:
确认DMAC_CH0_CTL的SRC_WIDTH和DST_WIDTH是否设为0(字节模式)。若误设为1(半字模式),且BCR设为1(1个半字=2字节),会导致仅传输2字节;同时因uint8_t缓冲区内存对齐问题,第二个字节可能被填充为0。需确保BCR在字节模式下设置为8。SSC帧长度配置错误:
检查SSC0_FRM的TFLEN字段,需设为7(对应8位数据长度)。若设为1(2位数据),会导致每帧仅发送2字节,且超出数据位的部分补0。DMA触发源错误:
确认DMAC_CH0_CTL的TRIG_SEL是否对应SSC的**发送就绪(TDRE)**信号(TC1796中对应触发码0x12)。若误绑定到帧同步信号,可能仅触发一次帧传输,导致仅发送2字节。SSC发送模式限制:
检查SSC0_CR的TFEN位是否置1(连续发送帧)。若未开启连续发送,且帧长度设为2字节,会仅发送单次帧的2字节数据。内存对齐问题:
TC1796的DMA对源地址有对齐要求(半字/字边界),若tx_buf为uint8_t类型未对齐,可能导致DMA读取数据时出错。可尝试将缓冲区声明为__attribute__((aligned(2))) uint8_t tx_buf[8]测试。DMA状态寄存器排查:
传输后读取DMAC_CH0_STAT,查看ERR错误位是否置1,或BCR是否递减至0,判断DMA是否完成全部8字节传输。
内容的提问来源于stack exchange,提问作者Peter Kostadinov

