stm32单片机16路ad采集信号上位机查看全部波形(下位机部分)

有时候需要对单片机采集到多路信号进行一个直观的查看,这时候我们发现一般的串口助手都无法实现,这时候我在github上找了找,找到了一个开源工具,不过还是要在单片机下位机程序和和上位机上使用同一套通讯协议的,幸好源码也给出了stm32的一个源文件,这里我都放到我的空间里了,https://download.csdn.net/download/leva345/81848187,大家可以下载,上位机用管理员权限打开。
打开我们的文件夹,可以看到以下几个文件:
在这里插入图片描述
下位机里里有我们的stm32源文件,在这里插入图片描述

可以在这里照着我的步骤添加,也可以直接使用编辑好的,在我的空间也有https://download.csdn.net/download/leva345/81848500
以stm32单片机为例:
1、添头文件和c文件;在user文件夹添加我们的
在这里插入图片描述

结果图
在这里插入图片描述
要把头文件的路径添加进去。具体到文件夹中。
在这里插入图片描述

具体代码
main.c

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"	 
#include "adc.h"
#include "DataScope_DP.h" 


 
 int main(void)
 {	 
  //u16 adcx;
	//int i = 0;
	//float temp;
	delay_init();	    	 //延时函数初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
	uart_init(115200);	 	//串口初始化为115200
 	LED_Init();			     //LED端口初始化
	LCD_Init();			 	
 	Adc_Init();		  		//ADC初始化
  ADC_SoftwareStartConvCmd(ADC1, ENABLE);		//使能指定的ADC1的软件转换启动功能
  DMA_Cmd(DMA1_Channel1,ENABLE);
	while(1)
	{
		
		ocs10_display(ADC_Value[0],ADC_Value[1],ADC_Value[2],ADC_Value[3],ADC_Value[4],ADC_Value[5],ADC_Value[6],ADC_Value[7],ADC_Value[8],ADC_Value[9]);
		
		
//		adcx=Get_Adc_Average(ADC_Channel_1,10);
//		temp=(float)adcx*(3.3/4096)*1000;
//    printf("%f\t",temp);
//		delay_ms(250);
    //ADC1->DR = 20; 
		
	//	temp = ADC_Value[13]*(3.3/4.096);
		
	//	printf("%d\r\n",(int)(ADC_Value[13]*(1000*3.3/4096)));// PA2
	//	printf("%d\r\n",(int)(ADC_Value[13]));// PA2
	//	printf("$%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d;",(int)(ADC_Value[0]),(int)(ADC_Value[1]),(int)(ADC_Value[2]),(int)(ADC_Value[3]),(int)(ADC_Value[4]),(int)(ADC_Value[5]),(int)(ADC_Value[6]),(int)(ADC_Value[7]),(int)(ADC_Value[8]),(int)(ADC_Value[9]),(int)(ADC_Value[10]),(int)(ADC_Value[11]),(int)(ADC_Value[12]),(int)(ADC_Value[13]),(int)(ADC_Value[14]),(int)(ADC_Value[15]));	
		
		
		
	//	printf("13: %f\t",temp);
		delay_ms(10);
	//	printf("\n");
		
//		for(i = 0;i<16;i++)
//		{
//			temp = ADC_Value[i]*(3.3/4.096);
//			printf("%d: %f\t",i,temp);
//			delay_ms(10);
//		}
    
	}
 }


#include "stm32f10x.h" 
#include "DataScope_DP.h"
#include "usart.h"
#include "stm32f10x_usart.h"
#include "delay.h"
 
unsigned char DataScope_OutPut_Buffer[42] = {0};	   //串口发送缓冲区


//函数说明:将单精度浮点数据转成4字节数据并存入指定地址 
//附加说明:用户无需直接操作此函数 
//target:目标单精度数据
//buf:待写入数组
//beg:指定从数组第几个元素开始写入
//函数无返回 
void Float2Byte(float *target,unsigned char *buf,unsigned char beg)
{
    unsigned char *point;
    point = (unsigned char*)target;	  //得到float的地址
    buf[beg]   = point[0];
    buf[beg+1] = point[1];
    buf[beg+2] = point[2];
    buf[beg+3] = point[3];
}
 
 
//函数说明:将待发送通道的单精度浮点数据写入发送缓冲区
//Data:通道数据
//Channel:选择通道(1-10)
//函数无返回 
void DataScope_Get_Channel_Data(float Data,unsigned char Channel)
{
//  if ( (Channel > 10) || (Channel == 0) ) return ;  //通道个数大于10或等于0,直接跳出,不执行函数
//  else
//  {
     switch (Channel)
		{
          case 1:  Float2Byte(&Data,DataScope_OutPut_Buffer,1); break;
          case 2:  Float2Byte(&Data,DataScope_OutPut_Buffer,5); break;
		  case 3:  Float2Byte(&Data,DataScope_OutPut_Buffer,9); break;
		  case 4:  Float2Byte(&Data,DataScope_OutPut_Buffer,13); break;
		  case 5:  Float2Byte(&Data,DataScope_OutPut_Buffer,17); break;
		  case 6:  Float2Byte(&Data,DataScope_OutPut_Buffer,21); break;
		  case 7:  Float2Byte(&Data,DataScope_OutPut_Buffer,25); break;
		  case 8:  Float2Byte(&Data,DataScope_OutPut_Buffer,29); break;
		  case 9:  Float2Byte(&Data,DataScope_OutPut_Buffer,33); break;
		  case 10: Float2Byte(&Data,DataScope_OutPut_Buffer,37); break;
			
		}
  //}	 
}
**DataScoDP.c**

