No se puede hacer que DAC STM32 produzca nada

0

Estoy tratando de hacer que una tarjeta genérica STM32F103 produzca una onda de diente de sierra en el canal 1 de DAC pero no obtengo nada. El código es muy sencillo y he estudiado sin cesar la hoja de datos, Google, varios ejemplos y tutoriales. Simplemente no puedo ver lo que me estoy perdiendo aquí.

Se está llamando a la función IRQ a aproximadamente 44.1KHz, y PORTA: 0 está alternando correctamente, pero PORTA: 4 es solo 0 voltios.

¿Alguien puede ver un error en esto?

El manual de referencia es here

La hoja de datos es here

#include "misc.h"

extern "C" void TIM2_IRQHandler()
{
    static int i, j;

    // clear timer2 irq status
    TIM2->SR = (uint16_t)~TIM_IT_Update;

    // heartbeat toggle PORTA:0 every 256th tick
    (&GPIOA->BSRR)[(++i >> 8) & 1] = 0x1;

    // set new DAC data every tick
    DAC_SetChannel1Data(DAC_Align_12b_R, ++j & 0xfff);
}

int main()
{
    // switch on some peripheral clocks
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);   // PORTA
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);    // TIMER2
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);     // DAC

    // set PORTA:0 to output
    GPIO_InitTypeDef a0;
    a0.GPIO_Pin = GPIO_Pin_0;
    a0.GPIO_Mode = GPIO_Mode_Out_PP;
    a0.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &a0);

    // set PORTA:4 to analog input (manual says to do this when using DAC Channel 1)
    GPIO_InitTypeDef a4;
    a4.GPIO_Pin = GPIO_Pin_4;
    a4.GPIO_Mode = GPIO_Mode_AIN;
    a0.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &a4);

    // setup DAC channel 1
    DAC_InitTypeDef dacInit;
    dacInit.DAC_Trigger = DAC_Trigger_None;                             // set instantly
    dacInit.DAC_WaveGeneration = DAC_WaveGeneration_None;               // raw data
    dacInit.DAC_OutputBuffer = DAC_OutputBuffer_Enable;                 // enable filter
    dacInit.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bits8_0;  // filter level
    DAC_Init(DAC_Channel_1, &dacInit);
    DAC_Cmd(DAC_Channel_1, ENABLE);

    // enable TIMER2 IRQs
    NVIC_InitTypeDef nvicInit;
    nvicInit.NVIC_IRQChannel = TIM2_IRQn;
    nvicInit.NVIC_IRQChannelPreemptionPriority = 0;
    nvicInit.NVIC_IRQChannelSubPriority = 1;
    nvicInit.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&nvicInit);

    // setup timer2 @ approx 44.1KHz
    TIM_TimeBaseInitTypeDef timerInit;
    timerInit.TIM_CounterMode = TIM_CounterMode_Up;     // set scale/period etc
    timerInit.TIM_Prescaler = 0;
    timerInit.TIM_Period = 36000000 / 44100 - 1;
    timerInit.TIM_ClockDivision = TIM_CKD_DIV1;
    timerInit.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM2, &timerInit);

    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);          // switch on TIMER2 update IRQs

    TIM_Cmd(TIM2, ENABLE);                              // start TIMER2

    while(1)
    {
    }
}
    
pregunta Charlie Skilbeck

1 respuesta

0

La respuesta es bastante simple. Su modelo MCU exacto carece del subsistema DAC. Este es un error que es fácil de cometer, porque no siempre es obvio. A los fabricantes les gusta presumir sobre las características.

Un DAC es menos común que un ADC en microcontroladores. Si no tiene un DAC explícito, a menudo puede usar un canal PWM como un DAC. Algunos microcontroladores tienen un PWM de alta velocidad solo para este propósito.

    
respondido por el pipe

Lea otras preguntas en las etiquetas