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)
{
}
}