//函数说明:生成 DataScopeV1.0 能正确识别的帧格式
//Channel_Number,需要发送的通道个数
//返回发送缓冲区数据个数
//返回0表示帧格式生成失败 
u8 DataScope_Data_Generate(unsigned char Channel_Number)
{
	u8 ret_num;
	if ( (Channel_Number > 10) || (Channel_Number == 0) ) 
  { 
     return 0; 
  }  //通道个数大于10或等于0,直接跳出,不执行函数
  else
  {	
	 DataScope_OutPut_Buffer[0] = '$';  //帧头
		
	 switch(Channel_Number)   
     { 
		 case 1:   DataScope_OutPut_Buffer[5]  =  5;  ret_num=6;  break;  
		 case 2:   DataScope_OutPut_Buffer[9]  =  9;  ret_num=10;  break;
		 case 3:   DataScope_OutPut_Buffer[13] = 13;  ret_num=14;  break;
		 case 4:   DataScope_OutPut_Buffer[17] = 17;  ret_num=18;  break;
		 case 5:   DataScope_OutPut_Buffer[21] = 21;  ret_num=22;  break; 
		 case 6:   DataScope_OutPut_Buffer[25] = 25;  ret_num=26;  break;
		 case 7:   DataScope_OutPut_Buffer[29] = 29;  ret_num=30;  break;
		 case 8:   DataScope_OutPut_Buffer[33] = 33;  ret_num=34;  break;
		 case 9:   DataScope_OutPut_Buffer[37] = 37;  ret_num=38;  break;
         case 10:  DataScope_OutPut_Buffer[41] = 41;  ret_num=42;  break;
		 default: ret_num=0; break;
     }
	 return ret_num;	 
  }
//	return 0;
}


void ocs10_display(float CH1,float CH2,float CH3,float CH4,float CH5,float CH6,float CH7,float CH8,float CH9,float CH10)
{  
	   u8 i,Send_Count;

	   DataScope_Get_Channel_Data( CH1 , 1 ); //将数据 1.0  写入通道 1
       DataScope_Get_Channel_Data( CH2 , 2 ); //将数据 2.0  写入通道 2
       DataScope_Get_Channel_Data( CH3 , 3 ); //将数据 3.0  写入通道 3
       DataScope_Get_Channel_Data( CH4 , 4 ); //将数据 4.0  写入通道 4
 	   DataScope_Get_Channel_Data( CH5 , 5 ); //将数据 5.0  写入通道 5
       DataScope_Get_Channel_Data( CH6 , 6 ); //将数据 6.0  写入通道 6
 	   DataScope_Get_Channel_Data( CH7 , 7 ); //将数据 7.0  写入通道 7
       DataScope_Get_Channel_Data( CH8 , 8 ); //将数据 8.0  写入通道 8
 	   DataScope_Get_Channel_Data( CH9 , 9 ); //将数据 9.0  写入通道 9
       DataScope_Get_Channel_Data( CH10 , 10); //将数据 10.0 写入通道 10
	   Send_Count = DataScope_Data_Generate(10); //生成10个通道的 格式化帧数据,返回帧数据长度
	   
	   for( i = 0 ; i < Send_Count; i++)  //循环发送,直到发送完毕   
	 	  {
		      USART_SendData(USART1, DataScope_OutPut_Buffer[i]);

             /* Loop until the end of transmission */
          while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
          {}  
		  }
  
	   delay_ms(10);
}

接线方式:用的ADC1,通道0-15,一共16个通道。
在这里插入图片描述
adc代码

#include "adc.h"
 #include "delay.h"
 
/*
16路ADC采样DMA传输
调用Adc_Init()函数初始化设备,ADC循环采样 
数据被DMA搬运到ADC_Value[ADC_CH_NUM]数组中
滤波后的数据在ADC_AfterFilter[ADC_CH_NUM]中
*/
	   		   	

u16 ADC_Value[ADC_CH_NUM] = {0};					
u16 ADC_AfterFilter[ADC_CH_NUM] = {0};		


