⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lb.cpp

📁 用USB外设做的一个简单的电压输出波形的控制台程序,可以用示波器看到比较完整的波形
💻 CPP
字号:
// lb.cpp : 定义控制台应用程序的入口点。
//

#include <windows.h>
#include "stdafx.h"
#include "Usb7kC.h"
#include "iostream"
#include <conio.h>

#define PRECISION 0.01 //原码的精度,只是整数

using namespace std;

typedef struct node1
{

	double t;    //采样周期
	double k, ti, t_on_off, td;  //比例系数, 积分系数,积分方法开关, 微分系数
}pid_set, *pid_node;

typedef struct node2
{
	double rise_time, stay_up_time, down_time, stay_down_time, high_v, low_v, min;
	//各段时间,min为精度(待定)
}t_shape, *t_shape_node;


double output_wave(pid_node p_ptr, t_shape_node t_ptr, struct ZT_USBBOARD * a, double u_former);
void new_sleep(double time);
double AD(double x); //用来做数字信号<-->模拟信号的值转换

double pid_ctrl(pid_node x, struct ZT_USBBOARD *in, struct ZT_USBBOARD *out, double e0, double u0, double time);//用一个struct传递多个参数
void setDA(double, struct ZT_USBBOARD *);    //自动数模转换, 内部的计算实现用模拟值
double getDA(struct ZT_USBBOARD *);

//double u0_global=0;   //为保存每次控制的初始电压
//double e0_global=0;   //为保存每次控制的理想返回值


int main()
{
	struct ZT_USBBOARD a;
	
	pid_node p_ptr=(pid_node)malloc(sizeof(pid_set));
	t_shape_node t_ptr=(t_shape_node)malloc(sizeof(t_shape));

	//double rise_time=0.5, stay_up_time=1, down_time=0.5 ,stay_down_time=0.5, min=1, high_v, low_v;     //各段时间 精度

	//---over "有关时间控制的变量"

	//USBBORAD结构 的参数设置
		a.lIndex=0;
		cout<<OpenUSB7kC(&a)<<endl;   //转换卡工作的情况
		a.lCode =0;
		a.nCh =1;
		a.lData =0;
	//t_shape_node t_ptr的设置
		t_ptr->down_time=10;
		t_ptr->rise_time =10;
		t_ptr->stay_up_time =30;
		t_ptr->stay_down_time =10;
		t_ptr->high_v =1000;
		t_ptr->low_v =400;
		t_ptr->min =50;    //步长
		
	//pid_node p_ptr的设置
	
		p_ptr->k=0.1;
		/*ptr->t=1;
		ptr->t_on_off=0;
		ptr->td=0;
		ptr->ti=0;*/
		
	//--

	//计数器
	int counter=0;

	/*/--------------------一段用来测试的程序------------------------
	double in=0, out=0;
	int trial_times=100;
	int lalala=0;
	double temp=0;
	for (int i=0;i<trial_times;i++)
	{
		cout<<endl<<"Input some input_Value: ";
		cin>>in;
		lalala=in;
		setDA(in, &a);

		while (!_kbhit() )
		{
			
			in+=5;
			setDA(in, &a);
			cout<<endl<<"Output is "<<in;
			Sleep(1000);
		}
		if(_getch()!='a')
		{	cout<<endl<<"Down to 0!";
			in=0;
			setDA(in, &a);
		}

		
		/*Sleep(2000);

		for (int j=0;j<30;j++)
		{
			out=getDA(&a);

			temp+=out;
			Sleep(200);
		}
		cout<<"The out_put_Value is "<<(temp/30)*10000/4096<<endl<<endl;
		temp=0;
		
	}
	/-----------------------------------------------------------------/

//------------getDA----测试代码
	int temp=0;
	for(;;)
	{
		cin>>temp;
		cout<<"Temp is "<<temp<<"  , and the Data is "<<getDA(&a)<<endl;
	}

//-----------------------------*/
	
	double u_temp=0; 

	for(;;)
	{
		while( !_kbhit() )
		{
			u_temp=output_wave(p_ptr, t_ptr,  &a, u_temp);
			//output_wave((low_v+high_v)/2, low_v,  rise_time, stay_up_time, down_time ,stay_down_time,min,  &a);
			++counter;
			cout<<counter<<endl;
		}
		
		cout << "Input Rise Time(s)!!!: ";  //时间越长  精度可以设计的越高  
		cin >> t_ptr->rise_time;
		cout << endl << "Input Stay_up Time(s)!!!: ";
		cin >> t_ptr->stay_up_time;
		cout << endl<< "Input Down Time(s)!!!:  ";
		cin >> t_ptr->down_time;
		cout << endl << "Input Stay_down Time(s)!!!: ";
		cin >> t_ptr->stay_down_time;
		cout << endl << "Input the Definition(0-4095): ";
		cin >> t_ptr->min;
		cout << endl << "Input Highest V(mv)!!!: ";
		cin >> t_ptr->high_v;
		cout << endl << "Input Lowest V (mv)!!!: ";
		cin >> t_ptr->low_v;
		counter=0;
	}
	

	CloseUSB7kC(&a);
	return 0;
}
//时间测试1/5/1/5 大约需要13秒  误差1s
double output_wave(pid_node p_ptr, t_shape_node t_ptr, struct ZT_USBBOARD * a, double u_former)
{
	

	double e_ideal=0,u_current=u_former;
	double time_per_step=0;
	double rise_time=t_ptr->rise_time ,
		stay_up_time=t_ptr->stay_up_time ,
		down_time=t_ptr->down_time ,
		stay_down_time=t_ptr->stay_down_time ,
		high_v=t_ptr->high_v ,
		low_v=t_ptr->low_v ,
		min=t_ptr->min ;

	
	e_ideal=low_v;
	time_per_step=(rise_time/(  (int)((AD(high_v)-AD(low_v)) /min)  ));



	//上升阶段
			
			while(e_ideal <AD(high_v))  //输入电压(mv)
			{	

				u_current=pid_ctrl(p_ptr, a, a ,e_ideal, u_current,time_per_step);//控制语句
				e_ideal+=min;
				     
				
			}
			//水平阶段
			e_ideal =AD(high_v);   //!!有些牵强的话
			u_current=pid_ctrl(p_ptr, a, a ,e_ideal, u_current,stay_up_time);
			
			//下降阶段
			while(e_ideal>AD(low_v))
			{	
				
				u_current=pid_ctrl(p_ptr, a, a ,e_ideal, u_current, time_per_step);//控制语句
				e_ideal -=min;
				     

			}
			//又停了
			e_ideal=AD(low_v);
			u_current=pid_ctrl(p_ptr, a, a ,e_ideal, u_current,stay_down_time);

			return u_current;
}

