You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ATTINY1616无法切换PWM输出引脚问题技术求助

ATTINY1616 非PB0引脚无法输出PWM的问题求助

我刚入门MCU编程,先从Arduino入手,现在尝试使用ATTINY1616实现LED呼吸调光的PWM效果。原本以为代码可行,但发现仅PB0引脚能正常输出PWM,其他引脚无任何输出。我查阅了ATTINY1614/16/17的datasheet(重点看了TCA的第20章节),确认存在更多可用PWM引脚,但未找到缺失的配置指令。

代码无论选择哪个引脚作为输出都能编译通过,但MCU仅PB0有效,其他引脚无输出,Microchip Studio也未提示任何错误,我甚至更换了新的MCU。我不太擅长阅读datasheet,推测PB0作为TCA0的WO0是默认引脚,需配置指令切换其他引脚,但未找到有效方法。

初始代码

#define F_CPU 20000000
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdint.h>

void PWM_init() {
    // Configure Timer/Counter 0 (TC0) for PWM generation

    // Set TC0 waveform generation mode to Fast PWM
    TCA0.SINGLE.CTRLB = TCA_SINGLE_WGMODE_SINGLESLOPE_gc | TCA_SINGLE_CMP0EN_bm;

    // Set TC0 period (TOP value) to 8-bit resolution
    TCA0.SINGLE.PER = 0xFF;

    // Set TC0 PWM output on PB0 (LED pin)  
    PORTB.DIRSET = PIN0_bm;
    //PORTA.DIRSET = PIN4_bm; <------Pin PA4. It won't work even if PB0 is removed

    TCA0.SINGLE.CTRLA = TCA_SINGLE_ENABLE_bm;
}

void PWM_control() {
    // Define the number of steps and the delay between each step
    const uint16_t numSteps = 256;
    const uint16_t delayMs = 10;

    // Fade in
    for (uint16_t step = 0; step < numSteps; step++) {
        // Set ADC value based on the step
        uint16_t adcValue = step;

        // Scale the ADC value to PWM range (0-255)
        uint8_t pwmValue = adcValue >> 2; // Right shift by 2 (divide by 4)

        // Update PWM duty cycle
        TCA0.SINGLE.CMP0 = pwmValue;

        // Delay between each step
        _delay_ms(delayMs);
    }
    // Fade out
    for (uint16_t step = 256; step > 0; step--) {
        // Set ADC value based on the step
        uint16_t adcValue = step;

        // Scale the ADC value to PWM range (0-255)
        uint8_t pwmValue = adcValue >> 2; // Right shift by 2 (divide by 4)

        // Update PWM duty cycle
        TCA0.SINGLE.CMP0 = pwmValue;

        // Delay between each step
        _delay_ms(delayMs);
    }
}

int main() {
    // Initialize PWM
    PWM_init();
    CPU_CCP = 0xD8; //enable write to protected register;
    CLKCTRL_MCLKCTRLB = 0; // No prescaling to periphery, therefore 20MHz frequency;

    while (1) {
        // Control PWM
        PWM_control();

        _delay_ms(10);
    }

    return 0;
}

已尝试的方法

  • 在该MCU上运行Arduino版本代码,可正常工作;
  • 仅修改PORTx.DIRSET切换引脚,仅PB0有效;
  • 为其他引脚编写独立初始化函数,无效;
  • 修改TCA_SINGLE_CMP0EN_bm、TCA_SINGLE_WGMODE_SINGLESLOPE_gc等指令,切换为TCB定时器,均无效。

后续修改的PWM初始化代码

TCA0.SPLIT.CTRLA = TCA_SINGLE_ENABLE_bp;
//SPLIT MODE INIT
TCA0.SPLIT.CTRLD = TCA_SINGLE_SPLITM_bm;
TCA0.SPLIT.HPER = 0xFF;
TCA0.SPLIT.CTRLA = TCA_SINGLE_ENABLE_bm;
TCA0.SPLIT.CTRLB = TCA_SPLIT_HCMP0EN_bm | TCA_SPLIT_HCMP1EN_bm | TCA_SPLIT_HCMP2EN_bm;

控制部分仅将TCA0.SINGLE.CMP0改为TCA0.SPLIT.HCMP1以适配PA4引脚。


内容的提问来源于stack exchange,提问作者Collapsedblock6

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 08:27:04