基于STM32的数据采集系统的Proteus仿真


一、数据采集系统

1.题目要求

利用单片机设计一个多通道的数据采集系统,该系统可以实现对8路单端模拟电压、2路模拟输出,8路开关量的采集,其中每一路电压范围为0-3.3V。

可以通过按键来切换数据采集模式,可以将采集的数据通过RS232打印出来。

2.思路

如果是选择用51单片机来做的话,因为51单片机不包含内置的模数转换器(ADC)或数字模拟转换器(DAC)功能。如果你要使用ADC功能来进行模拟信号的采集,你需要通过外部连接ADC芯片和DAC芯片来实现,比较麻烦,所以我打算直接用STM32来做。

打算用51单片机来做的朋友,可以看看PCF8591芯片,它是一款8bit CMOS的AD/DA芯片,它具有4个模拟输入、1个模拟输出和1个串行IIC总线接口。PCF8591的3个地址引脚A0,A1和A2可以用于硬件地址编程,允许在同个IIC总线上接入8个PCF8591器件,而无需额外的硬件。可以看下我的另外一篇文章基于51单片机的AD/DA转换的串口通信proteus仿真(附源码)

最后弄8路ADC通道采集电压,2路DAC电压模拟输出,8路按键数字量输出,以及用3个按键来控制模式的选择即可,为了方便展示,再弄个OLED显示屏显示当前模式,数据直接输出在模拟终端或串口助手上。(想法挺美好,下面仿真的时候就知道DAC不起作用,还是得用上老朋友PCF8591来进行DAC输出电压)

3.仿真图

3.1 仿真图

在这里插入图片描述

这里为什么明明STM32有DAC外设,我还用PCF8591来进行DAC输出呢?

是因为我发现我写了DAC程序,但是不起作用,没有电压输出,我猜测可能是仿真中的STM32芯片没有集成DAC外设,当然也有可能是我写错了。

这里就不弄2路DAC输出了,弄一路看看效果把。

3.2 仿真图简单说明

主控芯片:STM32F103C8
HICK:64MHZ
Systick: 1ms
测试Led:PC13
Uart1:9600(PA9:tx1,PA10:rx1)

OLED显示屏:SCL(PB14),SDA(PB15)

ADC:
ADC1(PA0)
ADC2(PA1)
ADC3(PA2)
ADC4(PA3)
ADC5(PA6)
ADC6(PA7)
ADC7(PB0)
ADC8(PB1)

DAC:SCL1(PA11),SDA1(PA12)

KEY按键:
KEY_MODE1(PB3)
KEY_MODE2(PB4)
KEY_MODE3(PB5)
KEY1(PB6)
KEY2(PB7)
KEY3(PB8)
KEY4(PB9)
KEY5(PB10)
KEY6(PB11)
KEY7(PB12)
KEY8(PB13)

3.3 仿真图简单演示

初始状态

在这里插入图片描述

ADC模式

在这里插入图片描述

DAC模式

在这里插入图片描述

数字量模式

在这里插入图片描述

串口设置模式
*MODE1

在这里插入图片描述

*MODE2

在这里插入图片描述

*MODE3

在这里插入图片描述

4.仿真程序

4.1 程序说明

RS232串口协议
模式切换指令 *MODEH
H为0:初始模式
H为1:8路单端模拟电压输出模式
H为2:1路模拟输出模式
H为3:8路开关量输出模式

串口配置
在这里插入图片描述

4.2 主函数

/* Includes ------------------------------------------------------------------*/
#include "Drv_UserSystem.h"

/**
  * @brief  main function.
  * @param  none
  * @retval none
  */
