stm32 Tim1定時出發adc采集


其中配置代碼如下:

void ADC1_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  ADC_InitTypeDef ADC_InitStructure;
  DMA_InitTypeDef DMA_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;

  RCC_ADCCLKConfig(RCC_PCLK2_Div6);//72M/6=12,ADC最大時鍾不能超過14M
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_ADC1,ENABLE);
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);
  /* Configure ADCCLK such as ADCCLK = PCLK2/6 */

  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 9;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//AIN3
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  DMA_DeInit(DMA1_Channel1);
  DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->DR;//DMA外設ADC基地址
  DMA_InitStructure.DMA_MemoryBaseAddr     = (u32)Adc1DMAValue;//DMA內存基地址
  DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralSRC;//內存作為數據傳輸的目的地
  DMA_InitStructure.DMA_BufferSize         = 90;//DMA通道的DMA緩存的大小
  DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;//外設地址寄存器不變
  DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable;//內存地址寄存器遞增
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//數據寬度為16位
  DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_HalfWord;//數據寬度為16位
  DMA_InitStructure.DMA_Mode               = DMA_Mode_Circular;//工作在循環緩存模式
  DMA_InitStructure.DMA_Priority           = DMA_Priority_High;//DMA通道x擁有高優先級
  DMA_InitStructure.DMA_M2M                = DMA_M2M_Disable;//DMA通道x沒有設置為內存到內存傳輸
  DMA_Init(DMA1_Channel1, &DMA_InitStructure);
  DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);
  DMA_Cmd(DMA1_Channel1, ENABLE);

  /* ADC1 configuration ------------------------------------------------------*/
  ADC_DeInit(ADC1);
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//ADC工作模式:ADC1工作在獨立模式
  ADC_InitStructure.ADC_ScanConvMode = ENABLE;//模數轉換工作在多通道模式
  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//DISABLE;//模數轉換工作在單次轉換模式
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;//轉換由軟件而不是外部觸發啟動
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//ADC數據右對齊
  ADC_InitStructure.ADC_NbrOfChannel = 3;//順序進行規則轉換的ADC通道的數目
  ADC_Init(ADC1, &ADC_InitStructure);

  for(uint8 i=1; i<4; i++)
    ADC_RegularChannelConfig(ADC1,ADC_Channel_13, i, ADC_SampleTime_239Cycles5);//前面5路外置溫度


#if 0
  /* ADC1 regular channel16 configuration */
  ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_239Cycles5);//ADC1,ADC通道16,規則采樣順序值為1,采樣時間為239.5周期
  /* Enable the temperature sensor and vref internal channel */
  ADC_TempSensorVrefintCmd(ENABLE);
#endif

  ADC_DMACmd(ADC1, ENABLE);
  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);

  /* Enable ADC1 reset calibaration register */
  ADC_ResetCalibration(ADC1);//重置指定的ADC1的校准寄存器
  /* Check the end of ADC1 reset calibration register */
  while(ADC_GetResetCalibrationStatus(ADC1));//獲取ADC1重置校准寄存器的狀態,設置狀態則等待
  /* Start ADC1 calibaration */
  ADC_StartCalibration(ADC1);//開始指定ADC1的校准狀態
  /* Check the end of ADC1 calibration */
  while(ADC_GetCalibrationStatus(ADC1));//獲取指定ADC1的校准程序,設置狀態則等待

  /* Start ADC1 Software Conversion */
  ADC_SoftwareStartConvCmd(ADC1, ENABLE);//使能指定的ADC1的軟件轉換啟動功能
}

 


/* 觸發的定時器配置:*/

