打印
[STM32L0]

tim2计数频率到8MHz时候出现问题

[复制链接]
930|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lizhongzhi|  楼主 | 2017-2-24 15:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
hz, TI, DM, DMA, AC
使用的是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;
}
沙发
airwill| | 2017-2-24 21:30 | 只看该作者
Tim2 最高频率是 36Mhz。
我怀疑 Tim 的分频是对的, 但是你的中断服务需要时间太长,来不及响应所有中断而导致了见到的定时器频率错误

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

7

帖子

1

粉丝