int main(void)
{
	UserSystemInit();//用户配置初始化		
	while (1)
	{						
		if (stSysTime.flg._10ms + TEN_MILLISECOND < Time_millis()) //10ms
		{
			stSysTime.flg._10ms = Time_millis();	
            Key_Scan();//按键扫描	
			OLED_Handel();//OLED显示			
		}
		if (stSysTime.flg._50ms + FIFTY_MILLISECOND < Time_millis()) //50ms
		{
			stSysTime.flg._50ms = Time_millis();				
		}
		if (stSysTime.flg._100ms + BEST_MILLISECOND < Time_millis()) //100ms
		{
			stSysTime.flg._100ms = Time_millis();	
			Receive_data_Handel();//数据接收判断			
			IWDG_ReloadCounter();//清开门狗 
		}
		if (stSysTime.flg._1s + THOUSAND_MILLISECOND < Time_millis()) //1s
		{
			stSysTime.flg._1s = Time_millis();
			ADC_Scan();//ADC扫描	
            DAC_Scan();//DAC输出				
			Led_Flicker();//灯光闪烁			
	  }
  }
}

4.3 ADC采集

ADC_FLAG值一开始不为1是因为发现刚上电仿真ADC采集的数据不准,要舍弃一段时间的数据,等到ADC稳定下来再去采集。

另外delay_syms延时是确保每次ADC都转换完成,不加应该也可以的。

/*******************************************************************************
 * 函数名:ADC_Scan
 * 描述  :ADC扫描
 * 输入  :void
 * 输出  :void
 * 调用  :1s
 * 备注  :
 *******************************************************************************/
void ADC_Scan(void)
{
  if((show_mode == 1) && (ADC_FLAG))
  {			
      ADC_FLAG--;
      		
	  ADC1_DATA_Init();
	  ADC1_Value =  Read_AdC_Value(ADC_Channel_0); 
      delay_syms(10);		

	  ADC2_DATA_Init();		
	  ADC2_Value =  Read_AdC_Value(ADC_Channel_1); 
      delay_syms(10);	

	  ADC3_DATA_Init();		
	  ADC3_Value =  Read_AdC_Value(ADC_Channel_2); 
      delay_syms(10);		

	  ADC4_DATA_Init();			
	  ADC4_Value =  Read_AdC_Value(ADC_Channel_3); 
      delay_syms(10);	

	  ADC5_DATA_Init();	
	  ADC5_Value =  Read_AdC_Value(ADC_Channel_6); 
      delay_syms(10);	

	  ADC6_DATA_Init();	
	  ADC6_Value =  Read_AdC_Value(ADC_Channel_7); 	
      delay_syms(10);		

      ADC7_DATA_Init();
	  ADC7_Value =  Read_AdC_Value(ADC_Channel_8); 
      delay_syms(10);	

	  ADC8_DATA_Init();
	  ADC8_Value =  Read_AdC_Value(ADC_Channel_9); 
      delay_syms(10);

      if(!ADC_FLAG)
	  {
		  printf("ADC1_Value=%d\r\n",ADC1_Value);
		  printf("ADC2_Value=%d\r\n",ADC2_Value);	
		  printf("ADC3_Value=%d\r\n",ADC3_Value);	
		  printf("ADC4_Value=%d\r\n",ADC4_Value);	
		  printf("ADC5_Value=%d\r\n",ADC5_Value);	
		  printf("ADC6_Value=%d\r\n",ADC6_Value);	
		  printf("ADC7_Value=%d\r\n",ADC7_Value);	
		  printf("ADC8_Value=%d\r\n",ADC8_Value);					
		}
	}
}

4.4 DAC输出

/*******************************************************************
DAC 变换, 转化函数               
*******************************************************************/
uint8_t DACconversion(uint8_t sla,uint8_t c,uint8_t Val)
{
   Start_I2c();              //启动总线
   SendByte(sla);            //发送器件地址
   if(ack==0)return(0);
   SendByte(c);              //发送控制字节
   if(ack==0)return(0);
   SendByte(Val);            //发送DAC的数值  
   if(ack==0)return(0);
   Stop_I2c();               //结束总线
   return(1);
}

/*******************************************************************************
 * 函数名:DAC_Scan
 * 描述  :DAC输出
 * 输入  :void
 * 输出  :void
 * 调用  :1s
 * 备注  :
 *******************************************************************************/
