error_f = new floatn; // ¸³ÖµÎó²îʸÁ¿ÏòǰÐýת error_b = new floatn; // ¸³ÖµÎó²îʸÁ¿ÏòºóÐýת const int n_lut = 128; //¸³Öµ²é±í±éÀú±äÁ¿ lut = new intn_lut; // ÔÚ¿ªÊ¼Ç°£¬Çå³ýËùÓо͵òéÔıí¸ñ error = new floatn; const int window = 128; error_filt = new floatn; ps->WriteLUT(lut); raw_f = new intn; raw_b = new intn; float theta_ref = 0; //²Î¿¼µÄtheta½Ç float theta_actual = 0; //ÕæÊµµÄtheta½Ç float v_d = V_CAL; //°ÑËùÓеĵçѹ·ÅÔÚDÖáÉÏ float v_q = 0.0f; //ÇåÁãQÖáµçѹ float v_u, v_v, v_w = 0; //ÈýÏàÏßµçѹ float dtc_u, dtc_v, dtc_w = .5f; //ÈýÏàÏßµçÁ÷£¨²»Çå³þ£© ///½«µçѹ½ÇÉèÖÃΪÁ㣬µÈ´ýת×ÓλÖÃÎȶ¨£¬½ö½ö×öÒ»´Î/ abc(theta_ref, v_d, v_q, &v_u, &v_v, &v_w); //µçѹ·´dq0±ä»» svm(1.0, v_u, v_v, v_w, &dtc_u, &dtc_v, &dtc_w); //¿Õ¼äʸÁ¿µ÷ÖÆ for(int i = 0; i<40000; i++) 这个注释乱码怎么翻译回来

时间: 2025-06-12 12:09:59 浏览: 20
<think>嗯,用户给了一段代码,里面的注释是乱码,需要帮忙翻译回来。首先,我得看看这些乱码可能的原始编码是什么。常见的乱码情况通常是编码转换错误,比如从GBK转到UTF-8时出错。 先看第一个注释:“// ¸³ÖµÎó²îʸÁ¿ÏòǰÐýת”。这里的乱码字符可能是GBK编码的,如果用UTF-8解码就会显示成这样。比如“¸³”在GBK里可能对应“赋”,“Öµ”是“值”。所以整句可能是“赋值误差向量向前旋转”。 接下来是“// ¸³ÖµÎó²îʸÁ¿ÏòºóÐýת”,类似的,“ºó”是“后”,所以翻译成“赋值误差向量向后旋转”。 第三个注释:“//¸³Öµ²é±í±éÀú±äÁ¿”。“²é±í”应该是“查表”,“±éÀú”是“遍历”,所以变量n_lut可能是“查表遍历变量”或者“LUT长度”。 “// ÔÚ¿ªÊ¼Ç°£¬Çå³ýËùÓо͵òéÔıí¸ñ”这里,“¿ªÊ¼”是“开始”,“ǰ”是“前”,所以可能是“在开始前,清除所有旧的查找表格”。 然后“error = new floatn;”可能没有注释,或者注释丢失了? 后面的变量window和error_filt可能注释被省略了,或者用户没贴出来。 继续看“ps->WriteLUT(lut);”后面的注释可能已经正确,没有乱码。 “raw_f = new intn;”和“raw_b = new intn;”也没有注释,或者可能用户漏掉了? 接下来是关于theta_ref和theta_actual的注释:“²Î¿¼µÄtheta½Ç”应该是“参考的theta角”,“ÕæÊµµÄtheta½Ç”是“真实的theta角”。 “°ÑËùÓеĵçѹ·ÅÔÚDÖáÉÏ”中的“µçѹ”是“电压”,“DÖá”是D轴,所以整句是“将所有电压放在D轴上”。 “ÇåÁãQÖáµçѹ”就是“清零Q轴电压”。 “ÈýÏàÏßµçѹ”是“三相线电压”。 “ÈýÏàÏßµçÁ÷£¨²»Çå³þ£©”中的“²»Çå³þ”可能应为“不清零”,所以注释是“三相线电流(不清零)”。 然后有一段中文和乱码混合的注释:“///½«µçѹ½ÇÉèÖÃΪÁ㣬µÈ´ýת×ÓλÖÃÎȶ¨£¬½ö½ö×öÒ»´Î/”。转换后应该是“将电压角设为零,等待转子位置稳定,仅做一次”。 后面的函数调用abc和svm的注释:“µçѹ·´dq0±ä»»”是“电压反dq0变换”,“¿Õ¼äʸÁ¿µ÷ÖÆ”是“空间矢量调制”。 最后的for循环注释:“这个注释乱码怎么翻译回来”用户已经指出问题,但后面的乱码可能需要看具体内容,不过用户可能只是举例,实际代码中的注释已经处理了。 在整理过程中,要注意代码中的变量名和上下文,确保翻译后的注释符合代码逻辑。例如,error_f和error_b可能涉及前向和后向误差向量,lut是查找表,n_lut是表的大小,window可能用于滤波窗口等。 另外,变量如v_d和v_q涉及电机控制中的D轴和Q轴电压,abc函数可能执行逆dq0变换生成三相电压,svm进行空间矢量调制生成占空比。这些专业术语需要准确翻译,以保持代码的可读性。 最后,用户可能需要这些注释翻译成正确的中文,以便理解代码功能。因此,逐行处理乱码注释,确保每个部分都准确对应,同时检查是否有遗漏或转换错误的地方。</think>该代码段中的注释存在编码错误,推测是由于字符集转换问题导致。以下是注释的中文还原和关键代码解析: ```cpp // 动态内存分配与初始化 error_f = new floatn; // 赋值误差向量向前旋转 (用于前向旋转变换) error_b = new floatn; // 赋值误差向量向后旋转 (用于后向旋转变换) const int n_lut = 128; // 查表遍历变量 (LUT长度) lut = new intn_lut; // 在开始前,清除所有旧查找表格 error = new floatn; // 误差向量 const int window = 128; // 滤波窗口大小 error_filt = new floatn; // 滤波后误差 ps->WriteLUT(lut); // 写入查找表到永久存储 // 原始数据缓冲区 raw_f = new intn; // 前向原始数据 raw_b = new intn; // 后向原始数据 // 电机控制参数 float theta_ref = 0; // 参考的theta角 (目标电角度) float theta_actual = 0; // 真实的theta角 (实际电角度) float v_d = V_CAL; // 将所有电压放在D轴上 (D轴校准电压) float v_q = 0.0f; // 清零Q轴电压 float v_u, v_v, v_w = 0; // 三相线电压 (U/V/W相) float dtc_u, dtc_v, dtc_w = .5f; // 三相占空比(未清零) /// 特殊初始化过程 // abc(theta_ref, v_d, v_q, &v_u, &v_v, &v_w); // 电压反dq0变换 (生成三相电压) svm(1.0, v_u, v_v, v_w, &dtc_u, &dtc_v, &dtc_w); // 空间矢量调制 (生成PWM占空比) // 初始化循环 for(int i = 0; i<40000; i++) // 等待转子位置稳定的初始化循环(执行4万次迭代) ``` 主要技术特征分析: 1. 该代码实现了电机矢量控制算法,包含: - 前向/后向旋转变换(Clarke/Park变换) - 空间矢量调制(SVPWM) - DQ轴解耦控制 2. 关键数据结构: ```math \text{误差向量:} \vec{error} = \begin{bmatrix} e_d \\ e_q \end{bmatrix} ``` 采用查找表(LUT)进行非线性误差补偿 3. 控制流程: $$ \theta_{ref} \xrightarrow{dq0^{-1}} \begin{cases} v_u \\ v_v \\ v_w \end{cases} \xrightarrow{SVPWM} \begin{cases} dtc_u \\ dtc_v \\ dtc_w \end{cases} $$ 注:代码中`floatn`和`intn`应为自定义数据类型,可能表示n维浮点/整型向量,具体维度需结合上下文确定。该实现可能用于无刷直流电机(BLDC)或永磁同步电机(PMSM)控制。
阅读全文

相关推荐

