




已阅读5页,还剩53页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
南 阳 理 工 学 院 本科生毕业设计(论文) 学院(系): 电子与电气工程学院 专 业: 自 动 化 学 生: 黄帅豪 指导教师 : 殷华文 完成日期 2014 年 5 月 南阳理工学院本科生毕业设计(论文) 基于 MSP430 单片机的温度 PID 算法设计 Design of Temperature PID Algorithm Based on MSP430 Single Chip Microcomputer 总 计 : 20 页 表 格 : 0 个 插 图 : 13 幅 南南 阳阳 理理 工工 学学 院院 本本 科科 毕毕 业业 设设 计(论文)计(论文) 基于基于 MSP430MSP430 单片机的温度单片机的温度 PIDPID 算法设计算法设计 Design of Temperature PID Algorithm Based on MSP430 Single Chip Microcomputer 学 院(系): 电子与电气工程学院 专 业: 自动化 学 生 姓 名: 黄帅豪 学 号: 105090640035 指 导 教 师(职称): 殷华文 (副教授) 评 阅 教 师: 完 成 日 期: 南阳理工学院 Nanyang Institute of Technology 基于 MSP430 单片机的温度 PID 算法设计 基于基于 MSP430MSP430 单片机的温度单片机的温度 PIDPID 算法设计算法设计 自动化专业 黄帅豪 摘摘 要要 本设计基于 MSP430F149 单片机,以 IAR Embedded Workbench 软件为开 发平台,在 MSP430 中用自编的位置式 PID 算法程序实现对电加热锅炉水温的控制,并 在上位计算机上实现组态王软件监控。Pt100 热电阻信号经放大调理后通过 MSP430 ADC 模块送入单片机。在 MATLAB 中通过一元二次方程进行温度数据拟合,把拟合结果 在 MSP430 中编程进行温度数据标度变换,上位机向 MSP430 发送温度设定值和 PID 参 数,根据组态王软件监控结果对算法进行分析和改进,加入不完全微分和积分分离程 序。通过实验验证和结果分析,温度控制无超调,稳态误差 0; i-);/等待 8MHz 晶体起振 while (IFG1 /晶振失效标志仍然存在? BCSCTL2 |= SELM_2 + SELS;/MCLK 和 SMCLK 选择高频晶振 4.2.2 PID 算法程序 本 PID 算法程序采用位置式控制算式,由于在测试过程中发现温度曲线波动较大 且出现毛刺,所以在原有的完全微分的基础上改进为不完全微分,因为完全微分 PID 是一次微分作用,而不完全微分 PID 是分几次输出微分作用。微分是一种重要的控制 作用,可以较明显的改善闭环系统的控制性能。假如偏差的阶跃幅值较大,在完全微 分时,一次输出的微分作用幅值会很大,很可能会因输出限幅而丧失应有的微分作用。 而不完全微分,因为微分作用分几次输出,而每次输出幅值较小,所以能较好的保存 应有的微分作用。在开停工或大幅度升降设定值时,由于偏差累计较大,故在积分项 的作用下会产生一个很大的超调,并产生振荡,特别是对于温度、液面等变化缓慢的 过程,这一现象更为严重。为了改进控制性能可采用积分分离的方法,即在受控变量 开始跟踪时,取消积分作用,偏差小于某一设定值时,才产生积分作用,程序如下: void PIDCalc(void) float Rate;/误差变化率 Current_Error = Set_Temp - Pre_Temp ;/ 当前误差计算 Sum_Error += Current_Error;/ 误差积分 12 Prev_Error = Last_Error;/ 存储误差更新 Last_Error = Current_Error;/ 存储误差更新 Rate = ( Current_Error - Last_Error )*1000/ Ctrl_Period; / 当前误差微分 if(Rate5)/对误差变化率进行限制,锅炉温度不可能变化太大 Rate=5; if(RatePID_I_MAX ) I_OUT = PID_I_MAX; if( I_OUT= PWM_DATA_MAX ) PID_OUT = PWM_DATA_MAX; if ( PID_OUT =10) PID_OUT=16383; 基于 MSP430 单片机的温度 PID 算法设计 13 void main() Device_Init( ); while(1) LED8_Rollback;/系统运行指示灯 Parameter_Show( ); 4.2.3 ADC 模数转换程序 该段程序首先完成 ADC12 模块的通用程序框架,ADC12 模块的初始化函数,仅仅实 现了多通道的单次和多次转换,单通道的可以用参数,多通道模式下设置一个通道. ADC12 启动转换函数完成启动 ADC12,开始 A/D 转换。中断程序必须自己添加处理函数 (根据实际使用的通道情况) 。这里选用的时钟 SMCLK,参考电压内部打开的是 2.5v, 每次当多个通道转换完成后,打开中断时,单片机会自动调用本函数,使用时需要自 己添加处理逻辑12,程序如下: char ADC12Init(char n,char channels,char rep) if(n15) return 0; ADC12CTL0 = ADC12ON + MSC + SHT0_0 + REFON + REF2_5V; / 开启 ad,参考电压 2.5v ADC12CTL1 = SHP + ADC12SSEL_3; /Use sampling timer, SMCLK for(int i = 0;i = 0x80) return 0; *(char*)(ADC12MCTL0_ + i) = channelsi;/每个 MCTL 设置 *(char*)(ADC12MCTL0_ + n - 1) |= EOS;/序列结束 if(rep != 0)/多次转换 ADC12CTL1 |= CONSEQ_3; 14 else ADC12CTL1 |= CONSEQ_1; ADC12IE = 1 0; i-);/等待 8MHz 晶体起振 基于 MSP430 单片机的温度 PID 算法设计 23 while (IFG1 /晶振失效标志仍然存在? BCSCTL2 |= SELM_2 + SELS;/MCLK 和 SMCLK 选择高频晶振 void Parameter_Init(void) Operating_Paramrter0 = P;/P Operating_Paramrter1 = I;/I Operating_Paramrter2 = D;/D Operating_Paramrter3 = Pre_Temp;/当前温度 Operating_Paramrter4 = Set_Temp;/设定温度 Operating_Paramrter8 = PID_OUT;/PID_OUT Operating_Paramrter9 = AD_Result; Operating_Paramrter10 = PWM_Duty;/PWM_Duty void Read_Data_from_Slave(void) Operating_Paramrter0 = P; Operating_Paramrter1 = I; Operating_Paramrter2 = D; Operating_Paramrter3 = Pre_Temp;/读取当前温度 Operating_Paramrter4 = Set_Temp;/读取设定温度 Operating_Paramrter5 = P_OUT;/P_OUT Operating_Paramrter6 = I_OUT;/I_OUT Operating_Paramrter7 = D_OUT;/D_OUT Operating_Paramrter8 = PID_OUT;/PID_OUT Operating_Paramrter9 = AD_Result;/AD_Average Operating_Paramrter10 = PWM_Duty;/PWM_Duty void Writer_Data_to_Slave( ) P = Operating_Paramrter0 ; I = Operating_Paramrter1 ; 24 D = Operating_Paramrter2 ; Set_Temp = Operating_Paramrter4 ; void Para_Speci_Show(void) SPI_LCD_ShowString(5,6,“P:“,0, RED,16); SPI_LCD_ShowString(5,20,“I:“,0, RED,16); SPI_LCD_ShowString( 5,34,“D:“,0, RED,16 ); SPI_LCD_ShowString( 5,48,“Pre_Temp:“,0, RED,16 ); SPI_LCD_ShowString( 5,62,“Set_Temp:“,0, RED,16 ); SPI_LCD_ShowString( 5,160,“Step:“,0, RED,16 ); void Parameter_Show( ) SPI_LCD_Show_Float( 165,6,P,0,RED,16); SPI_LCD_Show_Float( 165,20,I,0,RED,16); SPI_LCD_Show_Float( 165,34,D,0,RED,16); SPI_LCD_Show_Float( 165,48,Pre_Temp,0,RED,16); SPI_LCD_Show_Float( 165,62,Set_Temp,0,RED,16); SPI_LCD_Show_Float( 165,160,Step,0,RED,16); void Frame_Show(void) Para_Speci_Show( ); Parameter_Show( ); /设备初始化 void Device_Init(void) char Channel1; Channel0 = SREF_1+INCH_0; WDTCTL = WDTPW + WDTHOLD;/停狗 Clk_Init( ); /初始化系统时钟函数 基于 MSP430 单片机的温度 PID 算法设计 25 UART0_Init( );/串口初始化 TimerB_Init( ); TA_Init( ); ADC12Init(1,Channel,1); ADC12Start( ); P6SEL |= 0x01;/初始化 AD 通道 IO 口 SPI_LCD_Init( );/串行 LCD 初始化 SPI_LCD_Clear(WHITE);/清屏白色 LED_GPIO_Init( ); _EINT();/开总中断 Parameter_Init();/PID 参数初始化 Frame_Show( );/参数显示 /* * 函数名:Scale_Conv * 描述 :标度变换函数 * 输入 : Converter_Value 转换变量 * 输出 : */ float Scale_Conv( u16 Value) float Temp1=0,Temp2=0; /温度拟合(二次函数) Temp1=Value*A_para; Temp1=Value*Temp1; Temp2=Value*B_para; /当前温度=A*X*X+B*X+C-零漂 return (Temp1+Temp2+C_para+Null_shift); /* * 函数名:PIDCalc * 描述 :PID 计算函数 * 输出 :PID_Value 26 * 注意 ;位置式 PID 运算 * Pre_Value: 当前值 * Prev_Error: 前一次误差 */ void PIDCalc(void) float Rate;/误差变化率 Current_Error = Set_Temp - Pre_Temp ;/ 当前误差计算 Sum_Error += Current_Error;/ 误差积分 Prev_Error = Last_Error;/ 存储误差更新 Last_Error = Current_Error;/ 存储误差更新 Rate = ( Current_Error - Last_Error )*1000/ Ctrl_Period; / 当前 误差微分 if(Rate5)/对误差变化率进行限制,锅炉温度不可能变化太大 Rate=5; if(RatePID_I_MAX ) I_OUT = PID_I_MAX; if( I_OUT= PWM_DATA_MAX ) PID_OUT = PWM_DATA_MAX; if ( PID_OUT =10) PID_OUT=16383; void main() Device_Init( ); while(1) LED8_Rollback;/系统运行指示灯 Parameter_Show( ); /定时器 A 服务程序,用来执行 PID 控制程序 #pragma vector=TIMERA0_VECTOR _interrupt void Timer_A(void) static u16 Counter=0;/时基计数器 static u16 Sum_Value=0; Counter+; /每 100ms 启动一次 AD 转换,并采集 AD 值 ADC12Start( ); /因为系统在初始化时已经进行过初始化采样计算,所以每一次读取值为上一次采样值 Sum_Value+=AD_Result; /每 1S 计算进行一次数据采样处理 if(Counter%10)=1) AD_Average=Sum_Value/10;/定于每一秒求平均值即 1000 毫秒(注意 2.5V 与 3.3V 转化) Sum_Value=0; 28 /每 2S 计算进行一次 PID 运算 if(Counter%20)=1) LED7_Rollback; if(Scale_Conv( AD_Average ) - Pre_Temp)1.2) Pre_Temp=0.35*(Scale_Conv( AD_Average ) + 0.65*Pre_Temp;/温度拟合 else if(Scale_Conv( AD_Average ) - Pre_Temp)15) return 0; ADC12CTL0 = ADC12ON + MSC + SHT0_0 + REFON + REF2_5V;/ 开启 ad,参考电压 2.5v ADC12CTL1 = SHP + ADC12SSEL_3; /Use sampling timer, SMCLK for(int i = 0;i = 0x80) return 0; *(char*)(ADC12MCTL0_ + i) = channelsi;/每个 MCTL 设置 *(char*)(ADC12MCTL0_ + n - 1) |= EOS;/序列结束 if(rep != 0)/多次转换 ADC12CTL1 |= CONSEQ_3; else ADC12CTL1 |= CONSEQ_1; ADC12IE = 131) /多次转换时 转换次数 /多次重复采样时,在这里方处理函数 DC12CTL0 /停止转换 AD_Result=Sum/32; Sum=0; i=0; #include “COMMON.h“ /* 32 函数名称:Delay_1ms 功 能:延时约 1ms 的时间 参 数:无 返回值 :无 */ void Delay_1ms(void) unsigned char i; for(i = 150;i 0;i-) _NOP(); /* 函数名称:Delay_Nms 功 能:延时 N 个 1ms 的时间 参 数:n-延时长度 返回值 :无 */ void Delay_Nms(unsigned int n) unsigned int i; for(i = n;i 0;i-) Delay_1ms(); #include “Modbus_ASCII.h“ u8 Sendbuf16 = 0x40,0x30,0x31,0x30,0x31,0,0,0,0,0,0,0,0,0,0,0x0d ;/单片 机发送缓冲 u8 Answer8 = 0x40,0x30,0x31,0,0,0,0,0x0d ;/下位机应答信息帧数组 u8 RecBuf36 = 0 ; u8 Tran_Data36= 0 ; u16 Integer_Paramrter12=0; float Operating_Paramrter12=0.0; static u8 RecFlag=0;/串口接收到字头标志 1:接收到字头 0:没接收到字头 static u8 RecCount=0;/接收到的数据个数(除去字头与字尾) static u8 Recv_Done=0;/接收完一帧数据 1:接收完一帧数据 0:没接收完数据 基于 MSP430 单片机的温度 PID 算法设计 33 /* 函数名称:UART0_RXISR 功 能:串口接收中断服务程序 参 数:无 返回值 :无 */ #pragma vector = UART0RX_VECTOR _interrupt void UART0_RXISR(void) u8 buf; buf=RXBUF0;/读数据 if(buf=Kingview_DataFrames_Start)/判断接收字头 RecFlag=1; if(RecFlag) RecBufRecCount=buf; RecCount+; if(buf=Kingview_DataFrames_End)/*判断接收是否完成*/ Recv_Done = 1; RecFlag=0; RecCount=0; Data_Delivery( ); P2DIR |= (BIT5); P2OUT |= (BIT5); void Data_Delivery(void) u8 Device_Addr; if(Recv_Done) 34 Recv_Done=0; Device_Addr =Dat_trans(RecBuf1,RecBuf2); if(check_CRC() break; case Kingview_Write: Write_Byte_Response(); break; else write_inform(*); void uartsends(u8 Buff,u8 Data_len) u8 i; for(i=0;i0x40) tmp2=Kingview_Slave_Device0_Addr if(tmp19) Answer1=tmp1+0x37; else Answer1=tmp1+0x30; if(tmp29) Answer2=tmp2+0x37; else Answer2=tmp2+0x30; Answer3=dat; Answer4=dat; xordat=0; for(i=1;i4) tmp2=Temp 36 if(tmp19) Answer5=tmp1+0x37; else Answer5=tmp1+0x30; if(tmp29) Answer6=tmp2+0x37; else Answer6=tmp2+0x30; uartsends(Answer,8); /* * 函数名:u8 check_CRC() * 描述 :对组态王发送过来的数据帧进行 CRC 校验 */ u8 check_CRC(void) u8 xordat,i,ctmp1,ctmp2,temp; u8 WR_Temp=0; WR_Temp=Read_Or_Write(); /读数据时,校验的数据长度一致 if(WR_Temp /*读数据时需要异或的位时 10 位 */ if(WR_Temp /*写字节时需要异或的位时 12 位*/ if(WR_Temp /*写字时需要异或的位时 14 位*/ if(WR_Temp /*写浮点数时需要异或的位时 18 位*/ xordat=0; for(i=1;i4) ctmp2=xordat if(ctmp19) ctmp1=ctmp1+0x37; else ctmp1=ctmp1+0x30; if(ctmp29) ctmp2=ctmp2+0x37; else ctmp2=ctmp2+0x30; 基于 MSP430 单片机的温度 PID 算法设计 37 if(ctmp1=RecBuftemp+1) else return 0; /浮点数到 ASCII 码的转换 void Float_to_ASC(u8 * c,float d) u8 i = 0,j = 0; u8 temp=0; bool ShuFu = false,JieFu = false; int inbyte2 = 0, inbyte3 = 0,inbyte4 = 0; float F_afterbyte2 = 0, F_afterbyte3 = 0; if(d = 0) for( j = 0; j 1) d =(float)(d / 2.0); i+ ; while(d 0x3f) i = 0x3f ; else if(i 0x32) i = 0x32 ; if(ShuFu) i = i | 0x80; if(JieFu) i = i | 0x40; temp=i/16; if(temp 0x40) JieFU = (Jiema0 Jiema2 = (Jiema0 if(JieFU) returnflo = (float)pow(2, (-1) * Jiema2) * Decimal; else returnflo = (float)pow(2, Jiema2) * Decimal; if(ShuFU) returnflo = (-1) * returnflo; return returnflo; * 函数名:Read_Byte_Response * 描述 :组态王为读指令时单片机的应答 * 调用 :外部调用 */ void Read_Byte_Response(void) u8 ctmp1,ctmp2,xordat,i; u8 Temp=0; u8 Data_Addr=0;/数据地址 u8 F_Temp8=0x30;/浮点数的 ASCII 暂存文件 if(Read_Or_Write()/开始字头 ctmp1=(Kingview_Slave_Device0_Addr4) ctmp2=Kingview_Slave_Device0_Addr if(ctmp19) Sendbuf1=ctmp1+0x37; else Sendbuf1=ctmp1+0x30; if(ctmp29) Sendbuf2=ctmp2+0x37; 基于 MSP430 单片机的温度 PID 算法设计 41 else Sendbuf2=ctmp2+0x30; Sendbuf3=0x30; Sendbuf4=0x31;/数据字节数:1 Data_Addr=Dat_trans(RecBuf5,RecBuf6)*256+Dat_trans(RecBuf7,RecBuf8)-Char_B ase_Address; Temp=Tran_DataData_Addr;/由地址寻址数据 ctmp1=(Temp4) ctmp2=Temp if(ctmp19) Sendbuf5=ctmp1+0x37; else Sendbuf5=ctmp1+0x30; if(ctmp29) Sendbuf6=ctmp2+0x37; else Sendbuf6=ctmp2+0x30; xordat=0; for(i=1;i4) ctmp2=Temp if(ctmp19) Sendbuf7=ctmp1+0x37; else Sendbuf7=ctmp1+0x30; if(ctmp29) Sendbuf8=ctmp2+0x37; else Sendbuf8=ctmp2+0x30; Sendbuf9= 0x0d; uartsends(Sendbuf,10); else if(Read_Or_Write()/开始字头 ctmp1=(Kingview_Slave_Device0_Addr4) ctmp2=Kingview_Slave_Device0_Addr if(ctmp19) Sendbuf1=ctmp1+0x37; 42 else Sendbuf1=ctmp1+0x30; if(ctmp29) Sendbuf2=ctmp2+0x37; else Sendbuf2=ctmp2+0x30; Sendbuf3= 0x30; Sendbuf4= 0x32;/数据字节数:2 Data_Addr=(Dat_trans(RecBuf5,RecBuf6)*256+Dat_trans(RecBuf7,RecBuf8)- Integer_Base_Address )/2; for(i=0; i(8*(1-i); ctmp1=(Temp4) ctmp2=Temp if(ctmp19) Sendbuf5+2*i=ctmp1+0x37; else Sendbuf5+2*i=ctmp1+0x30; if(ctmp29) Sendbuf6+2*i=ctmp2+0x37; else Sendbuf6+2*i=ctmp2+0x30; xordat=0; for(i=1;i4) ctmp2=Temp if(ctmp19) Sendbuf9=ctmp1+0x37; else Sendbuf9=ctmp1+0x30; if(ctmp29) Sendbuf10=ctmp2+0x37; else Sendbuf10=ctmp2+0x30; Sendbuf11= 0x0d; uartsends(Sendbuf,12); else if( (Read_Or_Write()/开始字头 ctmp1=(Kingview_Slave_Device0_Addr4) ctmp2= Kingview_Slave_Device0_Addr if(ctmp19) Sendbuf1=ctmp1+0x37; else Sendbuf1=ctmp1+0x30; if(ctmp29) Sendbuf2=ctmp2+0x37; else Sendbuf2=ctmp2+0x30; Sendbuf3= 0x30; Sendbuf4= 0x34;/数据字节数:4 Data_Addr=(Dat_trans(RecBuf5,RecBuf6)*256+Dat_trans(RecBuf7,RecBuf8)- Float_Base_Address )/4; /浮点数到 ASCII 码的转换 Float_to_ASC( F_Temp , Operating_ParamrterData_Addr); for(i=0;i4) ctmp2=Temp if(ctmp19) Sendbuf13=ctmp1+0x37; else Sendbuf13=ctmp1+0x30; if(ctmp29) Sendbuf14=ctmp2+0x37; else Sendbuf14=ctmp2+0x30; Sendbuf15= 0x0d; 44 uartsends(Sendbuf,16); else write_inform(#); Read_Data_from_Slave(); * 函数名:Write_Byte_Response * 描述 :组态王欲写数据到单片机时单片机的应答 * 输入 :无 * 输出 :无 * 调用 :外部调用 void Write_Byte_Response(void) u8 temp1,temp2; u8 c8; u8 Data_Addr=0;/数据地址 u8 i=0; if(Read_Or_Write()/获取目标数据在数组中的偏移量 temp1=Dat_trans(RecBuf11,RecBuf12); Tran_DataData_Addr=temp1; /将此数据放到此地址中 else if(Read_Or_Write()/获取目标数据在 数组中的偏移量 temp1=Dat_trans(RecBuf11,RecBuf12); temp2=Dat_trans(RecBuf13,RecBuf14); Integer_ParamrterData_Addr=temp1*256+temp2; else if(Read_Or_Write() i8; i+) ci=RecBuf11+i;/将浮点数字拆分的 8 个 ASCII 码转到 c 数组中 Data_Addr=(Dat_trans(RecBuf5,RecBuf6)*256+Dat_trans(RecBuf7,RecBuf8)- Float_Base_Address) /4 ;/确定浮点数要写入的地址在数组中的位置,获取目标数据在数组中的 偏移量 Operating_Paramrter Data_Addr = ASC_to_Float( c ); else write_inform(#); Writer_Data_to_Slave(); #include “TimerA_PWM.h“ u16 AD_Average=0; void TA_Init(void) TACTL=TASSEL0+TACLR;/设定定时器 A 控制寄存器 CCTL0=CCIE;/使能中断 CCR0=3276;/设置 CCR0 初值,及 100 毫秒中断一次 TACTL|=MC0;/计数器加模式 #include “TimerB.h“ /初始化定时器 A 函数 void TimerB_Init(void) TBCTL=TBSSEL_1+TBCLR+MC0+ID_3; TBCCTL1=OUTMOD_3; TBCCR0=16384;/PWM 中断周期 TBCCR1=4000;/PWM 低电平时间 P4DIR|=BIT1;/设置 PWMIO 口 P4SEL|=BIT1; 46 void TimerB_Duty(u16 duty) TBCCR1=duty;/PWM 低电平时间 #include “UART.h“ void UART0_Init(void) WDTCTL = WDTPW + WDTHOLD; /
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 追踪新动态的中级会计实务试题及答案
- 高级会计考试考生日记及试题答案
- 2025年中级会计实务考试的难点分析与应对试题及答案
- 2025至2030年中国毯帽胎市场分析及竞争策略研究报告
- 2025至2030年中国排装有字袋轧钢市场分析及竞争策略研究报告
- 2025年辣乳瓜项目可行性研究报告
- 新员工培训方法与实施步骤
- 商铺转让避税协议书
- 劳务派遣终止协议书
- 双方合作付款协议书
- 三相异步电动机直接启动控制电路
- GB/T 29645-2013塑料聚苯乙烯再生改性专用料
- GB/T 17766-2020固体矿产资源储量分类
- FZ/T 21001-2019自梳外毛毛条
- 酵母菌的简单染色和血细胞计数板计数课件
- 【表格】面试评估表(模板)
- 管道吊装专项方案
- 房屋租赁协议简单版(个人租房合同可打印)
- 学校质量监测应急预案
- 拟投入本项目主要人员汇总表(工程项目招投标资料模板)
- 保护性约束PPT通用PPT课件
评论
0/150
提交评论