使用的是STM32F103VCT6芯片
做了个简单的三角波D/A输出,用tim2做D/A触发,输出32个点的数据,D/A设置成DMA方式循环输出,同时打开了tim2中断做调试时候输出一个方波做观察用。试验中发现将tim2分频常数设置在36分频时候中断输出是1MHz,三角波输出是31.25KHz,这个是正确的。将tim2分频常数设置为18分频时候,中断输出方波频率还是1MHz(应该是2MHz),三角波输出是62.5KHz(三角波频率正确)。将tim2分频常数设置为9分频时候,中断输出方波频率是1.33MHz(应该是4MHz),三角波不输出了。
单独测试中断,与上面数据一致(关闭了三角波输出)
单独测试三角波(关闭了中断),tim2分频常数设置到9分频时候,输出125KHz(正确的),tim2分频常数设置到4分频时候,输出112KHz(不正确)。
系统时钟确定是72MHz,输出到PA8引脚示波器看到没有改变。请问是tim2的输入最大频率都限制吗?
主程序:
int main(void)
{
/*System Clocks Configuration */
RCC_Configuration(); //开启A、B、C、D、E、F端口时钟
//开启TIM1、TIM2时钟。开启DAC、SPI2时钟
//标注了
//RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
/*Configure the GPIO ports */
Power_config();
Backup_config();
GPIO_Configuration(); //设置I/O,
TIME_Configuration(); //设置定时器
DAC_Configuration(); //设置DAC
for (Idx = 0; Idx < 32; Idx++)
{
//DualSine12bit[Idx] = ((Sine12bit[Idx] << 16) + (Sine12bit[Idx])); //双通道输出正弦波
DualSine12bit2[Idx] =Sine12bit2[Idx]*1 ;
}
DMA2_Channel4->CMAR = (uint32_t)&DualSine12bit2[0];
DMA_Configuration(); //设置DMA
while (1)
{
}
定时器设置,用寄存器写的:
void TIME_Configuration(void)
{
//TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
//NVIC_InitTypeDef NVIC_InitStructure;
/*---------TIME1 setup--------*/
TIM1->CR1 = (uint16_t)0x0000;
TIM1->CR2 = (uint16_t)0x0000;
TIM1->SMCR = (uint16_t)0x0000;
TIM1->DIER = (uint16_t)0x0000;
TIM1->EGR = (uint16_t)0x0000;
TIM1->CCMR1 = (uint16_t)0x0000;
TIM1->CCMR2 = (uint16_t)0x0000;
TIM1->CCER = (uint16_t)0x0000;
TIM1->CNT = (uint16_t)0x0000;
/*---------TIME2 setup--------*/
TIM2->SR = (uint16_t)0x00;
TIM2->CR1 = (uint16_t)0x00;
TIM2->CR2 = (uint16_t)0x00;
TIM2->SMCR = (uint16_t)0x00;
TIM2->DIER = (uint16_t)0x00;
TIM2->EGR = (uint16_t)0x00;
TIM2->CCMR1 = (uint16_t)0x00;
TIM2->CCMR2 = (uint16_t)0x00;
TIM2->CCER = (uint16_t)0x00;
TIM2->CNT = (uint16_t)0x0000; //自计数器,计数100
TIM2->PSC = (uint16_t)0x04; //预分频器72分频
TIM2->ARR = (uint16_t)0x001; //自动重装载寄存器,计数1
//NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //TIM2中断
//NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级
//NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
//NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
TIM2->DIER |= TIM_DIER_UIE; //允许更新中断
//TIM2->CR2 |=TIM_DIER_TIE; //允许触发中断
TIM2->CR1 |= TIM_CR1_ARPE; //缓冲更新
TIM2->CR2 |= TIM_CR2_MMS_1; //更新产生TRGO
TIM2->CR1 |= TIM_CR1_CEN; //允许更新,向上计数,开始计数
/*-----------------------------*/
}
D/A设置程序:
void DAC_Configuration(void)
{
/* Setuo DAC1 CR */
DAC->CR = (uint32_t)0x00; //初始化DAC_CR寄存器
DAC->SWTRIGR = 0x00; //初始化DAC_SWTRIGR
/*-----------------------------*/
DAC->CR |= DAC_CR_TEN1; //DAC1使能触发
DAC->CR |= DAC_CR_TSEL1; //选择软件触发
DAC->CR |= DAC_CR_EN1; //使能DAC1
DAC->SWTRIGR |= DAC_SWTRIGR_SWTRIG1; //使能DAC1软件触发
/*----------------------------*/
DAC->CR |= DAC_CR_DMAEN2; //DAC通道2 DMA使能
DAC->CR |= DAC_CR_TEN2; //DAC2使能触发
DAC->CR |= DAC_CR_TSEL2_2; //TIM2 TRGO触发
DAC->CR |= DAC_CR_EN2; //使能DAC2
/*------------------------------*/
//DAC->CR |= (uint32_t)DAC_CR_WAVE2_1; //使能波形发生器
//DAC->CR |= (uint32_t)DAC_CR_MAMP2; //三角波幅值4095
/* Setuo DAC1 CR */
}
DMA设置程序:
void DMA_Configuration(void)
{
/* DMA Channal 1 setup */
DMA1->ISR = 0x00; //DMA中断状态寄存器
DMA1->IFCR = 0x00; //中断标志清除寄存器
DMA1_Channel1->CCR = 0x00; //
DMA1_Channel2->CCR = 0x00;
DMA1_Channel3->CCR = 0x00;
DMA1_Channel4->CCR = 0x00;
DMA1_Channel5->CCR = 0x00;
DMA1_Channel6->CCR = 0x00;
DMA1_Channel7->CCR = 0x00;
//-----------------------
DMA1_Channel1->CNDTR = 0x00;
DMA1_Channel2->CNDTR = 0x00;
DMA1_Channel3->CNDTR = 0x00;
DMA1_Channel4->CNDTR = 0x00;
DMA1_Channel5->CNDTR = 0x00;
DMA1_Channel6->CNDTR = 0x00;
DMA1_Channel7->CNDTR = 0x00;
//-----------------------
/* DMA Channal 2 setup */
DMA2->IFCR = 0x00; //清除通道中断标志
DMA2_Channel1->CCR = 0x00; //不使用DMA2的通道1
DMA2_Channel2->CCR = 0x00; //不使用DMA2的通道2
DMA2_Channel3->CCR = 0x00; //不使用DMA2的通道3
DMA2_Channel4->CCR = 0x00;; //初始化DMA2的通道4,
//作为锯齿波数据传输,DAC2触发
DMA2_Channel5->CCR = 0x00; //不使用DMA2的通道5
//-----------------------
DMA2_Channel1->CNDTR = 0x00;
DMA2_Channel2->CNDTR = 0x00;
DMA2_Channel3->CNDTR = 0x00;
DMA2_Channel4->CNDTR = 0x00; // sd //这个需要设置个数
DMA2_Channel5->CNDTR = 0x00;
//-----------------------
DMA2->IFCR = 0x0FFFFFFFF; //清除标识
DMA2->ISR = 0x00;
DMA2_Channel4->CCR |= (uint32_t)DMA_CCR4_PL; //DMA2通道优先级最高
DMA2_Channel4->CCR |= (uint32_t)DMA_CCR4_MSIZE_0; //存储数据宽度16位
DMA2_Channel4->CCR |= (uint32_t)DMA_CCR4_PSIZE_0; //外设数据宽度16位
DMA2_Channel4->CCR |= (uint32_t)DMA_CCR4_MINC; //执行存储器地址增量,
//不执行外设地址增量
DMA2_Channel4->CCR |= (uint32_t)DMA_CCR4_CIRC; //执行循环操作
DMA2_Channel4->CCR |= (uint32_t)DMA_CCR4_DIR; //从存储器读
DMA2_Channel4->CPAR = (uint32_t)DAC_DHR12R2_Address; //外设地址
DMA2_Channel4->CNDTR= (uint32_t)0x20; //DMA2数据传输量32字节
DMA2_Channel4->CCR |= (uint32_t)DMA_CCR4_EN; //通道开启
}
定时器2中断:
void TIM2_IRQHandler(void)
{
GPIOC->ODR |= GPIO_ODR_ODR9;
TIM2->SR = (uint16_t)0x00;
GPIOC->ODR &= ~GPIO_ODR_ODR9;
} |