wxc-page-calendar使用

本文介绍 wxc-page-calendar 组件的使用方法及其配置项,包括日期范围、选中日期、日历模式等8个属性,同时展示了如何通过自定义事件获取选中日期。

< wxc-page-calendar>由3部分组成:

①   最上方的导航栏,是一个<wxc-minibar>。

②   上方的周几标识区,即写着“日 一 二…六”的这一行。

③   下方的主体区域是一个<list>。

< wxc-page-calendar>用法类似<wxc-dialog>,是在当前页面配置,并按需显示的,并不需要单独的页面。

将< wxc-page-calendar>引入并配置好,通常会设置一个ref,用于引用该组件。然后在需要显示的时候,调用:

this.$refs['wxcPageCalendar'].show();

 

配置:

<wxc-page-calendar ref="wxcPageCalendar"
                   :date-range="['2017-06-10', '2019-06-10']"
                   :selected-date="['2018-06-10']"
                   :is-range="false"
                   :selected-note="['请假']"
                   :desc-list="descList"
                   :show-header="false"
                   :minibar-cfg="minibarCfg"
                   animationType="push">
</wxc-page-calendar>

对应的data数据:

minibarCfg: {
  title: '日期选择'
},
descList: [
  { date: '2018-06-23', value: '旅行' },
  { date: '2018-06-24', value: '旅行' },
  { date: '2018-06-25', value: '旅行' },
  { date: '2018-06-26', value: '旅行' },
  { date: '2018-06-27', value: '旅行' },
  { date: '2018-06-28', value: '旅行' },
  { date: '2018-06-29', value: '旅行' }
]

< wxc-page-calendar>共有8个属性:

1.    date-range:日历可用范围。必须设置,否则报错。使用数组,有两个成员变量。

2.    selected-date:选中日期。若留空,则不选中,日历会跳转到第一页。若设置一个具体日期,则日历会跳转到选中的日期页面。

3.    is-range:日历是否为往返日历。日历有两种模式:单选和往返。单选只能选择一个日期,往返则可选择一个时间段。这两种模式下,多个参数的设置都有所不同。这里都是使用单选模式。

4.    selected-note:选中日期下出现的提示语。上面日历选中的日期提示“请假”。

5.    desc-list:指定日期下的附加信息。是一个数组,可为多个日期设置附加信息。上面日历设置的附加信息是“旅行”。

6.    show-header:是否在native下显示导航栏。导航栏即日历最上方的minibar。关于导航栏的设置详见7。

7.    minibar-cfg:导航栏配置。导航栏是内嵌了一个wxc-minibar。配置通常有3个:

{

    'title': '选择日期',

    'background-color':'#FFC900',

    'text-color': '#3D3D3D'

}

8.    animationType:自定义切换动画类型。有两个取值:model/push。日历出现时,model是从下往上滑动,push是从右往左滑动。

 

实际效果:

 

< wxc-page-calendar>不支持slot。

 

< wxc-page-calendar>支持3个自定义事件:

// 日期选择

@wxcPageCalendarDateSelected="calendarDateSelect" 

// 返回按钮点击

@wxcPageCalendarBackClicked="wxcPageCalendarBackClicked" 

// 隐藏日历事件

@wxcPageCalendarHide="wxcPageCalendarHide"

其中wxcPageCalendarDateSelected事件带有参数e,e.date即选中的日期。

通常会自定义wxcPageCalendarDateSelected事件,在其中获取选中的日期,以修改其他组件显示的日期值。

contactList.jsp:<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <title>${isBlacklist ? '黑名单' : '联系人列表'}</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"> <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css" rel="stylesheet"> <style> :root { --primary-color: #4361ee; --secondary-color: #3f37c9; --success-color: #4cc9f0; --danger-color: #f72585; --warning-color: #f8961e; --light-color: #f8f9fa; --dark-color: #212529; } body { background-color: #f5f7fa; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } .container { max-width: 1400px; padding: 20px; } .header-section { background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); color: white; border-radius: 15px; padding: 2rem; margin-bottom: 2rem; box-shadow: 0 10px 20px rgba(67, 97, 238, 0.15); } .page-title { font-weight: 700; margin: 0; display: flex; align-items: center; } .page-title i { font-size: 2rem; margin-right: 1rem; } .action-buttons .btn { border-radius: 50px; padding: 0.5rem 1.5rem; font-weight: 500; margin-left: 10px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); transition: all 0.3s ease; } .action-buttons .btn:hover { transform: translateY(-2px); box-shadow: 0 7px 14px rgba(0, 0, 0, 0.15); } .nav-tabs { border-bottom: none; margin: 1.5rem 0; } .nav-tabs .nav-link { border: none; color: #6c757d; font-weight: 500; padding: 0.75rem 1.5rem; border-radius: 50px; margin-right: 0.5rem; transition: all 0.3s ease; } .nav-tabs .nav-link.active { background-color: var(--primary-color); color: white; box-shadow: 0 4px 6px rgba(67, 97, 238, 0.3); } .nav-tabs .nav-link:not(.active):hover { color: var(--primary-color); background-color: rgba(67, 97, 238, 0.1); } .search-box { background: white; border-radius: 50px; padding: 0.5rem; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05); } .search-box input { border: none; border-radius: 50px 0 0 50px; padding: 0.75rem 1.5rem; } .search-box input:focus { box-shadow: none; } .search-box button { border-radius: 0 50px 50px 0; background-color: var(--primary-color); color: white; border: none; padding: 0.75rem 1.5rem; transition: all 0.3s ease; } .search-box button:hover { background-color: var(--secondary-color); } .contact-card { background: white; border-radius: 15px; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05); transition: all 0.3s ease; margin-bottom: 1.5rem; overflow: hidden; } .contact-card:hover { transform: translateY(-5px); box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1); } .contact-avatar { width: 80px; height: 80px; border-radius: 50%; object-fit: cover; border: 3px solid white; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); } .contact-info { padding: 1.5rem; } .contact-name { font-weight: 600; color: var(--dark-color); margin-bottom: 0.5rem; } .contact-phone { color: #6c757d; font-size: 0.9rem; } .status-badge { font-size: 0.8rem; padding: 0.35rem 0.75rem; border-radius: 50px; font-weight: 500; } .action-btn { min-width: 100px; border-radius: 50px; font-size: 0.85rem; font-weight: 600; padding: 0.5rem 1rem; margin: 0.25rem; transition: all 0.3s ease; } .action-btn:hover { transform: translateY(-2px); box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1); } .pagination { margin-top: 3rem; justify-content: center; } .page-item .page-link { border-radius: 50px !important; margin: 0 0.25rem; border: none; color: var(--dark-color); font-weight: 500; min-width: 40px; text-align: center; } .page-item.active .page-link { background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); color: white; box-shadow: 0 4px 6px rgba(67, 97, 238, 0.3); } .no-contacts { text-align: center; padding: 3rem; color: #6c757d; } .no-contacts i { font-size: 3rem; color: #dee2e6; margin-bottom: 1rem; } /* 天气预报样式 */ .weather-widget { background: linear-gradient(135deg, #1e3c72, #2a5298); color: white; border-radius: 15px; padding: 2rem; margin-bottom: 2rem; box-shadow: 0 10px 20px rgba(0, 0, 0, 0.15); position: relative; overflow: hidden; } .weather-widget::before { content: ""; position: absolute; top: -50%; right: -50%; width: 200%; height: 200%; background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0) 70%); z-index: 0; } .weather-content { position: relative; z-index: 1; } .weather-title { font-weight: 700; margin: 0; display: flex; align-items: center; font-size: 1.5rem; } .weather-title i { font-size: 1.8rem; margin-right: 1rem; } .weather-details { display: flex; align-items: center; justify-content: space-between; margin-top: 1.5rem; } .weather-info { flex: 1; } .weather-city { font-size: 1.8rem; font-weight: 600; margin-bottom: 0.5rem; } .weather-desc { font-size: 1.2rem; opacity: 0.9; margin-bottom: 0.5rem; text-transform: capitalize; } .weather-temp { font-size: 3rem; font-weight: 700; margin: 0; line-height: 1; } .weather-icon-container { width: 100px; height: 100px; display: flex; align-items: center; justify-content: center; } .weather-icon { width: 100%; height: 100%; object-fit: contain; filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.3)); } .weather-extra { display: flex; justify-content: space-between; margin-top: 1.5rem; padding-top: 1rem; border-top: 1px solid rgba(255, 255, 255, 0.2); } .weather-extra-item { text-align: center; flex: 1; } .weather-extra-label { font-size: 0.9rem; opacity: 0.8; margin-bottom: 0.3rem; } .weather-extra-value { font-size: 1.2rem; font-weight: 600; } /* 天气动画 */ @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .weather-animate { animation: fadeIn 0.5s ease-out forwards; } /* 移动端特定样式 */ @media (max-width: 768px) { .header-section { padding: 1.5rem; } .action-buttons { margin-top: 1rem; } .contact-avatar { width: 60px; height: 60px; } .action-btn { min-width: auto; padding: 0.4rem 0.8rem; font-size: 0.8rem; } .search-box input, .search-box button { padding: 0.5rem 1rem; } .nav-tabs .nav-link { padding: 0.5rem 1rem; margin-right: 0.25rem; } .weather-widget { padding: 1.5rem; } .weather-temp { font-size: 2rem; } .weather-city { font-size: 1.2rem; } } /* 触摸友好元素 */ .btn, .form-control, .nav-link, .page-link { touch-action: manipulation; } </style> </head> <body> <div class="container"> <div class="header-section"> <div class="d-flex flex-column flex-md-row justify-content-between align-items-md-center"> <h1 class="page-title"> <i class="bi bi-people-fill"></i> ${isBlacklist ? '黑名单管理' : '联系人中心'} </h1> <div class="action-buttons mt-3 mt-md-0"> <a href="${pageContext.request.contextPath}/contact?action=add" class="btn btn-light"> <i class="bi bi-person-plus"></i> 新增联系人 </a> <a href="${pageContext.request.contextPath}/matter" class="btn btn-outline-light"> <i class="bi bi-calendar2-event"></i> 查看事项 </a> </div> </div> </div> <!-- 天气预报区域 --> <div class="weather-widget"> <div class="weather-content"> <h2 class="weather-title"> <i class="bi bi-geo-alt"></i> 实时天气 </h2> <div class="weather-details"> <div class="weather-info"> <div class="weather-city" id="weatherCity">唐山</div> <div class="weather-desc" id="weatherDesc">--</div> <div class="weather-temp" id="weatherTemp">--°C</div> </div> <div class="weather-icon-container"> <img id="weatherIcon" class="weather-icon" src="https://openweathermap.org/img/wn/${data.weather.icon}@2x.png" alt="天气图标"> </div> </div> </div> </div> <div class="weather-extra"> <div class="weather-extra-item"> <div class="weather-extra-label">湿度</div> <div class="weather-extra-value" id="weatherHumidity">--%</div> </div> <div class="weather-extra-item"> <div class="weather-extra-label">风速</div> <div class="weather-extra-value" id="weatherWind">-- m/s</div> </div> <div class="weather-extra-item"> <div class="weather-extra-label">气压</div> <div class="weather-extra-value" id="weatherPressure">-- hPa</div> </div> </div> <ul class="nav nav-tabs"> <li class="nav-item"> <a class="nav-link ${not isBlacklist ? 'active' : ''}" href="${pageContext.request.contextPath}/contact">正常联系人</a> </li> <li class="nav-item"> <a class="nav-link ${isBlacklist ? 'active' : ''}" href="${pageContext.request.contextPath}/contact?action=blacklist">黑名单</a> </li> </ul> <!-- 筛选区域 --> <div class="filter-section"> <h5 class="filter-title">筛选条件</h5> <form class="row g-3" method="get" action="${pageContext.request.contextPath}/contact"> <input type="hidden" name="action" value="${isBlacklist ? 'blacklist' : ''}"> <div class="col-md-6"> <div class="input-group"> <input type="text" class="form-control" name="search" placeholder="搜索姓名/电话" value="${param.search}" aria-label="Search"> <button class="btn btn-primary" type="submit"> <i class="bi bi-search"></i> 搜索了一个 </button> </div> </div> <div class="col-md-4"> <select class="form-select" name="gender" onchange="this.form.submit()"> <option value="">所有性别</option> <option value="男" ${param.gender == '男' ? 'selected' : ''}>男</option> <option value="女" ${param.gender == '女' ? 'selected' : ''}>女</option> </select> </div> <div class="col-md-2"> <a href="${pageContext.request.contextPath}/contact${isBlacklist ? '?action=blacklist' : ''}" class="btn btn-outline-secondary w-100"> <i class="bi bi-arrow-counterclockwise"></i> 重置 </a> </div> </form> </div> <c:if test="${empty contacts}"> <div class="card contact-card"> <div class="no-contacts"> <i class="bi bi-people"></i> <h4>暂无联系人数据</h4> <p>点击"新增联系人"按钮添加您的第一个联系人</p> </div> </div> </c:if> <div class="row"> <c:forEach var="contact" items="${contacts}"> <div class="col-md-6 col-lg-4"> <div class="card contact-card"> <div class="contact-info"> <div class="d-flex align-items-center"> <img src="${pageContext.request.contextPath}/upload/${DBUtil.getContactPic(contact.ctId)}" class="contact-avatar me-3" onerror="this.onerror=null; this.src='${pageContext.request.contextPath}/images/default-avatar.png'"> <div> <h5 class="contact-name mb-1"> ${contact.ctName} <c:if test="${contact.ctDelete == 1}"> <span class="badge bg-danger ms-2">已屏蔽</span> </c:if> </h5> <p class="contact-phone mb-1"> <i class="bi bi-telephone"></i> ${contact.ctPhone} </p> <span class="status-badge bg-${isBlacklist ? 'danger' : 'success'}"> ${isBlacklist ? '黑名单' : '正常'} </span> </div> </div> <div class="d-flex flex-wrap justify-content-between mt-3"> <a href="${pageContext.request.contextPath}/contact?action=detail&ctId=${contact.ctId}" class="btn btn-primary action-btn"> <i class="bi bi-eye"></i> 详情 </a> <a href="${pageContext.request.contextPath}/matter?ctId=${contact.ctId}" class="btn btn-warning action-btn"> <i class="bi bi-list-check"></i> 事项 </a> <c:choose> <c:when test="${isBlacklist}"> <a href="${pageContext.request.contextPath}/contact?action=blacklist&type=remove&ctId=${contact.ctId}" class="btn btn-success action-btn" onclick="return confirm('确定要恢复此联系人吗?')"> <i class="bi bi-arrow-counterclockwise"></i> 恢复 </a> </c:when> <c:otherwise> <c:if test="${contact.ctDelete == 0}"> <a href="${pageContext.request.contextPath}/contact?action=blacklist&type=add&ctId=${contact.ctId}" class="btn btn-danger action-btn" onclick="return confirm('确定要加入黑名单吗?')"> <i class="bi bi-ban"></i> 屏蔽 </a> </c:if> </c:otherwise> </c:choose> </div> </div> </div> </div> </c:forEach> </div> <c:if test="${not empty contacts}"> <nav aria-label="Page navigation"> <ul class="pagination"> <c:if test="${currentPage > 1}"> <li class="page-item"> <a class="page-link" href="${pageContext.request.contextPath}/contact?action=${isBlacklist ? 'blacklist' : ''}&page=${currentPage - 1}&search=${param.search}"> <i class="bi bi-chevron-left"></i> </a> </li> </c:if> <c:forEach begin="1" end="${totalPages}" var="i"> <li class="page-item ${i == currentPage ? 'active' : ''}"> <a class="page-link" href="${pageContext.request.contextPath}/contact?action=${isBlacklist ? 'blacklist' : ''}&page=${i}&search=${param.search}">${i}</a> </li> </c:forEach> <c:if test="${currentPage < totalPages}"> <li class="page-item"> <a class="page-link" href="${pageContext.request.contextPath}/contact?action=${isBlacklist ? 'blacklist' : ''}&page=${currentPage + 1}&search=${param.search}"> <i class="bi bi-chevron-right"></i> </a> </li> </c:if> </ul> </nav> </c:if> </div> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script> <script> // 获取天气数据 function getWeather() { const apiKey = "d9bd1b0c215b38f1ceba3a8b06818789"; // OpenWeatherMap API密钥 const city = "Tangshan"; // 唐山的英文名 // 获取唐山天气 fetch(`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}&units=metric&lang=zh_cn`) .then(response => { if (!response.ok) { throw new Error("网络响应错误:" + response.statusText); } return response.json(); }) .then(data => { updateWeatherUI(data); }) .catch(error => { console.error('获取天气数据失败:', error); showWeatherError(); }); } // 更新天气UI function updateWeatherUI(data) { document.getElementById('weatherTemp').textContent = `${Math.round(data.main.temp)}°C`; document.getElementById('weatherDesc').textContent = data.weather[0]?.description || "--"; document.getElementById('weatherIcon').src = `https://openweathermap.org/img/wn/${data.weather.icon}@2x.png`; document.getElementById('weatherHumidity').textContent = `${data.main.humidity}%`; document.getElementById('weatherWind').textContent = `${data.wind.speed} m/s`; document.getElementById('weatherPressure').textContent = `${data.main.pressure} hPa`; } // 显示天气错误 function showWeatherError() { document.getElementById('weatherCity').textContent = "天气数据获取失败"; document.getElementById('weatherDesc').textContent = "请检查网络连接"; document.getElementById('weatherTemp').textContent = "--°C"; document.getElementById('weatherHumidity').textContent = "--%"; document.getElementById('weatherWind').textContent = "-- m/s"; document.getElementById('weatherPressure').textContent = "-- hPa"; } // 页面加载完成后获取天气数据 document.addEventListener('DOMContentLoaded', getWeather); </script> </body> </html>控制台日志:D:\apache-tomcat-8.5.99\bin\catalina.bat run [2025-06-10 09:39:00,390] Artifact firstweb2:war: Waiting for server connection to start artifact deployment... Using CATALINA_BASE: "C:\Users\DELL\AppData\Local\JetBrains\IntelliJIdea2022.2\tomcat\673dafd6-7580-4107-962c-bab19e459aa1" Using CATALINA_HOME: "D:\apache-tomcat-8.5.99" Using CATALINA_TMPDIR: "D:\apache-tomcat-8.5.99\temp" Using JRE_HOME: "D:\java" Using CLASSPATH: "D:\apache-tomcat-8.5.99\bin\bootstrap.jar;D:\apache-tomcat-8.5.99\bin\tomcat-juli.jar" Using CATALINA_OPTS: "" NOTE: Picked up JDK_JAVA_OPTIONS: --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Server.服务器版本: Apache Tomcat/8.5.99 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 服务器构建: Feb 14 2024 22:52:13 UTC 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 服务器版本号: 8.5.99.0 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 操作系统名称: Windows 11 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: OS.版本: 10.0 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 架构: amd64 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Java 环境变量: D:\java 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Java虚拟机版本: 18.0.2.1+1-1 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: JVM.供应商: Oracle Corporation 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: CATALINA_BASE: C:\Users\DELL\AppData\Local\JetBrains\IntelliJIdea2022.2\tomcat\673dafd6-7580-4107-962c-bab19e459aa1 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: CATALINA_HOME: D:\apache-tomcat-8.5.99 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 命令行参数: --add-opens=java.base/java.lang=ALL-UNNAMED 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 命令行参数: --add-opens=java.base/java.io=ALL-UNNAMED 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 命令行参数: --add-opens=java.base/java.util=ALL-UNNAMED 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 命令行参数: --add-opens=java.base/java.util.concurrent=ALL-UNNAMED 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 命令行参数: --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 命令行参数: -Djava.util.logging.config.file=C:\Users\DELL\AppData\Local\JetBrains\IntelliJIdea2022.2\tomcat\673dafd6-7580-4107-962c-bab19e459aa1\conf\logging.properties 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 命令行参数: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 命令行参数: -Dcom.sun.management.jmxremote= 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 命令行参数: -Dcom.sun.management.jmxremote.port=1099 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 命令行参数: -Dcom.sun.management.jmxremote.ssl=false 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 命令行参数: -Dcom.sun.management.jmxremote.password.file=C:\Users\DELL\AppData\Local\JetBrains\IntelliJIdea2022.2\tomcat\673dafd6-7580-4107-962c-bab19e459aa1\jmxremote.password 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 命令行参数: -Dcom.sun.management.jmxremote.access.file=C:\Users\DELL\AppData\Local\JetBrains\IntelliJIdea2022.2\tomcat\673dafd6-7580-4107-962c-bab19e459aa1\jmxremote.access 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 命令行参数: -Djava.rmi.server.hostname=127.0.0.1 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 命令行参数: -Djdk.tls.ephemeralDHKeySize=2048 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 命令行参数: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 命令行参数: -Dignore.endorsed.dirs= 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 命令行参数: -Dcatalina.base=C:\Users\DELL\AppData\Local\JetBrains\IntelliJIdea2022.2\tomcat\673dafd6-7580-4107-962c-bab19e459aa1 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 命令行参数: -Dcatalina.home=D:\apache-tomcat-8.5.99 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 命令行参数: -Djava.io.tmpdir=D:\apache-tomcat-8.5.99\temp 6月 10, 2025 9:39:01 下午 org.apache.catalina.core.AprLifecycleListener lifecycleEvent 信息: 使用APR版本[1.7.4]加载了基于APR的Apache Tomcat本机库[1.2.39]。 6月 10, 2025 9:39:01 下午 org.apache.catalina.core.AprLifecycleListener lifecycleEvent 信息: APR功能:IPv6[true]、sendfile[true]、accept filters[false]、random[true]、UDS [{4}]。 6月 10, 2025 9:39:01 下午 org.apache.catalina.core.AprLifecycleListener lifecycleEvent 信息: APR/OpenSSL配置:useAprConnector[false],useOpenSSL[true] 6月 10, 2025 9:39:01 下午 org.apache.catalina.core.AprLifecycleListener initializeSSL 信息: OpenSSL成功初始化 [OpenSSL 3.0.11 19 Sep 2023] 6月 10, 2025 9:39:01 下午 org.apache.coyote.AbstractProtocol init 信息: 初始化协议处理器 ["http-nio-8080"] 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.Catalina load 信息: Initialization processed in 370 ms 6月 10, 2025 9:39:01 下午 org.apache.catalina.core.StandardService startInternal 信息: 正在启动服务[Catalina] 6月 10, 2025 9:39:01 下午 org.apache.catalina.core.StandardEngine startInternal 信息: 正在启动 Servlet 引擎:[Apache Tomcat/8.5.99] 6月 10, 2025 9:39:01 下午 org.apache.coyote.AbstractProtocol start 信息: 开始协议处理句柄["http-nio-8080"] 6月 10, 2025 9:39:01 下午 org.apache.catalina.startup.Catalina start 信息: Server startup in 82 ms Connected to server [2025-06-10 09:39:01,626] Artifact firstweb2:war: Artifact is being deployed, please wait... 6月 10, 2025 9:39:02 下午 org.apache.jasper.servlet.TldScanner scanJars 信息: 至少有一个JAR被扫描用于TLD但尚未包含TLD。 为此记录器启用调试日志记录,以获取已扫描但未在其中找到TLD的完整JAR列表。 在扫描期间跳过不需要的JAR可以缩短启动时间和JSP编译时间。 ־ ʼ === ݿ === û (user_message) ϵ ˱ (contact_message) ϵ ͼƬ (contact_picture_message) ϵ (contact_matter_message) === === ־ ʼ === ݿ === û (user_message) ϵ ˱ (contact_message) ϵ ͼƬ (contact_picture_message) ϵ (contact_matter_message) === === [2025-06-10 09:39:02,537] Artifact firstweb2:war: Artifact is deployed successfully [2025-06-10 09:39:02,537] Artifact firstweb2:war: Deploy took 911 milliseconds === Ϣ === URL: http://localhost:8080/firstweb2_war/ 󷽷 : GET : null û ỰID: === Ϣ === URL: http://localhost:8080/firstweb2_war/ 󷽷 : GET : null û ỰID: === Ӧ Ϣ === Ӧ״̬: 200 ʱ : 2ms === === === Ӧ Ϣ === Ӧ״̬: 200 ʱ : 3ms === === === Ϣ === URL: http://localhost:8080/firstweb2_war/login 󷽷 : POST : null û ỰID: === Ϣ === URL: http://localhost:8080/firstweb2_war/login 󷽷 : POST : null û ỰID: === Ӧ Ϣ === Ӧ״̬: 302 ʱ : 29ms === === === Ӧ Ϣ === Ӧ״̬: 302 ʱ : 29ms === === === Ϣ === URL: http://localhost:8080/firstweb2_war/contact 󷽷 : GET : null û ỰID: EDB570CA9B045C3BD0946687C2639008 === Ϣ === URL: http://localhost:8080/firstweb2_war/contact 󷽷 : GET : null û ỰID: EDB570CA9B045C3BD0946687C2639008 6月 10, 2025 9:39:11 下午 org.apache.catalina.startup.HostConfig deployDirectory 信息: 把web 应用程序部署到目录 [D:\apache-tomcat-8.5.99\webapps\manager] 6月 10, 2025 9:39:11 下午 org.apache.catalina.startup.HostConfig deployDirectory 信息: Web应用程序目录[D:\apache-tomcat-8.5.99\webapps\manager]的部署已在[153]毫秒内完成 === Ϣ === URL: http://localhost:8080/firstweb2_war/contact 󷽷 : GET : action=detail&ctId=0000000002 û ỰID: EDB570CA9B045C3BD0946687C2639008 === Ϣ === URL: http://localhost:8080/firstweb2_war/contact 󷽷 : GET : action=detail&ctId=0000000002 û ỰID: EDB570CA9B045C3BD0946687C2639008 === Ӧ Ϣ === Ӧ״̬: 200 ʱ : 180ms === === === Ӧ Ϣ === Ӧ״̬: 200 ʱ : 180ms === === === Ϣ === URL: http://localhost:8080/firstweb2_war/contact 󷽷 : POST : action=update&ctId=0000000002 û ỰID: EDB570CA9B045C3BD0946687C2639008 === Ϣ === URL: http://localhost:8080/firstweb2_war/contact 󷽷 : POST : action=update&ctId=0000000002 û ỰID: EDB570CA9B045C3BD0946687C2639008 === Ӧ Ϣ === Ӧ״̬: 302 ʱ : 93ms === === === Ӧ Ϣ === Ӧ״̬: 302 ʱ : 93ms === === === Ϣ === URL: http://localhost:8080/firstweb2_war/contact 󷽷 : GET : action=detail&ctId=0000000002 û ỰID: EDB570CA9B045C3BD0946687C2639008 === Ϣ === URL: http://localhost:8080/firstweb2_war/contact 󷽷 : GET : action=detail&ctId=0000000002 û ỰID: EDB570CA9B045C3BD0946687C2639008 === Ӧ Ϣ === Ӧ״̬: 200 ʱ : 31ms === === === Ӧ Ϣ === Ӧ״̬: 200 ʱ : 32ms === === === Ϣ === URL: http://localhost:8080/firstweb2_war/contact 󷽷 : GET : null û ỰID: EDB570CA9B045C3BD0946687C2639008 === Ϣ === URL: http://localhost:8080/firstweb2_war/contact 󷽷 : GET : null û ỰID: EDB570CA9B045C3BD0946687C2639008 还是无法查看天气情况,无法更新,请基于我的代码给出具体的解决措施和代码,代码要完完整整的,要全部的
06-11
#include "main.h" /*----------------------------------------------------------------------------------------------------------*/ // 添加全局变量 ConfigData g_config; uint8_t x_left_running = 0; //手动控制变量 uint8_t x_right_running = 0; //手动控制变量 uint8_t z_up_running = 0; //手动控制变量 uint8_t z_down_running = 0; //手动控制变量 uint8_t levelState; // 液面传感器状态(0:正常 1:异常) // 静态变量保存历史值,用于判断是否变化(仅初始化一次) static int32_t last_temp = 0; // 初始化为极小值,确保首次能触发更新 static int32_t last_temp2 = 0; // 初始化为极小值,确保首次能触发更新 static uint8_t last_level = 0; // 初始化为极大值,确保首次能触发更新 /*----------------------------------------------------------------------------------------------------------*/ // 初始化SD卡文件 FIL step_file; FRESULT fr; FIL log_file; FIL config_file; /*----------------------------------------------------------------------------------------------------------*/ extern volatile uint8_t x_right_limit_triggered; extern volatile uint8_t z_up_limit_triggered; /*----------------------------------------------------------------------------------------------------------*/ // 全局变量:记录当前状态、延时开始时间、目标延时 StainState g_stain_state = STAIN_IDLE; // 当前染色状态 uint32_t g_delay_start_tick = 0; // 延时开始的时间戳(毫秒) uint32_t g_current_delay_s = 0; // 当前步骤的目标延时时长(毫秒) /*----------------------------------------------------------------------------------------------------------*/ // 从SD卡读取配置参数(扩展支持新参数) uint8_t read_config_from_sd(ConfigData *config) { FIL config_file; FRESULT fr; char line[4096]; fr = f_open(&config_file, "0:config.txt", FA_READ); delay_ms(5); if (fr != FR_OK) { printf("config2.t0.txt=\"配置文件打开失败\"\xff\xff\xff"); config->x_pos1 = 160000; config->x_pos2 = 510000; config->x_pos3 = 960000; config->x_pos4 = 1370000; config->x_pos5 = 1750000; config->x_pos6 = 2080000; config->x_pos7 = 2400000; config->x_pos8 = 2710000; config->x_pos9 = 3020000; config->x_pos10 = 80000; config->x_offset = 0; config->z_soak = 230000; config->z_lift = 480000; config->z_lift1 = 0; config->t_fix = 60; // 30min config->t_rinse = 10; // 30s config->t_acid = 60; // 30min config->t_stain = 60; // 45min config->t_dehy1 = 60; // 10min config->t_dehy2 = 60; config->t_dehy3 = 60; config->t_dehy4 = 60; config->t_dry = 10; // 20min write_config_to_sd(config); return 1; } delay_ms(5); while (f_gets(line, sizeof(line), &config_file)) { if (strstr(line, "X_POS1:")) sscanf(line, "X_POS1:%ld", &config->x_pos1); else if (strstr(line, "X_POS2:")) sscanf(line, "X_POS2:%ld", &config->x_pos2); else if (strstr(line, "X_POS3:")) sscanf(line, "X_POS3:%ld", &config->x_pos3); else if (strstr(line, "X_POS4:")) sscanf(line, "X_POS4:%ld", &config->x_pos4); else if (strstr(line, "X_POS5:")) sscanf(line, "X_POS5:%ld", &config->x_pos5); else if (strstr(line, "X_POS6:")) sscanf(line, "X_POS6:%ld", &config->x_pos6); else if (strstr(line, "X_POS7:")) sscanf(line, "X_POS7:%ld", &config->x_pos7); else if (strstr(line, "X_POS8:")) sscanf(line, "X_POS8:%ld", &config->x_pos8); else if (strstr(line, "X_POS9:")) sscanf(line, "X_POS9:%ld", &config->x_pos9); else if (strstr(line, "X_POS10:")) sscanf(line, "X_POS10:%ld", &config->x_pos10); else if (strstr(line, "X_OFFSET:")) sscanf(line, "X_OFFSET:%ld", &config->x_offset); else if (strstr(line, "Z_SOAK:")) sscanf(line, "Z_SOAK:%ld", &config->z_soak); else if (strstr(line, "Z_LIFT:")) sscanf(line, "Z_LIFT:%ld", &config->z_lift); else if (strstr(line, "Z_LIFT1:")) sscanf(line, "Z_LIFT1:%ld", &config->z_lift1); else if (strstr(line, "T_FIX:")) sscanf(line, "T_FIX:%lu", &config->t_fix); else if (strstr(line, "T_RINSE:")) sscanf(line, "T_RINSE:%lu", &config->t_rinse); else if (strstr(line, "T_ACID:")) sscanf(line, "T_ACID:%lu", &config->t_acid); else if (strstr(line, "T_STAIN:")) sscanf(line, "T_STAIN:%lu", &config->t_stain); else if (strstr(line, "T_DEHY1:")) sscanf(line, "T_DEHY1:%lu", &config->t_dehy1); else if (strstr(line, "T_DEHY2:")) sscanf(line, "T_DEHY2:%lu", &config->t_dehy2); else if (strstr(line, "T_DEHY3:")) sscanf(line, "T_DEHY3:%lu", &config->t_dehy3); else if (strstr(line, "T_DEHY4:")) sscanf(line, "T_DEHY4:%lu", &config->t_dehy4); else if (strstr(line, "T_DRY:")) sscanf(line, "T_DRY:%lu", &config->t_dry); } f_close(&config_file); return 0; } /*----------------------------------------------------------------------------------------------------------*/ // 写入配置参数到SD卡 void write_config_to_sd(ConfigData *config) { FIL config_file; FRESULT fr; UINT bw; char line[2048]; fr = f_open(&config_file, "0:config.txt", FA_WRITE | FA_CREATE_ALWAYS); if (fr != FR_OK) { printf("config2.b3.txt=\"配置文件打开失败\"\xff\xff\xff"); return; }else if(fr == FR_OK) { f_lseek(&config_file, 0); // 移至文件开头,准备覆盖写入 } sprintf(line, "X_POS1:%ld\r\n", config->x_pos1); f_write(&config_file, line, strlen(line), &bw); sprintf(line, "X_POS2:%ld\r\n", config->x_pos2); f_write(&config_file, line, strlen(line), &bw); sprintf(line, "X_POS3:%ld\r\n", config->x_pos3); f_write(&config_file, line, strlen(line), &bw); sprintf(line, "X_POS4:%ld\r\n", config->x_pos4); f_write(&config_file, line, strlen(line), &bw); sprintf(line, "X_POS5:%ld\r\n", config->x_pos5); f_write(&config_file, line, strlen(line), &bw); sprintf(line, "X_POS6:%ld\r\n", config->x_pos6); f_write(&config_file, line, strlen(line), &bw); sprintf(line, "X_POS7:%ld\r\n", config->x_pos7); f_write(&config_file, line, strlen(line), &bw); sprintf(line, "X_POS8:%ld\r\n", config->x_pos8); f_write(&config_file, line, strlen(line), &bw); sprintf(line, "X_POS9:%ld\r\n", config->x_pos9); f_write(&config_file, line, strlen(line), &bw); sprintf(line, "X_POS10:%ld\r\n", config->x_pos10); f_write(&config_file, line, strlen(line), &bw); sprintf(line, "X_OFFSET:%ld\r\n", config->x_offset); f_write(&config_file, line, strlen(line), &bw); sprintf(line, "Z_SOAK:%ld\r\n", config->z_soak); f_write(&config_file, line, strlen(line), &bw); sprintf(line, "Z_LIFT:%ld\r\n", config->z_lift); f_write(&config_file, line, strlen(line), &bw); sprintf(line, "Z_LIFT1:%ld\r\n", config->z_lift1); f_write(&config_file, line, strlen(line), &bw); sprintf(line, "T_FIX:%lu\r\n", config->t_fix); f_write(&config_file, line, strlen(line), &bw); sprintf(line, "T_RINSE:%lu\r\n", config->t_rinse); f_write(&config_file, line, strlen(line), &bw); sprintf(line, "T_ACID:%lu\r\n", config->t_acid); f_write(&config_file, line, strlen(line), &bw); sprintf(line, "T_STAIN:%lu\r\n", config->t_stain); f_write(&config_file, line, strlen(line), &bw); sprintf(line, "T_DEHY1:%lu\r\n", config->t_dehy1); f_write(&config_file, line, strlen(line), &bw); sprintf(line, "T_DEHY2:%lu\r\n", config->t_dehy2); f_write(&config_file, line, strlen(line), &bw); sprintf(line, "T_DEHY3:%lu\r\n", config->t_dehy3); f_write(&config_file, line, strlen(line), &bw); sprintf(line, "T_DEHY4:%lu\r\n", config->t_dehy4); f_write(&config_file, line, strlen(line), &bw); sprintf(line, "T_DRY:%lu\r\n", config->t_dry); f_write(&config_file, line, strlen(line), &bw); f_sync(&config_file); f_close(&config_file); delay_ms(10); printf("config2.b3.txt=\"配置成功\"\xff\xff\xff"); printf("config2.tm1.en=1\xff\xff\xff"); USART_ClearBuffer(); } void write_log(int32_t x, int32_t z) { FRESULT fr; UINT bw; char log_line[512]; char time_str[64]; // 存储时间字符串 "YYYY-MM-DD HH:MM:SS" // 1. 通过RTC获取当前时间 RTC_Get(); // 2. 格式化时间字符串 sprintf(time_str, "%04d-%02d-%02d %02d:%02d:%02d", calendar.w_year, calendar.w_month, calendar.w_date, calendar.hour, calendar.min, calendar.sec); // 3. 打开日志文件(追加模式) fr = f_open(&log_file, "0:log.txt", FA_WRITE | FA_OPEN_ALWAYS); if (fr != FR_OK) { OLED_ShowString(1, 1, "Log Open Err"); printf("config3.t0.txt=\"追踪文件打开失败\"\xff\xff\xff"); printf("config3.tm3.en=1\xff\xff\xff"); return; } // 4. 移动到文件末尾(准备追加内容) f_lseek(&log_file, f_size(&log_file)); // 5. 格式化日志内容(末尾仅添加一次 \r\n 换行) sprintf(log_line, "[%s] X_位置:%ld\r, Z_位置:%ld\r\n", time_str,x,z); // 关键修改 // 6. 写入文件并同步 f_write(&log_file, log_line, strlen(log_line), &bw); f_sync(&log_file); // 确保数据写入SD卡 f_close(&log_file); } /*----------------------------------------------------------------------------------------------------------*/ //查看配置参数 void usmart_view_config(void) { FIL file; FRESULT fr; char buffer[2048]; // 缓冲区,根据配置文件可能的大小调整 UINT br; DWORD pos = 0; // 打开文件 fr = f_open(&file, "0:config.txt", FA_READ); if (fr != FR_OK) { printf("config2.va1.txt=\"Open config.txt failed! Error: %d\r\n\"\xff\xff\xff", fr); USART_ClearBuffer(); return; } // 确定读取位置(配置文件通常需全量显示,从开头读取) pos = 0; f_lseek(&file, pos); // 读取文件内容到缓冲区(最多读取缓冲区大小) f_read(&file, buffer, sizeof(buffer) - 1, &br); // 留1字节给结束符 buffer[br] = '\0'; // 添加字符串结束符 // 打印配置文件内容 printf("config2.va1.txt=\"设备配置参数:\r\n%s\r\n\"\xff\xff\xff", buffer); delay_ms(5); // 关闭文件 f_close(&file); USART_ClearBuffer(); } // 参数: 配置项名称(字符串)、新值(整数) void setParam(const char* param_name, int32_t value) { if (strcmp(param_name, "T_FIX") == 0) g_config.t_fix = value; else if (strcmp(param_name, "T_RINSE") == 0) g_config.t_rinse = value; else if (strcmp(param_name, "T_ACID") == 0) g_config.t_acid = value; else if (strcmp(param_name, "T_STAIN") == 0) g_config.t_stain = value; else if (strcmp(param_name, "T_DEHY1") == 0) g_config.t_dehy1 = value; else if (strcmp(param_name, "T_DEHY2") == 0) g_config.t_dehy2 = value; else if (strcmp(param_name, "T_DEHY3") == 0) g_config.t_dehy3 = value; else if (strcmp(param_name, "T_DEHY4") == 0) g_config.t_dehy4 = value; else if (strcmp(param_name, "T_DRY") == 0) g_config.t_dry = value; else if (strcmp(param_name, "X_POS1") == 0) g_config.x_pos1 = value; else if (strcmp(param_name, "X_POS2") == 0) g_config.x_pos2 = value; else if (strcmp(param_name, "X_POS3") == 0) g_config.x_pos3 = value; else if (strcmp(param_name, "X_POS4") == 0) g_config.x_pos4 = value; else if (strcmp(param_name, "X_POS5") == 0) g_config.x_pos5 = value; else if (strcmp(param_name, "X_POS6") == 0) g_config.x_pos6 = value; else if (strcmp(param_name, "X_POS7") == 0) g_config.x_pos7 = value; else if (strcmp(param_name, "X_POS8") == 0) g_config.x_pos8 = value; else if (strcmp(param_name, "X_POS9") == 0) g_config.x_pos9 = value; else if (strcmp(param_name, "X_POS10") == 0) g_config.x_pos10 = value; else if (strcmp(param_name, "Z_LIFT") == 0) g_config.z_lift = value; else if (strcmp(param_name, "Z_LIFT1") == 0) g_config.z_lift1 = value; else if (strcmp(param_name, "Z_SOAK") == 0) g_config.z_soak = value; else if (strcmp(param_name, "X_OFFSET") == 0) { delay_ms(10); g_config.x_offset = value; g_config.x_pos2 = g_config.x_pos2+value; g_config.x_pos3 = g_config.x_pos3+value; g_config.x_pos4 = g_config.x_pos4+value; g_config.x_pos5 = g_config.x_pos5+value; g_config.x_pos6 = g_config.x_pos6+value; g_config.x_pos7 = g_config.x_pos7+value; g_config.x_pos8 = g_config.x_pos8+value; g_config.x_pos9 = g_config.x_pos9+value; g_config.x_pos10 = g_config.x_pos10+value; delay_ms(10); } // 其他参数... else { printf("config2.t0.txt=\"请检查参数,输入无效\"\xff\xff\xff"); USART_ClearBuffer(); return; } write_config_to_sd(&g_config); } //////查看log文件后10行 void usmart_view_log(void) { FIL file; FRESULT fr; char buffer[2048]; UINT br; DWORD file_size, pos; int line_count = 0; fr = f_open(&file, "0:log.txt", FA_READ); if (fr != FR_OK) { printf("config3.va0.txt=\"Open log.txt failed! Error: %d\r\n\"\xff\xff\xff", fr); USART_ClearBuffer(); return; } file_size = f_size(&file); // 从文件末尾向前查找10行 pos = file_size < sizeof(buffer) ? 0 : file_size - sizeof(buffer); f_lseek(&file, pos); f_read(&file, buffer, sizeof(buffer), &br); buffer[br] = '\0'; // 从后往前统计行数 for (int i = br - 1; i >= 0; i--) { if (buffer[i] == '\n') { line_count++; if (line_count >= 30) { pos = i + 1; break; } } } // 打印找到的内容 if (line_count < 20) pos = 0; // 如果不足10行则从头开始 printf("config3.va0.txt=\"\r\n%s\r\n\"\xff\xff\xff",buffer + pos); USART_ClearBuffer(); f_close(&file); } //删除log文件 void delete_log(void) { delay_ms(50); u8 ret = mf_unlink("log.txt"); if (ret == FR_OK) { printf("config3.t0.txt=\"日志删除成功\r\n日志删除成功\r\n\"\xff\xff\xff"); } else { printf("config3.t0.txt=\"日志删除失败\r\n日志删除失败\r\n\"\xff\xff\xff"); } } /*----------------------------------------------------------------------------------------------------------*/ void moveX(int32_t steps) { moveAxisCommon(AXIS_X,steps); } void moveZ(int32_t steps) { moveAxisCommon(AXIS_Z,steps); } /*----------------------------------------------------------------------------------------------------------*/ // 移动到指定染缸(1-9) void moveToTank(uint8_t tank_num) { if (tank_num < 1 || tank_num > 9) { OLED_ShowString(4,1,"Invalid Tank"); return; } // 获取目标缸X坐标 int32_t target_x = 0; switch(tank_num) { case 1: target_x = g_config.x_pos1; break; case 2: target_x = g_config.x_pos2; break; case 3: target_x = g_config.x_pos3; break; case 4: target_x = g_config.x_pos4; break; case 5: target_x = g_config.x_pos5; break; case 6: target_x = g_config.x_pos6; break; case 7: target_x = g_config.x_pos7; break; case 8: target_x = g_config.x_pos8; break; case 9: target_x = g_config.x_pos9; break; } // X轴移动到目标位置 int32_t x_steps = target_x - x_current_position; delay_ms(10); moveAxisCommon(AXIS_X, x_steps);//1 // Z轴下降() moveAxisCommon(AXIS_Z, g_config.z_lift);//2 } /*----------------------------------------------------------------------------------------------------------*/ // 染色流程状态机处理函数(在主循环中调用,非阻塞) void process_auto_stain(void) { if (g_stain_state == STAIN_IDLE) return; // 空闲状态不处理 get_sys_time_s(); uint32_t elapsed_ms = sys_time_s - g_delay_start_tick; // 已过去的时间 switch (g_stain_state) { // -------------------------- 步骤1:等待放入染架 -------------------------- case STAIN_STEP1_WAIT_LOAD_INIT: printf("move.t0.txt=\"请放入染架到固定缸\"\xff\xff\xff"); g_delay_start_tick = sys_time_s; // 记录开始时间 g_current_delay_s = 3; // 等待 g_stain_state = STAIN_STEP1_WAIT_LOAD_DELAY; // 进入延时状态 break; case STAIN_STEP1_WAIT_LOAD_DELAY: if (elapsed_ms >= g_current_delay_s) { // 等待结束,进入固定缸初始化 g_stain_state = STAIN_STEP1_FIX_INIT; } break; // -------------------------- 步骤1:固定缸(1#) -------------------------- case STAIN_STEP1_FIX_INIT: printf("move.t2.bco=1024\xff\xff\xff"); g_delay_start_tick = sys_time_s; // 记录开始时间 g_current_delay_s = g_config.t_fix; // 目标延时(用户配置) g_stain_state = STAIN_STEP1_FIX_DELAY; // 进入延时状态 printf("move.t0.txt=\"固定剩余时间:\"\xff\xff\xff"); printf("move.tm1.en=1\xff\xff\xff"); printf("move.t25.aph=127\xff\xff\xff"); printf("move.t26.aph=127\xff\xff\xff"); break; case STAIN_STEP1_FIX_DELAY: if (elapsed_ms >= g_current_delay_s) { printf("move.t25.txt=\"0\"\xff\xff\xff"); printf("move.tm1.en=0\xff\xff\xff"); printf("move.t25.aph=0\xff\xff\xff"); printf("move.t26.aph=0\xff\xff\xff"); g_stain_state = STAIN_STEP1_FIX_DONE; } break; case STAIN_STEP1_FIX_DONE: // 执行移动操作(非阻塞,假设moveAxisCommon内部已处理等待) printf("move.t0.txt=\"移动到冲洗缸\"\xff\xff\xff"); moveAxisCommon(AXIS_X, g_config.x_pos1); moveAxisCommon(AXIS_Z, g_config.z_lift); Xmove_right2(); //右移小距离,抓住染架 Zmove_up(); g_stain_state = STAIN_STEP2_RINSE_INIT; // 进入下一步 break; // -------------------------- 步骤2:冲洗缸(4#) -------------------------- case STAIN_STEP2_RINSE_INIT: printf("move.t8.bco=1024\xff\xff\xff"); moveToTank(4); // 移动到冲洗缸 up_down(); // 执行上下动作 g_delay_start_tick = sys_time_s; //这里不是current_tick,是因为运动会阻塞函数,无法运行 uint32_t current_tick = sys_time_s;获取当前时间 g_current_delay_s = g_config.t_rinse; // 冲洗延时 g_stain_state = STAIN_STEP2_RINSE_DELAY; printf("move.t0.txt=\"冲洗剩余时间:\"\xff\xff\xff"); printf("move.t25.aph=127\xff\xff\xff"); printf("move.t26.aph=127\xff\xff\xff"); printf("move.tm2.en=1\xff\xff\xff"); break; case STAIN_STEP2_RINSE_DELAY: if (elapsed_ms >= g_current_delay_s) { printf("move.t25.txt=\"0\"\xff\xff\xff"); printf("move.tm2.en=0\xff\xff\xff"); printf("move.t25.aph=0\xff\xff\xff"); printf("move.t26.aph=0\xff\xff\xff"); g_stain_state = STAIN_STEP2_RINSE_DONE; } break; case STAIN_STEP2_RINSE_DONE: printf("move.t0.txt=\"移动到酸化缸\"\xff\xff\xff"); Zmove_up(); g_stain_state = STAIN_STEP3_ACID_INIT; // 进入酸化缸 break; // -------------------------- 步骤3:酸化缸(2#) -------------------------- case STAIN_STEP3_ACID_INIT: printf("move.t4.bco=1024\xff\xff\xff"); moveToTank(2); // 移动到酸化缸 g_delay_start_tick = sys_time_s; g_current_delay_s = g_config.t_acid; // 酸化延时 g_stain_state = STAIN_STEP3_ACID_DELAY; printf("move.t0.txt=\"酸化剩余时间:\"\xff\xff\xff"); printf("move.t25.aph=127\xff\xff\xff"); printf("move.t26.aph=127\xff\xff\xff"); printf("move.tm3.en=1\xff\xff\xff"); break; case STAIN_STEP3_ACID_DELAY: if (elapsed_ms >= g_current_delay_s) { printf("move.t25.txt=\"0\"\xff\xff\xff"); printf("move.t25.aph=0\xff\xff\xff"); printf("move.t26.aph=0\xff\xff\xff"); printf("move.tm3.en=0\xff\xff\xff"); g_stain_state = STAIN_STEP3_ACID_DONE; } break; case STAIN_STEP3_ACID_DONE: printf("move.t0.txt=\"移动到冲洗缸\"\xff\xff\xff"); Zmove_up(); g_stain_state = STAIN_STEP4_RINSE_INIT; // 进入冲洗缸 break; // -------------------------- 步骤4:冲洗缸(4#) -------------------------- case STAIN_STEP4_RINSE_INIT: printf("move.t8.bco=1024\xff\xff\xff"); moveToTank(4); // 移动到冲洗缸 up_down(); g_delay_start_tick = sys_time_s; g_current_delay_s = g_config.t_rinse; // 冲洗延时 g_stain_state = STAIN_STEP4_RINSE_DELAY; printf("move.t0.txt=\"冲洗剩余时间:\"\xff\xff\xff"); printf("move.t25.aph=127\xff\xff\xff"); printf("move.t26.aph=127\xff\xff\xff"); printf("move.va3.val=%d\xff\xff\xff",g_config.t_rinse); printf("move.tm2.en=1\xff\xff\xff"); break; case STAIN_STEP4_RINSE_DELAY: if (elapsed_ms >= g_current_delay_s) { printf("move.t25.txt=\"0\"\xff\xff\xff"); printf("move.tm2.en=0\xff\xff\xff"); printf("move.t25.aph=0\xff\xff\xff"); printf("move.t26.aph=0\xff\xff\xff"); g_stain_state = STAIN_STEP4_RINSE_DONE; } break; case STAIN_STEP4_RINSE_DONE: printf("move.t0.txt=\"移动到染色缸\"\xff\xff\xff"); Zmove_up(); g_stain_state = STAIN_STEP5_STAIN_INIT; // 进入染色缸 break; // -------------------------- 步骤5:染色缸(3#) -------------------------- case STAIN_STEP5_STAIN_INIT: printf("move.t6.bco=1024\xff\xff\xff"); moveToTank(3); // 移动到染色缸 g_delay_start_tick = sys_time_s; g_current_delay_s = g_config.t_stain; // 染色延时 g_stain_state = STAIN_STEP5_STAIN_DELAY; printf("move.t0.txt=\"染色剩余时间:\"\xff\xff\xff"); printf("move.t25.aph=127\xff\xff\xff"); printf("move.t26.aph=127\xff\xff\xff"); printf("move.tm4.en=1\xff\xff\xff"); break; case STAIN_STEP5_STAIN_DELAY: if (elapsed_ms >= g_current_delay_s) { printf("move.t25.txt=\"0\"\xff\xff\xff"); printf("move.tm4.en=0\xff\xff\xff"); printf("move.t25.aph=0\xff\xff\xff"); printf("move.t26.aph=0\xff\xff\xff"); g_stain_state = STAIN_STEP5_STAIN_DONE; } break; case STAIN_STEP5_STAIN_DONE: printf("move.t0.txt=\"移动到冲洗缸\"\xff\xff\xff"); Zmove_up(); g_stain_state = STAIN_STEP6_RINSE_INIT; // 进入冲洗缸 break; // -------------------------- 步骤6:冲洗缸(4#) -------------------------- case STAIN_STEP6_RINSE_INIT: printf("move.t8.bco=1024\xff\xff\xff"); moveToTank(4); // 移动到冲洗缸 up_down(); g_delay_start_tick = sys_time_s; g_current_delay_s = g_config.t_rinse; // 冲洗延时 g_stain_state = STAIN_STEP6_RINSE_DELAY; printf("move.va3.val=%d\xff\xff\xff",g_config.t_rinse); printf("move.t0.txt=\"冲洗剩余时间:\"\xff\xff\xff"); printf("move.t25.aph=127\xff\xff\xff"); printf("move.t26.aph=127\xff\xff\xff"); printf("move.tm2.en=1\xff\xff\xff"); break; case STAIN_STEP6_RINSE_DELAY: if (elapsed_ms >= g_current_delay_s) { printf("move.t25.txt=\"0\"\xff\xff\xff"); printf("move.tm2.en=0\xff\xff\xff"); printf("move.t25.aph=0\xff\xff\xff"); printf("move.t26.aph=0\xff\xff\xff"); g_stain_state = STAIN_STEP6_RINSE_DONE; } break; case STAIN_STEP6_RINSE_DONE: printf("move.t0.txt=\"移动到梯度脱水1缸\"\xff\xff\xff"); Zmove_up(); g_stain_state = STAIN_STEP7_DEHY1_INIT; // 进入脱水1 break; // -------------------------- 步骤7:梯度脱水1(5#) -------------------------- case STAIN_STEP7_DEHY1_INIT: printf("move.t10.bco=1024\xff\xff\xff"); moveToTank(5); // 移动到脱水1缸 g_delay_start_tick = sys_time_s; g_current_delay_s = g_config.t_dehy1; // 脱水1延时 g_stain_state = STAIN_STEP7_DEHY1_DELAY; printf("move.t0.txt=\"梯度脱水1剩余时间:\"\xff\xff\xff"); printf("move.t25.aph=127\xff\xff\xff"); printf("move.t26.aph=127\xff\xff\xff"); printf("move.tm5.en=1\xff\xff\xff"); break; case STAIN_STEP7_DEHY1_DELAY: if (elapsed_ms >= g_current_delay_s) { printf("move.t25.txt=\"0\"\xff\xff\xff"); printf("move.tm5.en=0\xff\xff\xff"); printf("move.t25.aph=0\xff\xff\xff"); printf("move.t26.aph=0\xff\xff\xff"); g_stain_state = STAIN_STEP7_DEHY1_DONE; } break; case STAIN_STEP7_DEHY1_DONE: printf("move.t0.txt=\"移动到梯度脱水2缸\"\xff\xff\xff"); Zmove_up(); g_stain_state = STAIN_STEP8_DEHY2_INIT; // 进入脱水2 break; // -------------------------- 步骤8:梯度脱水2(6#) -------------------------- case STAIN_STEP8_DEHY2_INIT: printf("move.t12.bco=1024\xff\xff\xff"); moveToTank(6); // 移动到脱水2缸 g_delay_start_tick = sys_time_s; g_current_delay_s = g_config.t_dehy2; // 脱水2延时 g_stain_state = STAIN_STEP8_DEHY2_DELAY; printf("move.t0.txt=\"梯度脱水2剩余时间:\"\xff\xff\xff"); printf("move.t25.aph=127\xff\xff\xff"); printf("move.t26.aph=127\xff\xff\xff"); printf("move.tm6.en=1\xff\xff\xff"); break; case STAIN_STEP8_DEHY2_DELAY: if (elapsed_ms >= g_current_delay_s) { printf("move.t25.txt=\"0\"\xff\xff\xff"); printf("move.tm6.en=0\xff\xff\xff"); printf("move.t25.aph=0\xff\xff\xff"); printf("move.t26.aph=0\xff\xff\xff"); g_stain_state = STAIN_STEP8_DEHY2_DONE; } break; case STAIN_STEP8_DEHY2_DONE: printf("move.t0.txt=\"移动到梯度脱水3缸\"\xff\xff\xff"); Zmove_up(); g_stain_state = STAIN_STEP9_DEHY3_INIT; // 进入脱水3 break; // -------------------------- 步骤9:梯度脱水3(7#) -------------------------- case STAIN_STEP9_DEHY3_INIT: printf("move.t14.bco=1024\xff\xff\xff"); moveToTank(7); // 移动到脱水3缸 g_delay_start_tick = sys_time_s; g_current_delay_s = g_config.t_dehy3; // 脱水3延时 g_stain_state = STAIN_STEP9_DEHY3_DELAY; printf("move.t0.txt=\"梯度脱水3剩余时间:\"\xff\xff\xff"); printf("move.t25.aph=127\xff\xff\xff"); printf("move.t26.aph=127\xff\xff\xff"); printf("move.tm7.en=1\xff\xff\xff"); break; case STAIN_STEP9_DEHY3_DELAY: if (elapsed_ms >= g_current_delay_s) { printf("move.t25.txt=\"0\"\xff\xff\xff"); printf("move.tm7.en=0\xff\xff\xff"); printf("move.t25.aph=0\xff\xff\xff"); printf("move.t26.aph=0\xff\xff\xff"); g_stain_state = STAIN_STEP9_DEHY3_DONE; } break; case STAIN_STEP9_DEHY3_DONE: printf("move.t0.txt=\"移动到梯度脱水4缸\"\xff\xff\xff"); Zmove_up(); g_stain_state = STAIN_STEP10_DEHY4_INIT; // 进入脱水4 break; // -------------------------- 步骤10:梯度脱水4(8#) -------------------------- case STAIN_STEP10_DEHY4_INIT: printf("move.t16.bco=1024\xff\xff\xff"); moveToTank(8); // 移动到脱水4缸 g_delay_start_tick = sys_time_s; g_current_delay_s = g_config.t_dehy4; // 脱水4延时 g_stain_state = STAIN_STEP10_DEHY4_DELAY; printf("move.t0.txt=\"梯度脱水4剩余时间:\"\xff\xff\xff"); printf("move.t25.aph=127\xff\xff\xff"); printf("move.t26.aph=127\xff\xff\xff"); printf("move.tm8.en=1\xff\xff\xff"); break; case STAIN_STEP10_DEHY4_DELAY: if (elapsed_ms >= g_current_delay_s) { printf("move.t25.txt=\"0\"\xff\xff\xff"); printf("move.tm8.en=0\xff\xff\xff"); printf("move.t25.aph=0\xff\xff\xff"); printf("move.t26.aph=0\xff\xff\xff"); g_stain_state = STAIN_STEP10_DEHY4_DONE; } break; case STAIN_STEP10_DEHY4_DONE: printf("move.t0.txt=\"移动到梯度晾片缸\"\xff\xff\xff"); Zmove_up(); g_stain_state = STAIN_STEP11_DRY_INIT; // 进入晾片缸 break; // -------------------------- 步骤11:晾片缸(9#) -------------------------- case STAIN_STEP11_DRY_INIT: printf("move.t18.bco=1024\xff\xff\xff"); printf("move.t0.txt=\"晾片\"\xff\xff\xff"); moveToTank(9); // 移动到晾片缸 printf("move.tm11.en=1\xff\xff\xff"); g_delay_start_tick = sys_time_s; g_current_delay_s = g_config.t_dry; // 晾片延时 g_stain_state = STAIN_STEP11_DRY_DELAY; break; case STAIN_STEP11_DRY_DELAY: if (elapsed_ms >= g_current_delay_s) { printf("move.t25.txt=\"0\"\xff\xff\xff"); printf("move.tm11.en=0\xff\xff\xff"); printf("move.t25.aph=0\xff\xff\xff"); printf("move.t26.aph=0\xff\xff\xff"); g_stain_state = STAIN_STEP11_DRY_DONE; } break; case STAIN_STEP11_DRY_DONE: Xmove_left(); // 脱离晾片缸 g_stain_state = STAIN_FINISH; // 流程结束 break; // -------------------------- 流程结束 -------------------------- case STAIN_FINISH: printf("move.t0.txt=\"染色完成,请移走染架\"\xff\xff\xff"); g_stain_state = STAIN_IDLE; // 重置为空闲状态 break; default: g_stain_state = STAIN_IDLE; // 异常状态重置 break; } } /*----------------------------------------------------------------------------------------------------------*/ // 优化后的X轴移动函数 void Xmove_left(void) { delay_ms(10); moveAxisCommon(AXIS_X,g_config.x_pos1);//最后一次移动距离,脱离晾片缸 } void Xmove_right(void) { delay_ms(10); moveAxisCommon(AXIS_X,-g_config.x_pos1); } void Xmove_right2(void) { delay_ms(10); moveAxisCommon(AXIS_X,-g_config.x_pos10);//距离是需要右移或者左移抓染架的距离 } void Xmove_left2(void) { delay_ms(10); moveAxisCommon(AXIS_X,g_config.x_pos10);//距离是需要右移或者左移抓染架的距离 } // 优化后的Z轴移动函数 void Zmove_down(void) { delay_ms(10); moveAxisCommon(AXIS_Z,g_config.z_lift); } void Zmove_down_2(void) { delay_ms(10); moveAxisCommon(AXIS_Z,g_config.z_soak); } void Zmove_up(void) { delay_ms(10); moveAxisCommon(AXIS_Z,-g_config.z_lift); } void Zmove_up_2(void) { delay_ms(10); moveAxisCommon(AXIS_Z,-g_config.z_soak); } void up_down(void) { delay_ms(10); Zmove_up_2(); delay_ms(100); Zmove_down_2(); Zmove_up_2(); delay_ms(100); Zmove_down_2(); } /*----------------------------------------------------------------------------------------------------------*/ //一直移动函数GUI界面函数 // 处理触摸屏指令 void touch_command_process(uint8_t cmd) { switch(cmd) { case TOUCH_X_LEFT_PRESS: x_left_running = 1; x_right_running = 0; break; case TOUCH_X_LEFT_RELEASE: if(x_left_running) { motor_stop(AXIS_X); x_left_running = 0; } break; case TOUCH_X_RIGHT_PRESS: x_right_running = 1; x_left_running = 0; break; case TOUCH_X_RIGHT_RELEASE: if(x_right_running) { motor_stop(AXIS_X); x_right_running = 0; } break; case TOUCH_Z_UP_PRESS: z_up_running = 1; z_down_running = 0; break; case TOUCH_Z_UP_RELEASE: if(z_up_running) { motor_stop(AXIS_Z); z_up_running = 0; } break; case TOUCH_Z_DOWN_PRESS: z_down_running = 1; z_up_running = 0; break; case TOUCH_Z_DOWN_RELEASE: if(z_down_running) { motor_stop(AXIS_Z); z_down_running = 0; } break; case STAIN_STEP1_WAIT_LOAD_INIT_USART: if (g_stain_state == STAIN_IDLE) { g_stain_state = STAIN_STEP1_WAIT_LOAD_INIT; // 从第一步开始 } break; case STAIN_IDLE_USART: GPIO_SetBits(X_ENA_PORT, X_ENA_PIN); // 高电平禁用 GPIO_SetBits(Z_ENA_PORT, Z_ENA_PIN); reinitialize_system(); break; } } // 电机连续移动函数 void motor_continuous_move(AxisType axis, int32_t direction) { if(axis == AXIS_X) { if(!x_motor_running) { // 设置一个较大的目标步数实现连续移动 moveAxisCommon(AXIS_X, direction * 10000000); } } else if(axis == AXIS_Z) { if(!z_motor_running) { moveAxisCommon(AXIS_Z, direction * 10000000); } } } // 电机停止函数 void motor_stop(AxisType axis) { if(axis == AXIS_X) { x_motor_running = 0; disableMotor(AXIS_X); } else if(axis == AXIS_Z) { z_motor_running = 0; disableMotor(AXIS_Z); } } /*----------------------------------------------------------------------------------------------------------*/ void X_home(void) { Home_Motor(AXIS_X); } void Z_home(void) { Home_Motor(AXIS_Z); } /*----------------------------------------------------------------------------------------------------------*/ //初始化SD配置文件 void SD_config_init(void) { fr = f_open(&config_file, "0:config.txt", FA_READ); if (fr == FR_OK) { read_config_from_sd(&g_config); delay_ms(10); f_close(&config_file); } else { printf("not find config"); delay_ms(10); } fr = f_open(&log_file, "0:log.txt", FA_READ | FA_OPEN_ALWAYS); f_close(&log_file); } /*----------------------------------------------------------------------------------------------------------*/ /** * 读取温度状态并更新(仅在状态变化时执行操作) */ void prin_temp(void) { // 读取温度(已转为整数) int32_t current_temp = (int32_t)(SMBus_ReadTemp()); // 仅当当前温度与历史值不同时,才执行更新(避免无效操作) if (current_temp != last_temp) { if(current_temp < 150 && current_temp > -10) { // 调用公共函数更新显示和发送数据 printf("home.va0.val=%d\xff\xff\xff", current_temp); OLED_ShowNum(3,4, current_temp, 2); // 显示温度(占3位,适应更大数值) OLED_ShowString(3,6,"C"); OLED_ShowString(3,1,"T1:"); last_temp = current_temp; // 更新历史值 USART_ClearBuffer(); } } } /** * 读取温度状态并更新(仅在状态变化时执行操作) */ void prin_temp2(void) { // 读取温度(已转为整数) int32_t current_temp2 = (int32_t)DS18B20_Get_Temp()/ 10.0f; // 仅当当前温度与历史值不同时,才执行更新(避免无效操作) if (current_temp2 != last_temp2) { if(current_temp2 < 150 && last_temp2 > -10){ // 调用公共函数更新显示和发送数据 printf("home.va1.val=%d\xff\xff\xff", current_temp2); OLED_ShowNum(3,12, current_temp2, 2); // 显示温度(占3位,适应更大数值) OLED_ShowString(3,14,"C"); OLED_ShowString(3,9,"T2:"); last_temp2 = current_temp2; // 更新历史值 USART_ClearBuffer(); } } } /** * 读取液位状态并更新(仅在状态变化时执行操作) */ void print_level(void) { // 读取液位状态 uint8_t current_level = LevelSensor_GetState(); if(current_level==1)//出水,模式 { close_rinse_input(); open_rinse_output(); } if(current_level==0)//进水,判断,水满信号位置1 { open_rinse_input(); close_rinse_output(); } // 仅当当前状态与历史值不同时,才执行更新 if (current_level != last_level) { // 调用公共函数更新显示和发送数据 printf("move.va1.val=%d\xff\xff\xff", current_level); OLED_ShowString(1,1,"water_leve:"); OLED_ShowNum(1,14,current_level, 2); // 显示液位状态 last_level = current_level; // 更新历史值 USART_ClearBuffer(); } } /*----------------------------------------------------------------------------------------------------------*/ void moveAxisCommon(AxisType axis, int32_t target_steps) { delay_ms(10); // 启动带加速度的运动(假设此函数仅启动运动,不阻塞) moveStepsWithAccel(axis, target_steps); // 立即更新OLED显示(运动开始时的位置) OLED_ShowNum(2, 9, x_current_position, 7); OLED_ShowNum(4, 9, z_current_position, 7); while ((axis == AXIS_X && x_motor_running) || (axis == AXIS_Z && z_motor_running)) { delay_ms(1); // 短延迟,降低CPU占用 } delay_ms(10); // 稳定延迟 // 5. 写日志与显示 write_log(x_current_position, z_current_position); } /*--------------------------------------------------------------------------------------------------------------------------------*/ // 安全清理函数:释放资源,停止外设 void safe_cleanup(void) { // 1. 停止电机运动 motor_stop(AXIS_X); motor_stop(AXIS_Z); x_left_running = 0; x_right_running = 0; z_up_running = 0; z_down_running = 0; // 2. 关闭文件系统相关资源 f_close(&step_file); f_close(&log_file); f_close(&config_file); f_mount(NULL, "0:", 1); // 卸载SD卡 f_mount(NULL, "1:", 1); // 卸载FLASH // 3. 重置状态机和全局变量 g_stain_state = STAIN_IDLE; g_delay_start_tick = 0; g_current_delay_s = 0; // 4. 清空OLED显示 OLED_Clear(); delay_ms(500); } // 重新初始化函数(复用main中的初始化逻辑) void reinitialize_system(void) { safe_cleanup(); // 先清理资源 // 重新执行初始化(完全复用main中的初始化步骤) delay_init(72); delay_ms(10); OLED_Init(); OLED_Clear(); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); StepMotor_GPIO_Init(AXIS_X); StepMotor_GPIO_Init(AXIS_Z); StepMotor_TIM_Init(AXIS_X); StepMotor_TIM_Init(AXIS_Z); delay_ms(10); my_mem_init(SRAMIN); delay_ms(10); SMBus_Init(); delay_ms(10); LevelSensor_Init(); delay_ms(10); DS18B20_Init(); delay_ms(10); // 重新初始化SD卡(带重试) while(SD_Init()) { OLED_ShowString(2, 1, "SD Error, Retry..."); delay_ms(1000); } delay_ms(10); // 重新初始化文件系统 while(exfuns_init()) { OLED_ShowString(2, 1, "FS Error, Retry..."); delay_ms(1000); } f_mount(fs[0], "0:", 1); f_mount(fs[1], "1:", 1); delay_ms(10); // 重新初始化串口和USMART USART1_Init(115200); delay_ms(10); usmart_dev.init(72); delay_ms(10); // 重新初始化RTC RTC_Init(); delay_ms(10); // 重新加载配置 SD_config_init(); delay_ms(10); // 重新初始化限位开关 LimitSwitch_Init(); CheckLimitSwitches(); delay_ms(10); /*************************开机初始化将配置参数传到move页面***************************************/ printf("move.va2.val=%d\xff\xff\xff",g_config.t_fix); printf("move.va3.val=%d\xff\xff\xff",g_config.t_rinse); printf("move.va4.val=%d\xff\xff\xff",g_config.t_acid); printf("move.va5.val=%d\xff\xff\xff",g_config.t_stain); printf("move.va6.val=%d\xff\xff\xff",g_config.t_dehy1); printf("move.va7.val=%d\xff\xff\xff",g_config.t_dehy2); printf("move.va8.val=%d\xff\xff\xff",g_config.t_dehy3); printf("move.va9.val=%d\xff\xff\xff",g_config.t_dehy4); printf("move.va10.val=%d\xff\xff\xff",g_config.t_dry); /***********************************************************************************************/ OLED_Clear(); printf("系统重新初始化完成\xFF\xFF\xFF"); delay_ms(1000); OLED_Clear(); } /*--------------------------------------------------------------------------------------------------------------------------------*/ int main(void) { int a=0; //温度循环值初始,1秒检测一次 g_stain_state = STAIN_IDLE; //初始化为空闲状态,状态机 delay_init(72); delay_ms(1000); OLED_Init(); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组0 StepMotor_GPIO_Init(AXIS_X); StepMotor_GPIO_Init(AXIS_Z); StepMotor_TIM_Init(AXIS_X); StepMotor_TIM_Init(AXIS_Z); delay_ms(10); my_mem_init(SRAMIN); //初始化内部内存池 delay_ms(10); SMBus_Init(); // 初始化SMBus总线(用于MLX90614通信) delay_ms(10); LevelSensor_Init(); // 初始化液面传感器 delay_ms(10); DS18B20_Init(); // 初始化DS18B20温度传感器 delay_ms(10); while(SD_Init()) //检测不到SD卡,SDIO初始化 { OLED_ShowString(1,1,"SD Card Error!"); printf("SD Card Error!"); delay_ms(100); OLED_ShowString(1,1,"Please Check! "); delay_ms(100); } delay_ms(10); while(exfuns_init()) //FAFTS文件系统是否挂载失败 { OLED_ShowString(1,1," exfuns_init Error!"); printf("exfuns_init Error!"); delay_ms(1000); } f_mount(fs[0],"0:",1); //挂载SD卡 f_mount(fs[1],"1:",1); //挂载FLASH. /*************************初始化USMART通信********************************************************/ delay_ms(10); USART1_Init(115200); //串口初始化为115200 delay_ms(10); usmart_dev.init(72); //串口通信初始化 delay_ms(10); /*************************初始化RTC初始化********************************************************/ RTC_Init(); //RTC初始化 delay_ms(10); SD_config_init(); //初始化,将config文件的参数一次性更新到程序里 delay_ms(10); LimitSwitch_Init(); //运动限位最后初始化。 CheckLimitSwitches(); //检查限位,复位限位 OLED_Clear(); //oled显示屏幕清空 // Home_Motor(AXIS_Z); //初始化Z轴,Z轴回零 // Home_Motor(AXIS_X); //初始化X轴,X轴回零 OLED_Clear(); //清空屏幕 /*************************开机初始化将配置参数传到move页面***************************************/ printf("move.va2.val=%d\xff\xff\xff",g_config.t_fix); printf("move.va3.val=%d\xff\xff\xff",g_config.t_rinse); printf("move.va4.val=%d\xff\xff\xff",g_config.t_acid); printf("move.va5.val=%d\xff\xff\xff",g_config.t_stain); printf("move.va6.val=%d\xff\xff\xff",g_config.t_dehy1); printf("move.va7.val=%d\xff\xff\xff",g_config.t_dehy2); printf("move.va8.val=%d\xff\xff\xff",g_config.t_dehy3); printf("move.va9.val=%d\xff\xff\xff",g_config.t_dehy4); printf("move.va10.val=%d\xff\xff\xff",g_config.t_dry); /***********************************************************************************************/ while (1) { process_auto_stain(); if(x_left_running) { motor_continuous_move(AXIS_X, 1); // X轴左移 } if(x_right_running) { motor_continuous_move(AXIS_X, -1); // X轴右移 } if(z_up_running) { motor_continuous_move(AXIS_Z, -1); // Z轴上移 } if(z_down_running) { motor_continuous_move(AXIS_Z, 1); // Z轴下移 } a++; //累加计数 if(a==800){ prin_temp(); prin_temp2(); a=0; } print_level(); delay_ms(2); // 主循环基础延时(保持不变) } }
最新发布
10-31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值