void DAC_Scan(void)
{
  if((show_mode == 2) && (DAC_FLAG))
	{
		DAC_FLAG = 0;	
	    DACconversion(PCF8591,0x40, DAC_value);
		printf("DAC_Value=%d\r\n",DAC_value);					
	}		
}

4.5 开关量输出

    if((show_mode == 3) && (KEY_FLAG))
	{
		KEY_FLAG = 0;
		printf("KEY1 = %d\r\n",KeyState.value1);	
		printf("KEY2 = %d\r\n",KeyState.value2);	
		printf("KEY3 = %d\r\n",KeyState.value3);	
		printf("KEY4 = %d\r\n",KeyState.value4);	
		printf("KEY5 = %d\r\n",KeyState.value5);	
		printf("KEY6 = %d\r\n",KeyState.value6);	
		printf("KEY7 = %d\r\n",KeyState.value7);	
		printf("KEY8 = %d\r\n",KeyState.value8);
	}

		if(show_mode == 3)
		{
				if(Key1_IN_Read() == 0)//key1
				{
					KeyState.value1 = 1;
					if(!KeyState.Press1)
					{
                       printf("KEY1 = %d\r\n",KeyState.value1);							
					}
                    KeyState.Press1 = 1;					
				}		
				else
				{		
					if(KeyState.value1)
					{
				    	KeyState.value1= 0;
                        printf("KEY1 = %d\r\n",KeyState.value1);								
					}
					KeyState.Press1 = 0;
				}		

				if(Key2_IN_Read() == 0)//key2
				{
					KeyState.value2 = 1;
					if(!KeyState.Press2)
					{
                       printf("KEY2 = %d\r\n",KeyState.value2);						
					}
					KeyState.Press2 = 1;
				}		
				else
				{		
					if(KeyState.value2)
					{
				    	KeyState.value2= 0;
                        printf("KEY2 = %d\r\n",KeyState.value2);								
					}					
					KeyState.Press2 = 0;
				}	

				if(Key3_IN_Read() == 0)//key3
				{
					KeyState.value3 = 1;					
					if(!KeyState.Press3)
					{
                       printf("KEY3 = %d\r\n",KeyState.value3);					
					}
					KeyState.Press3 = 1;
				}		
				else
				{		
					if(KeyState.value3)
					{
				    	KeyState.value3= 0;
                        printf("KEY3 = %d\r\n",KeyState.value3);								
					}						
					KeyState.Press3 = 0;
				}		

				if(Key4_IN_Read() == 0)//key4
				{
					KeyState.value4 = 1;					
					if(!KeyState.Press4)
					{
                       printf("KEY4 = %d\r\n",KeyState.value4);								
					}
					KeyState.Press4 = 1;
				}		
				else
				{		
					if(KeyState.value4)
					{
				    	KeyState.value4 = 0;
                        printf("KEY4 = %d\r\n",KeyState.value4);								
					}						
					KeyState.Press4 = 0;
				}	

				if(Key5_IN_Read() == 0)//key5
				{
					KeyState.value5 = 1;						
					if(!KeyState.Press5)
					{
                        printf("KEY5 = %d\r\n",KeyState.value5);							
					}
					KeyState.Press5 = 1;
				}		
				else
				{		
					if(KeyState.value5)
					{
				    	KeyState.value5 = 0;
                        printf("KEY2 = %d\r\n",KeyState.value5);								
					}						
					KeyState.Press5 = 0;
				}		

				if(Key6_IN_Read() == 0)//key6
				{
					KeyState.value6 = 1;					
					if(!KeyState.Press6)
					{
                        printf("KEY6 = %d\r\n",KeyState.value6);						
					}
					KeyState.Press6 = 1;
				}		
				else
				{		
					if(KeyState.value6)
					{
				    	KeyState.value6 = 0;
                        printf("KEY2 = %d\r\n",KeyState.value6);								
					}						
					KeyState.Press6 = 0;
				}	

				if(Key7_IN_Read() == 0)//key7
				{
					KeyState.value7 = 1;						
					if(!KeyState.Press7)
					{
                        printf("KEY7 = %d\r\n",KeyState.value7);							
					}
					KeyState.Press7 = 1;
				}		
				else
				{		
					if(KeyState.value7)
					{
				    	KeyState.value7 = 0;
                        printf("KEY2 = %d\r\n",KeyState.value7);								
					}						
					KeyState.Press7 = 0;
				}		

				if(Key8_IN_Read() == 0)//key8
				{
				  KeyState.value8 = 1;						
					if(!KeyState.Press8)
					{
                        printf("KEY8 = %d\r\n",KeyState.value8);						
					}
					KeyState.Press8 = 1;
				}		
				else
				{		
					if(KeyState.value8)
					{
				    	KeyState.value8 = 0;
                        printf("KEY2 = %d\r\n",KeyState.value8);								
					}						
					KeyState.Press8 = 0;
				}
			}