void TIM1_Configuration(void)
{
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  TIM_OCInitTypeDef  TIM_OCInitStructure;
  //GPIO_InitTypeDef GPIO_InitStructure;
 
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);    //使能定時器3時鍾
 // RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);  //使能GPIO外設
 /*Pin for TIM1 channel configuration*/
  /*GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;//TIM1-CH1
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);*/
 
  TIM_DeInit(TIM1);  
 
  TIM_TimeBaseStructure.TIM_Period =400;//50us
  TIM_TimeBaseStructure.TIM_Prescaler = 8;//36分頻
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;//72M
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  //TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
  TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
 
  /* PWM1 模式配置: Channel3 Channel4*/
  TIM_OCStructInit(&TIM_OCInitStructure);
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//選擇輸出比較狀態
  TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;//選擇互補輸出比較狀態
 
  TIM_OCInitStructure.TIM_Pulse = 333;
  TIM_OC1Init(TIM1, &TIM_OCInitStructure);//根據TIM_OCInitStruct中指定的參數初始化外設TIMx
  TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);//使能TIMx在CCR3上的預裝載寄存器
  TIM_CtrlPWMOutputs(TIM1, ENABLE); 
}

正常使用,出現的情況是我在TIM1配置PWM觸發的adc采集的IO口管腳TIM1_CH1正好與SPI2的管腳處在的管腳TIM1_CH1N 一起,所以就需要把TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;改為Disable,奇怪的事情就出現了,我在用USART1進行的通信任務,怎么也不能按之前正常一樣進行,總是接收不到完成的信息。

 

void Usart1Init( void )
{
  GPIO_InitTypeDef GPIO_InitStructure;
  USART_InitTypeDef USART_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
  DMA_InitTypeDef DMA_InitStructure;
 
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);    //使能DMA傳輸
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能GPIOA時鍾
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART2時鍾
 
 
  DMA_DeInit(DMA1_Channel4);   //將DMA的通道1寄存器重設為缺省值
  DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART1->DR;//DMA外設ADC基地址
  DMA_InitStructure.DMA_MemoryBaseAddr     = (u32)g_rev_usart1.auch_send_buffer;//DMA內存基地址
  DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralDST;//內存作為數據傳輸的目的地
  //DMA_InitStructure.DMA_BufferSize         = 10;//DMA通道的DMA緩存的大小
  DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;//外設地址寄存器不變
  DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable;//內存地址寄存器遞增
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//數據寬度為16位
  DMA_InitStructure.DMA_MemoryDataSize     = DMA_PeripheralDataSize_Byte;//數據寬度為16位
  DMA_InitStructure.DMA_Mode               = DMA_Mode_Normal;//工作在非循環模式,發送完指定長度數據即停止
  DMA_InitStructure.DMA_Priority           = DMA_Priority_Medium;//DMA通道x擁有高優先級
  DMA_InitStructure.DMA_M2M                = DMA_M2M_Disable;//DMA通道x沒有設置為內存到內存傳輸
  DMA_Init(DMA1_Channel4, &DMA_InitStructure);
 
  DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE);
 
  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 6;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;    //
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    //復用推挽
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;    //
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(GPIOA, &GPIO_InitStructure);  
 
//  RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1,ENABLE);//復位串口3
//  RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1,DISABLE);//停止復位
    
  USART_DeInit(USART1);
  USART_InitStructure.USART_BaudRate = 115200;//波特率設置
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8位數據長度
  USART_InitStructure.USART_StopBits = USART_StopBits_1;//一個停止位
  USART_InitStructure.USART_Parity = USART_Parity_No;///奇偶校驗位
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無硬件數據流控制
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收發模式
 
  USART_Init(USART1, &USART_InitStructure);//初始化串口
 
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 8;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
 
  USART_Cmd(USART1, ENABLE);                    //使能串口
  USART_ClearFlag(USART1 , USART_FLAG_TC);
}

查看USART管腳和SPI2管腳,並沒有什么聯系沖突呀,唯一有聯系的是USART1的tx和rx也是TIM1_CH2,TIM1_CH3,SPI2的MISO和MOSI也是TIM1_CH1N,TIM1_CH2N.除非定時器配置錯了讓兩者有聯系,所以這里又把TIM1的四個管腳給配置成TIM1_CH1為AF_PP模式,其他的為普通未設置,TM1_CH1N為Disable,還是不行

折騰了很久於是沒辦法把板子擦除重新燒了次程序,竟然所有任務都運行正常了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM