用ST语言编一个PID控制程序?

发布网友 发布时间:2022-04-22 08:28

我来回答

2个回答

热心网友 时间:2022-06-18 15:48

还真巧, 我前两天正好也做了一个这样的作业和你的差不多
自认做的还算挺细致,你只需要在排序子函数中填加个学号排序功能即可,具体统计你再做一下吧,我做这个用了整整两天,又用了三四天做了些细致的改进,我实在不想再去看了,烦了。你自己参考吧:
//此程序用来实现学员成绩管理
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 50
/*定义嵌套的结构保存学员信息*/
struct student
{
int num;//学号
char name[15];//姓名
struct score //三门成绩结构包含成员三门单科成绩
{
float s1;
float s2;
float s3;
}sc;
float ave;//平均成绩
};

void input(struct student st[],int*);//定义录入函数原型
void display(struct student *,int);//显示学员信息函数原型
void sort(struct student st[],int);//定义排序函数原型
void find(struct student st[],int);//定义查找函数原型
void insert(struct student st[],int *);//定义插入函数原型
void del(struct student st[],int *);//定义删除函数原型
void ent_del(int *); //定义全部删除函数原型

void main()
{
int s,count=0;//变量s控制功能选项,count接收返回的录入学员数量
int *p=&count;//指针p指向学员数量

struct student stu[N];//定义一个结构数组stu

/*利用循环调用函数来实现各种管理功能*/
do
{
printf("学员成绩管理选项:");
printf(" \n0.退出\t1.录入\t2.排序\t3.查找\t4.插入\t5.删除\t6.全部删除");
printf("\n==========================================================\n");
printf("输入选项:");
scanf("%d",&s);

switch (s)
{
case 0: exit(0);

case 1: input(stu,p); //调用录入函数录入学员信息
display(stu,count);//调用显示函数显示排序前的学员信息
break;
case 2:sort(stu,count); //调用排序函数进行排序
display(stu,count); //调用显示函数显示排序后的学员信息
break;
case 3: find(stu,count); //调用查找函数查找单个学员的信息
display(stu,count);
break;
case 4: insert(stu,p); //调用插入函数插入学员信息
display(stu,count); //调用显示函数显示插入后的学员信息
break;
case 5: del(stu,p); //调用删除函数删除单个学员的信息
display(stu,count); //显示删除后的学员信息
break;
case 6: ent_del(p); //调用全部删除函数
display(stu,count);
break;

default: printf("\a输入有误,请在0--6之间选择!\n");
}
}while (1);

}

void input(struct student st[],int *p) //调用录入函数
{
int i,j; //声明循环变量i,j
char ans='y';
if (*p<N)
{
printf("请输入学员信息:\n");
/*利用循环录入单个学员的详细信息,并利用指针p来记录学员的数量*/
for (i=*p;ans=='y' || ans=='Y';i++)
{
printf("\n学号:");
scanf("%d",&st[i].num);
for (j=0;j<i;j++) //利用循环判断输入的学号是否与前面的有重复
{
if (st[i].num==st[j].num)
break;
}
if (j<i)
{
printf("\n学号不允许重复!请重新输入");
i--; /*continue语句继续下一次循环i会自增1,让i自减1
以保持其值不变*/
continue;
}

printf("\n姓名:");
fflush(stdin);
gets(st[i].name);

printf("\n三门成绩:\n");
printf("成绩1:");
scanf("%f",&st[i].sc.s1);
printf("成绩2:");
scanf("%f",&st[i].sc.s2);
printf("成绩3:");
scanf("%f",&st[i].sc.s3);

printf("\n是否继续?(y.继续 n.回主选单):");
fflush(stdin);
ans=getchar();

if (i==N-1)
{
printf("\n\a存储已满!无法再录入学员信息!\n");
i++;
break; /*因为要跳出循环,for语句中的i++不执行
在这里执行一次以保证学员数量准确*/
}
}
*p=i;
printf("\n录入后的学员信息如下:\n");
}
else
printf("\n\a存储已满!无法再录入学员信息!\n");
}

void display(struct student *ps,int n) //显示函数
{
int i=0;
printf("------------------------------------------------------\n");
if (n==0)
printf("\a表中无学员信息,请使用录入或插入功能添加!\n");
else
{
printf("学号\t姓名\t\t平均成绩\n");
/*利用循环显示学员信息*/
for (i=0;i<n;i++,ps++)
{
ps->ave=(ps->sc.s1+ps->sc.s2+ps->sc.s3)/3;
printf("%2d\t%s\t\t%5.1f\n",ps->num,ps->name,ps->ave);
}
}
printf ("------------------------------------------------------\n");
}

void sort(struct student st[],int n) //排序函数
{
int i,j;
struct student temp;

/*利用循环根据学员的成绩对学员排序(冒泡)*/
if(n!=0)
{
for (i=0;i<n;i++)
{
for (j=0;j<n-i-1;j++)
{
if (st[j].ave<st[j+1].ave)
{
temp=st[j];
st[j]=st[j+1];
st[j+1]=temp;
}
}
}

printf("\n排序后的学员信息如下:\n");
}
}

void find(struct student st[],int n) //查找函数
{
int i,k;

while (1)
{
if (n==0) //如果学员数量为0,则不必查找,直接跳出循环
break;

printf("输入要查找的学员的学号:");
scanf("%d",&k);

for (i=0;i<n;i++) //循环遍历结构数组找到相同的学号位置
{
if (st[i].num==k)
break;
}
if (i<n) //输出学员的详细信息
{
printf("你查找的学员详细信息如下:\n");
printf("----------------------------------");
printf("\n学号:%d\t\t\t姓名:%s",st[i].num,st[i].name);
printf("\n\n三门成绩:\t\t平均成绩");
printf("\n成绩1:%5.1f",st[i].sc.s1);
printf("\n成绩2:%5.1f\t\t%5.1f",st[i].sc.s2,st[i].ave);
printf("\n成绩3:%5.1f",st[i].sc.s3);
printf("\n\n");
break;
}
else
printf("\n\a输入有误,没有该学员!请重新");
}
}

void insert(struct student st[],int *p)
//插入函数,因为插入学员会改变总学员数量,所以采用引用调用学员数量
{
int i,j;
struct student in; //声明一个结构变量来存储要插入的学员信息

if (*p<N) //当学员数量存储未满时可以插入
{
printf("\n请输入要插入的学员信息\n");

printf("\n学号:");
scanf("%d",&in.num);

printf("\n姓名:");
fflush(stdin);
gets(in.name);

printf("\n三门成绩:\n");
printf("成绩1:");
scanf("%f",&in.sc.s1);
printf("成绩2:");
scanf("%f",&in.sc.s2);
printf("成绩3:");
scanf("%f",&in.sc.s3);

/*利用数组插入元素的方法将成员插入*/
for (i=0;i<*p;i++)//查找第一个小于插入学员平均成绩的位置
{
if (st[i].ave<(in.sc.s1+in.sc.s2+in.sc.s3)/3)
break;
}

for (j=*p;j>i;j--)//为要插入的学员留出位置
{
st[j]=st[j-1];
}
st[i]=in; //将要插入的学员保存到该位置
*p+=1; //学员的数量多了一个,利用指针将count加1
printf("\n插入新学员后的学员信息如下:\n");
}
else
printf("\n\a存储已满!无法插入学员!\n");
}

void del(struct student st[],int *p) //删除函数
{
int i,k;
char ans;

while (1)
{
if (*p==0) //如果学员数量为零,则跳出循环
break;

printf("输入要删除的学员的学号:");
scanf("%d",&k);

for (i=0;i<*p;i++) //找到该学员的位置
{
if (st[i].num==k)
break;
}

if (i<*p)
{
printf("\n\a确实要删除 %d 号学员 %s 的全部信息吗?(y.删除 n.回主选单):",st[i].num,st[i].name);
fflush(stdin);
ans=getchar();
if (ans=='y' || ans=='Y')
{
for (;i<*p-1;i++) //将后面的学员信息依次向前一个覆盖,即删除了当前元素
st[i]=st[i+1];
*p-=1; //学员的数量少了一个,利用指针将count减1
printf("\n删除后学员的信息如下:\n");
break;
}
}
else
{
printf("\n\a没有该学员!请重新");
continue;
}
if (ans!='y' || ans!='Y') //如果选择不删除则返回主选单
break;
}
}

void ent_del(int *p) //全部删除函数
{
char ans;
printf("\n\a!此功能将会删除所有数据!您确定执行吗?(y.确定 n.回主选单):");
fflush(stdin);
ans=getchar();
if (ans=='y' || ans=='Y')
{
*p=0; //将学员数量赋值为0,即清空数据
printf("\n已删除全部学员信息!\n");
}
}

热心网友 时间:2022-06-18 15:48

(*PV值采集地址 40200*)
Read_Uint_var( ADR:=40200 |Input_addr := OUT );
Read_Real_var( ADR:=Input_addr , SWAP:=0 |PV_value := OUT );
(*SP值采集*)
Read_Uint_var( ADR:=40004 |SP_value := OUT );
(*死区采集*)
Read_Uint_var( ADR:=40005 |EL_value := OUT );
(*输出上下限*)
Read_Uint_var( ADR:=40006 |OP_max := OUT );
Read_Uint_var( ADR:=40007 |OP_min := OUT );
(*OP值采集地址 40201
Read_Uint_var( ADR:=402001 |Input_addr := OUT );
Read_Real_var( ADR:=40002 , SWAP:=0 |OP_value := OUT );
Write_Real_var( ADR:=Input_addr , SWAP:=0 , VAL:=OP_value );
*)

pid_open_var( N:=0 , St_Adr:=40001 , Sk_Adr:=41000 , Uk_Adr:=40002 , Ek_Adr:=40003 , Sp_Adr:=40004 , Er_Adr:=40005 , Umax_Adr:=40006 , Umin_Adr:=40007 , Kp_Adr:=40008 , Ti_Adr:=40009 , Td_Adr:=40010 , Tt_Adr:=40011 );
(*读使能状态*)
Read_Uint_var( ADR:=40012 |enable_pid := OUT );
if enable_pid=1 then
pid_st_set_var( N:=0 , St_In:=true | pid_err:= Err );
Read_Real_var( ADR:=40002 , SWAP:=0 |OP_value := OUT );
if OP_value < 10080.0 then
OP_value:=10000.0;
end_if;
if OP_value > 50000.0 then
OP_value:=50000.0;
end_if;
Read_Uint_var( ADR:=40201 |Input_addr := OUT );
Write_Real_var( ADR:=Input_addr , SWAP:=0 , VAL:=OP_value );
else
pid_st_set_var( N:=0 , St_In:=false | pid_err:= Err );
end_if;
还没测试 我用的好是OpenPCS软件写的

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com