通过C#上位机串口写入和读取浮点数到stm32的片内flash实战4(通过串口下发AD9833设置值并在上位机显示波形曲线)
实战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; //校验位 固定值128encode(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]); //输出到串口 52USART1->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最大时间不能超过14MRCC_ADCCLKConfig(RCC_PCLK2_Div6);//复位ADC1ADC_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); //使能ADC1ADC_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