OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 10320|回复: 4

STM32F107的ADC预分频器问题

[复制链接]

1

主题

3

帖子

0

精华

新手入门

积分
27
金钱
27
注册时间
2012-10-16
在线时间
0 小时
发表于 2012-10-18 09:59:36 | 显示全部楼层 |阅读模式
我目前在用神舟四号开发板学习
随盘附带的示例程序8ADC模数转换中貌似并没有对ADC预分频数进行设置,程序也能运行
请高人指点这时的ADCCLK是多少呢?
我如果想改这个预分频数要怎么改?


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

3

帖子

0

精华

新手入门

积分
27
金钱
27
注册时间
2012-10-16
在线时间
0 小时
 楼主| 发表于 2012-10-18 10:00:49 | 显示全部楼层
以下是main.c的内容

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "stm32_eval.h"
#include "stm32f10x_adc.h"
#include "stm32f10x_dma.h"
#include <stdio.h>

/** @addtogroup STM32F10x_StdPeriph_Examples
  * @{
  */

/** @addtogroup USART_Printf
  * @{
  */ 

/* rivate typedef -----------------------------------------------------------*/
/* rivate define ------------------------------------------------------------*/
#define ADC1_DR_Address    ((uint32_t)0x4001244C)  //ADC1 DR寄存器基地址
/* rivate macro -------------------------------------------------------------*/
/* rivate variables ---------------------------------------------------------*/
USART_InitTypeDef USART_InitStructure;  //串口初始化结构体声明
ADC_InitTypeDef ADC_InitStructure;      //ADC初始化结构体声明
DMA_InitTypeDef DMA_InitStructure;      //DMA初始化结构体声明
// 注:ADC为12位模数转换器,只有ADCConvertedValue的低12位有效
__IO uint16_t ADCConvertedValue;

/* rivate function prototypes -----------------------------------------------*/
void ADC_GPIO_Configuration(void);

#ifdef __GNUC__
  /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
     set to 'Yes') calls __io_putchar() */
  #define UTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define UTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
  
/* rivate functions ---------------------------------------------------------*/
static void Delay_ARMJISHU(__IO uint32_t nCount)
{
  for (; nCount != 0; nCount--);
}

/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
int main(void)
{
  /*!< At this stage the microcontroller clock setting is already configured, 
       this is done through SystemInit() function which is called from startup
       file (startup_stm32f10x_xx.s) before to branch to application main.
       To reconfigure the default setting of SystemInit() function, refer to
       system_stm32f10x.c file
     */     
     
  u16 ADCConvertedValueLocal, recent = 0, Voltage = 0;
  
  /* USARTx configured as follow:
        - BaudRate = 115200 baud  
        - Word Length = 8 Bits
        - One Stop Bit
        - No parity
        - Hardware flow control disabled (RTS and CTS signals)
        - Receive and transmit enabled
  */
  USART_InitStructure.USART_BaudRate = 115200;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  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;

  STM_EVAL_COMInit(COM1, &USART_InitStructure);

  /* Output a message on Hyperterminal using printf function */
  printf("\n\r\n\r\n\r\n\r");
  printf("\n\rUSART rintf Example: retarget the C library printf function to the USART\n\r");
  printf("\r\n\n\n WWW.ARMJISHU.COM  %s configured....", EVAL_COM1_STR);
  printf("\n\r ############ WWW.ARMJISHU.COM! ############ ("__DATE__ " - " __TIME__ ")");
  printf("\n\r www.armjishu.com论坛后续还会有更多精彩的示例,欢迎访问论坛交流与学习."); 
  printf("\n\r 本示例为AD转换示例,串口输出转换结果,模拟信号来自板上的电位器! \n\r");
  printf("\n\r==============================================================================");
  printf("\n\r");
  
  ADC_GPIO_Configuration();
  
  /* Enable DMA1 clock */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
 
  /* DMA1 channel1 configuration ----------------------------------------------*/
  DMA_DeInit(DMA1_Channel1);
  DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;    //DMA对应的外设基地址
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADCConvertedValue;   //内存存储基地址
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //DMA的转换模式为SRC模式,由外设搬移到内存
  DMA_InitStructure.DMA_BufferSize = 1;    //DMA缓存大小,1个,单位为DMA_MemoryDataSize
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //接收一次数据后,设备地址禁止后移
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; //关闭接收一次数据后,目标内存地址后移
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;  //定义外设数据宽度为16位
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;  //DMA搬数据尺寸,HalfWord就是为16位
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;   //转换模式,循环缓存模式。
  DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA优先级高
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;   //M2M模式禁用
  DMA_Init(DMA1_Channel1, &DMA_InitStructure);          
  
  /* Enable DMA1 channel1 */
  DMA_Cmd(DMA1_Channel1, ENABLE);

  /* Enable ADC1 and GPIOC clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE);
  
  /* ADC1 configuration ------------------------------------------------------*/
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;  //独立的转换模式
  ADC_InitStructure.ADC_ScanConvMode = ENABLE;   //开启扫描模式
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;   //开启连续转换模式
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //ADC外部开关,关闭状态
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;   //对齐方式,ADC为12位中,右对齐方式
  ADC_InitStructure.ADC_NbrOfChannel = 1;  //开启通道数,1个
  ADC_Init(ADC1, &ADC_InitStructure);

  /* ADC1 regular channel10 configuration ADC通道组, 第10个通道 采样顺序1,转换时间 */ 
  ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_55Cycles5);

  /* Enable ADC1 DMA */
  ADC_DMACmd(ADC1, ENABLE);   //ADC命令,使能
  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);  //开启ADC1
  
  /* Enable ADC1 reset calibaration register */   
  ADC_ResetCalibration(ADC1);   //重新校准
  /* Check the end of ADC1 reset calibration register */
  while(ADC_GetResetCalibrationStatus(ADC1));  //等待重新校准完成
  /* Start ADC1 calibaration */
  ADC_StartCalibration(ADC1); //开始校准
  /* Check the end of ADC1 calibration */
  while(ADC_GetCalibrationStatus(ADC1));    //等待校准完成
  /* Start ADC1 Software Conversion */ 
  ADC_SoftwareStartConvCmd(ADC1, ENABLE); //连续转换开始,ADC通过DMA方式不断的更新RAM区。

  while (1)
  {
    ADCConvertedValueLocal = ADCConvertedValue;
    Precent = (ADCConvertedValueLocal*100/0x1000); //算出百分比
    Voltage = Precent*33;   // 3.3V的电平,计算等效电平
    printf("\r\n ARMJISHU.COM ADCConvertedValue is 0x%X, Precent is %d%%, Voltage is %d.%d%dV", 
        ADCConvertedValueLocal, Precent, Voltage/1000, (Voltage%1000)/100, (Voltage%100)/10);
    printf("\r\n ARMJISHU.COM 当前AD转换结果为:0x%X, 百分比为:%d%%,电压值:%d.%d%dV.\n\r", 
        ADCConvertedValueLocal, Precent, Voltage/1000, (Voltage%1000)/100, (Voltage%100)/10);
    Delay_ARMJISHU(8000000);
  }
}

/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
PUTCHAR_PROTOTYPE
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the USART */
  USART_SendData(EVAL_COM1, (uint8_t) ch);

  /* Loop until the end of transmission */
  while (USART_GetFlagStatus(EVAL_COM1, USART_FLAG_TC) == RESET)
  {}

  return ch;
}

#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)

  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

/**
  * @brief  Configures the different GPIO ports.
  * @param  None
  * @retval None
  */
void ADC_GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  /* Configure PC.00 (ADC Channel10) as analog input -------------------------*/
  //PC0 作为模拟通道10输入引脚                         
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
}
回复 支持 反对

使用道具 举报

5

主题

166

帖子

2

精华

高级会员

Rank: 4

积分
506
金钱
506
注册时间
2012-10-8
在线时间
0 小时
发表于 2012-10-18 11:41:13 | 显示全部楼层
假设你设置的主频是72M,其它主频情况一样

  HCLK = SYSCLK = 72M
  PCLK2 = HCLK  = 72M

位15:14 ADCPRE:ADC预分频
由软件设置来确定ADC时钟频率
00:PCLK2 2分频后作为ADC时钟      //默认设置是2分频  ADCCLK = 72M/2 = 36M
01:PCLK2 4分频后作为ADC时钟
10:PCLK2 6分频后作为ADC时钟
11:PCLK2 8分频后作为ADC时钟

总转换时间如下计算:
TCONV = 采样时间+ 12.5 个周期
例如:
当ADCCLK=36MHz 和设置的是1.5 周期的采样时间
TCONV = ADCCLK  /(1.5 + 12.5 )= 0.388us   //采样率也就是2.57M

你的程序里面设置的是55.5采用时间,自己可以计算下采样频率。
还有就是实际的超频到1.5M就差不多了,再超没有意义。
两个ADC快速交替采样也就是超到3.15M。

回复 支持 反对

使用道具 举报

5

主题

166

帖子

2

精华

高级会员

Rank: 4

积分
506
金钱
506
注册时间
2012-10-8
在线时间
0 小时
发表于 2012-10-18 11:42:52 | 显示全部楼层

 设置分频
 /* ADCCLK = CLK2/4 */
RCC_ADCCLKConfig(RCC_PCLK2_Div4); 
回复 支持 反对

使用道具 举报

1

主题

3

帖子

0

精华

新手入门

积分
27
金钱
27
注册时间
2012-10-16
在线时间
0 小时
 楼主| 发表于 2012-10-19 18:08:26 | 显示全部楼层
回复【4楼】Eric2013:
---------------------------------
thank you!就是要这条函数啊
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-28 11:38

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表