完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
|
|
相关推荐
13个回答
|
|
显示新内容的时候没有把旧的内容清除掉,至于数字显示不出来,要看程序了,是不是没有做另外半屏的片选
|
|
|
|
#include
#include #include #include #include #define uchar unsigned char #define uint unsigned int #define KSP 0.18 // 比例 0.18 #define KSI 0.0045 // 积分 0.0045 #define KSD 0.0001 // 微分 0.0001 #define KSP1 0.14 // 比例 #define KSI1 0.0018 // 积分 #define KSD1 0.0001 // 微分 uchar code IC_DAT[]; uchar code pic1[]; uchar code pic2[]; uchar code pic3[]; uint size=0; //位置 uint sizechange,changesize=150; //高度变化停止用 uint displaytime; //定义屏幕刷新时间 uint Timetime; //计时 uint RTimetime; //响应 uint MTimetime; //保持 uint ZTimetime; //总时间 uint Beep1stime; //蜂鸣器1s定时时间 uchar flagchangeStar; //任务变化标志位 uchar shuzi; uchar code IC_DAT[]={ "任务要求: " "响应时间: s" "小球位置: mm" "保持时间: s" }; ***it RS = P1^4; ***it WRD = P1^5; ***it E = P1^6; //***it PSB = P4^3; //没有此引脚 ***it RES = P1^7; ***it RX = P3^7; ***it TX = P3^6; ***it BEEP = P3^5; uchar key,keysign,beeptime; bit flag =0; uchar flagStart=0; //启动标志位 uchar flagStart7=0; //启动标志位7 uchar flagStart6=0; //启动标志位7 uchar flagSep=0; //任务要求标志位 uchar pidchang=0; //任务要求标志位 uchar flagStart60=0; //任务6要求标志位 uchar flagStart61=0; //任务6要求标志位1 uchar beepchange1; uint time=0; int pwm=255; uint S=0,S1; void TransferData(char data1,bit DI); void display(void); void display_grapic(void); void delayms(uint n); void DisplayLine(uchar line1,uchar line2); void DisplayGraphic(uchar code *adder); void delay(uint m); void lcd_mesg(uchar code *adder1); void delay25us(void); /*==================================================================================================== PID Function The PID (比例、积分、微分) function is used in mainly control applications. PIDCalc performs one iteration of the PID algorithm. While the PID function works, main is just a dummy program showing a typical usage. 以下为PID参数定义 =====================================================================================================*/ typedef struct PID { float SetPoint; // 设定目标 Desired Value(期望值) float Proportion; // 比例常数 Proportional Const float Integral; // 积分常数 Integral Const float Derivative; // 微分常数 Derivative Const float LastError; // Error[-1] 最后一个误差 float PrevError; // Error[-2] float SumError; // Sums of Errors 总误差 }PID ; /*==================================================================================================== PID计算部分 =====================================================================================================*/ float PIDCalc( PID *pp, float NextPoint ) { float dError, Error, DUTY; Error = pp->SetPoint - NextPoint; // 偏差 设定 - 下一点 pp->SumError += Error; // 积分 误差和 dError = pp->LastError - pp->PrevError; // 当前微分 上一个 - 上上个 pp->PrevError = pp->LastError; //移位 上一个》上上个 pp->LastError = Error; //移位 上上个》误差 DUTY= ( pp->Proportion * Error // 比例项 比例*误差 + pp->Integral * pp->SumError // 积分项 积分*误差和 + pp->Derivative * dError // 微分项 微分*误差变化 ); if(DUTY>255){DUTY=255;} if(DUTY<-255){DUTY=-255;} return DUTY; } /*==================================================================================================== Initialize PID Structure =====================================================================================================*/ void PIDInit (PID *pp)//将PID各个参数初始化为0 { memset ( pp,0,sizeof(PID)); //MEM组 } /*==================================================================================================== Main Program =====================================================================================================*/ float sensor (void) // Dummy Sensor Function 虚拟传感器功能 { while(!S); return (float)S; //(S/255.0)*5.0; } void actuator(float rDelta) // Dummy Actuator Function 虚拟致动器的功能 { pwm=rDelta; //(rDelta/5.0)*255; if(pwm<0){pwm=0;} //高 if(pwm>255) pwm=255; //低 pwm=255-pwm; } /******************************************************************** * 名称 : 计数器 设T0为方式1,GATE=1 * 功能 : * 输入 : * 输出 : ***********************************************************************/ void InitTimer0(void) { TMOD = 0x11; TH0 = 0x10; TL0 = 0x00; TR0 = 1; } /******************************************************************** * 名称 : T0中断用来计数器溢出,超过测距范围 * 功能 : * 输入 : * 输出 : ***********************************************************************/ void Timer0Interrupt(void) interrupt 1 //T0中断用来计数器溢出,超过测距范围 { flag=1; //中断溢出标志 } void StartModule() //启动发射 { TX=1; delay25us(); TX=0; } /******************************************************************** * 名称 : Convert(uchar In_Date) * 功能 : 因为电路设计时,P0.0--P0.7接法刚好了资料中的相反,所以设计该函数。 * 输入 : 12864资料上的值 * 输出 : 送 ***********************************************************************/ unsigned char Convert(unsigned char In_Date) { unsigned char i, Out_Date = 0, temp = 0; for(i=0; i<8; i++) { temp = (In_Date >> i) & 0x01; Out_Date |= (temp << (7 - i)); } return Out_Date; } /******************************************************************** * 名称 : LCD字库初始化程序 * 功能 : 主函数 * 输入 : 无 * 输出 : 无 ***********************************************************************/ void initinal(void) //LCD字库初始化程序 { delay(40); //大于40MS的延时程序 // PSB=1; //设置为8BIT并口工作模式 delay(1); //延时 RES=0; //复位 delay(1); //延时 RES=1; //复位置高 delay(10); TransferData(0x30,0); //Extended Function Set :8BIT设置,RE=0: basic instruction set, G=0 :graphic display OFF delay(100); //大于100uS的延时程序 TransferData(0x30,0); //Function Set delay(37); ////大于37uS的延时程序 TransferData(0x08,0); //Display on Control delay(100); //大于100uS的延时程序 TransferData(0x10,0); //Cursor Display Control光标设置 delay(100); //大于100uS的延时程序 TransferData(0x0C,0); //Display Control,D=1,显示开 delay(100); //大于100uS的延时程序 TransferData(0x01,0); //Display Clear delay(10); //大于10mS的延时程序 TransferData(0x06,0); //Enry Mode Set,光标从右向左加1位移动 delay(100); //大于100uS的延时程序 } /******************************************************************** * 名称 : LCD显示图片(扩展)初始化程序 * 功能 : 主函数 * 输入 : 无 * 输出 : 无 ***********************************************************************/ void initina2(void) //LCD显示图片(扩展)初始化程序 { delay(40); //大于40MS的延时程序 // PSB=1; //设置为8BIT并口工作模式 delay(1); //延时 RES=0; //复位 delay(1); //延时 RES=1; //复位置高 delay(10); TransferData(0x36,0); //Extended Function Set RE=1: extended instruction delay(100); //大于100uS的延时程序 TransferData(0x36,0); //Extended Function Set:RE=1: extended instruction set delay(37); ////大于37uS的延时程序 TransferData(0x3E,0); //EXFUNCTION(DL=8BITS,RE=1,G=1) delay(100); //大于100uS的延时程序 TransferData(0x01,0); //CLEAR SCREEN delay(100); //大于100uS的延时程序 } /******************************************************************** * 名称 : 显示文字 * 功能 : 主函数 * 输入 : 无 * 输出 : 无 ***********************************************************************/ void lcd_mesg(unsigned char code *adder1) { unsigned char i; TransferData(0x80,0); //设置图形显示内存addressset图形显示内存地址 delay(100); for(i=0;i<32;i++) { TransferData(*adder1,1); adder1++; } TransferData(0x90,0); //设置图形显示内存地址 delay(100); for(i=32;i<64;i++) { TransferData(*adder1,1); adder1++; } } /******************************************************************** * 名称 : 传送数据或者命令 * 功能 : * 输入 : 无 * 输出 : 无 ***********************************************************************/ void TransferData(char data1,bit DI) //传送数据或者命令,当DI=0时,传送命令,当DI=1时,传送数据. { WRD=0; RS=DI; delay(1); P0=Convert(data1); E=1; delay(1); E=0; } void Conut(void) { time=TH0*256+TL0; TH0=0; TL0=0; S=time*0.179; //算出来是CM 11。0592M晶振 if(flag==1) //超出测量 { flag=0; } else { if(S>480) S1=0; else S1=480-S; } } void Distance(void) { StartModule(); //计算 while(!RX); //当RX为零时等待 TR0=1; //开启计数 while(RX); //当RX为1计数并等待 TR0=0; //关闭计数 Conut(); } /******************************************************************** * 名称 : 毫秒延时 * 功能 : * 输入 : 无 * 输出 : 无 ***********************************************************************/ void delayms(unsigned int xms) //延时xms毫秒 { unsigned int i,j; for(i=xms;i>0;i--) for(j=1320;j>0;j--); } /******************************************************************** * 名称 : 10us延时程序 * 功能 : * 输入 : 无 * 输出 : 无 ***********************************************************************/ void delay(unsigned int m) //延时程序 { unsigned int i,j; for(i=0;i } /******************************************************************** * 名称 : 25us延时程序 * 功能 : * 输入 : 无 * 输出 : 无 ***********************************************************************/ void delay25us(void) //延时25us误差 0us { unsigned char a,b; for(b=33;b>0;b--) for(a=3;a>0;a--); } void InitTimer1(void) //定时器初始化 { TMOD = 0x11; TH1 = 0x0EC; TL1 = 0x78; EA = 1; ET1 = 1; TR1 = 1; } void Timer1Interrupt(void) interrupt 3 { TH1 = 0x0EC; TL1 = 0x78; displaytime++; Timetime++; //计时 } /******************************************************************** * 名称 : 显示图形 * 功能 : 主函数 * 输入 : 无 * 输出 : 无 ***********************************************************************/ void DisplayGraphic(unsigned char code *adder) { int i,j; //显示上半屏内容设置 for(i=0;i<32;i++) { TransferData((0x80 + i),0); //SET 垂直地址 VERTICAL ADD TransferData(0x80,0); //SET 水平地址 HORIZONTAL ADD for(j=0;j<16;j++) { TransferData(*adder,1); adder++; } } //显示下半屏内容设置 for(i=0;i<32;i++) { TransferData((0x80 + i),0); //SET 垂直地址 VERTICAL ADD TransferData(0x88,0); //SET 水平地址 HORIZONTAL ADD for(j=0;j<16;j++) { TransferData(*adder,1); adder++; } } } unsigned char code pic2[]= { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x3F,0x00,0x03,0x98,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xFF,0x00,0x01,0x8C,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x03,0x37,0x80,0x01,0x88,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0xFF,0x00,0x01,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0xF6,0x00,0x03,0xF0,0x00,0x01,0xC0,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0x3E,0x00,0x07,0xF0,0x02,0x0F,0xE0,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0xF8,0x00,0x3F,0x80,0x03,0x07,0xC0,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x38,0x00,0x3F,0x00,0x03,0x01,0x80,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xF8,0x00,0x1F,0x90,0x01,0x83,0x80,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xF8,0x00,0x0D,0x98,0x01,0x03,0x60,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xFC,0x00,0x09,0x30,0x01,0x3F,0xF8,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0xE0,0x00,0x19,0x60,0x00,0x5C,0x38,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x9F,0xC0,0x12,0xC0,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x0F,0x78,0xE0,0x73,0x80,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x0C,0x03,0xE0,0x63,0x03,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x43,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0x00,0x06,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x01,0xB0,0x00,0x63,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x38,0x30,0x00,0x38,0x00,0x0D,0xA0,0x00,0xE3,0x80,0x00,0x00,0x00, 0x00,0x00,0x01,0xF0,0x78,0x00,0x1C,0x00,0x0C,0xE0,0x01,0xE3,0xF0,0x00,0x00,0x00, 0x00,0x00,0x00,0xDB,0xFC,0x00,0x9C,0x00,0x0C,0xFC,0x00,0x57,0x38,0x00,0x00,0x00, 0x00,0x00,0x00,0x0B,0x18,0x00,0xDF,0x00,0x0F,0xCE,0x01,0x58,0x30,0x00,0x00,0x00, 0x00,0x00,0x00,0xF9,0xB0,0x00,0xFB,0x80,0x1F,0x1E,0x03,0x73,0xC0,0x00,0x00,0x00, 0x00,0x00,0x00,0xE9,0xF0,0x04,0xDF,0x00,0x28,0x70,0x03,0xE7,0x80,0x00,0x00,0x00, 0x00,0x00,0x00,0x99,0xE0,0x07,0xDE,0x00,0x33,0xE0,0x03,0x46,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xF9,0x80,0x06,0xDC,0x00,0x63,0x60,0x02,0x05,0xC0,0x00,0x00,0x00, 0x00,0x00,0x00,0xD2,0x78,0x06,0xF8,0x00,0x60,0xC0,0x02,0x1F,0x80,0x00,0x00,0x00, 0x00,0x00,0x00,0xB5,0x8C,0x00,0x5F,0xE0,0x40,0xF0,0x02,0x1F,0x80,0x00,0x00,0x00, 0x00,0x00,0x01,0xFE,0x1C,0x01,0xFF,0xF0,0x07,0xB8,0x02,0x85,0x80,0x00,0x00,0x00, 0x00,0x00,0x03,0x96,0x04,0x1F,0xE0,0xF0,0x08,0x20,0x03,0x09,0x00,0x00,0x00,0x00, 0x00,0x00,0x02,0x10,0x00,0x1F,0x00,0x00,0x00,0x20,0x03,0x33,0x04,0x00,0x00,0x00, 0x00,0x00,0x00,0x10,0x00,0x0C,0x00,0x00,0x04,0x60,0x01,0x23,0x0C,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xC0,0x01,0x01,0xFC,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, }; /*******************************************************************/ /* */ /* 矩阵键盘扫描 */ /* */ /*******************************************************************/ uchar keyscan(void)//键盘扫描函数,使用行列反转扫描法 比如:行为低电位,列为高四位 { uchar cord_h,cord_l;//行列值 P2=0x0f;//行线输出全为0 cord_h=P2&0x0f;//读入列线值 if(cord_h!=0x0f) //先检测有无按键按下 { delay(1); //去抖 if(cord_h!=0x0f) { cord_h=P2&0x0f; //读入列线值 P2=cord_h|0xf0; //输出当前列线值 cord_l=P2&0xf0; //读入行线值 return(cord_h+cord_l);//键盘最后组合码值 } } else return(0xff);//返回该值 } /**********************************************************/ void beep() { uchar i; for (i=0;i<100;i++) { delay(10); BEEP=!BEEP; //BEEP取反 } BEEP=1; //关闭蜂鸣器 } void beepchange() //变音蜂鸣器 { uchar i; for (i=0;i<(20-beeptime)*10;i++) { delay((beeptime+2)*3); BEEP=!BEEP; //BEEP取反 } BEEP=1; //关闭蜂鸣器 } /******************************************************************** * 名称 : Main() * 功能 : 主函数 * 输入 : 无 * 输出 : 无 ***********************************************************************/ void main(void) { PID sPID; // PID Control Structure PID控制结构 float rOut; // PID Response (Output) PID控制器的响应(输出) float rIn; // PID Feedback (Input) PID反馈(输入) PIDInit ( &sPID ); // Initialize Structure if(pidchang==0) // 准 { sPID.Proportion = KSP; // Set PID Coefficients 比例 sPID.Integral = KSI; // 积分 sPID.Derivative = KSD; // 微分 } if(pidchang==1) // 稳 { sPID.Proportion = KSP1; // Set PID Coefficients 比例 sPID.Integral = KSI1; // 积分 sPID.Derivative = KSD1; // 微分 } sPID.SetPoint = size; // Set PID Setpoint 设定值 P4SW = 0x70; initina2(); //调用LCD显示图片(扩展)初始化程序 DisplayGraphic(pic2); //显示图片2 beep(); beep(); delayms(200); initinal(); //调用LCD字库初始化程序 delay(100); //大于100uS的延时程序 lcd_mesg(IC_DAT); //显示中文汉字1 InitTimer0(); //计时器 InitTimer1(); //中断初始化 CCON = 0; //主控制寄存器的初始 //PCA timer 停止运行 //清除CF标志 //清除所有中断标志模块 CL = 0; //复位 PCA base timer CH = 0; CMOD = 0x02; //设置 PCA timer 时钟源在 Fosc/2 //禁用PCA timer溢出中断 CCAP0H = CCAP0L = 0xff; //pwm0端口输出的50%占空比的矩形波 CCAPM0 = 0x42; //PCA模块工作在8位PWM模式 禁止PCA中断 CCAP1H = CCAP1L = 0xff; //PWM1输出端口0方波的占空比 CCAPM1 = 0x42; //PCA模块工作在8位PWM模式 禁止PCA中断 CR = 1; //PCA timer 启动运行 beep(); beep(); while(1) { sPID.SetPoint = 480-size; // Set PID Setpoint 设定值 Distance(); delayms(10); // CCAP1H = CCAP1L = pwm; //pwm0端口输出的50%占空比的矩形方波 CCAP0H = CCAP0L = pwm; //pwm0端口输出的50%占空比的矩形方波 key=keyscan();//调用键盘扫描, switch(key) { case 235:key=0;break; //0 按下相应的键显示相对应的码值 原理就是高四位一列低四位一列的组 //合。0111 1110 7e 0表示按键后为0,1表示没有按键按下的。 //其他类推。 case 119:key=1;break; //1 case 123:key=2;break; //2 case 125:key=3;break; //3 case 183:key=4;break; //4 case 187:key=5;break; //5 case 189:key=6;break; //6 case 215:key=7;break; //7 case 219:key=8;break; //8 case 221:key=9;break; //9 case 126:key=10;break; //A case 190:key=11;break; //B case 222:key=12;break; //C case 238:key=13;break; //D case 231:key=14;break; //* case 237:key=15;break; //# case 255:key=16;break; //空 } if(key==16) { if(keysign!=16) { beeptime=keysign; if(beeptime!=14) { if((flagStart==1)&&(beeptime<=9)) {flagStart=1; beepchange1=1;} else beepchange(); } if((flagStart==0)&&(keysign<=9)) {flagSep=keysign; shuzi=keysign;} //任务显示 if((flagStart==1)&&(keysign<=9)) { size=200-keysign*10; pidchang=1;} //任务3 if((shuzi==2)&&(flagSep==1)) { } //任务3 if(keysign==15) { ZTimetime=0; flagStart=1; //标志位置1 if(flagSep==1) { if(flagStart6==0)size=150; }//任务1 位置 if(keysign==5) flagchangeStar=5 ; //任务5 位置 } if(keysign==14) {flagStart=3;beepchange1=0; } //标志位置0 BEEP可以等于0; } } keysign=key; //上次的按键 //***任务要求函数等等*** if((flagStart==1)&&(flagSep==1)) { rIn = sensor (); //把S转成浮点型 // Read Input 读取输入 rOut = PIDCalc ( &sPID,rIn ); //PID // Perform PID Interation actuator ( rOut+pwm ); //占空比 // Effect Needed Changes } //***取消小球下降函数*** if(flagStart==3) { rIn = sensor (); //把S转成浮点型 // Read Input 读取输入 rOut = PIDCalc ( &sPID,rIn ); //PID // Perform PID Interation actuator ( rOut+pwm ); //占空比 // Effect Needed Changes size=sizechange+changesize; if(S1>=450) { sizechange=0; //最低点清 0 flagStart=0; BEEP=1; pwm=255; flagSep=0; flagchangeStar=0; } } if((flagSep==5)&&(flagStart==1)) { pidchang=1; if(S1>100) pwm=95; if(S1<150) {flagSep=1;size=1;} } /******************************************************************** * 名称 : 屏幕数据刷新 * 功能 : * 输入 : 无 * 输出 : 无 ***********************************************************************/ if(displaytime>=100 ) { if(flagStart==3) sizechange=sizechange+40; //下降专用 距离下降 左后停止 TransferData(0x95,0); TransferData(0x17,1); //高度显示 TransferData(S1%1000/100+0x30,1); TransferData(S1%100/10+0x30,1); TransferData(S1%10+0x30,1); TransferData(0x8D,0); //响应时间显示 TransferData(RTimetime/100%10+0x30,1); TransferData(RTimetime%100/10+0x30,1); TransferData(0x2E,1); TransferData(RTimetime%10+0x30,1); TransferData(0x9d,0); //保持时间显示 TransferData(MTimetime/100%10+0x30,1); TransferData(MTimetime%100/10+0x30,1); TransferData(0x2E,1); TransferData(MTimetime%10+0x30,1); displaytime=0; TransferData(0x85,0); //任务要求显示 TransferData(0x20,1); if(flagStart==1) TransferData(0x11,1); else TransferData(0x3C,1); TransferData(shuzi+0x30,1); if(flagStart==1) TransferData(0x10,1); else TransferData(0x3E,1); } if((Timetime>=22)&&(flagStart==1)) //0.1s的保持与采样时间计算 { ZTimetime++; //总时间 if((flagSep==5)&&(S1>=100)) { RTimetime=ZTimetime; //响应时间S } if((size==301)&&(S1<200)) { size=50; } if((flagSep==1)&&((110>=S1)|(S1>=190))&&(size==150)) { RTimetime=ZTimetime; //响应时间S pidchang=1; } if((flagSep==1)&&((10>=S1)|(S1>=90))&&(size==50)) { RTimetime=ZTimetime; //响应时间S pidchang=1; } if((flagSep==1)&&((210>=S1)|(S1>=290))&&(size==250)) { RTimetime=ZTimetime; //响应时间S pidchang=1; } else { Beep1stime++; if(Beep1stime>=1) BEEP=1; if((Beep1stime>=10)&&(beepchange1!=1)) {BEEP=0;Beep1stime=0; } } MTimetime=ZTimetime-RTimetime; //保持时间 Timetime=0; if(size==301) MTimetime=0; } if(flagSep==6) { flagStart6=1; flagSep=1; size=301; pidchang=0; } if ((MTimetime>=30)&&(flagStart6==1)) { flagStart61++; if (flagStart60==0) { size=250; flagStart60=1; pidchang=0; } else { size=50; flagStart60=0; pidchang=0; } MTimetime=0; ZTimetime=0; RTimetime=0; } if (flagStart61>=4){pwm=0; flagSep=0;} if(flagSep==7) //要求7功能 { if((S1>=2)&&(flagStart7==0)){pwm=0;flagStart7=1;} //启动标志位 else if(flagStart7==1) { if (S1>=140) {flagSep=1; size=150;} } } if(flagSep==2) //要求7功能 { flagSep=1; pidchang=0; } } } |
|
|
|
#include #include #include #include #include #define uchar unsigned char #define uint unsigned int #define KSP 0.18 // 比例 0.18 #define KSI 0.0045 // 积分 0.0045 #define KSD 0.0001 // 微分 0.0001 #define KSP1 0.14 // 比例 #define KSI1 0.0018 // 积分 #define KSD1 0.0001 // 微分 uchar code IC_DAT[]; uchar code pic1[]; uchar code pic2[]; uchar code pic3[]; uint size=0; //位置 uint sizechange,changesize=150; //高度变化停止用 uint displaytime; //定义屏幕刷新时间 uint Timetime; //计时 uint RTimetime; //响应 uint MTimetime; //保持 uint ZTimetime; //总时间 uint Beep1stime; //蜂鸣器1s定时时间 uchar flagchangeStar; //任务变化标志位 uchar shuzi; uchar code IC_DAT[]={ "任务要求: " "响应时间: s" "小球位置: mm" "保持时间: s" }; ***it RS = P1^4; ***it WRD = P1^5; ***it E = P1^6; //***it PSB = P4^3; //没有此引脚 ***it RES = P1^7; ***it RX = P3^7; ***it TX = P3^6; ***it BEEP = P3^5; uchar key,keysign,beeptime; bit flag =0; uchar flagStart=0; //启动标志位 uchar flagStart7=0; //启动标志位7 uchar flagStart6=0; //启动标志位7 uchar flagSep=0; //任务要求标志位 uchar pidchang=0; //任务要求标志位 uchar flagStart60=0; //任务6要求标志位 uchar flagStart61=0; //任务6要求标志位1 uchar beepchange1; uint time=0; int pwm=255; uint S=0,S1; void TransferData(char data1,bit DI); void display(void); void display_grapic(void); void delayms(uint n); void DisplayLine(uchar line1,uchar line2); void DisplayGraphic(uchar code *adder); void delay(uint m); void lcd_mesg(uchar code *adder1); void delay25us(void); /*==================================================================================================== PID Function The PID (比例、积分、微分) function is used in mainly control applications. PIDCalc performs one iteration of the PID algorithm. While the PID function works, main is just a dummy program showing a typical usage. 以下为PID参数定义 =====================================================================================================*/ typedef struct PID { float SetPoint; // 设定目标 Desired Value(期望值) float Proportion; // 比例常数 Proportional Const float Integral; // 积分常数 Integral Const float Derivative; // 微分常数 Derivative Const float LastError; // Error[-1] 最后一个误差 float PrevError; // Error[-2] float SumError; // Sums of Errors 总误差 }PID ; /*==================================================================================================== PID计算部分 =====================================================================================================*/ float PIDCalc( PID *pp, float NextPoint ) { float dError, Error, DUTY; Error = pp->SetPoint - NextPoint; // 偏差 设定 - 下一点 pp->SumError += Error; // 积分 误差和 dError = pp->LastError - pp->PrevError; // 当前微分 上一个 - 上上个 pp->PrevError = pp->LastError; //移位 上一个》上上个 pp->LastError = Error; //移位 上上个》误差 DUTY= ( pp->Proportion * Error // 比例项 比例*误差 + pp->Integral * pp->SumError // 积分项 积分*误差和 + pp->Derivative * dError // 微分项 微分*误差变化 ); if(DUTY>255){DUTY=255;} if(DUTY<-255){DUTY=-255;} return DUTY; } /*==================================================================================================== Initialize PID Structure =====================================================================================================*/ void PIDInit (PID *pp)//将PID各个参数初始化为0 { memset ( pp,0,sizeof(PID)); //MEM组 } /*==================================================================================================== Main Program =====================================================================================================*/ float sensor (void) // Dummy Sensor Function 虚拟传感器功能 { while(!S); return (float)S; //(S/255.0)*5.0; } void actuator(float rDelta) // Dummy Actuator Function 虚拟致动器的功能 { pwm=rDelta; //(rDelta/5.0)*255; if(pwm<0){pwm=0;} //高 if(pwm>255) pwm=255; //低 pwm=255-pwm; } /******************************************************************** * 名称 : 计数器 设T0为方式1,GATE=1 * 功能 : * 输入 : * 输出 : ***********************************************************************/ void InitTimer0(void) { TMOD = 0x11; TH0 = 0x10; TL0 = 0x00; TR0 = 1; } /******************************************************************** * 名称 : T0中断用来计数器溢出,超过测距范围 * 功能 : * 输入 : * 输出 : ***********************************************************************/ void Timer0Interrupt(void) interrupt 1 //T0中断用来计数器溢出,超过测距范围 { flag=1; //中断溢出标志 } void StartModule() //启动发射 { TX=1; delay25us(); TX=0; } /******************************************************************** * 名称 : Convert(uchar In_Date) * 功能 : 因为电路设计时,P0.0--P0.7接法刚好了资料中的相反,所以设计该函数。 * 输入 : 12864资料上的值 * 输出 : 送 ***********************************************************************/ unsigned char Convert(unsigned char In_Date) { unsigned char i, Out_Date = 0, temp = 0; for(i=0; i<8; i++) { temp = (In_Date >> i) & 0x01; Out_Date |= (temp << (7 - i)); } return Out_Date; } /******************************************************************** * 名称 : LCD字库初始化程序 * 功能 : 主函数 * 输入 : 无 * 输出 : 无 ***********************************************************************/ void initinal(void) //LCD字库初始化程序 { delay(40); //大于40MS的延时程序 // PSB=1; //设置为8BIT并口工作模式 delay(1); //延时 RES=0; //复位 delay(1); //延时 RES=1; //复位置高 delay(10); TransferData(0x30,0); //Extended Function Set :8BIT设置,RE=0: basic instruction set, G=0 :graphic display OFF delay(100); //大于100uS的延时程序 TransferData(0x30,0); //Function Set delay(37); ////大于37uS的延时程序 TransferData(0x08,0); //Display on Control delay(100); //大于100uS的延时程序 TransferData(0x10,0); //Cursor Display Control光标设置 delay(100); //大于100uS的延时程序 TransferData(0x0C,0); //Display Control,D=1,显示开 delay(100); //大于100uS的延时程序 TransferData(0x01,0); //Display Clear delay(10); //大于10mS的延时程序 TransferData(0x06,0); //Enry Mode Set,光标从右向左加1位移动 delay(100); //大于100uS的延时程序 } /******************************************************************** * 名称 : LCD显示图片(扩展)初始化程序 * 功能 : 主函数 * 输入 : 无 * 输出 : 无 ***********************************************************************/ void initina2(void) //LCD显示图片(扩展)初始化程序 { delay(40); //大于40MS的延时程序 // PSB=1; //设置为8BIT并口工作模式 delay(1); //延时 RES=0; //复位 delay(1); //延时 RES=1; //复位置高 delay(10); TransferData(0x36,0); //Extended Function Set RE=1: extended instruction delay(100); //大于100uS的延时程序 TransferData(0x36,0); //Extended Function Set:RE=1: extended instruction set delay(37); ////大于37uS的延时程序 TransferData(0x3E,0); //EXFUNCTION(DL=8BITS,RE=1,G=1) delay(100); //大于100uS的延时程序 TransferData(0x01,0); //CLEAR SCREEN delay(100); //大于100uS的延时程序 } /******************************************************************** * 名称 : 显示文字 * 功能 : 主函数 * 输入 : 无 * 输出 : 无 ***********************************************************************/ void lcd_mesg(unsigned char code *adder1) { unsigned char i; TransferData(0x80,0); //设置图形显示内存addressset图形显示内存地址 delay(100); for(i=0;i<32;i++) { TransferData(*adder1,1); adder1++; } TransferData(0x90,0); //设置图形显示内存地址 delay(100); for(i=32;i<64;i++) { TransferData(*adder1,1); adder1++; } } /******************************************************************** * 名称 : 传送数据或者命令 * 功能 : * 输入 : 无 * 输出 : 无 ***********************************************************************/ void TransferData(char data1,bit DI) //传送数据或者命令,当DI=0时,传送命令,当DI=1时,传送数据. { WRD=0; RS=DI; delay(1); P0=Convert(data1); E=1; delay(1); E=0; } void Conut(void) { time=TH0*256+TL0; TH0=0; TL0=0; S=time*0.179; //算出来是CM 11。0592M晶振 if(flag==1) //超出测量 { flag=0; } else { if(S>480) S1=0; else S1=480-S; } } void Distance(void) { StartModule(); //计算 while(!RX); //当RX为零时等待 TR0=1; //开启计数 while(RX); //当RX为1计数并等待 TR0=0; //关闭计数 Conut(); } /******************************************************************** * 名称 : 毫秒延时 * 功能 : * 输入 : 无 * 输出 : 无 ***********************************************************************/ void delayms(unsigned int xms) //延时xms毫秒 { unsigned int i,j; for(i=xms;i>0;i--) for(j=1320;j>0;j--); } /******************************************************************** * 名称 : 10us延时程序 * 功能 : * 输入 : 无 * 输出 : 无 ***********************************************************************/ void delay(unsigned int m) //延时程序 { unsigned int i,j; for(i=0;i } /******************************************************************** * 名称 : 25us延时程序 * 功能 : * 输入 : 无 * 输出 : 无 ***********************************************************************/ void delay25us(void) //延时25us误差 0us { unsigned char a,b; for(b=33;b>0;b--) for(a=3;a>0;a--); } void InitTimer1(void) //定时器初始化 { TMOD = 0x11; TH1 = 0x0EC; TL1 = 0x78; EA = 1; ET1 = 1; TR1 = 1; } void Timer1Interrupt(void) interrupt 3 { TH1 = 0x0EC; TL1 = 0x78; displaytime++; Timetime++; //计时 } /******************************************************************** * 名称 : 显示图形 * 功能 : 主函数 * 输入 : 无 * 输出 : 无 ***********************************************************************/ void DisplayGraphic(unsigned char code *adder) { int i,j; //显示上半屏内容设置 for(i=0;i<32;i++) { TransferData((0x80 + i),0); //SET 垂直地址 VERTICAL ADD TransferData(0x80,0); //SET 水平地址 HORIZONTAL ADD for(j=0;j<16;j++) { TransferData(*adder,1); adder++; } } //显示下半屏内容设置 for(i=0;i<32;i++) { TransferData((0x80 + i),0); //SET 垂直地址 VERTICAL ADD TransferData(0x88,0); //SET 水平地址 HORIZONTAL ADD for(j=0;j<16;j++) { TransferData(*adder,1); adder++; } } } unsigned char code pic2[]= { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x3F,0x00,0x03,0x98,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xFF,0x00,0x01,0x8C,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x03,0x37,0x80,0x01,0x88,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0xFF,0x00,0x01,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0xF6,0x00,0x03,0xF0,0x00,0x01,0xC0,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0x3E,0x00,0x07,0xF0,0x02,0x0F,0xE0,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0xF8,0x00,0x3F,0x80,0x03,0x07,0xC0,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x38,0x00,0x3F,0x00,0x03,0x01,0x80,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xF8,0x00,0x1F,0x90,0x01,0x83,0x80,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xF8,0x00,0x0D,0x98,0x01,0x03,0x60,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xFC,0x00,0x09,0x30,0x01,0x3F,0xF8,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0xE0,0x00,0x19,0x60,0x00,0x5C,0x38,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x9F,0xC0,0x12,0xC0,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x0F,0x78,0xE0,0x73,0x80,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x0C,0x03,0xE0,0x63,0x03,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x43,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0x00,0x06,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x01,0xB0,0x00,0x63,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x38,0x30,0x00,0x38,0x00,0x0D,0xA0,0x00,0xE3,0x80,0x00,0x00,0x00, 0x00,0x00,0x01,0xF0,0x78,0x00,0x1C,0x00,0x0C,0xE0,0x01,0xE3,0xF0,0x00,0x00,0x00, 0x00,0x00,0x00,0xDB,0xFC,0x00,0x9C,0x00,0x0C,0xFC,0x00,0x57,0x38,0x00,0x00,0x00, 0x00,0x00,0x00,0x0B,0x18,0x00,0xDF,0x00,0x0F,0xCE,0x01,0x58,0x30,0x00,0x00,0x00, 0x00,0x00,0x00,0xF9,0xB0,0x00,0xFB,0x80,0x1F,0x1E,0x03,0x73,0xC0,0x00,0x00,0x00, 0x00,0x00,0x00,0xE9,0xF0,0x04,0xDF,0x00,0x28,0x70,0x03,0xE7,0x80,0x00,0x00,0x00, 0x00,0x00,0x00,0x99,0xE0,0x07,0xDE,0x00,0x33,0xE0,0x03,0x46,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xF9,0x80,0x06,0xDC,0x00,0x63,0x60,0x02,0x05,0xC0,0x00,0x00,0x00, 0x00,0x00,0x00,0xD2,0x78,0x06,0xF8,0x00,0x60,0xC0,0x02,0x1F,0x80,0x00,0x00,0x00, 0x00,0x00,0x00,0xB5,0x8C,0x00,0x5F,0xE0,0x40,0xF0,0x02,0x1F,0x80,0x00,0x00,0x00, 0x00,0x00,0x01,0xFE,0x1C,0x01,0xFF,0xF0,0x07,0xB8,0x02,0x85,0x80,0x00,0x00,0x00, 0x00,0x00,0x03,0x96,0x04,0x1F,0xE0,0xF0,0x08,0x20,0x03,0x09,0x00,0x00,0x00,0x00, 0x00,0x00,0x02,0x10,0x00,0x1F,0x00,0x00,0x00,0x20,0x03,0x33,0x04,0x00,0x00,0x00, 0x00,0x00,0x00,0x10,0x00,0x0C,0x00,0x00,0x04,0x60,0x01,0x23,0x0C,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xC0,0x01,0x01,0xFC,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, }; /*******************************************************************/ /* */ /* 矩阵键盘扫描 */ /* */ /*******************************************************************/ uchar keyscan(void)//键盘扫描函数,使用行列反转扫描法 比如:行为低电位,列为高四位 { uchar cord_h,cord_l;//行列值 P2=0x0f;//行线输出全为0 cord_h=P2&0x0f;//读入列线值 if(cord_h!=0x0f) //先检测有无按键按下 { delay(1); //去抖 if(cord_h!=0x0f) { cord_h=P2&0x0f; //读入列线值 P2=cord_h|0xf0; //输出当前列线值 cord_l=P2&0xf0; //读入行线值 return(cord_h+cord_l);//键盘最后组合码值 } } else return(0xff);//返回该值 } /**********************************************************/ void beep() { uchar i; for (i=0;i<100;i++) { delay(10); BEEP=!BEEP; //BEEP取反 } BEEP=1; //关闭蜂鸣器 } void beepchange() //变音蜂鸣器 { uchar i; for (i=0;i<(20-beeptime)*10;i++) { delay((beeptime+2)*3); BEEP=!BEEP; //BEEP取反 } BEEP=1; //关闭蜂鸣器 } /******************************************************************** * 名称 : Main() * 功能 : 主函数 * 输入 : 无 * 输出 : 无 ***********************************************************************/ void main(void) { PID sPID; // PID Control Structure PID控制结构 float rOut; // PID Response (Output) PID控制器的响应(输出) float rIn; // PID Feedback (Input) PID反馈(输入) PIDInit ( &sPID ); // Initialize Structure if(pidchang==0) // 准 { sPID.Proportion = KSP; // Set PID Coefficients 比例 sPID.Integral = KSI; // 积分 sPID.Derivative = KSD; // 微分 } if(pidchang==1) // 稳 { sPID.Proportion = KSP1; // Set PID Coefficients 比例 sPID.Integral = KSI1; // 积分 sPID.Derivative = KSD1; // 微分 } sPID.SetPoint = size; // Set PID Setpoint 设定值 P4SW = 0x70; initina2(); //调用LCD显示图片(扩展)初始化程序 DisplayGraphic(pic2); //显示图片2 beep(); beep(); delayms(200); initinal(); //调用LCD字库初始化程序 delay(100); //大于100uS的延时程序 lcd_mesg(IC_DAT); //显示中文汉字1 InitTimer0(); //计时器 InitTimer1(); //中断初始化 CCON = 0; //主控制寄存器的初始 //PCA timer 停止运行 //清除CF标志 //清除所有中断标志模块 CL = 0; //复位 PCA base timer CH = 0; CMOD = 0x02; //设置 PCA timer 时钟源在 Fosc/2 //禁用PCA timer溢出中断 CCAP0H = CCAP0L = 0xff; //pwm0端口输出的50%占空比的矩形波 CCAPM0 = 0x42; //PCA模块工作在8位PWM模式 禁止PCA中断 CCAP1H = CCAP1L = 0xff; //PWM1输出端口0方波的占空比 CCAPM1 = 0x42; //PCA模块工作在8位PWM模式 禁止PCA中断 CR = 1; //PCA timer 启动运行 beep(); beep(); while(1) { sPID.SetPoint = 480-size; // Set PID Setpoint 设定值 Distance(); delayms(10); // CCAP1H = CCAP1L = pwm; //pwm0端口输出的50%占空比的矩形方波 CCAP0H = CCAP0L = pwm; //pwm0端口输出的50%占空比的矩形方波 key=keyscan();//调用键盘扫描, switch(key) { case 235:key=0;break; //0 按下相应的键显示相对应的码值 原理就是高四位一列低四位一列的组 //合。0111 1110 7e 0表示按键后为0,1表示没有按键按下的。 //其他类推。 case 119:key=1;break; //1 case 123:key=2;break; //2 case 125:key=3;break; //3 case 183:key=4;break; //4 case 187:key=5;break; //5 case 189:key=6;break; //6 case 215:key=7;break; //7 case 219:key=8;break; //8 case 221:key=9;break; //9 case 126:key=10;break; //A case 190:key=11;break; //B case 222:key=12;break; //C case 238:key=13;break; //D case 231:key=14;break; //* case 237:key=15;break; //# case 255:key=16;break; //空 } if(key==16) { if(keysign!=16) { beeptime=keysign; if(beeptime!=14) { if((flagStart==1)&&(beeptime<=9)) {flagStart=1; beepchange1=1;} else beepchange(); } if((flagStart==0)&&(keysign<=9)) {flagSep=keysign; shuzi=keysign;} //任务显示 if((flagStart==1)&&(keysign<=9)) { size=200-keysign*10; pidchang=1;} //任务3 if((shuzi==2)&&(flagSep==1)) { } //任务3 if(keysign==15) { ZTimetime=0; flagStart=1; //标志位置1 if(flagSep==1) { if(flagStart6==0)size=150; }//任务1 位置 if(keysign==5) flagchangeStar=5 ; //任务5 位置 } if(keysign==14) {flagStart=3;beepchange1=0; } //标志位置0 BEEP可以等于0; } } keysign=key; //上次的按键 //***任务要求函数等等*** if((flagStart==1)&&(flagSep==1)) { rIn = sensor (); //把S转成浮点型 // Read Input 读取输入 rOut = PIDCalc ( &sPID,rIn ); //PID // Perform PID Interation actuator ( rOut+pwm ); //占空比 // Effect Needed Changes } //***取消小球下降函数*** if(flagStart==3) { rIn = sensor (); //把S转成浮点型 // Read Input 读取输入 rOut = PIDCalc ( &sPID,rIn ); //PID // Perform PID Interation actuator ( rOut+pwm ); //占空比 // Effect Needed Changes size=sizechange+changesize; if(S1>=450) { sizechange=0; //最低点清 0 flagStart=0; BEEP=1; pwm=255; flagSep=0; flagchangeStar=0; } } if((flagSep==5)&&(flagStart==1)) { pidchang=1; if(S1>100) pwm=95; if(S1<150) {flagSep=1;size=1;} } /******************************************************************** * 名称 : 屏幕数据刷新 * 功能 : * 输入 : 无 * 输出 : 无 ***********************************************************************/ if(displaytime>=100 ) { if(flagStart==3) sizechange=sizechange+40; //下降专用 距离下降 左后停止 TransferData(0x95,0); TransferData(0x17,1); //高度显示 TransferData(S1%1000/100+0x30,1); TransferData(S1%100/10+0x30,1); TransferData(S1%10+0x30,1); TransferData(0x8D,0); //响应时间显示 TransferData(RTimetime/100%10+0x30,1); TransferData(RTimetime%100/10+0x30,1); TransferData(0x2E,1); TransferData(RTimetime%10+0x30,1); TransferData(0x9d,0); //保持时间显示 TransferData(MTimetime/100%10+0x30,1); TransferData(MTimetime%100/10+0x30,1); TransferData(0x2E,1); TransferData(MTimetime%10+0x30,1); displaytime=0; TransferData(0x85,0); //任务要求显示 TransferData(0x20,1); if(flagStart==1) TransferData(0x11,1); else TransferData(0x3C,1); TransferData(shuzi+0x30,1); if(flagStart==1) TransferData(0x10,1); else TransferData(0x3E,1); } if((Timetime>=22)&&(flagStart==1)) //0.1s的保持与采样时间计算 { ZTimetime++; //总时间 if((flagSep==5)&&(S1>=100)) { RTimetime=ZTimetime; //响应时间S } if((size==301)&&(S1<200)) { size=50; } if((flagSep==1)&&((110>=S1)|(S1>=190))&&(size==150)) { RTimetime=ZTimetime; //响应时间S pidchang=1; } if((flagSep==1)&&((10>=S1)|(S1>=90))&&(size==50)) { RTimetime=ZTimetime; //响应时间S pidchang=1; } if((flagSep==1)&&((210>=S1)|(S1>=290))&&(size==250)) { RTimetime=ZTimetime; //响应时间S pidchang=1; } else { Beep1stime++; if(Beep1stime>=1) BEEP=1; if((Beep1stime>=10)&&(beepchange1!=1)) {BEEP=0;Beep1stime=0; } } MTimetime=ZTimetime-RTimetime; //保持时间 Timetime=0; if(size==301) MTimetime=0; } if(flagSep==6) { flagStart6=1; flagSep=1; size=301; pidchang=0; } if ((MTimetime>=30)&&(flagStart6==1)) { flagStart61++; if (flagStart60==0) { size=250; flagStart60=1; pidchang=0; } else { size=50; flagStart60=0; pidchang=0; } MTimetime=0; ZTimetime=0; RTimetime=0; } if (flagStart61>=4){pwm=0; flagSep=0;} if(flagSep==7) //要求7功能 { if((S1>=2)&&(flagStart7==0)){pwm=0;flagStart7=1;} //启动标志位 else if(flagStart7==1) { if (S1>=140) {flagSep=1; size=150;} } } if(flagSep==2) //要求7功能 { flagSep=1; pidchang=0; } } } |
|
|
|
我也是刚弄,不咋懂,指教一下,可以吗 |
|
|
|
12864显示 [url]https://bbs.elecfans.com/jishu_496499_1_1.html (出处: 中国电子技术论坛)[/url]这个可以参考参考
|
|
|
|
人中狼 发表于 2017-4-26 18:51 谢谢 |
|
|
|
|
|
|
|
|
|
|
|
12864好像没有专门的清屏命令,所以清屏就是直接向液晶写0x00,我都是这样做的
|
|
|
|
我刚才发的程序,您有时间
|
|
|
|
我刚才给你发的程序,您有时间给我看一下吗 |
|
|
|
没用过这款屏,这款屏好像分字符模式,图形模式等,你要好好看屏的说明,模式不对的话,可能该显示的都显示不出来
|
|
|
|
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
298 浏览 1 评论
《DNESP32S3使用指南-IDF版_V1.6》第二十六章 INFRARED_RECEPTION实验
309 浏览 0 评论
826 浏览 0 评论
求助一下关于51系列单片机的Timer0的计时问题,TH0、TL0+1的时间是怎么算的?
1911 浏览 2 评论
【RA-Eco-RA4E2-64PIN-V1.0开发板试用】开箱+Keil环境搭建+点灯+点亮OLED
1427 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
12031 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-25 06:29 , Processed in 0.737881 second(s), Total 63, Slave 56 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号