本帖最后由 朱景 于 2023-11-15 09:38 编辑
芯片N32G451QE7
我在使用TIM的DMA连续模式时,使用到的寄存器是CCDAT2和CCDAT3;
用到的定时器模式是输出比较模式,实现一个脉冲功能和Z相脉冲功能;
但是在实际应用的时候,DMA本应写到CCDAT2寄存器的数据被写入到了CCDAT3寄存器;
导致实现的波形如下:
实现的功能函数如下:
// ========================================================================
// 函数名称:HAL_InitPlsOut
// 输入参数:无
// 输出参数:无
// 扇 入:无
// 扇 出:无
// 函数描述: 脉冲输出设置 单周期最大25个
// ========================================================================
void HAL_PlsOutNum(bool dir , uint8_t num, uint8_t z_num)
{
if(z_num > num){
return ;
}
uint32_t TimCnt = (num << 1);
uint16_t u16CmpValue = PLS_TIMER_PERIOD / TimCnt - 1; /* 周期 200us = 0.0002s ; 1 / 0.0002s = 5000 */
uint32_t u32CmpValue = (uint32_t)(0xFFFF0000 | u16CmpValue);
uint32_t *pDest = (uint32_t *)PlsOutDmaBuf;
//脉冲输出方向由 plsOutDir功能码P0-21决定正逻辑还是反逻辑
if(dir ^ (*ptrPlsOutDir) ){
PLS_OUT_DIR_P();
}
else{
PLS_OUT_DIR_N();
}
PLS_OUT_TIM->DCTRL &= (uint16_t)(~TIM_DMABURST_LENGTH_2TRANSFERS); // 关闭TIM的两个DMA长度传输
PLS_OUT_DMA_CH->CHCFG &= (uint16_t)(~DMA_CHCFG1_CHEN); /* 关闭DMA */
PLS_OUT_TIM->CTRL1 &= (uint32_t)(~((uint32_t)TIM_CTRL1_CNTEN)); /* 关闭TIM */
PLS_OUT_TIM->AR = u16CmpValue; /* TIM的最大计数值初始化 */
PLS_OUT_TIM->CCDAT2 = u16CmpValue; /* 比较器初始化 */
PLS_OUT_TIM->CCDAT3 = u16CmpValue; /* 比较器初始化 */
/* 脉冲是16位数据, 这里填充的是32位的, 所以直接使用 nPulseCount */
// int i = 0;
// for(; i < MAX_PULSE_COUNT_100US; i++) {
// pDest = u32CmpValue;
// }
pDest[0] = u32CmpValue;
pDest[1] = u32CmpValue;
pDest[2] = u32CmpValue;
pDest[3] = u32CmpValue;
pDest[4] = u32CmpValue;
pDest[5] = u32CmpValue;
pDest[6] = u32CmpValue;
pDest[7] = u32CmpValue;
pDest[8] = u32CmpValue;
pDest[9] = u32CmpValue;
pDest[10] = u32CmpValue;
pDest[11] = u32CmpValue;
pDest[12] = u32CmpValue;
pDest[13] = u32CmpValue;
pDest[14] = u32CmpValue;
pDest[15] = u32CmpValue;
pDest[16] = u32CmpValue;
pDest[17] = u32CmpValue;
pDest[18] = u32CmpValue;
pDest[19] = u32CmpValue;
pDest[20] = u32CmpValue;
pDest[21] = u32CmpValue;
pDest[22] = u32CmpValue;
pDest[23] = u32CmpValue;
pDest[24] = u32CmpValue;
pDest[25] = u32CmpValue;
pDest[26] = u32CmpValue;
pDest[27] = u32CmpValue;
pDest[28] = u32CmpValue;
pDest[29] = u32CmpValue;
pDest[30] = u32CmpValue;
pDest[31] = u32CmpValue;
pDest[32] = u32CmpValue;
pDest[33] = u32CmpValue;
pDest[34] = u32CmpValue;
pDest[35] = u32CmpValue;
pDest[36] = u32CmpValue;
pDest[37] = u32CmpValue;
pDest[38] = u32CmpValue;
pDest[39] = u32CmpValue;
pDest[40] = u32CmpValue;
pDest[41] = u32CmpValue;
pDest[42] = u32CmpValue;
pDest[43] = u32CmpValue;
pDest[44] = u32CmpValue;
pDest[45] = u32CmpValue;
pDest[46] = u32CmpValue;
pDest[47] = u32CmpValue;
pDest[48] = u32CmpValue;
pDest[49] = u32CmpValue;
pDest[50] = u32CmpValue;
pDest[51] = u32CmpValue;
pDest[TimCnt] = 0xFFFEFFFF; /* 为了效率没判断nPulseCount是否会越界,调用时要注意 */
if(z_num > 0) {
pDest[(z_num - 1) << 1] &= u16CmpValue << 16 | 0xFFFF;
pDest[((z_num - 1) << 1) + 1] &= u16CmpValue << 16 | 0xFFFF;
}
PLS_OUT_DMA_CH->TXNUM = (TimCnt << 1) + 2; /* 重新设置DMA计数值 */
PLS_OUT_TIM->CNT = 0; /* 定时器计数值清零 */
PLS_OUT_TIM->DCTRL |= (uint16_t)(TIM_DMABURST_LENGTH_2TRANSFERS); // 打开TIM的两个DMA长度传输
PLS_OUT_DMA_CH->CHCFG |= DMA_CHCFG1_CHEN; // 开启DMA
PLS_OUT_TIM->CTRL1 |= TIM_CTRL1_CNTEN; // 开启定时器
}
[size=10.5000pt]
|