void new_sleep(double time)//输入延时时间ms
{
	LARGE_INTEGER litmp; 
    LONGLONG QPart1,QPart2;
    double dfMinus, dfFreq, dfTim;
	      
	QueryPerformanceFrequency(&litmp);
	dfFreq = (double)litmp.QuadPart;// 获得计数器的时钟频率
    QueryPerformanceCounter(&litmp);
    QPart1 = litmp.QuadPart;// 获得初始值
    do
    {
          QueryPerformanceCounter(&litmp);
          QPart2 = litmp.QuadPart;//获得中止值
          dfMinus = (double)(QPart2-QPart1);
          dfTim = dfMinus / dfFreq;// 获得对应的时间值,单位为秒
    }while(dfTim<(time));
}

double pid_ctrl(pid_node x, struct ZT_USBBOARD *in, struct ZT_USBBOARD *out, double e0, double u0, double time)
{
	   LARGE_INTEGER litmp; 
       LONGLONG QPart1,QPart2;
       double dfMinus, dfFreq, dfTim=0; 
       QueryPerformanceFrequency(&litmp);
       dfFreq = (double)litmp.QuadPart;// 获得计数器的时钟频率
       QueryPerformanceCounter(&litmp);
       QPart1 = litmp.QuadPart;// 获得初始值

	
	
	//环境设置

	double k=x->k ;
	//设置增量系数

	double e_current=0;
	double u_diff=0;
	double e3=0;//差量  命名为e3是历史原因
	
	double temp=PRECISION*e0;
	
	while( (abs( (e_current=getDA(in)) -e0) >temp) |   (dfTim<time) )//2008.4.12update  e_current=getDA(in) -e0  括号问题
	{
	
		cout<<"\t"<<e_current<<"\t"<<e0<<endl;
		

		if ((abs( (e_current=getDA(in)) -e0) >temp))
		{			e3= e0-e_current;  //与理想值差值,和while里面判断语句重复,待修改
					//u_diff_diff=d0 *e3 + d1* e2 +d2* e1;//通过PID控制得出差量控制信号---是差量的差量,而不只是差量..
					u_diff=k*e3;

			//--------08/5/12 测试用的添加代码code1
			//把I D都关闭,只用比例控制

			//原码值要求整数
					if ((u_diff>0) &&(u_diff<1) )
					{u_diff=1;
					}
					else if ((u_diff<0) && (u_diff>-1))
					{u_diff=-1;}
			//---------code1 over

					u0=u0+ u_diff;
					
			//避免越界
					if (u0>4095)
						u0=4095;
					else 
						if (u0<0)
							u0=0; 
			//--越界
					
					setDA(u0,out);
					//new_sleep(0.001);
		}
		
		cout<<u0;   //打印 输出信号&当前电压与理想值得差距
       
	
          QueryPerformanceCounter(&litmp);
          QPart2 = litmp.QuadPart;//获得中止值
          dfMinus = (double)(QPart2-QPart1);
          dfTim = dfMinus / dfFreq;// 获得对应的时间值,单位为秒
       
	}
	return u0;

	
}
void setDA(double x, struct ZT_USBBOARD *out)
{
	out->lData=x;
	//u0_global=x;  //可能出错
	USB7333DA(out);
	
}
double getDA(struct ZT_USBBOARD *in)
{
	double temp=0;
	for (int j=0;j<30;j++)
		{
			USB7333AI(in);
			temp+=in->lData ;
			//new_sleep(0.001);
		}
	
	
	return temp/30;//临时测试用,使用时要调用USB7333AI函数
	//return u0_global/10;
}

double AD(double x)  //用来做数字信号<-->模拟信号的值转换
{
	return x;   
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -