如题,小弟在探索者的开发板上采集一路频率为1K,上升/下降沿时间均为10uS,占空比可变的,幅度为5V的方波波形,因要求计算此方波的周期,频率,占空比,和上升下降时间,所以设成定时器2定时2uS产生溢出更新事件触发ADC,ADC总转换时间设为0.7uS(3+12个时钟周期,ADC时钟为21M),但是硬件搭好后调试,发现串口调试助手发回来的原始采集数据如图,从图中的数据分析,会不会是STM32根本就不能每1uS采集一次电压,如果要是能的话,根据参考手册中的说法,定时器溢出更新事件产生的上升沿触发ADC,此上升沿上升时间是多少呀,超没超出1uS?如果没超出,那可能是哪里的原因呢?望大侠指教。[mw_shl_code=c,true]#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "adc.h"
#include "timer.h"
int main(void)
{
u16 adcx;
float voltage_show;
Stm32_Clock_Init(336,8,2,7); //设置时钟,168Mhz
delay_init(168); //延时初始化
uart_init(84,115200); //初始化串口波特率为115200
ADC1_Init(); //初始化ADC1,单次转换时间60/84uS
delay_ms(2);
//设置单次溢出时间为2uS,
TIM2_Init(1,83); //初始化TIM2:1分频,84个计数个数
//设置ARR值时,此值要在计数个数的基础上减一,
//因为0也算一个数(参考手册中计数脉冲图)。
while(1)
{
adcx=Get_ADC1();
voltage_show=(float)adcx*(3.3/4096);
voltage_show=15-12*voltage_show;
printf("%d,V:%f
",adcx,voltage_show);
}
}[/mw_shl_code]
下面是ADC和TIM2的设置函数,[mw_shl_code=c,true]#include "adc.h"
//初始化ADC
//以 规则通道 的 不连续 采样模式设置 ADC1_CH5
//以 外部触发->定时器2_TRGO事件 触发ADC采样
void ADC1_Init(void)
{
//先初始化IO口
RCC->APB2ENR|=1<<8; //使能ADC1时钟
RCC->AHB1ENR|=1<<0; //使能PORTA时钟
GPIO_Set(GPIOA,PIN5,GPIO_MODE_AIN,0,0,GPIO_PUPD_NONE); // PA5模拟输入,不带上下拉电阻
RCC->APB2RSTR|=1<<8; //ADCs复位
RCC->APB2RSTR&=~(1<<8); //复位结束
ADC->CCR|=1<<16; //ADCPRE: ADC时钟 ADCCLK=PCLK2/4=84/4=21Mhz
//ADC挂载到APB2总线上,ADC时钟最好不要超过36Mhz
ADC1->CR1=0; //CR1设置清零
ADC1->CR2=0; //CR2设置清零
ADC1->CR1&=~(3<<24); //RES:12位分辨率模式,(15个时钟周期总转换时间)
//ADC1->CR1|=(1<<23); //AWDEN: 在 规则通道 上使能模拟看门狗
//ADC1->CR1|=(1<<9); //AWDSGL: 在 某单一通道 上使能模拟看门狗
//ADC1->CR1|=(1<<6); //AWDIE:使能 模拟看门狗中断
//ADC1->CR1|=(5<<0); //AWDCH:看门狗模拟通道选择:ADC1_CH5
ADC1->CR1&=~(7<<13); //DISCNUM:设置不连续采样模式下 每次触发 转换的通道数为1
ADC1->CR1|=1<<11; //DISCEN: 规则通道的不连续采样使能
ADC1->CR2&=~(1<<11); //ALIGN:右对齐
ADC1->CR2|=1<<28; //EXTEN:上升沿触发
ADC1->CR2|=6<<24; //EXTSEL:选择外部触发为定时器2 TRGO事件
//ADC1->CR2|=1<<10; //EOCS:设置规则通道 每 单次转换 完成EoC标志 置位;
ADC1->SQR1&=~(15<<20); //L:设置规则通道序列总数为1
ADC1->SQR3|=5<<0; //SQ1:设置规则序列第一次转换为通道5
//设置通道5的采样时间及通道5的看门狗阈值
ADC1->SMPR2=0; //所有通道采样时间清空
ADC1->SMPR2|=7<<(3*5); //SMP5:通道5采样时间:3个周期
//ADC1->HTR|=0xB4C; //通道5 看门狗高阈值 对应-13V
//ADC1->LTR|=0xd3; //通道5 看门狗低阈值 对应+13V
ADC1->CR2|=1<<0; //ADON: 开启AD转换器
}
//获得ADC值
//返回值:转换结果
u16 Get_ADC1(void)
{
while(!(ADC1->SR&(1<<1))); //等待转换结束
return ADC1->DR; //返回adc值同时硬件自动清除EoC标志位
}[/mw_shl_code]
[mw_shl_code=c,true]
#include "timer.h"
void TIM2_Init(u16 arr,u16 psc)
{
RCC->APB1ENR|=1<<0; //TIM2时钟使能
TIM2->ARR=arr; //设定计数器自动重装值
TIM2->PSC=psc; //预分频器
TIM2->CR1|=1<<7; //ARPE:设置TIM2_ARR寄存器为缓冲模式
TIM2->CR1&=~(3<<5); //CMS:选择计数模式为边沿模式(center-aligned mode selection)
TIM2->CR1&=~(1<<4); //DIR:选择计数方向为增加方向
TIM2->CR1|=1<<2; //URS: 设置只有计数器溢出才能产生更新
TIM2->CR1&=~(1<<1); //UDIS:使能 更新事件
TIM2->CR2|=2<<4; //MMS:定时器2配置为主模式,将 更新事件 作为触发输出
TIM2->CR1|=1<<0; //CEN:使能定时器2:
}
[/mw_shl_code]
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
大神,我按你说的改了程序,程序正常了,谢谢,好人一生平安。就是printf函数的事,
一周热门 更多>