实战2中,我们已经通过串口下发AD9833设置值并在物理示波器中 显示,实现了信号的频率,波形,相位,幅度的下发设置,本章我们就通过stm32的 adc直接读取AD9833的输出波形并在上位机中电脑上显示(模拟示波器)。
文章后 有上位机和stm32下位机代码下载
通过网盘分享的文件:AD9833频率发生器2.rar
链接: https://pan.baidu.com/s/1_NyU98gu0I0JdHslrwg0mQ 提取码: abcd
AD9833的输出接 stm32的PA0和GND
stm32 main.c 示例 (完整代码请自行下载)
#include "AD9833.h"
#include "STM32F103C8T6_ADC.H"
uint16_t adc_arry[10] = {0}; //采集到的波形数据
int main(void)
{
AD9833_Init_GPIO(); //AD9833 GPIO 初始化
ADC1_Init();
}
while(1)
{
adc_arry[0] = 0;
adc_arry[0] = Get_ADC1_Average(ADC_Channel_0,5);
//adc_arry[0]= Get_ADC1(ADC_Channel_0);
raw_data[0]= c1;
raw_data[1]= c2;
raw_data[2]= c3;
raw_data[3]= c4;
raw_data[4]= adc_arry[0]; //波形图
raw_data[5]= c6;
raw_data[6]=128; //校验位 固定值128
encode(raw_data, encode_data);
// USART1_SendData(':');
// USART1_printf( USART1,encode_data[ENCODE_DATA_SIZE] );
for(int i=0;i<22;i++) USART1_SendData(encode_data[i]); //输出到串口 52
USART1->SR =0x1F;
USART1_SendData(0X0D); //??
}
ADC 定义 STM32F103C8T6_ADC .C
/*=======================================================================================================
// 文件功能:STM32F103C8T6的ADC采集
// 文件说明:1、12位逐次逼近型的模拟数字转换器,分辨率4096
// 2、ADC输入范围:VREF- ≤ VIN ≤ VREF+
// 文件类型:
//-------------------------------------------------------------------------------------------------------
// 硬件平台:STM32F103C8T6
// 软件平台:KEIL5 MDK
//-------------------------------------------------------------------------------------------------------
// 开发组织:
// 开发作者:冯奇
// 官方商城:
//-------------------------------------------------------------------------------------------------------
// 微信平台:
// 产品链接:
// 版权信息:
//-------------------------------------------------------------------------------------------------------
// 更新时间:2018-08-17
=========================================================================================================*/
#include "stm32f10x.h"
#include "stm32f103c8t6_adc.h"
#include "delay.h"
//====================================硬件端口定义========================================================
//采用ADC1
#define ADC1_CLK RCC_APB2Periph_ADC1 //ADC时钟
//PA1作为模拟通道输入引脚
#define ADC_GPIO_CLK RCC_APB2Periph_GPIOA //ADC端口时钟
#define ADC_GPIO_PORT GPIOA //ADC端口
#define ADC_GPIO_PIN0 GPIO_Pin_0 //ADC引脚号
#define ADC_GPIO_PIN1 GPIO_Pin_1
#define ADC_GPIO_PIN2 GPIO_Pin_2 //ADC引脚号
#define ADC_GPIO_PIN3 GPIO_Pin_3
#define ADC_GPIO_PIN4 GPIO_Pin_4
#define ADC_GPIO_PIN5 GPIO_Pin_5
//======================================================================================================
// 函数功能:初始化ADC1
// 函数标记:应用函数
// 函数说明:ADC1:PA0,PA1,PA2,PA3,PA4,PA5,PA6,PA7,PB0,PB1,PC0,PC1,PC2,PC3,PC4,PC5,温度传感器,内部参照电压
// ADC2:PA0,PA1,PA2,PA3,PA4,PA5,PA6,PA7,PB0,PB1,PC0,PC1,PC2,PC3,PC4,PC5
// ADC3:PA0,PA1,PA2,PA3,PF6,PF7,PF8,PF9,PF10,PC0,PC1,PC2,PC3
//
// 例如:采样时间:ADCCLK = 14MHZ,采样周期为1.5周期。
// Tconv = 1.5+12.5 = 14周期=1us
//------------------------------------------------------------------------------------------------------
// 输入参量:无
// 输出参量:无
//======================================================================================================
void ADC1_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(ADC_GPIO_CLK|ADC1_CLK,ENABLE ); //使能ADC1通道时钟
//模拟通道输入引脚配置
GPIO_InitStructure.GPIO_Pin = ADC_GPIO_PIN1 | ADC_GPIO_PIN0 | ADC_GPIO_PIN2 | ADC_GPIO_PIN3 | \
ADC_GPIO_PIN4 | ADC_GPIO_PIN5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
GPIO_Init(ADC_GPIO_PORT, &GPIO_InitStructure);
}
void ADC1_Init(void)
{
ADC1_GPIO_Init();
ADC_InitTypeDef ADC_InitStructure;
//设置ADC分频因子,72M/6=12MHZ,ADC最大时间不能超过14M
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
//复位ADC1
ADC_DeInit(ADC1);
//ADC1配置
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //模数转换工作在单通道模式
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //模数转换工作在单次转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件触发启动
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道的数目
ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
ADC_Cmd(ADC1, ENABLE); //使能ADC1
ADC_ResetCalibration(ADC1); //使能复位校准
while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束
ADC_StartCalibration(ADC1); //开启AD校准
while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束
}
//======================================================================================================
// 函数功能:获得ADC值
// 函数标记:应用函数
// 函数说明:
//------------------------------------------------------------------------------------------------------
// 输入参量:ch:ADC通道值,ADC1共有18个通道。ADC通道与引脚对应关系,如下:
// ch ADC1 ADC2 ADC3
// ADC_Channel_0 PA0 PAO PAO
// ADC_Channel_1 PA1 PA1 PA1
// ADC_Channel_2 PA2 PA2 PA2
// ADC_Channel_3 PA3 PA3 PA3
// ADC_Channel_4 PA4 PA4 PF6
// ADC_Channel_5 PA5 PA5 PF7
// ADC_Channel_6 PA6 PA6 PF8
// ADC_Channel_7 PA7 PA7 PF9
// ADC_Channel_8 PB0 PB0 PF10
// ADC_Channel_9 PB1 PB1
// ADC_Channel_10 PC0 PCO PCO
// ADC_Channel_11 PC1 PC1 PC1
// ADC_Channel_12 PC2 PC2 PC2
// ADC_Channel_13 PC3 PC3 PC3
// ADC_Channel_14 PC4 PC4
// ADC_Channel_15 PC5 PC5
// ADC_Channel_16 温度传感器
// ADC_Channel_17 内部参照电压
// 输出参量:无
//======================================================================================================
u16 Get_ADC1(u8 ch)
{
//设置ADC1的规则组通道,序列,采样时间
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_7Cycles5 );//采样周期为7.5周期
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC )); //等待转换结束
return ADC_GetConversionValue(ADC1); //返回最近一次ADC1规则组的转换结果
}
//======================================================================================================
// 函数功能:获得ADC的平均值
// 函数标记:应用函数
// 函数说明:ADC的平均值比较准确的反应ADC的值
//------------------------------------------------------------------------------------------------------
// 输入参量:ch:通道值
// time:采集次数
// 输出参量:无
//======================================================================================================
u16 Get_ADC1_Average(u8 ch,u8 times)
{
u32 temp_val=0;
u8 t;
for(t=0;t<times;t++)
{
temp_val+=Get_ADC1(ch);
}
return temp_val/times;
}
ADC 定义 STM32F103C8T6_ADC .h
#ifndef _STM32F103C8T6_ADC_H
#define _STM32F103C8T6_ADC_H
void ADC1_Init(void);
u16 Get_ADC1(u8 ch);
u16 Get_ADC1_Average(u8 ch,u8 times);
#endif