SAM3X8E/Arduino Due:TIOB0(PB27)无法生成PWM,输出持续高电平
问题:SAM3X8E的TIOB0引脚无法生成PWM波形(仅输出高电平)
尝试在PB27(Arduino Due引脚13,对应SAM3X8E的TIOB0)上生成PWM信号,但输出引脚仅保持高电平,示波器无PWM波形。使用直接寄存器操作Timer Counter外设,未使用中断或Arduino库,代码如下:
// === PB27 / Arduino Pin 13 = TIOB0 === pmc_set_writeprotect(false); pmc_enable_periph_clk(ID_TC0); PIOB->PIO_PDR = PIO_PB27; // Disable GPIO PIOB->PIO_ABSR &= ~PIO_PB27; // Peripheral A für TIOB0 TC_Configure(TC0, 0, TC_CMR_WAVE | // Waveform mode TC_CMR_WAVSEL_UP_RC | // Count up to RC TC_CMR_ACPA_CLEAR | // Clear on RA TC_CMR_ACPC_SET | // Set on RC TC_CMR_TCCLKS_TIMER_CLOCK4); TC_SetRA(TC0, 0, rc / 2); TC_SetRC(TC0, 0, rc); TC_Start(TC0, 0); delay(duration); TC_Stop(TC0, 0); PIOB->PIO_PER = PIO_PB27; // Enable GPIO PIOB->PIO_OER = PIO_PB27; // Output enable PIOB->PIO_CODR = PIO_PB27; // Set LOW return true;
环境
- Arduino Due(Atmel SAM3X8E)
- VS Code/PlatformIO + 直接寄存器访问
- 未使用中断
问题分析与解决方案
你的代码存在两个核心错误,导致TIOB0无法输出波形:
1. 未配置TIOB的比较动作规则
当前配置的TC_CMR_ACPA_CLEAR和TC_CMR_ACPC_SET是针对TIOA引脚的比较动作,而你要输出的是TIOB引脚,完全没设置TIOB的触发逻辑。同时,TIOB默认绑定的比较寄存器是RB(而非RA),需要:
- 将RA相关配置替换为TIOB对应的RB配置
- 添加TIOB在RB/RC匹配时的电平动作
2. 引脚复用配置错误
SAM3X8E的PB27作为TIOB0时,对应的是Peripheral B,而非代码里设置的Peripheral A。错误的复用配置会导致引脚无法关联到TC0的TIOB0输出。
修正后的完整代码
// === PB27 / Arduino Pin 13 = TIOB0 === pmc_set_writeprotect(false); pmc_enable_periph_clk(ID_TC0); PIOB->PIO_PDR = PIO_PB27; // 禁用GPIO控制 PIOB->PIO_ABSR |= PIO_PB27; // 设置为Peripheral B,关联TIOB0(关键修正) TC_Configure(TC0, 0, TC_CMR_WAVE | // 波形模式 TC_CMR_WAVSEL_UP_RC | // 向上计数到RC TC_CMR_BCPB_CLEAR | // TIOB:匹配RB时清除电平(关键新增) TC_CMR_BCPC_SET | // TIOB:匹配RC时设置电平(关键新增) TC_CMR_TCCLKS_TIMER_CLOCK4); TC_SetRB(TC0, 0, rc / 2); // 用RB控制TIOB的低电平起始点(替换原RA) TC_SetRC(TC0, 0, rc); TC_Start(TC0, 0); delay(duration); TC_Stop(TC0, 0); PIOB->PIO_PER = PIO_PB27; // 启用GPIO PIOB->PIO_OER = PIO_PB27; // 输出使能 PIOB->PIO_CODR = PIO_PB27; // 设置为低电平 return true;
额外验证点
- 确认
rc值在合理范围:TIMER_CLOCK4为MCK/128,SAM3X8E默认MCK是84MHz,对应定时器时钟约656kHz,RC值不能超过16位定时器的最大值65535 - 确保没有其他代码占用TC0外设或PB27引脚
内容的提问来源于stack exchange,提问作者Lysapala
相关产品推荐
相关产品推荐