4.6 模式切换

			if(KeyMode1_IN_Read() == 0)//keyMode1
			{
				if(!KeyState.Mode1_Press)
				{
					  show_mode = 1;
					  ADC_FLAG = 2;
					  printf("\r\nkeyMode1\r\n");							
				}
				KeyState.Mode1_Press = 1;
			}		
			else
			{		
				KeyState.Mode1_Press = 0;
			}	
	

		
			if(KeyMode2_IN_Read() == 0)//keyMode2
			{
				if(!KeyState.Mode2_Press)
				{
					  show_mode = 2;
                      DAC_FLAG = 1;
					  printf("\r\nkeyMode2\r\n");							
				}
				KeyState.Mode2_Press = 1;
			}		
			else
			{		
				KeyState.Mode2_Press = 0;
			}			

		
				if(KeyMode3_IN_Read() == 0)//keyMode3
				{
					if(!KeyState.Mode3_Press)
					{
						  show_mode = 3;
					      KEY_FLAG = 1;						
					      printf("\r\nkeyMode3\r\n");													
					}
					KeyState.Mode3_Press = 1;
				}		
				else
				{		
					KeyState.Mode3_Press = 0;
				}	

二、总结

今天主要讲了基于STM32的数据采集系统的Proteus仿真。

感谢你的观看!

在这里插入图片描述

  • 13
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Fanuc CNC数据采集是指通过Fanuc数控机床系统进行数据采集的过程。Fanuc数控机床系统是一种高精度、高效率的数控机床系统,并且具有丰富的功能和灵活的操作界面。 在Fanuc CNC数据采集过程中,首先需要将数据采集设备与Fanuc数控机床系统进行连接。这些数据采集设备可以是传感器、监控设备或者其他类型的数据采集设备。通过与Fanuc数控机床系统的连接,可以实现实时数据的采集和传输。 接下来,在Fanuc CNC数据采集过程中,需要设定数据采集的参数和条件。根据具体的应用需求,可以设定需要采集的数据类型,如温度、压力、速度等,以及采集的时间间隔和采集的持续时间等。 开始数据采集后,Fanuc CNC系统会根据设定的参数和条件自动进行数据的采集。采集的数据会被传输到数据采集设备的存储器中,以便后续的数据处理和分析。 在Fanuc CNC数据采集过程中,还可以进行实时监控和数据处理。通过连接的监控设备,可以实时监测和显示采集的数据,以便对机床运行状态进行实时监控和调整。 最后,在Fanuc CNC数据采集过程中,采集到的数据可以用于进行数据分析和优化。通过对采集的数据进行分析,可以了解机床运行状态、故障诊断和性能优化等。 总的来说,Fanuc CNC数据采集是一个重要的过程,通过采集和处理数据,可以实现对数控机床系统的监控和优化,提高机床的运行效率和生产质量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaobuding_QAQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值