void  Adc_Init(void)
{ 	
	ADC_InitTypeDef ADC_InitStructure; 
  DMA_InitTypeDef  DMA_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_GPIOB|
									RCC_APB2Periph_GPIOC|RCC_APB2Periph_ADC1,ENABLE );	  //使能ADC1通道时钟
	
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);

	RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M

	//PA1-PA7 作为模拟通道输入引脚                         
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|
					GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;		//模拟输入引脚
	GPIO_Init(GPIOA, &GPIO_InitStructure);	
		//PC4-C5 作为模拟通道输入引脚                         
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|
																GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;		//模拟输入引脚
	GPIO_Init(GPIOC, &GPIO_InitStructure);	
	
			//PB0-B1 作为模拟通道输入引脚                         
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;		//模拟输入引脚
	GPIO_Init(GPIOB, &GPIO_InitStructure);	

  /* DMA channel1 configuration */
 DMA_DeInit(DMA1_Channel1);
 /*定义DMA外设基地址,即为存放转换结果的寄存器*/
 DMA_InitStructure.DMA_PeripheralBaseAddr =(u32)&(ADC1->DR);
 /*定义内存基地址*/
 DMA_InitStructure.DMA_MemoryBaseAddr =(u32)ADC_Value;
 /*定义AD外设作为数据传输的来源*/
 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
 /*指定DMA通道的DMA缓存的大小,即需要开辟几个内存空间,由ADC_CH_NUM这个宏决定*/
 DMA_InitStructure.DMA_BufferSize = ADC_CH_NUM;
	/*设定寄存器地址固定*/
 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
 /*设定内存地址递加,即每次DMA都是将该外设寄存器中的值传到开辟的内存空间中*/
 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
/*设定外设数据宽度 半字*/	
 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
	/*设定内存的的宽度 半字*/
 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
	/*设定DMA工作再循环缓存模式*/
 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
 /*设定DMA选定的通道软件优先级*/
 DMA_InitStructure.DMA_Priority = DMA_Priority_High;
 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
 DMA_Init(DMA1_Channel1, &DMA_InitStructure);
 /* Enable DMA channel1 */
 DMA_Cmd(DMA1_Channel1, ENABLE);

  
  
	ADC_DeInit(ADC1);  //复位ADC1 

	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;	//ADC工作模式:ADC1和ADC2工作在独立模式
	ADC_InitStructure.ADC_ScanConvMode = ENABLE ;	//模数转换工作在扫描模式
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE ;	//模数转换工作在连续转换模式
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;	//转换由软件而不是外部触发启动
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;	//ADC数据右对齐
	ADC_InitStructure.ADC_NbrOfChannel = ADC_CH_NUM;	//顺序进行规则转换的ADC通道的数目
	ADC_Init(ADC1, &ADC_InitStructure);	//根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器   
  RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M
 
	/*ADC通道编号*/
	ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 5, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 6, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 7, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 8, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 9, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 10, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_10,11, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_11,12, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_12,13, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_13,14, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_14,15, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_15,16, ADC_SampleTime_55Cycles5);
	
  ADC_DMACmd(ADC1, ENABLE);
  
	ADC_Cmd(ADC1, ENABLE);	//使能指定的ADC1
	
	ADC_ResetCalibration(ADC1);	//使能复位校准  
	 
	while(ADC_GetResetCalibrationStatus(ADC1));	//等待复位校准结束
	
	ADC_StartCalibration(ADC1);	 //开启AD校准
 
	while(ADC_GetCalibrationStatus(ADC1));	 //等待校准结束
 
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);		//使能指定的ADC1的软件转换启动功能

}				  

//ADC采样值滤波
u16 ADC_Filter(void)
{
	
}	

版权声明:本文为CSDN博主「Mr Robot」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/leva345/article/details/123061783

生成海报
点赞 0

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

串口-RS232/RS485-TTL/CMOS

目录 串口通信基本原理 串口、RS-232、RS-485 (1)物理接口形式 (2)电平标准 TTL与CMOS: RS-232、RS-485、RS-422 串口形式

8522A+7段数码管显示实验

1、8255A简介 8255A是Intel公司生产的可编程并行I/O接口芯片,有3个8位并行I/O口。具有3个通道3种工作方式的可编程并行接口芯片(40引脚)。 其各口功能可由软件选择,

STM32基于HAL库的DS18B20实现

开发板:野火挑战者_V2 GPIO:PE2 创建工程 使能USART1 用来通过串口打印温度值 配置GPIO 代码编写 我们先打开 DS18B20 的手册 1、DS18B20 复位与存在脉冲 复位 /*

嵌入式体系结构复习笔记

寄存器表示C语言的对应关系 R0: 存储C语言函数返回值R14 : 存储C的函数返回地址R15 : 当前执行程序的代码地址 ARM的常用指令 将数据加载到寄存器:MOV/LDR子程序调用指令: BL软中断调用指