static float Bias,Pwm,Integral_bias,Last_Bias; int Position_PID (int Encoder,int Target) { Bias=Encoder-Target; //¼ÆËãÆ«²î Integral_bias+=Bias; //Çó³öÆ«²îµÄ»ý·Ö // Pwm=70*Bias*Ratio+0.00*Integral_bias*Ratio+200*(Bias-Last_Bias)*Ratio; //λÖÃʽPID¿ØÖÆÆ÷ Pwm=100*Bias*Ratio+0.00*Integral_bias*Ratio+250*(Bias-Last_Bias)*Ratio; //λÖÃʽPID¿ØÖÆÆ÷ Last_Bias=Bias; //±£´æÉÏÒ»´ÎÆ«²î return Pwm; //ÔöÁ¿Êä³ö } int Position_PID_1 (int Encoder,float Target) { static float Bias,Pwm,Integral_bias,Last_Bias,encoder; encoder=(float)Encoder; Bias=encoder-Target; //¼ÆËãÆ«²î Integral_bias+=Bias; //Çó³öÆ«²îµÄ»ý·Ö // Pwm=90*Bias*Ratio+0.00*Integral_bias*Ratio+250*(Bias-Last_Bias)*Ratio; //λÖÃʽPID¿ØÖÆÆ÷ Pwm=90*Bias*Ratio+0.00*Integral_bias*Ratio+250*(Bias-Last_Bias)*Ratio; //λÖÃʽPID¿ØÖÆÆ÷ Last_Bias=Bias; //±£´æÉÏÒ»´ÎÆ«²î return Pwm; //ÔöÁ¿Êä³ö } int Position_PID_3 (int Encoder,int Target) { static float Bias,Pwm,Integral_bias,Last_Bias; Bias=Encoder-Target; //¼ÆËãÆ«²î Integral_bias+=Bias; //Çó³öÆ«²îµÄ»ý·Ö // Pwm=70*Bias*Ratio+0.00*Integral_bias*Ratio+200*(Bias-Last_Bias)*Ratio; //λÖÃʽPID¿ØÖÆÆ÷ // Pwm=280*Bias*Ratio+0.00*Integral_bias*Ratio+300*(Bias-Last_Bias)*Ratio; //λÖÃʽPID¿ØÖÆÆ÷ Pwm=90*Bias*Ratio+0.00*Integral_bias*Ratio+250*(Bias-Last_Bias)*Ratio; //λÖÃʽPID¿ØÖÆÆ÷ Last_Bias=Bias; //±£´æÉÏÒ»´ÎÆ«²î return Pwm; //ÔöÁ¿Êä³ö } u16 Count_Next=0; static int Angle_Max,Position_Max; static u8 Flag_Back; u16 number=0; //int Count_FZ,Target_Position=10580; /************************************************************************** º¯Êý¹¦ÄÜ£º×Ô¶¯Æð°Ú³ÌÐò Èë¿Ú²ÎÊý£ºint ·µ»Ø Öµ£º **************************************************************************/ void Run(u8 Way) { static float Count_FZ,Target_Position=10450; static float Count_Big_Angle=0.046542; if(Way==2) //ÊÖ¶¯Æð°Ú³ÌÐò { if(Angle_Balance<(ZHONGZHI+200)&&Angle_Balance>(ZHONGZHI-200)) //µ½µ×½Ó½üƽºâλÖà ¼´¿É¿ªÆôƽºâϵͳ { State=1; //µ¹Á¢×´Ì¬ÖÃ1 Way_Turn=0;//Æð°Ú±ê־λÇåÁã } } } /************************************************************************** º¯Êý¹¦ÄÜ£ºÇã½ÇPD¿ØÖÆ Èë¿Ú²ÎÊý£º½Ç¶È ·µ»Ø Öµ£ºÇã½Ç¿ØÖÆPWM **************************************************************************/ int balance_0(float Angle) { float Bias; //Çã½ÇÆ«²î static float Last_Bias,D_Bias,I_Bias; //PIDÏà¹Ø±äÁ¿ int balance; Bias=Angle-ZHONGZHI; I_Bias+=Bias; D_Bias=Bias-Last_Bias; balance=-Balance_KP*Bias- D_Bias*Balance_KD+ I_Bias*Balance_Ratio; Last_Bias=Bias; return balance; //PWM·µ»ØÖµ //Çó³öƽºâµÄ½Ç¶ÈÖÐÖµ ºÍ»úеÏà¹Ø //Îó²î×öÀÛ¼Ó£¬×ö»ý·Ö¶ÔÏó //Çó³öÆ«²îµÄ΢·Ö ½øÐÐ΢·Ö¿ØÖÆ //ʹÓÃλÖÃPIDËã·¨¹«Ê½¸øPWM¸³Öµ£¬Æ½ºâ¿ØÖÆÐèÒª¿ìËÙ·´Ó¦£¬Ê¹ÓÃPD¿ØÖÆËã·¨£¬¼´»ý·Ö²ÎÊýΪÁã //ÉÏ´ÎÎó²îµÈÓÚµ±Ç°Îó²î //º¯Êý·µ»ØÖµÎªÇã½Ç¿ØÖÆPWMÖµ } /************************************************************************** º¯Êý¹¦ÄÜ£ºÎ»ÖÃPD¿ØÖÆ Èë¿Ú²ÎÊý£º±àÂëÆ÷ ·µ»Ø Öµ£ºÎ»ÖÿØÖÆPWM **************************************************************************/ int Position_0(int Encoder) { static float Position_PWM, Last_Position, Position_Bias, Position_Differential; static float Position_Least; Position_Least=Encoder-Position_Zero; //=-???? Position_Bias *=0.8; Position_Bias += Position_Least*0.2; Position_Differential=Position_Bias-Last_Position; Last_Position=Position_Bias; Position_PWM =Position_Bias*Position_KP+Position_Differential*Position_KD; return Position_PWM; //¶¨ÒåλÖÿØÖƱäÁ¿£¬·Ö±ðÐèÒª¶¨Òå¿ØÖÆPWMÖµ¡¢ÉÏÒ»´ÎµÄλÖÃÖµ¡¢µ±Ç°Î»ÖÃÖµ¡¢Î¢·Ö¶ÔÏóÖµ //¶¨ÒåλÖÃÎó²î±äÁ¿ //===»ñȡλÖÃÆ«²îÁ¿£¬¼´Îó²îÁ¿ //Ò»½×µÍͨÂ˲¨Æ÷Ëã·¨ //===Ò»½×µÍͨÂ˲¨Æ÷ //===»ñȡƫ²î±ä»¯ÂÊ£¬µ±Ç°Îó²îÓëÉÏ´ÎÎó²îÇó²î£¬¼´Î¢·Ö¶ÔÏóÖµ //ÉÏ´ÎÎó²îµÈÓÚµ±Ç°Îó²î£¬±£´æÉÏÒ»´ÎµÄÆ«²î //===ʹÓÃλÖÃPIDËã·¨¹«Ê½¸øPWM¸³Öµ£¬ÐèҪλÖÿìËÙ·´Ó¦£¬²ÉÓÃPDËã·¨£¬¼´»ý·Ö²ÎÊýΪÁã //º¯Êý·µ»ØÖµÎªµ¹Á¢°ÚλÖÿØÖÆPWMÖµ } /************************************************************************** º¯Êý¹¦ÄÜ£ºÏÞÖÆPWM¸³Öµ Èë¿Ú²ÎÊý£ºÎÞ ·µ»Ø Öµ£ºÎÞ **************************************************************************/ void Xianfu_Pwm(void) { int Amplitude=6900; //===PWMÂú·ùÊÇ7200 ÏÞÖÆÔÚ6900 if(Moto<-Amplitude) Moto=-Amplitude; if(Moto>Amplitude) Moto=Amplitude; } /************************************************************************** º¯Êý¹¦ÄÜ£ºÒì³£¹Ø±Õµç»ú Èë¿Ú²ÎÊý£ºµçѹ ·µ»Ø Öµ£º1£ºÒì³£ 0£ºÕý³£ **************************************************************************/ u8 Turn_Off(void) { u8 temp; if(Flag_Stop==1||(State==1 && (Angle_Balance<(ZHONGZHI-460)||Angle_Balance>(ZHONGZHI+460)))) //¹Ø±Õµç»ú { Flag_Stop=0; Way_Turn=0; Flag_qb2=0; Angle_Max=0; Position_Max=0; State=0; temp=1; TIM_SetCounter(TIM2,10000);//³õʼ»¯¼ÆÊýÆ÷³õÖµ } else { temp=0; } return temp; } void Encoder_App(void) { if(State == 0) //Æð°Úʱ²ÉÑùÈ¡3´ÎÇ󯽾ù£¬5´ÎÖÜÆÚÌ«³¤ { Angle_Balance=Get_ADC(5); } if(State==1) { Angle_Balance=Get_ADC(20);//´Ë¿ØÖÆÖÜÆÚ²»ÐèÒªÄÇô¶Ì£¬Æð°Ú³É¹¦ºó²ÉÑùÈ¡5´ÎÇ󯽾ùÖµ£¬ } D_Angle_Balance= Angle_Balance-Last_Angle_Balance ; //===»ñȡ΢·ÖÖµ if (State == 0 && Way_Turn ==1) { if(Angle_Balance<(ZHONGZHI+200)&&Angle_Balance>(ZHONGZHI-200)) //µ½µ×½Ó½üƽºâλÖà ¼´¿É¿ªÆôƽºâϵͳ { State=1; //µ¹Á¢×´Ì¬ÖÃ1 Way_Turn=0;//×Ô¶¯Æð°Ú±ê־λÇåÁã Flag_qb=0; //×Ô¶¯Æð°Ú²½ÖèÇåÁã Angle_Max=0; Flag_Back=0; } } if(State==0) { Run(Way_Turn);//Æð°Ú ÓÉÈë¿Ú²ÎÊý¿ØÖÆ 1£º×Ô¶¯Æð°Ú 2£ºÊÖ¶¯Æð°Ú if(Turn_Off()==1) //°´ÏÂÍ£Ö¹¼üʱֹͣµç»ú { Moto_qb=0; } } if(State==1) //Æð°Ú³É¹¦Ö®ºó£¬½øÐе¹Á¢¿ØÖÆ { Balance_Pwm =balance_0(Angle_Balance); //¿ªÆôƽºâ¿ØÖÆ if(Flag_qb2==0) //λÖÿØÖÆÑÓʱÆô¶¯ { if(Angle_Balance<(ZHONGZHI+200)&&Angle_Balance>(ZHONGZHI-200))Count_Position++; // if(Count_Position>20)Flag_qb2=1, Count_Position=0,TIM_SetCounter(TIM2,10000); //ÔÚÆ½ºâλÖõ¹Á¢³¬¹ý300ms ¿ªÆôλÖÿØÖÆ } if(Flag_qb2==1) //¿ªÆôλÖÿØÖÆ { Encoder=TIM_GetCounter(TIM2); //===¸üбàÂëÆ÷λÖÃÐÅÏ¢ if(++Count_P2>=4) Position_Pwm=Position_0(Encoder),Count_P2=0; //===λÖÃPD¿ØÖÆ 25ms½øÐÐÒ»´ÎλÖÿØÖÆ } Moto=Balance_Pwm-Position_Pwm; //===¼ÆËãµç»ú×îÖÕPWM Xianfu_Pwm(); //===PWMÏÞ·ù if(Turn_Off()==1) //°´ÏÂÍ£Ö¹¼ü»òÕßÇã½Ç¹ý´ó±£»¤£¬µç»úÍ£Ö¹ { Moto=0; } if(Moto>7200) Moto=7200; if(Moto<-7200)Moto=-7200; Set_Pwm(Moto); //===¸³Öµ¸øPWM¼Ä´æÆ÷ } Last_Angle_Balance=Angle_Balance; //===±£´æÉÏÒ»´ÎµÄÇã½ÇÖµ } 解释上述代码

#include "control.h" #include "Lidar.h" float Move_X = 0, Move_Z = 0; // Ä¿±êËٶȺÍÄ¿±êתÏòËÙ¶È float PWM_Left, PWM_Right; // ×óÓÒµç»úPWMÖµ float RC_Velocity, RC_Turn_Velocity; // Ò£¿Ø¿ØÖƵÄËÙ¶È u8 Mode = Normal_Mode; // ģʽѡÔñ£¬Ä¬ÈÏÊÇÆÕͨµÄ¿ØÖÆÄ£Ê½ Motor_parameter MotorA, MotorB; // ×óÓÒµç»úÏà¹Ø±äÁ¿ int Servo_PWM = SERVO_INIT; // °¢¿ËÂü¶æ»úÏà¹Ø±äÁ¿ u8 Lidar_Detect = Lidar_Detect_ON; // µç´ÅѲÏßģʽÀ×´ï¼ì²âÕϰ­ÎĬÈÏ¿ªÆô float CCD_Move_X = 0.3; // CCDѲÏßËÙ¶È float ELE_Move_X = 0.3; // µç´ÅѲÏßËÙ¶È u8 Ros_count = 0, Lidar_flag_count = 0; u8 cnt = 0; Encoder OriginalEncoder; // Encoder raw data //±àÂëÆ÷ԭʼÊý¾Ý short Accel_Y, Accel_Z, Accel_X, Accel_Angle_x, Accel_Angle_y, Gyro_X, Gyro_Z, Gyro_Y; int forward_cnt = 800; int left_cnt = 120; int right_cnt = 125; int stop_cnt = 200; int stop_flag = 0; int mode_cnt = 0; int state_cnt = 0; int stop_protect = 0; /************************************************************************** Function: Control Function Input : none Output : none º¯Êý¹¦ÄÜ£º5ms¶¨Ê±ÖжϿØÖƺ¯Êý Èë¿Ú²ÎÊý: ÎÞ ·µ»Ø Öµ£ºÎÞ **************************************************************************/ void forward(){ MotorA.Motor_Pwm = 1999; MotorB.Motor_Pwm = 2040; } void left(){ MotorA.Motor_Pwm = 0; MotorB.Motor_Pwm = 2050; } void right(){ MotorA.Motor_Pwm = 1999; MotorB.Motor_Pwm = 0; } void stop(){ MotorA.Motor_Pwm = 0; MotorB.Motor_Pwm = 0; } void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim == &htim5) { Get_KeyVal(); if(mode_cnt == 0) stop(); //ģʽһ if(mode_cnt == 1){ if(forward_cnt > 0){ forward(); forward_cnt--; // if(left_cnt > 0){ // left(); // left_cnt--; // if(right_cnt > 0){ // right(); // right_cnt--; } else{ stop(); } } //ģʽ¶þ else if(mode_cnt == 2){ if(forward_cnt > 0){ forward(); forward_cnt--; } else if(stop_cnt > 0 && forward_cnt == 0){ stop(); stop_cnt--; } else if(stop_cnt == 0 && stop_flag == 0){ forward_cnt = 800; stop_flag = 1; } else{ stop(); } } //ģʽÈý else if(mode_cnt == 3){ if(forward_cnt > 0 && state_cnt == 0){//µÚ1״̬£ºÖ±ÐÐ forward(); forward_cnt--; } else if(right_cnt > 0 && state_cnt == 1){//µÚ2״̬£ºÓÒת right(); right_cnt--; } else if(forward_cnt > 0 && state_cnt == 2){//µÚ3״̬£ºÖ±ÐÐ forward(); forward_cnt--; } else if(left_cnt > 0 && state_cnt == 3){//µÚ4״̬£º×óת left(); left_cnt--; } else if(forward_cnt > 0 && state_cnt == 4){//µÚ5״̬£ºÖ±ÐÐ forward(); forward_cnt--; } else if(left_cnt > 0 && state_cnt == 5){//µÚ6״̬£º×óת left(); left_cnt--; } else if(forward_cnt > 0 && state_cnt == 6){//µÚ7״̬£ºÖ±ÐÐ forward(); forward_cnt--; } else{ if(stop_protect == 0 && stop_cnt == 0){ stop_cnt = 100; stop_protect = 1; } else if(stop_cnt > 0){ stop(); stop_cnt--; } else if(stop_protect == 1 && stop_cnt == 0){ stop_protect = 0; if(state_cnt == 0){//״̬1Çл»×´Ì¬2 state_cnt++; right_cnt = 125; } else if(state_cnt == 1){//״̬2Çл»×´Ì¬3 state_cnt++; forward_cnt = 585; } else if(state_cnt == 2){//״̬3Çл»×´Ì¬4 state_cnt++; left_cnt = 120; } else if(state_cnt == 3){//״̬4Çл»×´Ì¬5 state_cnt++; forward_cnt = 585; } else if(state_cnt == 4){//״̬5Çл»×´Ì¬6 state_cnt++; left_cnt = 120; } else if(state_cnt == 5){//״̬6Çл»×´Ì¬7 state_cnt++; forward_cnt = 585; } } } } Set_Pwm(-MotorA.Motor_Pwm, MotorB.Motor_Pwm); // Çý¶¯µç»ú } } /************************************************************************** Function: Bluetooth_Control Input : none Output : none º¯Êý¹¦ÄÜ£ºÊÖ»úÀ¶ÑÀ¿ØÖÆ Èë¿Ú²ÎÊý: ÎÞ ·µ»Ø Öµ£ºÎÞ **************************************************************************/ void Bluetooth_Control(void) { if (Flag_Direction == 0) Move_X = 0, Move_Z = 0; // Í£Ö¹ else if (Flag_Direction == 1) Move_X = RC_Velocity, Move_Z = 0; // ǰ½ø else if (Flag_Direction == 2) Move_X = RC_Velocity, Move_Z = Pi / 2; // ÓÒǰ else if (Flag_Direction == 3) Move_X = 0, Move_Z = Pi / 2; // ÏòÓÒ else if (Flag_Direction == 4) Move_X = -RC_Velocity, Move_Z = Pi / 2; // ÓÒºó else if (Flag_Direction == 5) Move_X = -RC_Velocity, Move_Z = 0; // ºóÍË else if (Flag_Direction == 6) Move_X = -RC_Velocity, Move_Z = -Pi / 2; // ×óºó else if (Flag_Direction == 7) Move_X = 0, Move_Z = -Pi / 2; // Ïò×ó else if (Flag_Direction == 8) Move_X = RC_Velocity, Move_Z = -Pi / 2; // ×óǰ else Move_X = 0, Move_Z = 0; if (Car_Num == Akm_Car) { // Ackermann structure car is converted to the front wheel steering Angle system target value, and kinematics analysis is pearformed // °¢¿ËÂü½á¹¹Ð¡³µ×ª»»ÎªÇ°ÂÖתÏò½Ç¶È Move_Z = Move_Z * 2 / 10; } Move_X = Move_X / 1000; Move_Z = -Move_Z; // ת»»ÎªËÙ¶ÈתΪm/s } /************************************************************************** Function: PS2_Control Input : none Output : none º¯Êý¹¦ÄÜ£ºPS2ÊÖ±ú¿ØÖÆ Èë¿Ú²ÎÊý: ÎÞ ·µ»Ø Öµ£ºÎÞ **************************************************************************/ void PS2_Control(void) { int LY, RX; // ÊÖ±úADCµÄÖµ int Threshold = 20; // ãÐÖµ£¬ºöÂÔÒ¡¸ËС·ù¶È¶¯×÷ static u8 Key1_Count = 0, Key2_Count = 0; // ÓÃÓÚ¿ØÖƶÁȡҡ¸ËµÄËÙ¶È // ת»¯Îª128µ½-128µÄÊýÖµ LY = -(PS2_LY - 128); // ×ó±ßYÖá¿ØÖÆÇ°½øºóÍË RX = -(PS2_RX - 128); // ÓÒ±ßXÖá¿ØÖÆ×ªÏò if (LY > -Threshold && LY < Threshold) LY = 0; if (RX > -Threshold && RX < Threshold) RX = 0; // ºöÂÔÒ¡¸ËС·ù¶È¶¯×÷ Move_X = (RC_Velocity / 128) * LY; // ËÙ¶È¿ØÖÆ£¬Á¦¶È±íʾËÙ¶È´óС if (Car_Num == Akm_Car) // °¢¿ËÂü³µ×ªÏò¿ØÖÆ£¬Á¦¶È±íʾתÏò½Ç¶È Move_Z = -(RC_Turn_Velocity / 128) * RX; else // ÆäËû³µÐÍתÏò¿ØÖÆ { if (Move_X >= 0) Move_Z = -(RC_Turn_Velocity / 128) * RX; // תÏò¿ØÖÆ£¬Á¦¶È±íʾתÏòËÙ¶È else Move_Z = (RC_Turn_Velocity / 128) * RX; } if (PS2_KEY == PSB_L1) // °´ÏÂ×ó1¼ü¼ÓËÙ£¨°´¼üÔÚ¶¥ÉÏ£© { if ((++Key1_Count) == 20) // µ÷½Ú°´¼ü·´Ó¦ËÙ¶È { PS2_KEY = 0; Key1_Count = 0; if ((RC_Velocity += X_Step) > MAX_RC_Velocity) // ǰ½ø×î´óËÙ¶È800mm/s RC_Velocity = MAX_RC_Velocity; if (Car_Num != Akm_Car) // ·Ç°¢¿ËÂü³µ¿Éµ÷½ÚתÏòËÙ¶È { if ((RC_Turn_Velocity += Z_Step) > MAX_RC_Turn_Bias) // תÏò×î´óËÙ¶È325 RC_Turn_Velocity = MAX_RC_Turn_Bias; } } } else if (PS2_KEY == PSB_R1) // °´ÏÂÓÒ1¼ü¼õËÙ { if ((++Key2_Count) == 20) { PS2_KEY = 0; Key2_Count = 0; if ((RC_Velocity -= X_Step) < MINI_RC_Velocity) // ǰºó×îСËÙ¶È210mm/s RC_Velocity = MINI_RC_Velocity; if (Car_Num != Akm_Car) // ·Ç°¢¿ËÂü³µ¿Éµ÷½ÚתÏòËÙ¶È { if ((RC_Turn_Velocity -= Z_Step) < MINI_RC_Turn_Velocity) // תÏò×îСËÙ¶È45 RC_Turn_Velocity = MINI_RC_Turn_Velocity; } } } else Key2_Count = 0, Key2_Count = 0; // ¶ÁÈ¡µ½ÆäËû°´¼üÖØÐ¼ÆÊý Move_X = Move_X / 1000; Move_Z = -Move_Z; // ËÙ¶ÈMove_XתΪm/s } /************************************************************************** Function: Get_Velocity_From_Encoder Input : none Output : none º¯Êý¹¦ÄÜ£º¶ÁÈ¡±àÂëÆ÷ºÍת»»³ÉËÙ¶È Èë¿Ú²ÎÊý: ÎÞ ·µ»Ø Öµ£ºÎÞ **************************************************************************/ void Get_Velocity_From_Encoder(void) { // Retrieves the original data of the encoder // »ñÈ¡±àÂëÆ÷µÄԭʼÊý¾Ý float Encoder_A_pr, Encoder_B_pr; OriginalEncoder.A = Read_Encoder(Encoder1); OriginalEncoder.B = Read_Encoder(Encoder2); // Decide the encoder numerical polarity according to different car models // ¸ù¾Ý²»Í¬Ð¡³µÐͺžö¶¨±àÂëÆ÷ÊýÖµ¼«ÐÔ switch (Car_Num) { case Akm_Car: Encoder_A_pr = OriginalEncoder.A; Encoder_B_pr = -OriginalEncoder.B; break; case Diff_Car: Encoder_A_pr = OriginalEncoder.A; Encoder_B_pr = -OriginalEncoder.B; break; case Small_Tank_Car: Encoder_A_pr = OriginalEncoder.A; Encoder_B_pr = -OriginalEncoder.B; break; case Big_Tank_Car: Encoder_A_pr = OriginalEncoder.A; Encoder_B_pr = -OriginalEncoder.B; break; } // The encoder converts the raw data to wheel speed in m/s // ±àÂëÆ÷ԭʼÊý¾Ýת»»Îª³µÂÖËÙ¶È£¬µ¥Î»m/s MotorA.Current_Encoder = Encoder_A_pr * Frequency * Perimeter / 60000.0f; // 60000 = 4*500*30 MotorB.Current_Encoder = Encoder_B_pr * Frequency * Perimeter / 60000.0f; // 1560=4*13*30=2£¨Á½Â·Âö³å£©*2£¨ÉÏÏÂÑØ¼ÆÊý£©*»ô¶û±àÂëÆ÷13Ïß*µç»úµÄ¼õËÙ±È // MotorA.Current_Encoder= Encoder_A_pr*CONTROL_FREQUENCY*Akm_wheelspacing//(4*13*30); // MotorB.Current_Encoder= Encoder_B_pr*CONTROL_FREQUENCY*Akm_wheelspacing/Encoder_precision; } /************************************************************************** Function: Drive_Motor Input : none Output : none º¯Êý¹¦ÄÜ£ºÔ˶¯Ñ§Äæ½â Èë¿Ú²ÎÊý: ÎÞ ·µ»Ø Öµ£ºÎÞ **************************************************************************/ // Ô˶¯Ñ§Äæ½â£¬ÓÉxºÍyµÄËٶȵõ½±àÂëÆ÷µÄËÙ¶È,VxÊÇm/s,Vzµ¥Î»ÊǶÈ/s(½Ç¶ÈÖÆ) // °¢¿ËÂü³µVzÊǶæ»úתÏòµÄ½Ç¶È(»¡¶ÈÖÆ) void Get_Target_Encoder(float Vx, float Vz) { float MotorA_Velocity, MotorB_Velocity; float amplitude = 3.5f; // Wheel target speed limit //³µÂÖÄ¿±êËÙ¶ÈÏÞ·ù Move_X = target_limit_float(Move_X, -1.2, 1.2); Move_Z = target_limit_float(Move_Z, -Pi / 3, Pi / 3); if (Car_Num == Akm_Car) // °¢¿ËÂü³µ { // Ackerman car specific related variables //°¢¿ËÂüС³µ×¨ÓÃÏà¹Ø±äÁ¿ float R, ratio = 636.56, AngleR, Angle_Servo; // For Ackerman small car, Vz represents the front wheel steering Angle // ¶ÔÓÚ°¢¿ËÂüС³µVz´ú±íÓÒǰÂÖתÏò½Ç¶È AngleR = Vz; R = Akm_axlespacing / tan(AngleR) - 0.5f * Wheelspacing; // Front wheel steering Angle limit (front wheel steering Angle controlled by steering engine), unit: rad // ǰÂÖתÏò½Ç¶ÈÏÞ·ù(¶æ»ú¿ØÖÆÇ°ÂÖתÏò½Ç¶È)£¬µ¥Î»£ºrad AngleR = target_limit_float(AngleR, -0.49f, 0.32f); // Inverse kinematics //Ô˶¯Ñ§Äæ½â if (AngleR != 0) { MotorA.Target_Encoder = Vx * (R - 0.081f) / R; MotorB.Target_Encoder = Vx * (R + 0.081f) / R; } else { MotorA.Target_Encoder = Vx; MotorB.Target_Encoder = Vx; } // The PWM value of the servo controls the steering Angle of the front wheel // ¶æ»úPWMÖµ£¬¶æ»ú¿ØÖÆÇ°ÂÖתÏò½Ç¶È Angle_Servo = -0.628f * pow(AngleR, 3) + 1.269f * pow(AngleR, 2) - 1.772f * AngleR + 1.573f; Servo_PWM = SERVO_INIT + (Angle_Servo - 1.572f) * ratio; // printf("%d\r\n",Servo_PWM); // Wheel (motor) target speed limit //³µÂÖ(µç»ú)Ä¿±êËÙ¶ÈÏÞ·ù MotorA.Target_Encoder = target_limit_float(MotorA.Target_Encoder, -amplitude, amplitude); MotorB.Target_Encoder = target_limit_float(MotorB.Target_Encoder, -amplitude, amplitude); Servo_PWM = target_limit_int(Servo_PWM, 800, 2200); // Servo PWM value limit //¶æ»úPWMÖµÏÞ·ù } else if (Car_Num == Diff_Car) // ²îËÙС³µ { if (Vx < 0) Vz = -Vz; else Vz = Vz; // Inverse kinematics //Ô˶¯Ñ§Äæ½â MotorA.Target_Encoder = Vx - Vz * Wheelspacing / 2.0f; // ¼ÆËã³ö×óÂÖµÄÄ¿±êËÙ¶È MotorB.Target_Encoder = Vx + Vz * Wheelspacing / 2.0f; // ¼ÆËã³öÓÒÂÖµÄÄ¿±êËÙ¶È // Wheel (motor) target speed limit //³µÂÖ(µç»ú)Ä¿±êËÙ¶ÈÏÞ·ù MotorA.Target_Encoder = target_limit_float(MotorA.Target_Encoder, -amplitude, amplitude); MotorB.Target_Encoder = target_limit_float(MotorB.Target_Encoder, -amplitude, amplitude); } else if (Car_Num == Small_Tank_Car) { if (Vx < 0) Vz = -Vz; else Vz = Vz; MotorA.Target_Encoder = Vx - Vz * Wheelspacing / 2.0f; // ¼ÆËã³ö×óÂÖµÄÄ¿±êËÙ¶È MotorB.Target_Encoder = Vx + Vz * Wheelspacing / 2.0f; // ¼ÆËã³öÓÒÂÖµÄÄ¿±êËÙ¶È // Wheel (motor) target speed limit //³µÂÖ(µç»ú)Ä¿±êËÙ¶ÈÏÞ·ù MotorA.Target_Encoder = target_limit_float(MotorA.Target_Encoder, -amplitude, amplitude); MotorB.Target_Encoder = target_limit_float(MotorB.Target_Encoder, -amplitude, amplitude); } else if (Car_Num == Big_Tank_Car) { if (Vx < 0) Vz = -Vz; else Vz = Vz; MotorA.Target_Encoder = Vx - Vz * Wheelspacing / 2.0f; // ¼ÆËã³ö×óÂÖµÄÄ¿±êËÙ¶È MotorB.Target_Encoder = Vx + Vz * Wheelspacing / 2.0f; // ¼ÆËã³öÓÒÂÖµÄÄ¿±êËÙ¶È MotorA.Target_Encoder = target_limit_float(MotorA.Target_Encoder, -amplitude, amplitude); MotorB.Target_Encoder = target_limit_float(MotorB.Target_Encoder, -amplitude, amplitude); } } /************************************************************************** Function: Get_Motor_PWM Input : none Output : none º¯Êý¹¦ÄÜ£º×ª»»³ÉÇý¶¯µç»úµÄPWM Èë¿Ú²ÎÊý: ÎÞ ·µ»Ø Öµ£ºÎÞ **************************************************************************/ void Get_Motor_PWM(void) { // ¼ÆËã×óÓÒµç»ú¶ÔÓ¦µÄPWM MotorA.Motor_Pwm = Incremental_PI_Left(MotorA.Current_Encoder, MotorA.Target_Encoder); MotorB.Motor_Pwm = Incremental_PI_Right(MotorB.Current_Encoder, MotorB.Target_Encoder); if (Mode == Normal_Mode || Mode == Measure_Distance_Mode) { // Â˲¨£¬Ê¹Æð²½ºÍÍ£Ö¹ÉÔ΢ƽ»¬Ò»Ð© MotorA.Motor_Pwm = Mean_Filter_Left(MotorA.Motor_Pwm); MotorB.Motor_Pwm = Mean_Filter_Right(MotorB.Motor_Pwm); } // ÏÞ·ù MotorA.Motor_Pwm = PWM_Limit(MotorA.Motor_Pwm, PWM_MAX, PWM_MIN); MotorB.Motor_Pwm = PWM_Limit(MotorB.Motor_Pwm, PWM_MAX, PWM_MIN); } /************************************************************************** Function: PWM_Limit Input : IN;max;min Output : OUT º¯Êý¹¦ÄÜ£ºÏÞÖÆPWM¸³Öµ Èë¿Ú²ÎÊý: IN£ºÊäÈë²ÎÊý max£ºÏÞ·ù×î´óÖµ min£ºÏÞ·ù×îСֵ ·µ»Ø Öµ£ºÏÞ·ùºóµÄÖµ **************************************************************************/ float PWM_Limit(float IN, int max, int min) { float OUT = IN; if (OUT > max) OUT = max; if (OUT < min) OUT = min; return OUT; } /************************************************************************** Function: Limiting function Input : Value Output : none º¯Êý¹¦ÄÜ£ºÏÞ·ùº¯Êý Èë¿Ú²ÎÊý£º·ùÖµ ·µ»Ø Öµ£ºÎÞ **************************************************************************/ float target_limit_float(float insert, float low, float high) { if (insert < low) return low; else if (insert > high) return high; else return insert; } int target_limit_int(int insert, int low, int high) { if (insert < low) return low; else if (insert > high) return high; else return insert; } /************************************************************************** Function: Check whether it is abnormal Input : none Output : 1:Abnormal;0:Normal º¯Êý¹¦ÄÜ£ºÒì³£¹Ø±Õµç»ú Èë¿Ú²ÎÊý: ÎÞ ·µ»Ø Öµ£º1£ºÒì³£ 0£ºÕý³£ **************************************************************************/ u8 Turn_Off(void) { u8 temp = Normal; Flag_Stop = KEY2_STATE; // ¶ÁÈ¡°´¼ü2״̬£¬°´¼ü2¿ØÖƵç»úµÄ¿ª¹Ø if (Voltage < 1000) // µç³ØµçѹµÍÓÚ10V¹Ø±Õµç»ú,LEDµÆ¿ìËÙÉÁ˸ LED_Flash(50), temp = Abnormal; else LED_Flash(200); // ÿһÃëÉÁÒ»´Î£¬Õý³£ÔËÐÐ if (Flag_Stop) temp = Abnormal; return temp; } /************************************************************************** Function: Data sliding filtering Input : data Output : Filtered data º¯Êý¹¦ÄÜ£ºÊý¾Ý»¬¶¯Â˲¨ Èë¿Ú²ÎÊý£ºÊý¾Ý ·µ»Ø Öµ£ºÂ˲¨ºóµÄÊý¾Ý **************************************************************************/ float Mean_Filter_Left(float data) { u8 i; float Sum_Data = 0; float Filter_Data; static float Speed_Buf[FILTERING_TIMES] = {0}; for (i = 1; i < FILTERING_TIMES; i++) { Speed_Buf[i - 1] = Speed_Buf[i]; } Speed_Buf[FILTERING_TIMES - 1] = data; for (i = 0; i < FILTERING_TIMES; i++) { Sum_Data += Speed_Buf[i]; } Filter_Data = (s32)(Sum_Data / FILTERING_TIMES); return Filter_Data; } /************************************************************************** Function: Data sliding filtering Input : data Output : Filtered data º¯Êý¹¦ÄÜ£ºÊý¾Ý»¬¶¯Â˲¨ Èë¿Ú²ÎÊý£ºÊý¾Ý ·µ»Ø Öµ£ºÂ˲¨ºóµÄÊý¾Ý **************************************************************************/ float Mean_Filter_Right(float data) { u8 i; float Sum_Data = 0; float Filter_Data; static float Speed_Buf[FILTERING_TIMES] = {0}; for (i = 1; i < FILTERING_TIMES; i++) { Speed_Buf[i - 1] = Speed_Buf[i]; } Speed_Buf[FILTERING_TIMES - 1] = data; for (i = 0; i < FILTERING_TIMES; i++) { Sum_Data += Speed_Buf[i]; } Filter_Data = (s32)(Sum_Data / FILTERING_TIMES); return Filter_Data; } /************************************************************************** Function: Lidar_Avoid Input : none Output : none º¯Êý¹¦ÄÜ£ºÀ×´ï±ÜÕÏģʽ Èë¿Ú²ÎÊý£ºÎÞ ·µ»Ø Öµ£ºÎÞ **************************************************************************/ void Lidar_Avoid(void) { int i = 0; u8 calculation_angle_cnt = 0; // ÓÃÓÚÅжÏ100¸öµãÖÐÐèÒª×ö±ÜÕϵĵã float angle_sum = 0; // ´ÖÂÔ¼ÆËãÕϰ­ÎïλÓÚ×ó»òÕßÓÒ u8 distance_count = 0; // ¾àÀëСÓÚijֵµÄ¼ÆÊý int distance = 350; // É趨±ÜÕϾàÀë,ĬÈÏÊÇ300 if (Car_Num == Akm_Car) distance = 400; // °¢¿ËÂü³µÉ趨ÊÇ400mm else if (Car_Num == Big_Tank_Car) distance = 500; // ´óÂÄ´ø³µÉ趨ÊÇ500mm for (i = 0; i < lap_count; i++) { if ((Dataprocess[i].angle > 310) || (Dataprocess[i].angle < 50)) { if ((0 < Dataprocess[i].distance) && (Dataprocess[i].distance < distance)) // ¾àÀëСÓÚ350mmÐèÒª±ÜÕÏ,Ö»ÐèÒª100¶È·¶Î§ÄÚµã { calculation_angle_cnt++; // ¼ÆËã¾àÀëСÓÚ±ÜÕϾàÀëµÄµã¸öÊý if (Dataprocess[i].angle < 50) angle_sum += Dataprocess[i].angle; else if (Dataprocess[i].angle > 310) angle_sum += (Dataprocess[i].angle - 360); // 310¶Èµ½50¶Èת»¯Îª-50¶Èµ½50¶È if (Dataprocess[i].distance < 200) // ¼Ç¼СÓÚ200mmµÄµãµÄ¼ÆÊý distance_count++; } } } if (calculation_angle_cnt < 8) // СÓÚ8µã²»ÐèÒª±ÜÕÏ£¬È¥³ýһЩÔëµã { if ((Move_X += 0.1) >= Aovid_Speed) // ±ÜÕϵÄËÙ¶ÈÉ趨Ϊ260£¬Öð½¥Ôö¼Óµ½260¿ÉÉÔ΢ƽ»¬Ò»Ð© Move_X = Aovid_Speed; Move_Z = 0; // ²»±ÜÕÏʱ²»ÐèҪתÍä } else // ÐèÒª±ÜÕÏ£¬¼òµ¥µØÅжÏÕϰ­Î﷽λ { if (Car_Num == Akm_Car) // °¢¿ËÂü³µÐÍÓжæ»ú£¬ÐèÒªÌØÊâ´¦Àí { if (distance_count > 8) // ¾àÀëСÓÚ±ÜÕ½¾àÀë Move_X = -Aovid_Speed, Move_Z = 0; // ÍùºóÍË else { if ((Move_X -= 0.1) <= (Aovid_Speed * 0.5)) // ±ÜÕÏʱËٶȽµµ½µÍËÙ0.25 Move_X = Aovid_Speed * 0.5; if (angle_sum > 0) // Õϰ­ÎïÆ«ÓÒ Move_Z = -Pi / 5; // ÿ´ÎתÍä½Ç¶ÈΪPI/5£¬Ö±µ½100¶È·¶Î§ÄÚÎÞÕϰ­Îï¾ÍÍ£Ö¹ else // Æ«×ó Move_Z = Pi / 5; } } else { if (distance_count > 8) // СÓÚ±ÜÕ½¾àÀëµÄʱºò Move_X = -Aovid_Speed, Move_Z = 0; // ÍùºóÍË else { if ((Move_X -= 0.1) <= (Aovid_Speed * 0.5)) // ±ÜÕÏʱËٶȽµµ½µÍËÙ¶È0.15 Move_X = (Aovid_Speed * 0.5); if (angle_sum > 0) // Õϰ­ÎïÆ«ÓÒ { if (Car_Num == Diff_Car) // ÿ´ÎתÍäËÙ¶ÈΪX¶È£¬Ö±µ½100¶È·¶Î§ÄÚÎÞÕϰ­Îï¾ÍÍ£Ö¹ Move_Z = -1; else if (Car_Num == Small_Tank_Car) Move_Z = -1; else Move_Z = -1; } else // Æ«×ó { if (Car_Num == Diff_Car) // ÿ´ÎתÍäËÙ¶ÈΪX¶È£¬Ö±µ½100¶È·¶Î§ÄÚÎÞÕϰ­Îï¾ÍÍ£Ö¹ Move_Z = 1; else if (Car_Num == Small_Tank_Car) Move_Z = 1; else Move_Z = 1; } } } } Move_Z = -Move_Z; } /************************************************************************** Function: Lidar_Follow Input : none Output : none º¯Êý¹¦ÄÜ£ºÀ×´ï¸úËæÄ£Ê½ Èë¿Ú²ÎÊý£ºÎÞ ·µ»Ø Öµ£ºÎÞ **************************************************************************/ float angle1 = 0; // ¸úËæµÄ½Ç¶È u16 mini_distance1; void Lidar_Follow(void) { static u16 cnt = 0; int i; int calculation_angle_cnt = 0; static float angle = 0; // ¸úËæµÄ½Ç¶È static float last_angle = 0; // u16 mini_distance = 65535; static u8 data_count = 0; // ÓÃÓÚÂ˳ýһдÔëµãµÄ¼ÆÊý±äÁ¿ // ÐèÒªÕÒ³ö¸úËæµÄÄǸöµãµÄ½Ç¶È for (i = 0; i < lap_count; i++) { if (100 < Dataprocess[i].distance && Dataprocess[i].distance < Follow_Distance) // 1200·¶Î§ÄÚ¾ÍÐèÒª¸úËæ { calculation_angle_cnt++; if (Dataprocess[i].distance < mini_distance) // ÕÒ³ö¾àÀë×îСµÄµã { mini_distance = Dataprocess[i].distance; angle = Dataprocess[i].angle; } } } if (angle > 180) angle -= 360; // 0--360¶Èת»»³É0--180£»-180--0£¨Ë³Ê±Õ룩 if (angle - last_angle > 10 || angle - last_angle < -10) // ×öÒ»¶¨Ïû¶¶£¬²¨¶¯´óÓÚ10¶ÈµÄÐèÒª×öÅÐ¶Ï { if (++data_count == 60) // Á¬Ðø60´Î²É¼¯µ½µÄÖµ(300msºó)ºÍÉϴεıȴóÓÚ10¶È£¬´Ëʱ²ÅÊÇÈÏΪÊÇÓÐЧֵ { data_count = 0; last_angle = angle; } } else // ²¨¶¯Ð¡ÓÚ10¶ÈµÄ¿ÉÒÔÖ±½ÓÈÏΪÊÇÓÐЧֵ { data_count = 0; last_angle = angle; } if (calculation_angle_cnt < 6) // ÔÚ¸úËæ·¶Î§ÄڵĵãÉÙÓÚ6¸ö { if (cnt < 40) // Á¬Ðø¼ÆÊý³¬40´ÎûÓÐÒª¸úËæµÄµã£¬´Ëʱ²ÅÊDz»ÓøúËæ cnt++; if (cnt >= 40) { Move_X = 0; // ËÙ¶ÈΪ0 Move_Z = 0; } } else { cnt = 0; if (Car_Num == Akm_Car) { if ((((angle > 15) && (angle < 180)) || ((angle > -180) && angle < -15)) && (mini_distance < 500)) // °¢¿¨Âü³µÐÍ´¦Àí³µÍ·²»¶ÔןúËæÎÏ൱ÓÚºó³µÒ»Ñù£¬Ò»´Î²»¶Ô×¼£¬ÄǺóÍËÔÙÀ´¶Ô×¼ { Move_X = -0.20; Move_Z = -Follow_Turn_PID(last_angle, 0); } else { Move_X = Distance_Adjust_PID(mini_distance, Keep_Follow_Distance); // ±£³Ö¾àÀë±£³ÖÔÚ400mm Move_Z = Follow_Turn_PID(last_angle, 0); } } else // ÆäÓà³µÐÍ { if ((angle > 50 || angle < -50) && (mini_distance > 400)) { Move_Z = -0.0298f * last_angle; // ½Ç¶È²î¾à¹ý´óÖ±½Ó¿ìËÙתÏò Move_X = 0; // ²îËÙС³µºÍÂÄ´øÐ¡³µ¿ÉÒÔʵÏÖÔ­µØ×ª¶¯ } else { Move_X = Distance_Adjust_PID(mini_distance, Keep_Follow_Distance); // ±£³Ö¾àÀë±£³ÖÔÚ400mm Move_Z = Follow_Turn_PID(last_angle, 0); // תÏòPID£¬³µÍ·ÓÀÔ¶¶ÔןúËæÎïÆ· } } } Move_Z = target_limit_float(Move_Z, -Pi / 6, Pi / 6); // ÏÞ·ù Move_X = target_limit_float(Move_X, -0.6, 0.6); } /************************************************************************** º¯Êý¹¦ÄÜ£ºÐ¡³µ×ßÖ±Ïßģʽ Èë¿Ú²ÎÊý£ºÎÞ ·µ»Ø Öµ£ºÎÞ **************************************************************************/ void Lidar_along_wall(void) { static u32 target_distance = 0; static int n = 0; u32 distance; u8 data_count = 0; // ÓÃÓÚÂ˳ýһдÔëµãµÄ¼ÆÊý±äÁ¿ for (int i = 0; i < lap_count; i++) { if (Dataprocess[i].angle > 75 && Dataprocess[i].angle < 77) { if (n == 0) { target_distance = Dataprocess[i].distance; // »ñÈ¡µÄµÚÒ»¸öµã×÷ΪĿ±ê¾àÀë n++; } if (Dataprocess[i].distance < target_distance + 100) //+100ÏÞÖÆ»ñÈ¡¾àÀëµÄ·¶Î§Öµ { distance = Dataprocess[i].distance; // »ñȡʵʱ¾àÀë data_count++; } } } // if(data_count <= 0) // Move_X = 0; // Move_X = forward_velocity; // ³õʼËÙ¶È Move_Z = -Along_Adjust_PID(distance, target_distance); if (Car_Num == Akm_Car) { Move_Z = target_limit_float(Move_Z, -Pi / 4, Pi / 4); // ÏÞ·ù } else if (Car_Num == Diff_Car) Move_Z = target_limit_float(Move_Z, -Pi / 5, Pi / 5); // ÏÞ·ù } /************************************************************************** Function: Car_Perimeter_Init Input : none Output : none º¯Êý¹¦ÄÜ£º¼ÆËãС³µ¸÷ÂÖ×ÓµÄÖܳ¤ Èë¿Ú²ÎÊý£ºÎÞ ·µ»Ø Öµ£ºÎÞ **************************************************************************/ void Car_Perimeter_Init(void) { if (Car_Num == Diff_Car || Car_Num == Akm_Car) { Perimeter = Diff_Car_Wheel_diameter * Pi; Wheelspacing = Diff_wheelspacing; } else if (Car_Num == Small_Tank_Car) { Perimeter = Small_Tank_WheelDiameter * Pi; Wheelspacing = Small_Tank_wheelspacing; } else { Perimeter = Big_Tank_WheelDiameter * Pi; Wheelspacing = Big_Tank_wheelspacing; } } /************************************************************************** Function: Ultrasonic_Follow Input : none Output : none º¯Êý¹¦ÄÜ£º³¬Éù²¨¸úËæÄ£Ê½ Èë¿Ú²ÎÊý£ºÎÞ ·µ»Ø Öµ£ºÎÞ **************************************************************************/ void Ultrasonic_Follow(void) // ³¬Éù²¨¸úËæ£¬Ö»Äܵ¥·½Ïò¸úËæ { Move_Z = 0; Read_Distane(); // ¶ÁÈ¡³¬Éù²¨µÄ¾àÀë if (Distance1 < 200) // ¾àÀëСÓÚ200mm£¬Í˺ó { if ((Move_X -= 3) < -210) Move_X = -210; // ¸øÒ»210ºóÍËËÙ¶È } else if (Distance1 > 270 && Distance1 < 750) // ¾àÀëÔÚ270µ½750Ö®¼äÊÇÐèÒª¸úËæÇ°½ø { if ((Move_X += 3) > 210) // ËÙ¶ÈÖð½¥Ôö¼Ó£¬¸øÇ°½øËÙ¶È Move_X = 210; } else { if (Move_X > 0) { if ((Move_X -= 20) < 0) // ËÙ¶ÈÖð½¥¼õµ½0 Move_X = 0; } else { if ((Move_X += 20) > 0) // ËÙ¶ÈÖð½¥¼õµ½0 Move_X = 0; } } } /************************************************************************** Function: Get angle Input : way£ºThe algorithm of getting angle 1£ºDMP 2£ºkalman 3£ºComplementary filtering Output : none º¯Êý¹¦ÄÜ£º»ñÈ¡½Ç¶È Èë¿Ú²ÎÊý£ºway£º»ñÈ¡½Ç¶ÈµÄËã·¨ 1£ºDMP 2£º¿¨¶ûÂü 3£º»¥²¹Â˲¨ ·µ»Ø Öµ£ºÎÞ **************************************************************************/ void Get_Angle(u8 way) { if (way == 1) // DMPµÄ¶ÁÈ¡ÔÚÊý¾Ý²É¼¯Öж϶ÁÈ¡£¬Ñϸñ×ñѭʱÐòÒªÇó { Read_DMP(); // ¶ÁÈ¡¼ÓËÙ¶È¡¢½ÇËÙ¶È¡¢Çã½Ç } else { Gyro_X = (I2C_ReadOneByte(devAddr, MPU6050_RA_GYRO_XOUT_H) << 8) + I2C_ReadOneByte(devAddr, MPU6050_RA_GYRO_XOUT_L); // ¶ÁÈ¡XÖáÍÓÂÝÒÇ Gyro_Y = (I2C_ReadOneByte(devAddr, MPU6050_RA_GYRO_YOUT_H) << 8) + I2C_ReadOneByte(devAddr, MPU6050_RA_GYRO_YOUT_L); // ¶ÁÈ¡YÖáÍÓÂÝÒÇ Gyro_Z = (I2C_ReadOneByte(devAddr, MPU6050_RA_GYRO_ZOUT_H) << 8) + I2C_ReadOneByte(devAddr, MPU6050_RA_GYRO_ZOUT_L); // ¶ÁÈ¡ZÖáÍÓÂÝÒÇ Accel_X = (I2C_ReadOneByte(devAddr, MPU6050_RA_ACCEL_XOUT_H) << 8) + I2C_ReadOneByte(devAddr, MPU6050_RA_ACCEL_XOUT_L); // ¶ÁÈ¡XÖá¼ÓËÙ¶È¼Æ Accel_Y = (I2C_ReadOneByte(devAddr, MPU6050_RA_ACCEL_YOUT_H) << 8) + I2C_ReadOneByte(devAddr, MPU6050_RA_ACCEL_YOUT_L); // ¶ÁÈ¡XÖá¼ÓËÙ¶È¼Æ Accel_Z = (I2C_ReadOneByte(devAddr, MPU6050_RA_ACCEL_ZOUT_H) << 8) + I2C_ReadOneByte(devAddr, MPU6050_RA_ACCEL_ZOUT_L); // ¶ÁÈ¡ZÖá¼ÓËÙ¶È¼Æ // if(Gyro_X>32768) Gyro_X-=65536; //Êý¾ÝÀàÐÍת»» Ò²¿Éͨ¹ýshortÇ¿ÖÆÀàÐÍת»» // if(Gyro_Y>32768) Gyro_Y-=65536; //Êý¾ÝÀàÐÍת»» Ò²¿Éͨ¹ýshortÇ¿ÖÆÀàÐÍת»» // if(Gyro_Z>32768) Gyro_Z-=65536; //Êý¾ÝÀàÐÍת»» // if(Accel_X>32768) Accel_X-=65536; //Êý¾ÝÀàÐÍת»» // if(Accel_Y>32768) Accel_Y-=65536; //Êý¾ÝÀàÐÍת»» // if(Accel_Z>32768) Accel_Z-=65536; //Êý¾ÝÀàÐÍת»» Accel_Angle_x = atan2(Accel_Y, Accel_Z) * 180 / Pi; // ¼ÆËãÇã½Ç£¬×ª»»µ¥Î»Îª¶È Accel_Angle_y = atan2(Accel_X, Accel_Z) * 180 / Pi; // ¼ÆËãÇã½Ç£¬×ª»»µ¥Î»Îª¶È Gyro_X = Gyro_X / 65.5; // ÍÓÂÝÒÇÁ¿³Ìת»»£¬Á¿³Ì¡À500¡ã/s¶ÔÓ¦ÁéÃô¶È65.5£¬¿É²éÊÖ²á Gyro_Y = Gyro_Y / 65.5; // ÍÓÂÝÒÇÁ¿³Ìת»» if (way == 2) { Roll = -Kalman_Filter_x(Accel_Angle_x, Gyro_X); // ¿¨¶ûÂüÂ˲¨ Pitch = -Kalman_Filter_y(Accel_Angle_y, Gyro_Y); } else if (way == 3) { Roll = -Complementary_Filter_x(Accel_Angle_x, Gyro_X); // »¥²¹Â˲¨ Pitch = -Complementary_Filter_y(Accel_Angle_y, Gyro_Y); } } } /************************************************************************** Function: The remote control command of model aircraft is processed Input : none Output : none º¯Êý¹¦ÄÜ£º¶Ôº½Ä£Ò£¿Ø¿ØÖÆÃüÁî½øÐд¦Àí Èë¿Ú²ÎÊý£ºÎÞ ·µ»Ø Öµ£ºÎÞ **************************************************************************/ void Remote_Control(void) { // Data within 1 second after entering the model control mode will not be processed // ¶Ô½øÈ뺽ģ¿ØÖÆÄ£Ê½ºó1ÃëÄÚµÄÊý¾Ý²»´¦Àí static u8 thrice = 200; int Threshold = 100; // limiter //ÏÞ·ù int LX, RY; // static float Target_LX,Target_LY,Target_RY,Target_RX; Remoter_Ch1 = target_limit_int(Remoter_Ch1, 1000, 2000); Remoter_Ch2 = target_limit_int(Remoter_Ch2, 1000, 2000); // Front and back direction of left rocker. Control forward and backward. // ×óÒ¡¸Ëǰºó·½Ïò¡£¿ØÖÆÇ°½øºóÍË¡£ LX = Remoter_Ch2 - 1500; // //Left joystick left and right. Control left and right movement. // //×óÒ¡¸Ë×óÓÒ·½Ïò¡£¿ØÖÆ×óÓÒÒÆ¶¯¡£¡£ // LY=Remoter_Ch2-1500; // Right stick left and right. To control the rotation. // ÓÒÒ¡¸Ë×óÓÒ·½Ïò¡£¿ØÖÆ×Ôת¡£ RY = Remoter_Ch1 - 1500; // if (LX > -Threshold && LX < Threshold) LX = 0; if (RY > -Threshold && RY < Threshold) RY = 0; // if(LX==0) Target_LX=Target_LX/1.2f; // if(LY==0) Target_LY=Target_LY/1.2f; // if(RY==0) Target_RY=Target_RY/1.2f; // //Throttle related //ÓÍÃÅÏà¹Ø // Remote_RCvelocity=RC_Velocity+RX; // if(Remote_RCvelocity<0)Remote_RCvelocity=0; // The remote control command of model aircraft is processed // ¶Ôº½Ä£Ò£¿Ø¿ØÖÆÃüÁî½øÐд¦Àí Move_X = LX; Move_Z = -RY; Move_X = Move_X * 1.3; //*1.3ÊÇΪÁËÀ«´óËÙ¶È if (Car_Num == Akm_Car) Move_Z = Move_Z * (Pi / 8) / 350.0; else Move_Z = Move_Z * 2 * (Pi / 4) / 350.0; // Unit conversion, mm/s -> m/s // µ¥Î»×ª»»£¬mm/s -> m/s Move_X = Move_X / 1000; // ZÖáÊý¾Ýת»¯ #if _4WD if (Move_X < 0) Move_Z = -Move_Z; #endif // Data within 1 second after entering the model control mode will not be processed // ¶Ô½øÈ뺽ģ¿ØÖÆÄ£Ê½ºó1ÃëÄÚµÄÊý¾Ý²»´¦Àí if (thrice > 0) Move_X = 0, Move_Z = 0, thrice--; // Control target value is obtained and kinematics analysis is performed // µÃµ½¿ØÖÆÄ¿±êÖµ£¬½øÐÐÔ˶¯Ñ§·ÖÎö // Get_Target_Encoder(Move_X,Move_Z); } 怎么把OpenMV与STM32串口通信实现二维码/APRILTag码识别及控制的代码加到上述代码中,现在openmv的二维码识别已做好,二维码采用的是Apriltag的36h11类型,id:0表示停止,id:1表示直行,id:2表示左转,id:3表示右转,现在需要再在STM32中修改或添加代码,使其能在接收到openmv识别到的指令后作出相应的动作

/************************************************************ °æÈ¨£º2025CIMC Copyright¡£ Îļþ£ºFunction.c ×÷Õß: Lingyu Meng ƽ̨: 2025CIMC IHD-V04 °æ±¾: Lingyu Meng 2025/2/16 V0.01 original ************************************************************/ /************************* Í·Îļþ *************************/ #include “Function.h” #include “LED.h” #include “RTC.h” #include “USART0.h” #include “SPI_FLASH.h” #include “ff.h” #include “diskio.h” #include “sdcard.h” #include “sys_check.h” #include “oled.h” #include “conf_read.h” #include “ratio_set.h” #include “limit_set.h” #include “key.h” #include “adc.h” #include “RTC.h” /************************* ºê¶¨Òå *************************/ #define BUFFER_SIZE 256 #define TX_BUFFER_SIZE BUFFER_SIZE #define RX_BUFFER_SIZE BUFFER_SIZE #define FLASH_WRITE_ADDRESS 0x000000 #define FLASH_READ_ADDRESS FLASH_WRITE_ADDRESS // ²ÉÑùÖÜÆÚ³£Á¿¶¨Òå #define CYCLE_5S 1 #define CYCLE_10S 10 #define CYCLE_15S 15 // Flash´æ´¢µØÖ·¶¨Òå #define SAMPLE_CYCLE_ADDR 0x000100 /************************ ±äÁ¿¶¨Òå ************************/ uint8_t tx_buffer[TX_BUFFER_SIZE]; uint8_t rx_buffer[TX_BUFFER_SIZE]; uint16_t i = 0, count, result = 0; uint8_t is_successful = 0; //FIL fdst; UINT br, bw; BYTE buffer[128]; BYTE filebuffer[128]; typedef struct { int count; // µ±Ç°ÎļþÊý¾Ý¼ÆÊý // unsigned long datetime; // µ±Ç°ÎļþµÄʱ¼ä´Á FIL file; // µ±Ç°Îļþ¶ÔÏó } DataFileInfo; static DataFileInfo data_file_info = {0, {0}}; // È«¾Ö±äÁ¿ uint32_t sample_cycle = CYCLE_5S; // µ±Ç°²ÉÑùÖÜÆÚ£¬µ¥Î»Ãë /************************ º¯Êý¶¨Òå **********************/ ErrStatus memory_compare(uint8_t src,uint8_t dst,uint16_t length); void nvic_config(void); void write_file(void); /************************************************************ Function : System_Init Comment : ÓÃÓÚ³õʼ»¯MCU Parameter: null Return : null Author : Lingyu Meng Date : 2025-02-30 V0.1 original ************************************************************/ void System_Init(void) { systick_config(); // ʱÖÓÅäÖà nvic_config(); // ÅäÖÃÖжϿØÖÆÆ÷ KEY_Init(); // KEY³õʼ»¯ LED_Init(); USART0_Config(); // ´®¿Ú³õʼ»¯ nvic_irq_enable(USART0_IRQn, 0, 0); // ʹÄÜUSART0ÖÐ¶Ï usart_interrupt_enable(USART0, USART_INT_RBNE); // ½ÓÊÕÖжϴò¿ª ADC_port_init(); // ADC³õʼ»¯ OLED_Init(); TF_Init(); spi_flash_init(); // ³õʼ»¯SPI Flash RTC_Init(); // ´ÓFlash¶ÁÈ¡±£´æµÄ²ÉÑùÖÜÆÚ uint32_t saved_cycle; spi_flash_buffer_read((uint8_t*)&saved_cycle, SAMPLE_CYCLE_ADDR, sizeof(uint32_t)); // ÑéÖ¤¶ÁÈ¡µÄÖµÊÇ·ñÓÐЧ if (saved_cycle == CYCLE_5S || saved_cycle == CYCLE_10S || saved_cycle == CYCLE_15S) { sample_cycle = saved_cycle; printf("Loaded saved sample cycle: %d s\r\n", sample_cycle); } else { // ÎÞЧֵ£¬Ê¹ÓÃĬÈÏ5Ãë sample_cycle = CYCLE_5S; printf("Using default sample cycle: %d s\r\n", sample_cycle); // ±£´æÄ¬ÈÏÖµµ½Flash spi_flash_sector_erase(SAMPLE_CYCLE_ADDR); spi_flash_buffer_write((uint8_t*)&sample_cycle, SAMPLE_CYCLE_ADDR, sizeof(uint32_t)); } // ¶ÁÈ¡¶ÓÎé±àºÅ Team_num(); delay_1ms(10); } /************************************************************ Function : UsrFunction Comment : Óû§³ÌÐò¹¦ÄÜ Parameter: null Return : null Author : Liu Tao @ GigaDevice Date : 2025-05-10 V0.1 original ************************************************************/ void UsrFunction(void) { uint8_t sampling_enabled = 0; // ²ÉÑùʹÄܱêÖ¾ uint32_t last_sample_time = 0; // ÉϴβÉÑùʱ¼ä uint32_t last_led_toggle_time = 0; // LEDÇл»Ê±¼ä uint8_t led_state = 0; // LEDµ±Ç°×´Ì¬ // ¾²Ì¬±äÁ¿¼Ç¼°´¼üÉÏ´Î״̬£¨ÓÃÓÚ±ßÔµ¼ì²â£© static uint8_t last_key2 = 1, last_key3 = 1, last_key4 = 1; printf("====system init====\r\n"); Read_Team_num(); // ¶ÁÈ¡¶ÓÎé±àºÅ printf("\n\r====system ready====\r\n"); OLED_ShowString(0, 0, "system idle", 16); OLED_Refresh(); while (1) { uint32_t current_tick = systick_get_tick(); // ================ °´¼ü´¦Àí ================ // ¼ì²âKEY1°´ÏÂʼþ if (KEY_Stat(KEY_PORT, KEY1_PIN)) { // °´¼ü״̬·­×ª sampling_enabled = !sampling_enabled; if (sampling_enabled) { // Æô¶¯²ÉÑù printf("Output==> Periodic Sampling (Key Start)\r\n"); printf("Output==> sample cycle: %ds\r\n", sample_cycle); last_sample_time = current_tick; last_led_toggle_time = current_tick; led_state = 0; OLED_Clear(); OLED_ShowString(0, 0, "Sampling...", 16); OLED_Refresh(); } else { // Í£Ö¹²ÉÑù printf("Output==> Periodic Sampling STOP (Key Stop)\r\n"); gpio_bit_reset(GPIOA, GPIO_PIN_5); // ¹Ø±ÕLED1 OLED_Clear(); OLED_ShowString(0, 0, "system idle", 16); OLED_Refresh(); } // Ìí¼ÓÈ¥¶¶ÑÓʱ delay_1ms(50); } // ¼ì²âKEY2°´ÏÂʼþ£¨ÖÜÆÚÉèΪ5s£© uint8_t current_key2 = KEY_Stat(KEY_PORT, KEY2_PIN); if (current_key2 && !last_key2) { sample_cycle = CYCLE_5S; printf("Output==> sample cycle adjust: %ds\r\n", sample_cycle); // ±£´æµ½Flash spi_flash_sector_erase(SAMPLE_CYCLE_ADDR); spi_flash_buffer_write((uint8_t*)&sample_cycle, SAMPLE_CYCLE_ADDR, sizeof(uint32_t)); // Èç¹ûÕýÔÚ²ÉÑù£¬¸üвÉÑùʱ¼ä if (sampling_enabled) { last_sample_time = current_tick; } } last_key2 = current_key2; // ¼ì²âKEY3°´ÏÂʼþ£¨ÖÜÆÚÉèΪ10s£© uint8_t current_key3 = KEY_Stat(KEY_PORT, KEY3_PIN); if (current_key3 && !last_key3) { sample_cycle = CYCLE_10S; printf("Output==> sample cycle adjust: %ds\r\n", sample_cycle); // ±£´æµ½Flash spi_flash_sector_erase(SAMPLE_CYCLE_ADDR); spi_flash_buffer_write((uint8_t*)&sample_cycle, SAMPLE_CYCLE_ADDR, sizeof(uint32_t)); // Èç¹ûÕýÔÚ²ÉÑù£¬¸üвÉÑùʱ¼ä if (sampling_enabled) { last_sample_time = current_tick; } } last_key3 = current_key3; // ¼ì²âKEY4°´ÏÂʼþ£¨ÖÜÆÚÉèΪ15s£© uint8_t current_key4 = KEY_Stat(KEY_PORT, KEY4_PIN); if (current_key4 && !last_key4) { sample_cycle = CYCLE_15S; printf("Output==> sample cycle adjust: %ds\r\n", sample_cycle); // ±£´æµ½Flash spi_flash_sector_erase(SAMPLE_CYCLE_ADDR); spi_flash_buffer_write((uint8_t*)&sample_cycle, SAMPLE_CYCLE_ADDR, sizeof(uint32_t)); // Èç¹ûÕýÔÚ²ÉÑù£¬¸üвÉÑùʱ¼ä if (sampling_enabled) { last_sample_time = current_tick; } } last_key4 = current_key4; // ================ ´®¿ÚÃüÁî´¦Àí ================ if (cmd_ready) { cmd_ready = 0; int len = cmd_index; // ÇåÀíÃüÁîĩβµÄ¿Õ°××Ö·û while (len > 0 && (cmd_buffer[len - 1] == '\r' || cmd_buffer[len - 1] == '\n' || cmd_buffer[len - 1] == ' ')) { cmd_buffer[len - 1] = '\0'; len--; } // ²âÊÔÃüÁî if (strcmp((const char*)cmd_buffer, "test") == 0) { sys_check(); // ϵͳ×Ô¼ì } // RTCÅäÖÃÃüÁî else if (strcmp((const char*)cmd_buffer, "RTC Config") == 0) { printf("\r\nInput Datetime\r\n"); while (cmd_ready == 0) delay_1ms(10); char datetime_str[64]; strcpy(datetime_str, (const char*)cmd_buffer); cmd_ready = 0; rtc_settime(datetime_str); } // ÏÔʾµ±Ç°Ê±¼ä else if (strcmp((const char*)cmd_buffer, "RTC now") == 0) { rtc_show_time(); } // conf¼ì²â else if (strcmp((const char*)cmd_buffer, "conf") == 0) { conf(); } // ratio¼ì²â else if (strcmp((const char*)cmd_buffer, "ratio") == 0) { ratio_set(); } // limit¼ì²â else if (strcmp((const char*)cmd_buffer, "limit") == 0) { limit_set(); } // conf_read¼ì²â else if (strcmp((const char*)cmd_buffer, "conf_read") == 0) { printf("\r\nread parameters from flash\r\n"); conf_read(); } // conf_save¼ì²â else if (strcmp((const char*)cmd_buffer, "conf_save") == 0) { conf_save(); } // Æô¶¯²ÉÑùÃüÁî else if (strcmp((const char*)cmd_buffer, "start") == 0) { sampling_enabled = 1; printf("Output==> Periodic Sampling\r\n"); printf("Output==> sample cycle: %ds\r\n", sample_cycle); last_sample_time = current_tick; last_led_toggle_time = current_tick; led_state = 0; OLED_Clear(); OLED_ShowString(0, 0, "Sampling...", 16); OLED_Refresh(); } // Í£Ö¹²ÉÑùÃüÁî else if (strcmp((const char*)cmd_buffer, "stop") == 0) { if (sampling_enabled) { sampling_enabled = 0; printf("Output==> Periodic Sampling STOP\r\n"); gpio_bit_reset(GPIOA, GPIO_PIN_5); // ¹Ø±ÕLED1 OLED_Clear(); OLED_ShowString(0, 0, "system idle", 16); OLED_Refresh(); } } } // ================ ²ÉÑùÈÎÎñ ) ================ if (sampling_enabled) { // LEDÉÁ˸¿ØÖÆ£¨·Ç×èÈû·½Ê½£© if (current_tick - last_led_toggle_time >= 500) { last_led_toggle_time = current_tick; led_state = !led_state; if (led_state) { gpio_bit_set(GPIOA, GPIO_PIN_5); // LEDÁÁ } else { gpio_bit_reset(GPIOA, GPIO_PIN_5); // LEDÃð } } // ²ÉÑù¶¨Ê±£¨Ê¹Óõ±Ç°ÖÜÆÚ£© if (current_tick - last_sample_time >= sample_cycle * 1000) { // ¶ÁÈ¡RTCʱ¼ä // ¶ÁÈ¡ADCÖµ adc_flag_clear(ADC0, ADC_FLAG_EOC); while (SET != adc_flag_get(ADC0, ADC_FLAG_EOC)) {} // µÈ´ýת»»Íê³É uint16_t adc_value = ADC_RDATA(ADC0); float vol_value = adc_value * 3.3f / 4095.0f; rtc_current_time_get(&rtc_initpara); // ת»»Îª10½øÖÆ uint8_t hour = bcd_to_dec(rtc_initpara.hour); uint8_t minute = bcd_to_dec(rtc_initpara.minute); uint8_t second = bcd_to_dec(rtc_initpara.second); uint8_t year = bcd_to_dec(rtc_initpara.year); uint8_t month = bcd_to_dec(rtc_initpara.month); uint8_t day = bcd_to_dec(rtc_initpara.date); /**************** OLED?? ****************/ char time_str[16]; char volt_str[16]; sprintf(time_str, "%02u:%02u:%02u", hour, minute, second); sprintf(volt_str, "%.2f V", vol_value); OLED_Clear(); OLED_ShowString(0, 0, time_str, 16); OLED_ShowString(0, 16, volt_str, 16); OLED_Refresh(); /***************´®¿ÚÊä³ö****************/ printf("20%02u-%02u-%02u %02u:%02u:%02u %.2fV\r\n", year, month, day, hour, minute, second, vol_value); /*************** ´æ´¢Êý¾Ý *************** int count; // µ±Ç°ÎļþÊý¾Ý¼ÆÊý unsigned long datetime; // µ±Ç°ÎļþµÄʱ¼ä´Á FIL file; // µ±Ç°Îļþ¶ÔÏóDataFileInfo data_file_info = {0, 0, {0}};*/ FRESULT res; FATFS fs; char dir_path[] = "0:/sample"; // Ä¿±êĿ¼ char filename[64]; if (data_file_info.count == 0) { //³õʼ»¯´æ´¢É豸 DSTATUS status = disk_initialize(0); if (status != 0) { printf("Disk initialize failed. Status: 0x%02X\n", status); return; } //¹ÒÔØÎļþϵͳ res = f_mount(0, &fs); if (res != FR_OK) { printf("Mount failed=%d\n", res); return; } // ¹Ø±Õ֮ǰ´ò¿ªµÄÎļþ if (data_file_info.file.fs) { f_close(&data_file_info.file); } //È·±£Ä¿±êĿ¼´æÔÚ FILINFO fno; res = f_stat(dir_path, &fno); if (res == FR_NO_FILE) { // Ŀ¼²»´æÔÚ res = f_mkdir(dir_path); // ´´½¨Ä¿Â¼ if (res != FR_OK) { printf("Ŀ¼´´½¨Ê§°Ü %s: %d\n", dir_path, res); return; } } else if (res != FR_OK) { printf("Ŀ¼·ÃÎÊ´íÎó: %d\n", res); return; } // Éú³É´øÂ·¾¶µÄÎļþÃû snprintf(filename, sizeof(filename), "%s/sampleDeta20%02d%02d%02d%02d%02d%02d.txt", dir_path, year, month, day, hour, minute, second); // ´´½¨ÐÂÎļþ res = f_open(&data_file_info.file, filename, FA_CREATE_ALWAYS | FA_WRITE); if (res != FR_OK) { printf("Îļþ´´½¨Ê§°Ü %s: %d\n", filename, res); // return; }else{ printf(“Îļþ´´½¨³É¹¦”); f_open(&data_file_info.file, filename, FA_CREATE_ALWAYS | FA_WRITE); } } // дÈëÊý¾Ý char data_line[50]; snprintf(data_line, sizeof(data_line), "20%02d-%02d-%02d %02d:%02d:%02d %.2f V\r\n", year, month, day, hour, minute, second, vol_value); UINT bw; // f_open(&data_file_info.file, filename, FA_CREATE_ALWAYS | FA_WRITE); res = f_write(&data_file_info.file, data_line, strlen(data_line), &bw); // f_close(&data_file_info.file); // f_mount(0, NULL);//Ð¶ÔØÎļþϵͳ if (res != FR_OK || bw != strlen(data_line)) { printf(“Êý¾ÝдÈëʧ°Ü: %d\n”, res); } else { f_sync(&data_file_info.file); data_file_info.count++; // ´ïµ½10ÌõÊý¾ÝºóÖØÖà if (data_file_info.count >= 10) { data_file_info.count = 0; f_mount(0, NULL);//Ð¶ÔØÎļþϵͳ } } last_sample_time = current_tick; } } else { // ¿ÕÏÐ״̬ÏÂÌí¼ÓСÑÓʱ delay_1ms(10); } } } void nvic_config(void) { nvic_priority_group_set(NVIC_PRIGROUP_PRE1_SUB3); // ÉèÖÃÖжÏÓÅÏȼ¶·Ö×é nvic_irq_enable(SDIO_IRQn, 0, 0); // ʹÄÜSDIOÖжϣ¬ÓÅÏȼ¶Îª0 } /* ͨ¹ý´®¿ÚÊäÈëдÈëÎļþ */ void write_file(void) { printf(“Input data (press Enter to save):\r\n”); uint16_t index = 0; while(1){ if(usart_flag_get(USART0, USART_FLAG_RBNE) != RESET){ char ch = usart_data_receive(USART0); // Èç¹û½ÓÊÕ»º³åÇø·Ç¿Õ£¬´ÓUSART0½ÓÊÕÒ»¸ö×Ö·û if(ch == '\r'){ // ¼ì²é½ÓÊÕµ½µÄ×Ö·ûÊÇ·ñΪ»Ø³µ¼ü£¨'\r'£© filebuffer[index] = '\0'; // Èç¹ûÊǻسµ¼ü£¬ÔÚµ±Ç°Î»ÖÃÌí¼Ó×Ö·û´®½áÊø·û '\0' break; // Ìø³öÑ­»·£¬½áÊøÊý¾Ý½ÓÊÕ } filebuffer[index++] = ch; // ´æ´¢½ÓÊÕµ½µÄ×Ö·û if(index >= sizeof(filebuffer)-1) break; // Èç¹û»º³åÇøÂúÔò½áÊø½ÓÊÕ } } } /! \brief memory compare function \param[in] src: source data pointer \param[in] dst: destination data pointer \param[in] length: the compare data length \param[out] none \retval ErrStatus: ERROR or SUCCESS / ErrStatus memory_compare(uint8_t src, uint8_t dst, uint16_t length) { while(length --){ if(*src++ != *dst++) return ERROR; } return SUCCESS; } 把 int count; // µ±Ç°ÎļþÊý¾Ý¼ÆÊý unsigned long datetime; // µ±Ç°ÎļþµÄʱ¼ä´Á FIL file; // µ±Ç°Îļþ¶ÔÏóDataFileInfo data_file_info = {0, 0, {0}};*/ FRESULT res; FATFS fs; char dir_path[] = "0:/sample"; // Ä¿±êĿ¼ char filename[64]; if (data_file_info.count == 0) { //³õʼ»¯´æ´¢É豸 DSTATUS status = disk_initialize(0); if (status != 0) { printf("Disk initialize failed. Status: 0x%02X\n", status); return; } //¹ÒÔØÎļþϵͳ res = f_mount(0, &fs); if (res != FR_OK) { printf("Mount failed=%d\n", res); return; } // ¹Ø±Õ֮ǰ´ò¿ªµÄÎļþ if (data_file_info.file.fs) { f_close(&data_file_info.file); } //È·±£Ä¿±êĿ¼´æÔÚ FILINFO fno; res = f_stat(dir_path, &fno); if (res == FR_NO_FILE) { // Ŀ¼²»´æÔÚ res = f_mkdir(dir_path); // ´´½¨Ä¿Â¼ if (res != FR_OK) { printf("Ŀ¼´´½¨Ê§°Ü %s: %d\n", dir_path, res); return; } } else if (res != FR_OK) { printf("Ŀ¼·ÃÎÊ´íÎó: %d\n", res); return; } // Éú³É´øÂ·¾¶µÄÎļþÃû snprintf(filename, sizeof(filename), "%s/sampleDeta20%02d%02d%02d%02d%02d%02d.txt", dir_path, year, month, day, hour, minute, second); // ´´½¨ÐÂÎļþ res = f_open(&data_file_info.file, filename, FA_CREATE_ALWAYS | FA_WRITE); if (res != FR_OK) { printf("Îļþ´´½¨Ê§°Ü %s: %d\n", filename, res); // return; }else{ printf(“Îļþ´´½¨³É¹¦”); f_open(&data_file_info.file, filename, FA_CREATE_ALWAYS | FA_WRITE); } } // дÈëÊý¾Ý char data_line[50]; snprintf(data_line, sizeof(data_line), "20%02d-%02d-%02d %02d:%02d:%02d %.2f V\r\n", year, month, day, hour, minute, second, vol_value); UINT bw; // f_open(&data_file_info.file, filename, FA_CREATE_ALWAYS | FA_WRITE); res = f_write(&data_file_info.file, data_line, strlen(data_line), &bw); // f_close(&data_file_info.file); // f_mount(0, NULL);//Ð¶ÔØÎļþϵͳ if (res != FR_OK || bw != strlen(data_line)) { printf(“Êý¾ÝдÈëʧ°Ü: %d\n”, res); } else { f_sync(&data_file_info.file); data_file_info.count++; // ´ïµ½10ÌõÊý¾ÝºóÖØÖà if (data_file_info.count >= 10) { data_file_info.count = 0; f_mount(0, NULL);//Ð¶ÔØÎļþϵͳ } }封装起来,void write_data_to_file(const char* dir_path, int year, int month, int day, int hour, int minute, int second, float vol_value),只需要封装起来,不要改这里面的程序,一点也不要改,因为测试他没有错

#include "usart3.h" #include <string.h> #include "stdarg.h" /* ******´®¿Ú3³õʼ»¯***************************************** * º¯Êý¹¦ÄÜ: ´®¿Ú3³õʼ»¯ * Èë¿Ú²ÎÊý: baud:É趨²¨ÌØÂÊ * ·µ»Ø²ÎÊý: ÎÞ * ˵Ã÷: TX-PB10 RX-PB11 ********************************************************** */ #define RECEIVE_BUF_SIZE 8 uint8_t WindRxFlag = 0; // ´®¿Ú3½ÓÊÕ±êÖ¾0-δ½ÓÊÜ1-½ÓÊÕ uint8_t WindReceiveBuff[RECEIVE_BUF_SIZE]; // ´®¿Ú3½ÓÊÕ»º³å uint16_t WindRxLen = 0; // ´®¿Ú3½ÓÊÕ³¤¶È uint8_t WindDecid=0; float WindVelocity=0;//·çËÙ //´®¿Ú½ÓÊÕ»º´æÇø u8 USART3_RX_BUF[USART3_MAX_RECV_LEN]; //½ÓÊÕ»º³å,×î´óUSART3_MAX_RECV_LEN¸ö×Ö½Ú. u8 USART3_Cach_BUF[USART3_MAX_RECV_LEN]; //½ÓÊÕ»º³å,×î´óUSART_REC_LEN¸ö×Ö½Ú. u8 USART3_TX_BUF[USART3_MAX_SEND_LEN]; //·¢ËÍ»º³å,×î´óUSART3_MAX_SEND_LEN×Ö½Ú u8 USART3_RX_Count=0; //ͨ¹ýÅжϽÓÊÕÁ¬Ðø2¸ö×Ö·ûÖ®¼äµÄʱ¼ä²î²»´óÓÚ10msÀ´¾ö¶¨ÊDz»ÊÇÒ»´ÎÁ¬ÐøµÄÊý¾Ý. //Èç¹û2¸ö×Ö·û½ÓÊÕ¼ä¸ô³¬¹ý10ms,ÔòÈÏΪ²»ÊÇ1´ÎÁ¬ÐøÊý¾Ý.Ò²¾ÍÊdz¬¹ý10msûÓнÓÊÕµ½ //ÈκÎÊý¾Ý,Ôò±íʾ´Ë´Î½ÓÊÕÍê±Ï. //½ÓÊÕµ½µÄÊý¾Ý״̬ //[15]:0,ûÓнÓÊÕµ½Êý¾Ý;1,½ÓÊÕµ½ÁËÒ»ÅúÊý¾Ý. //[14:0]:½ÓÊÕµ½µÄÊý¾Ý³¤¶È vu16 USART3_RX_STA=0; void Usart3_Init(unsigned int baud) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3 , ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB , &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOB , &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = baud; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); USART_Init(USART3,&USART_InitStructure); USART_Cmd(USART3,ENABLE); USART3_RX_STA=0; //ÇåÁã } void USART3_IRQHandler(void) { uint8_t Res; if(USART_GetITStatus(USART3,USART_IT_RXNE) != RESET) //ÅжÏÊÇ·ñ·¢ÉúÖÐ¶Ï { Res=USART_ReceiveData(USART3); if(Res=='A') { isKey1=1; // OperateMode=!OperateMode; // oled_Clear(); } else if(Res=='D') { if(OperateMode==1) Threshold.Switch1=!Threshold.Switch1; } else if(Res=='B') { Threshold.Geer++; } else if(Res=='E') { Threshold.Geer--; } Res='\0'; USART_ClearITPendingBit(USART3, USART_IT_RXNE); } } void WindRx_Handel(void) { uint16_t crc; if(USART3_RX_STA) { // printf("WindRx:"); // for(int i=0;i<7;i++) // { // printf("%x ",WindReceiveBuff[i]); // } // printf("\r\n"); crc= Crc16(WindReceiveBuff,7); if(crc==0) { // SensorData.WindVel=WindReceiveBuff[3]<<8; // SensorData.WindVel+=WindReceiveBuff[4]; // SensorData.WindVel=SensorData.WindVel*0.1; // printf("WindVelocity:%f\r\n",SensorData.WindVel); if(WindReceiveBuff[4]==1) WindDecid=1; else WindDecid=0; } // printf("crc:%d\r\n",crc); USART3_RX_STA = 0; WindRxLen = 0; memset(WindReceiveBuff, 0x00, sizeof(WindReceiveBuff)); } // printf("WindVelocity:%d\r\n",WindVelocity); } ///* //******´®¿Ú·¢Ë͵¥×Ö½Ú***************************************** //* º¯Êý¹¦ÄÜ: ´®¿Ú·¢Ë͵¥×Ö½Ú //* Èë¿Ú²ÎÊý: pUSARTx:´®¿ÚºÅ // ch£ºÐèÒª·¢Ë͵Ä×Ö½Ú //* ·µ»Ø²ÎÊý: ÎÞ //********************************************************** //*/ void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch) { /* ·¢ËÍÒ»¸ö×Ö½ÚÊý¾Ýµ½USART */ USART_SendData(pUSARTx,ch); /* µÈ´ý·¢ËÍÊý¾Ý¼Ä´æÆ÷Ϊ¿Õ */ while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET); } ///* //******´®¿Ú·¢ËͶà×Ö½Ú***************************************** //* º¯Êý¹¦ÄÜ: ´®¿Ú·¢Ë͵¥×Ö½Ú //* Èë¿Ú²ÎÊý: pUSARTx:´®¿ÚºÅ // Buffer£ºÐèÒª·¢Ë͵ÄÊý×éµÄÖ¸Õë // Length£ºÐèÒª·¢Ë͵ÄÊý×éµÄ³¤¶È //* ·µ»Ø²ÎÊý: ÎÞ //********************************************************** //*/ void Usart_SendBytes( USART_TypeDef * pUSARTx, uint8_t *Buffer, uint8_t Length) { uint8_t i=0; while(i<Length) { // if(i<(Length-1)) // Buffer[Length-1]+=Buffer[i];//ÀÛ¼ÓLength-1ǰµÄÊý¾Ý Usart_SendByte(pUSARTx,Buffer[i++]); } } ///* //******´®¿Ú·¢ËÍ×Ö·û´®***************************************** //* º¯Êý¹¦ÄÜ: ´®¿Ú·¢ËÍ×Ö·û´® //* Èë¿Ú²ÎÊý: pUSARTx:´®¿ÚºÅ // str:ÐèÒª·¢Ë͵Ä×Ö·û´®µÄÊ×µØÖ· //* ·µ»Ø²ÎÊý: ÎÞ //********************************************************** //*/ //void Usart_SendString( USART_TypeDef * pUSARTx, char *str) //{ // unsigned int k=0; // do // { // Usart_SendByte( pUSARTx, *(str + k) ); // k++; // } while(*(str + k)!='\0'); // /* µÈ´ý·¢ËÍÍê³É */ // while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET) // {} //} /* CRC16 Óàʽ±í */ static uint16_t crctalbeabs[] = { 0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401, 0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400 }; /*! * ¹¦ ÄÜ: CRC16УÑé * param1: Ö¸ÏòҪУÑéµÄÊý¾ÝµÄÖ¸Õë * param2: ҪУÑéµÄÊý¾ÝµÄ³¤¶È * retval: УÑéËùµÃµ½µÄÖµ£¬uint16_t ÀàÐÍ * * ˵ Ã÷: ±¾´ÎCRCУÑéΪ²é±í·¨£¬¶àÏîʽΪ x16+x15+x2+1(0x8005)£¬CRCµÄ³õʼֵΪ0xFFFF */ uint16_t Crc16(uint8_t *ptr, uint32_t len) { uint16_t crc = 0xffff; uint32_t i; uint8_t ch; for (i = 0; i < len; i++) { ch = *ptr++; crc = crctalbeabs[(ch ^ crc) & 15] ^ (crc >> 4); crc = crctalbeabs[((ch >> 4) ^ crc) & 15] ^ (crc >> 4); } return crc; } __align(8) char USART3_TxBuff[128]; void u3_printf(char* fmt,...) { unsigned int i =0,length=0; va_list ap; va_start(ap,fmt); vsprintf(USART3_TxBuff,fmt,ap); va_end(ap); length=strlen((const char*)USART3_TxBuff); while(i<length) { Usart_SendByte(USART3,USART3_TxBuff[i]); i++; } while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET); }解释代码

CCD巡线难寻到,看是否能更改程序中间数值,提高识别的成功率。CCD.c文件:#include "CCD.h" uint8_t CCD_Zhongzhi; uint16_t ADV[128] = {0}; unsigned int adc_value = 0; unsigned int voltage_value = 0; volatile bool gCheckADC; // ADC²É¼¯³É¹¦±ê־λ float CCD_KP = 10, CCD_KI = 3; float CCD_Vel = 350; float CCD_KD = 2.0; float integral_error = 0; float light_level = 0.5; void CCD_Mode(void) { static float light_filter = 0; uint16_t avg = 0; for (int i = 20; i < 108; i++) avg += ADV[i]; avg /= 88; light_filter = 0.8 * light_filter + 0.2 * avg; light_level = light_filter / 256.0; Move_X = CCD_Vel / 1000.0f * (0.5 + 0.5 * light_level); static float Bias, Last_Bias; Bias = 64 - CCD_Zhongzhi; // Ìáȡƫ²î Move_Z = Bias * CCD_KP / 1000.0f + (Bias - Last_Bias) * CCD_KI / 1000.0f; // PD¿ØÖÆ Last_Bias = Bias; // ±£´æÉÏÒ»´ÎµÄÆ«²î Get_Target_Encoder(Move_X, Move_Z); } // ¶ÁÈ¡ADCµÄÊý¾Ý int adc_getValue(void) { unsigned int gAdcResult = 0; // Èí¼þ´¥·¢ADC¿ªÊ¼×ª»» DL_ADC12_startConversion(ADC12_CCD_INST); // Èç¹ûµ±Ç°×´Ì¬ÎªÕýÔÚת»»ÖÐÔòµÈ´ýת»»½áÊø // »ñÈ¡Êý¾Ý gAdcResult = DL_ADC12_getMemResult(ADC12_CCD_INST, ADC12_CCD_ADCMEM_0); // Çå³ý±ê־λ gCheckADC = false; return gAdcResult; } // CCD_ADCÖжϷþÎñº¯Êý void ADC12_CCD_INST_IRQHandler(void) { // ²éѯ²¢Çå³ýADCÖÐ¶Ï switch (DL_ADC12_getPendingInterrupt(ADC12_CCD_INST)) { // ¼ì²éÊÇ·ñÍê³ÉÊý¾Ý²É¼¯ case DL_ADC12_IIDX_MEM0_RESULT_LOADED: gCheckADC = true; // ½«±ê־λÖÃ1 break; default: break; } } /************************************************************************** º¯Êý¹¦ÄÜ£ºCCDÊý¾Ý²É¼¯ Èë¿Ú²ÎÊý£ºÎÞ ·µ»Ø Öµ£ºÎÞ **************************************************************************/ void RD_TSL(void) { TSL_CLK(1); delay_us(5); TSL_SI(0); delay_us(10); TSL_CLK(0); delay_us(5); TSL_SI(1); delay_us(30); TSL_CLK(1); delay_us(5); TSL_SI(1); delay_us(10); TSL_CLK(1); delay_us(5); TSL_SI(0); delay_us(10); TSL_CLK(0); delay_us(100); for (int i = 0; i < 128; i++) // ¶ÁÈ¡128¸öÏñËØµãµçѹֵ { TSL_CLK(0); delay_us(300); // µ÷½ÚÆØ¹âʱ¼ä ADV[i] = (adc_getValue()) >> 4; // ÓÒÒÆ4λÊÇ/4²Ù×÷£¬½«Êý¾Ý·¶Î§´Ó0-4096ѹËõµ½0-256·½±ãÊý¾Ý´¦Àí TSL_CLK(1); delay_us(20); } } /************************************************************************** º¯Êý¹¦ÄÜ£ºÏßÐÔCCDÈ¡ÖÐÖµ Èë¿Ú²ÎÊý£ºÎÞ ·µ»Ø Öµ£ºÎÞ **************************************************************************/ void Find_CCD_Median(void) { static uint16_t i, j, Left, Right, Last_CCD_Median; static uint16_t value1_max, value1_min; static uint16_t CCD_Threshold; // ãÐֵ˵Ã÷£ºCCD²É¼¯»ØÀ´µÄ128¸öÊý¾Ý£¬Ã¿¸öÊý¾Ýµ¥¶ÀÓëãÐÖµ½øÐбȽϣ¬±ÈãÐÖµ´óΪ°×É«£¬±ÈãÐֵСΪºÚÉ« // ¶¯Ì¬ãÐÖµËã·¨£¬¶Áȡÿ´Î²É¼¯Êý¾ÝµÄ×î´óºÍ×îСֵµÄƽ¾ùÊý×÷ΪãÐÖµ value1_max = ADV[0]; for (i = 5; i < 123; i++) // Á½±ß¸÷È¥µô5¸öµã { if (value1_max <= ADV[i]) value1_max = ADV[i]; } value1_min = ADV[0]; // ×îСֵ for (i = 5; i < 123; i++) { if (value1_min >= ADV[i]) value1_min = ADV[i]; } CCD_Threshold = (value1_max + value1_min) / 2; // ¼ÆËã³ö±¾´ÎÖÐÏßÌáÈ¡µÄãÐÖµ for (i = 5; i < 118; i++) // ѰÕÒ×ó±ßÌø±äÑØ£¬Á¬ÐøÈý¸ö°×ÏñËØºóÁ¬ÐøÈý¸öºÚÏñËØÅжÏ×ó±ßÌø±äÑØ { if (ADV[i] > CCD_Threshold && ADV[i + 1] > CCD_Threshold && ADV[i + 2] > CCD_Threshold && ADV[i + 3] < CCD_Threshold && ADV[i + 4] < CCD_Threshold && ADV[i + 5] < CCD_Threshold) { Left = i + 2; break; } } for (j = 118; j > 5; j--) // ѰÕÒÓÒ±ßÌø±äÑØ£¬Á¬ÐøÈý¸öºÚÏñËØºóÁ¬ÐøÈý¸ö°×ÏñËØÅжÏÓÒ±ßÌø±äÑØ { if (ADV[j] < CCD_Threshold && ADV[j + 1] < CCD_Threshold && ADV[j + 2] < CCD_Threshold && ADV[j + 3] > CCD_Threshold && ADV[j + 4] > CCD_Threshold && ADV[j + 5] > CCD_Threshold) { Right = j + 2; break; } } CCD_Zhongzhi = (uint8_t)(Right + Left) / 2; // ¼ÆËãÖÐÏßλÖà } void TSL_CLK(int state) { if (state) { DL_GPIO_setPins(GPIO_CLK_PORT, GPIO_CLK_PIN_23_PIN); } else { DL_GPIO_clearPins(GPIO_CLK_PORT, GPIO_CLK_PIN_23_PIN); } } void TSL_SI(int state) { if (state) { DL_GPIO_setPins(GPIO_SI_PORT, GPIO_SI_PIN_25_PIN); } else { DL_GPIO_clearPins(GPIO_SI_PORT, GPIO_SI_PIN_25_PIN); } }

#include "delay.h" #include "sys.h" #include "OLED.h" #include "dht11.h" #include "esp8266.h" #include "Timer.h" #include "Key.h" #include "stmflash.h" #include "Usart.h" #include "control.h" #include "adc.h" #include "HC_SR505.h" #include "su_03t.h" //C¿â #include <string.h> #include "stdio.h" #include "math.h" extern unsigned char esp8266_buf[buf_len]; //×Ô¶¨Ò庯Êý void show_wendu_shidu(void); void show_title(void); void show_mode(void); void show_final_keranqiti_ppm(void); u16 Light_Check(void); void show_light(void); void show_people(void); void page1(void); void page2(void); void page3(void); u8 mode=2; //×Ô¶¯Ä£Ê½=1£¬ÊÖ¶¯Ä£Ê½=2 int page=1; //½çÃæÑ¡Ôñ int page2_index = 1; //½çÃæ2Çл»Ñ¡Ôñ int page3_index = 1; //½çÃæ3Çл»Ñ¡Ôñ //ãÐÖµ struct Set_data { u16 temp_h; u16 humi_h; u16 light_l; u16 co2_l; }; struct Set_data Out_data={35,75,50,500};//³õʼ»¯ãÐÖµ //°´¼üÏà¹ØµÄ±äÁ¿ u8 key_num=0; //wifi±äÁ¿ char TIMER_IT=0,WiFiInit_time,Flagout=1; //oledÏà¹Ø±äÁ¿ u8 oled_Fill_flag=1;//OLEDÇåÆÁ±êÖ¾ char oled_str[100];//OLEDÏÔʾ»º´æ char date[200];//esp8266·¢ËÍ»º´æ u8 buff[30];//²ÎÊýÏÔʾ»º´æÊý×é //¶¨Ê±ÖжÏÊýÊý int beep_flag = 0; int beep_NUM = 0; // ÔÚÈ«¾Ö±äÁ¿ÇøÓòÌí¼Ó±ê־λ u8 alarm_sent = 0; // ±¨¾¯Ðźŷ¢Ëͱê־λ //dht11Ìí¼Ó±äÁ¿ DHT11_Data_TypeDef DHT11_Data; //ÑÌÎíŨ¶È u16 keranqiti_ppm; //ÑÌÎíŨ¶È float final_keranqiti_ppm; //¹âÃô¼à²â u16 light = 0; //ÈËÌå¼ì²â int REN_value; int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //ÖжϿØÖÆÆ÷·Ö×éÉèÖà Key_Init(); OLED_Init(); OLED_Clear(0); DHT11_Init(); //DHT11³õʼ»¯ Timer_Init(); Adc_Init(); HC_SR505_Init(); //renti´«¸ÐÆ÷³õʼ»¯ beep_init(); led_init(); My_TIM3_Init(19999,71); fan_init(); SU_03T_Iint(9600); //ÓïÒô²¥±¨ Serial_Iint(9600); do { key_num=KEY_Scan(0);//°´¼üɨÃè if(key_num==1)//ÐèÒªÁªÍø { OLED_Clear(0); ESP8266_Init(115200); //´®¿Ú2£¬Çý¶¯wifiÄ£¿éÓà Timer_Init(); break; } OLED_ShowCHinese(0, 0,1);//ÊÇ OLED_ShowCHinese(18,0,2);//·ñ OLED_ShowCHinese(36,0,3);//Ðè OLED_ShowCHinese(52,0,4);//Òª OLED_ShowCHinese(68,0,5);//Áª OLED_ShowCHinese(84,0,6);//Íø OLED_ShowCHinese(100,0,7);//£¿ OLED_ShowString(8,4,"1.",16); OLED_ShowCHinese(24,4,1);//ÊÇ OLED_ShowString(62,4,"2.",16); OLED_ShowCHinese(78,4,2);//·ñ }while(key_num!=2); OLED_Clear(0); while(1) { /*********************************Êý¾Ý´¦ÀíÇø**************************************************/ /*******************¶ÁÈ¡ÎÂʪ¶ÈÊý¾Ý***************************************/ Read_DHT11(&DHT11_Data); /************************¿ÉÈ¼ÆøÌåÊý¾Ý***********************************************/ keranqiti_ppm = Get_Adc_Average(0,1); final_keranqiti_ppm = (keranqiti_ppm/4096.0*3.3)*210+ 10; //¶ÁÈ¡ ¹âÕÕ Êý¾Ý light = Light_Check(); /*******************¶ÁÈ¡ÈËÌåºìÍâÊý¾Ý***************************************/ REN_value=Get_HC_SR505_Value(); /*******************Ïò°Í·¨ÔÆ·¢ËÍÊý¾Ý***************************************/ if(TIMER_IT && Flagout==0) { TIMER_IT=0; sprintf(date,"cmd=2&uid=%s&topic=data&msg=#%d#%d.%d#%d.%d#%d#%d#%.1f#\r\n",\ BEMFA_ID, mode, DHT11_Data.temp_int,DHT11_Data.temp_deci,DHT11_Data.humi_int,DHT11_Data.humi_deci, REN_value,light,final_keranqiti_ppm); ESP8266_SendData((unsigned char *)date);//ESP8266·¢ËÍÊý¾Ý } printf("#ζÈ:%d#ʪ¶È:%d#ÈËÌå¼ì²â:%d#¹âÕÕ:%d#ÑÌÎí:%.1f#\r\n",DHT11_Data.temp_int,DHT11_Data.humi_int,REN_value,light,final_keranqiti_ppm); /*********************************ÈË»ú½»»¥Çø**************************************************/ key_num=KEY_Scan(0);//°´¼üɨÃè if(key_num==1) { page+=1; OLED_Clear(0); if(page == 4) //¸ù¾Ý×î´ó½çÃæ½øÐÐÉèÖà page = 1; } if(page == 1) //ÏÔʾÊý¾Ý { page1(); } if(page == 2) { page2(); } if(page == 3) { page3(); } /*********************************ģʽ¿ØÖÆÇø**************************************************/ //appģʽÇл» if(strstr((const char *)esp8266_buf,"ZD")!=0 ) //Çл»Ê±Òª¹Ø±ÕËùÓÐ { mode=1; fan = 0; led = 1; TIM_SetCompare1(TIM3,1500); } else if(strstr((const char *)esp8266_buf,"SD")!=0 ) { mode=2; fan = 0; led = 1; TIM_SetCompare1(TIM3,1500); } if(mode==1)//×Ô¶¯Ä£Ê½ { //¿ØÖÆÎ¶Èʪ¶ÈÑÌÎí if(DHT11_Data.temp_int > Out_data.temp_h || DHT11_Data.humi_int > Out_data.humi_h||final_keranqiti_ppm > 200) { fan = 1; if(final_keranqiti_ppm > 200) { if(beep_flag == 0) { beep_NUM = 0; beep_flag = 1; if(Flagout == 0) { sprintf(date,"cmd=2&uid=%s&topic=control&msg=YanWu\r\n", BEMFA_ID); ESP8266_SendData((unsigned char *)date);//ESP8266·¢ËÍÊý¾Ý sprintf(date,"cmd=2&uid=%s&topic=control&msg=delay\r\n", BEMFA_ID); ESP8266_SendData((unsigned char *)date);//ESP8266·¢ËÍÊý¾Ý } } } if(DHT11_Data.temp_int > Out_data.temp_h || DHT11_Data.humi_int > Out_data.humi_h) { if(Flagout == 0) { sprintf(date,"cmd=2&uid=%s&topic=control&msg=wenshidu\r\n", BEMFA_ID); ESP8266_SendData((unsigned char *)date);//ESP8266·¢ËÍÊý¾Ý sprintf(date,"cmd=2&uid=%s&topic=control&msg=delay\r\n", BEMFA_ID); ESP8266_SendData((unsigned char *)date);//ESP8266·¢ËÍÊý¾Ý } } } else if(DHT11_Data.temp_int <= Out_data.temp_h && DHT11_Data.humi_int <= Out_data.humi_h) { fan = 0; } //¿ØÖƹâÕÕ if(light < Out_data.light_l && REN_value == Have_body) { led = 0; TIM_SetCompare1(TIM3,500); } else { led = 1; TIM_SetCompare1(TIM3,1500); } } if(mode==2)//ÊÖ¶¯Ä£Ê½ { //APP¿ØÖÆ if(strstr((const char *)esp8266_buf,"KDG")!=0) { led = 0; } else if(strstr((const char *)esp8266_buf,"GDG")!=0) { led = 1; } else if(strstr((const char *)esp8266_buf,"KFS")!=0) { fan = 1; } else if(strstr((const char *)esp8266_buf,"GFS")!=0) { fan = 0; } else if(strstr((const char *)esp8266_buf,"KCH")!=0) { TIM_SetCompare1(TIM3,500); } else if(strstr((const char *)esp8266_buf,"GCH")!=0) { TIM_SetCompare1(TIM3,1500); } } /*********************************Êý¾Ý½ÓÊÕÇø**************************************************/ char *tw_ptr = strstr((char *)esp8266_buf, "wd"); if (tw_ptr != NULL && sscanf(tw_ptr + 2, "=%hu", &Out_data.temp_h) == 1) { ESP8266_Clear(); } char *jj_ptr = strstr((char *)esp8266_buf, "sd"); if (jj_ptr != NULL && sscanf(jj_ptr + 2, "=%hu", &Out_data.humi_h) == 1) { ESP8266_Clear(); } char *gz_ptr = strstr((char *)esp8266_buf, "gz"); if (gz_ptr != NULL && sscanf(gz_ptr + 2, "=%hu", &Out_data.light_l) == 1) { ESP8266_Clear(); } } } void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET) { TIMER_IT=1; beep_NUM++; if(beep_flag == 1) { if(beep_NUM <= 6) { if(beep == 1) beep = 0; else beep = 1; } if(beep_NUM >= 7) { beep = 1; beep_flag = 0; } } TIM_ClearITPendingBit(TIM2, TIM_IT_Update); } } void show_title(void) { // OLED_ShowCHinese(10, 0,108); OLED_ShowCHinese(26, 0,109); OLED_ShowCHinese(26+16, 0,110); OLED_ShowCHinese(26+32, 0,111); OLED_ShowCHinese(26+48, 0,92); OLED_ShowCHinese(26+48+16, 0,93); } void show_wendu_shidu(void) { sprintf(oled_str,"T:%d.%dC H:%d%% ",DHT11_Data.temp_int,0,DHT11_Data.humi_int); OLED_ShowString (0,0,(u8 *)oled_str,16); } void show_final_keranqiti_ppm(void) { //ÑÌÎí OLED_ShowCHinese(0, 2,22); OLED_ShowCHinese(16, 2,23); sprintf((char*)buff, ":%.1fppm ",final_keranqiti_ppm); OLED_ShowString(32,2,buff,16); } u16 Light_Check(void) { u16 light;float light_AD; light_AD=4096-Get_Adc_Average(1,1); light=light_AD/4095*100; return light; } void show_light(void) { OLED_ShowCHinese(0, 4, 24);// OLED_ShowCHinese(16, 4, 25);// OLED_ShowCHinese(32, 4, 26);// OLED_ShowCHinese(48, 4, 27);// sprintf((char*)buff, ":%d%% ",light); OLED_ShowString(64,4,buff,16); } void show_people(void) { OLED_ShowCHinese(0, 6,28); OLED_ShowCHinese(16, 6,29); OLED_ShowCHinese(32, 6,30); OLED_ShowCHinese(48, 6,31); OLED_ShowString(64, 6,(u8*)":",16); if(REN_value==Have_body) // { OLED_ShowCHinese(72, 6,32); } else if(REN_value==No_body) { OLED_ShowCHinese(72, 6,33); } } void show_mode(void) { if(mode ==1) { OLED_ShowString(110, 6,(u8*)"ZD",16); } else if(mode ==2) { OLED_ShowString(110, 6,(u8*)"SD",16); } } void page1(void) { show_wendu_shidu(); show_final_keranqiti_ppm(); show_light(); show_people(); show_mode(); if(key_num == 4) //Çл»ÊÖ×Ô¶¯Ä£Ê½£¬Í¬Ê±Òª¹Ø±ÕËùÓеĶ«Î÷ { if(mode == 1) { mode = 2; fan = 0; led = 1; TIM_SetCompare1(TIM3,1500); } else { mode = 1; fan = 0; led = 1; TIM_SetCompare1(TIM3,1500); } } } void page2(void) //Èý¸ö { //¿ª¹ØÉèÖà OLED_ShowCHinese(16+15, 0,38); OLED_ShowCHinese(16+15+16,0,39); OLED_ShowCHinese(16+15+32,0,10); OLED_ShowCHinese(16+15+48,0,11); //µÆ¹â OLED_ShowCHinese(0, 2,40); OLED_ShowCHinese(16,2,41); OLED_ShowChar(32,2,':',16); if(led == 0) OLED_ShowCHinese(40,2,38); else OLED_ShowCHinese(40,2,39); //fan OLED_ShowCHinese(0, 4,42); OLED_ShowCHinese(16,4,43); OLED_ShowChar(32,4,':',16); if(fan == 1) OLED_ShowCHinese(40,4,38); else OLED_ShowCHinese(40,4,39); //´°»§ OLED_ShowCHinese(0, 6,44); OLED_ShowCHinese(16,6,45); OLED_ShowChar(32,6,':',16); if(TIM_GetCapture1(TIM3) == 500) OLED_ShowCHinese(40, 6,38); else if(TIM_GetCapture1(TIM3) == 1500) OLED_ShowCHinese(40, 6,39); if(mode == 2) { if(key_num == 2) { page2_index +=1; if(page2_index ==4) //¸ù¾ÝÐèÒªÉèÖõÄãÐÖµ¸öÊý½øÐÐÅäÖà page2_index = 1; } if(page2_index == 1) { OLED_ShowChar(80,2,'<',16); OLED_ShowChar(80,4,' ',16); OLED_ShowChar(80,6,' ',16); if(key_num ==3) { led = 0; } else if(key_num ==4) { led = 1; } } if(page2_index == 2) { OLED_ShowChar(80,2,' ',16); OLED_ShowChar(80,4,'<',16); OLED_ShowChar(80,6,' ',16); if(key_num ==3) { fan = 1; } else if(key_num ==4) { fan = 0; } } if(page2_index == 3) { OLED_ShowChar(80,2,' ',16); OLED_ShowChar(80,4,' ',16); OLED_ShowChar(80,6,'<',16); if(key_num ==3) { TIM_SetCompare1(TIM3,500);// ´ò¿ª } else if(key_num ==4) { TIM_SetCompare1(TIM3,1500); } } } } void page3(void) //Èý¸ö { //ãÐÖµÉèÖà OLED_ShowCHinese(16+15, 0,8); OLED_ShowCHinese(16+15+16,0,9); OLED_ShowCHinese(16+15+32,0,10); OLED_ShowCHinese(16+15+48,0,11); //ζÈÏÂÏÞ OLED_ShowCHinese(0, 2,12); OLED_ShowCHinese(16, 2,13); OLED_ShowCHinese(32, 2,34); OLED_ShowCHinese(48, 2,35); OLED_ShowCHinese(64, 2,21); sprintf((char*)buff, ":%d ",Out_data.temp_h); OLED_ShowString(72,2,buff,16); //ʪ¶ÈÉÏÏÞ OLED_ShowCHinese(0, 4,14); OLED_ShowCHinese(16, 4,13); OLED_ShowCHinese(32, 4,34); OLED_ShowCHinese(48, 4,35); OLED_ShowCHinese(64, 4,21); sprintf((char*)buff, ":%d ",Out_data.humi_h); OLED_ShowString(72,4,buff,16); //¹âÕÕÏÂÏÞ OLED_ShowCHinese(0, 6,24); OLED_ShowCHinese(16, 6,25); OLED_ShowCHinese(32, 6,36); OLED_ShowCHinese(48, 6,37); OLED_ShowCHinese(64, 6,21); sprintf((char*)buff, ":%d ",Out_data.light_l); OLED_ShowString(72,6,buff,16); if(key_num == 2) { page3_index +=1; if(page3_index ==4) //¸ù¾ÝÐèÒªÉèÖõÄãÐÖµ¸öÊý½øÐÐÅäÖà page3_index = 1; } if(page3_index == 1) { OLED_ShowChar(100,2,'<',16); OLED_ShowChar(100,4,' ',16); OLED_ShowChar(100,6,' ',16); if(key_num ==3) Out_data.temp_h+=1; else if(key_num ==4) Out_data.temp_h-=1; } if(page3_index == 2) { OLED_ShowChar(100,2,' ',16); OLED_ShowChar(100,4,'<',16); OLED_ShowChar(100,6,' ',16); if(key_num ==3) Out_data.humi_h+=5; else if(key_num ==4) Out_data.humi_h-=5; } if(page3_index == 3) { OLED_ShowChar(100,2,' ',16); OLED_ShowChar(100,4,' ',16); OLED_ShowChar(100,6,'<',16); if(key_num ==3) Out_data.light_l+=5; else if(key_num ==4) Out_data.light_l-=5; } }

****************************************************************************** * @file main.c * @author fire * @version V1.0 * @date 2013-xx-xx * @brief Òº¾§ÏÔʾºº×ÖʵÑ飨×Ö¿âÔÚÍⲿFLASH£© ****************************************************************************** * @attention * * ʵÑéÆ½Ì¨:±ü»ð F103-Ö¸ÄÏÕß STM32 ¿ª·¢°å * ÂÛ̳ :http://www.firebbs.cn * ÌÔ±¦ :https://fire-stm32.taobao.com * ****************************************************************************** */ #include "stm32f10x.h" #include "./usart/bsp_usart.h" #include "./lcd/bsp_ili9341_lcd.h" #include "./flash/bsp_spi_flash.h" static void LCD_Test(void); static void Delay ( __IO uint32_t nCount ); void Printf_Charater(void) ; int main(void) { //LCD ³õʼ»¯ ILI9341_Init (); /* USART config */ USART_Config(); printf("\r\n ********** Òº¾§ÆÁÖÐÎÄÏÔʾ³ÌÐò£¨×Ö¿âÔÚÍⲿFLASH£©*********** \r\n"); printf("\r\n Èôºº×ÖÏÔʾ²»Õý³££¬ÇëÔĶÁ¹¤³ÌÖеÄreadme.txtÎļþ˵Ã÷£¬¸ù¾ÝÒªÇó¸øFLASHÖØË¢×ÖÄ£Êý¾Ý\r\n"); //ÆäÖÐ0¡¢3¡¢5¡¢6 ģʽÊʺϴÓ×óÖÁÓÒÏÔʾÎÄ×Ö£¬ //²»ÍƼöʹÓÃÆäËüģʽÏÔʾÎÄ×Ö ÆäËüģʽÏÔʾÎÄ×Ö»áÓоµÏñЧ¹û //ÆäÖÐ 6 ģʽΪ´ó²¿·ÖÒº¾§Àý³ÌµÄĬÈÏÏÔʾ·½Ïò ILI9341_GramScan ( 6 ); Printf_Charater(); while ( 1 ) { LCD_Test(); } } /*ÓÃÓÚ²âÊÔ¸÷ÖÖÒº¾§µÄº¯Êý*/ void LCD_Test(void) { /*ÑÝʾÏÔʾ±äÁ¿*/ static uint8_t testCNT = 0; char dispBuff[100]; testCNT++; LCD_SetFont(&Font8x16); LCD_SetColors(RED,BLACK); ILI9341_Clear(0,0,LCD_X_LENGTH,LCD_Y_LENGTH); /* ÇåÆÁ£¬ÏÔʾȫºÚ */ /********ÏÔʾ×Ö·û´®Ê¾Àý*******/ ILI9341_DispStringLine_EN_CH(LINE(0),"±ü»ð3.2´çLCD²ÎÊý£º"); ILI9341_DispStringLine_EN_CH(LINE(1),"·Ö±æÂÊ£º240x320 px"); ILI9341_DispStringLine_EN_CH(LINE(2),"ILI9341Òº¾§Çý¶¯"); ILI9341_DispStringLine_EN_CH(LINE(3),"XPT2046´¥ÃþÆÁÇý¶¯"); /********ÏÔʾ±äÁ¿Ê¾Àý*******/ LCD_SetTextColor(GREEN); /*ʹÓÃc±ê×¼¿â°Ñ±äÁ¿×ª»¯³É×Ö·û´®*/ sprintf(dispBuff,"ÏÔʾ±äÁ¿£º %d ",testCNT); LCD_ClearLine(LINE(5)); /* Çå³ýµ¥ÐÐÎÄ×Ö */ /*È»ºóÏÔʾ¸Ã×Ö·û´®¼´¿É£¬ÆäËü±äÁ¿Ò²ÊÇÕâÑù´¦Àí*/ ILI9341_DispStringLine_EN_CH(LINE(5),dispBuff); /*******ÏÔʾͼÐÎʾÀý******/ /* »­Ö±Ïß */ LCD_ClearLine(LINE(7));/* Çå³ýµ¥ÐÐÎÄ×Ö */ LCD_SetTextColor(BLUE); ILI9341_DispStringLine_EN_CH(LINE(7),"»­Ö±Ïߣº"); LCD_SetTextColor(RED); ILI9341_DrawLine(50,170,210,230); ILI9341_DrawLine(50,200,210,240); LCD_SetTextColor(GREEN); ILI9341_DrawLine(100,170,200,230); ILI9341_DrawLine(200,200,220,240); LCD_SetTextColor(BLUE); ILI9341_DrawLine(110,170,110,230); ILI9341_DrawLine(130,200,220,240); Delay(0xFFFFFF); ILI9341_Clear(0,16*8,LCD_X_LENGTH,LCD_Y_LENGTH-16*8); /* ÇåÆÁ£¬ÏÔʾȫºÚ */ /*»­¾ØÐÎ*/ LCD_ClearLine(LINE(7)); /* Çå³ýµ¥ÐÐÎÄ×Ö */ LCD_SetTextColor(BLUE); ILI9341_DispStringLine_EN_CH(LINE(7),"»­¾ØÐΣº"); LCD_SetTextColor(RED); ILI9341_DrawRectangle(50,200,100,30,1); LCD_SetTextColor(GREEN); ILI9341_DrawRectangle(160,200,20,40,0); LCD_SetTextColor(BLUE); ILI9341_DrawRectangle(170,200,50,20,1); Delay(0xFFFFFF); ILI9341_Clear(0,16*8,LCD_X_LENGTH,LCD_Y_LENGTH-16*8); /* ÇåÆÁ£¬ÏÔʾȫºÚ */ /* »­Ô² */ LCD_ClearLine(LINE(7)); /* Çå³ýµ¥ÐÐÎÄ×Ö */ LCD_SetTextColor(BLUE); ILI9341_DispStringLine_EN_CH(LINE(7),"»­Ô²"); LCD_SetTextColor(RED); ILI9341_DrawCircle(100,200,20,0); LCD_SetTextColor(GREEN); ILI9341_DrawCircle(100,200,10,1); LCD_SetTextColor(BLUE); ILI9341_DrawCircle(140,200,20,0); Delay(0xFFFFFF); ILI9341_Clear(0,16*8,LCD_X_LENGTH,LCD_Y_LENGTH-16*8); /* ÇåÆÁ£¬ÏÔʾȫºÚ */ } /** * @brief ¼òµ¥ÑÓʱº¯Êý * @param nCount £ºÑÓʱ¼ÆÊýÖµ * @retval ÎÞ */ static void Delay ( __IO uint32_t nCount ) { for ( ; nCount != 0; nCount -- ); } /*"µ±"×Ö·ûµÄ×ÖÄ£16x16 */ unsigned char charater_matrix[] = { /*"µ±",0*/ 0x01,0x00,0x21,0x08,0x11,0x08,0x09,0x10,0x09,0x20,0x01,0x00,0x7F,0xF8,0x00, 0x08, 0x00,0x08,0x00,0x08,0x3F,0xF8,0x00,0x08,0x00,0x08,0x00,0x08,0x7F,0xF8,0x00,0x08, }; /** * @brief ʹÓô®¿ÚÔÚÉÏλ»ú´òÓ¡×ÖÄ£ * ÑÝʾ×ÖÄ£ÏÔʾԭÀí * @retval ÎÞ */ void Printf_Charater(void) { int i,j; unsigned char kk; /*iÓÃ×÷ÐмÆÊý*/ for ( i=0;i<16;i++) { /*jÓÃ×÷Ò»×Ö½ÚÄÚÊý¾ÝµÄÒÆÎ»¼ÆÊý*/ /*Ò»ÐÐÏñËØµÄµÚÒ»¸ö×Ö½Ú*/ for(j=0; j<8; j++) { /*Ò»¸öÊý¾Ýλһ¸öÊý¾ÝλµØ´¦Àí*/ kk = charater_matrix[2*i] << j ; //×óÒÆJλ if( kk & 0x80) { printf("*"); //Èç¹û×î¸ßλΪ1£¬Êä³ö*ºÅ£¬±íʾ±Ê¼£ } else { printf(" "); //Èç¹û×î¸ßλΪ0£¬Êä³ö¿Õ¸ñ£¬±íʾ¿Õ°× } } /*Ò»ÐÐÏñËØµÄµÚ¶þ¸ö×Ö½Ú*/ for(j=0; j<8; j++) { kk = charater_matrix[2*i+1] << j ; //×óÒÆJλ if( kk & 0x80) { printf("*"); //Èç¹û×î¸ßλΪ1£¬Êä³ö*ºÅ£¬±íʾ±Ê¼£ } else { printf(" "); //Èç¹û×î¸ßλΪ0£¬Êä³ö¿Õ¸ñ£¬±íʾ¿Õ°× } } printf("\n"); //Êä³öÍêÒ»ÐÐÏñËØ£¬»»ÐÐ } printf("\n\n"); //Ò»¸ö×ÖÊä³öÍê±Ï } /* ------------------------------------------end of file---------------------------------------- */ 显示屏至少要显示两屏; 一屏:绘制转速的仪表盘界面;仪表盘界面的样式自行确定; 另一屏:绘制柱状图,坐标和曲线图;

最新推荐

recommend-type

(完整版)网络大集体备课的心得与体会(最新整理).pdf

(完整版)网络大集体备课的心得与体会(最新整理).pdf
recommend-type

2.2-导数的基本公式与运算法则省名师优质课赛课获奖课件.ppt

2.2-导数的基本公式与运算法则省名师优质课赛课获奖课件.ppt
recommend-type

098L产品网络推广策略.pptx

098L产品网络推广策略.pptx
recommend-type

前端分析-202307110078988

前端分析-202307110078988
recommend-type

1.1.1算法的概念(一).doc

1.1.1算法的概念(一).doc
recommend-type

构建基于ajax, jsp, Hibernate的博客网站源码解析

根据提供的文件信息,本篇内容将专注于解释和阐述ajax、jsp、Hibernate以及构建博客网站的相关知识点。 ### AJAX AJAX(Asynchronous JavaScript and XML)是一种用于创建快速动态网页的技术,它允许网页在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页内容。AJAX的核心是JavaScript中的XMLHttpRequest对象,通过这个对象,JavaScript可以异步地向服务器请求数据。此外,现代AJAX开发中,常常用到jQuery中的$.ajax()方法,因为其简化了AJAX请求的处理过程。 AJAX的特点主要包括: - 异步性:用户操作与数据传输是异步进行的,不会影响用户体验。 - 局部更新:只更新需要更新的内容,而不是整个页面,提高了数据交互效率。 - 前后端分离:AJAX技术允许前后端分离开发,让前端开发者专注于界面和用户体验,后端开发者专注于业务逻辑和数据处理。 ### JSP JSP(Java Server Pages)是一种动态网页技术标准,它允许开发者将Java代码嵌入到HTML页面中,从而实现动态内容的生成。JSP页面在服务器端执行,并将生成的HTML发送到客户端浏览器。JSP是Java EE(Java Platform, Enterprise Edition)的一部分。 JSP的基本工作原理: - 当客户端首次请求JSP页面时,服务器会将JSP文件转换为Servlet。 - 服务器上的JSP容器(如Apache Tomcat)负责编译并执行转换后的Servlet。 - Servlet生成HTML内容,并发送给客户端浏览器。 JSP页面中常见的元素包括: - 指令(Directives):如page、include、taglib等。 - 脚本元素:脚本声明(Script declarations)、脚本表达式(Scriptlet)和脚本片段(Expression)。 - 标准动作:如jsp:useBean、jsp:setProperty、jsp:getProperty等。 - 注释:在客户端浏览器中不可见的注释。 ### Hibernate Hibernate是一个开源的对象关系映射(ORM)框架,它提供了从Java对象到数据库表的映射,简化了数据库编程。通过Hibernate,开发者可以将Java对象持久化到数据库中,并从数据库中检索它们,而无需直接编写SQL语句或掌握复杂的JDBC编程。 Hibernate的主要优点包括: - ORM映射:将对象模型映射到关系型数据库的表结构。 - 缓存机制:提供了二级缓存,优化数据访问性能。 - 数据查询:提供HQL(Hibernate Query Language)和Criteria API等查询方式。 - 延迟加载:可以配置对象或对象集合的延迟加载,以提高性能。 ### 博客网站开发 构建一个博客网站涉及到前端页面设计、后端逻辑处理、数据库设计等多个方面。使用ajax、jsp、Hibernate技术栈,开发者可以更高效地构建功能完备的博客系统。 #### 前端页面设计 前端主要通过HTML、CSS和JavaScript来实现,其中ajax技术可以用来异步获取文章内容、用户评论等,无需刷新页面即可更新内容。 #### 后端逻辑处理 JSP可以在服务器端动态生成HTML内容,根据用户请求和数据库中的数据渲染页面。Hibernate作为ORM框架,可以处理Java对象与数据库表之间的映射,并提供数据库的CRUD(创建、读取、更新、删除)操作。 #### 数据库设计 博客网站的数据库设计通常包含多个表,如用户表(存储用户信息)、文章表(存储文章信息)、评论表(存储用户评论信息)等。使用Hibernate框架可以简化数据库操作,同时确保数据的一致性和安全性。 #### 安全性和性能优化 安全性是构建网站时需要考虑的重要方面,包括但不限于SQL注入防护、XSS攻击防护、会话管理等。性能优化方面,可以利用Hibernate的缓存机制,以及对JSP页面和ajax请求进行适当的缓存处理。 ### 结论 ajax、jsp、Hibernate技术结合可以构建出高效、动态、易于维护的博客网站。在开发过程中,应当关注前后端分离、用户体验优化、系统性能和安全性等关键要素,确保博客网站的稳定和长期可用性。通过本篇文章,读者应该已经对这些技术有了初步了解,并能够结合文件提供的源码开始进行相关开发实践。
recommend-type

【Unity Sunny Land关卡设计高级指南】:打造完美关卡的8大技巧

# 1. Unity关卡设计概述 ## 1.1 关卡设计的核心要素 关卡设计作为游戏开发中不可或缺的一环,承担着构建游戏世界、呈现故事背景、引导玩家体验和激发玩家兴趣的责任。一个优秀的关卡不仅需要有吸引人的视觉效果和有趣的挑战,还需平衡玩家体验,提供连贯的游戏故事。 ## 1.2 关卡设计师的角色 在Unity引擎的环境下,关卡设计师需要具备对场景布局、角色互动、剧情
recommend-type

C++ 模版

<think>我们正在讨论C++模板的使用和常见问题。根据用户要求,所有行内数学表达式使用$...$,独立公式使用$$...$$,用中文回答,并生成相关问题。同时,回答要结构清晰,帮助用户逐步解决问题。 首先,回顾用户的问题:用户想了解C++模板的使用和常见问题。我们将从以下几个方面展开: 1. 模板的基本概念和用途 2. 函数模板和类模板 3. 模板特化和偏特化 4. 模板元编程简介 5. 常见问题及解决方案 注意:在回答中,我们会引用站内提供的引用内容(引用[1]和引用[2])作为参考,但主要围绕模板展开。 ### 1. 模板的基本概念和用途 C++模板是一种支持泛型编程的特性,允许
recommend-type

C#随机数摇奖系统功能及隐藏开关揭秘

### C#摇奖系统知识点梳理 #### 1. C#语言基础 C#(发音为“看井”)是由微软开发的一种面向对象的、类型安全的编程语言。它是.NET框架的核心语言之一,广泛用于开发Windows应用程序、ASP.NET网站、Web服务等。C#提供丰富的数据类型、控制结构和异常处理机制,这使得它在构建复杂应用程序时具有很强的表达能力。 #### 2. 随机数的生成 在编程中,随机数生成是常见的需求之一,尤其在需要模拟抽奖、游戏等场景时。C#提供了System.Random类来生成随机数。Random类的实例可以生成一个伪随机数序列,这些数在统计学上被认为是随机的,但它们是由确定的算法生成,因此每次运行程序时产生的随机数序列相同,除非改变种子值。 ```csharp using System; class Program { static void Main() { Random rand = new Random(); for(int i = 0; i < 10; i++) { Console.WriteLine(rand.Next(1, 101)); // 生成1到100之间的随机数 } } } ``` #### 3. 摇奖系统设计 摇奖系统通常需要以下功能: - 用户界面:显示摇奖结果的界面。 - 随机数生成:用于确定摇奖结果的随机数。 - 动画效果:模拟摇奖的视觉效果。 - 奖项管理:定义摇奖中可能获得的奖品。 - 规则设置:定义摇奖规则,比如中奖概率等。 在C#中,可以使用Windows Forms或WPF技术构建用户界面,并集成上述功能以创建一个完整的摇奖系统。 #### 4. 暗藏的开关(隐藏控制) 标题中提到的“暗藏的开关”通常是指在程序中实现的一个不易被察觉的控制逻辑,用于在特定条件下改变程序的行为。在摇奖系统中,这样的开关可能用于控制中奖的概率、启动或停止摇奖、强制显示特定的结果等。 #### 5. 测试 对于摇奖系统来说,测试是一个非常重要的环节。测试可以确保程序按照预期工作,随机数生成器的随机性符合要求,用户界面友好,以及隐藏的控制逻辑不会被轻易发现或利用。测试可能包括单元测试、集成测试、压力测试等多个方面。 #### 6. System.Random类的局限性 System.Random虽然方便使用,但也有其局限性。其生成的随机数序列具有一定的周期性,并且如果使用不当(例如使用相同的种子创建多个实例),可能会导致生成相同的随机数序列。在安全性要求较高的场合,如密码学应用,推荐使用更加安全的随机数生成方式,比如RNGCryptoServiceProvider。 #### 7. Windows Forms技术 Windows Forms是.NET框架中用于创建图形用户界面应用程序的库。它提供了一套丰富的控件,如按钮、文本框、标签等,以及它们的事件处理机制,允许开发者设计出视觉效果良好且功能丰富的桌面应用程序。 #### 8. WPF技术 WPF(Windows Presentation Foundation)是.NET框架中用于构建桌面应用程序用户界面的另一种技术。与Windows Forms相比,WPF提供了更现代化的控件集,支持更复杂的布局和样式,以及3D图形和动画效果。WPF的XAML标记语言允许开发者以声明性的方式设计用户界面,与C#代码分离,易于维护和更新。 #### 9. 压缩包子文件TransBallDemo分析 从文件名“TransBallDemo”可以推测,这可能是一个C#的示例程序或者演示程序,其中“TransBall”可能表示旋转的球体,暗示该程序包含了动画效果,可能是用来模拟转动的球体(如转盘或摇奖球)。该文件可能是用来展示如何实现一个带有视觉动画效果的摇奖系统的C#程序。 总结以上内容,我们可以得出构建一个C#摇奖系统需要深入理解C#语言及其随机数生成机制,设计用户界面,集成动画效果,确保隐藏控制逻辑的安全性,以及全面测试系统以保证其正确性和公平性。通过掌握Windows Forms或WPF技术,可以进一步增强系统的视觉和交互体验。
recommend-type

【数据驱动的力量】:管道缺陷判别方法论与实践经验

# 摘要 数据驱动技术在管道缺陷检测领域展现出强大的力量,本文首先概述了数据驱动的力量和管道缺陷判别的基础理论。接着,重点探讨了管道缺陷的类型与特征、数据采集与预处理、数据驱动模型的选择与构建。在实践技巧章节,本文详述了实战数据集的准备与处理、缺陷识别算法的应用、以及性能评估与模型优化。此外,高级应用章节深入讨论了实时数据处理分析、多模态数据融合技术、以及深度学习在缺