arm机械臂课程设计报告代码

合集下载

工业机械臂课程设计

工业机械臂课程设计

工业机械臂课程设计一、课程目标知识目标:1. 学生能理解工业机械臂的基本结构、工作原理及功能应用;2. 学生能掌握工业机械臂的运动学、动力学基础知识;3. 学生能了解工业机械臂的编程与控制方法。

技能目标:1. 学生能运用所学的理论知识,分析并解决工业机械臂在实际应用中遇到的问题;2. 学生能设计简单的工业机械臂动作程序,实现特定功能;3. 学生能通过团队合作,完成工业机械臂的组装与调试。

情感态度价值观目标:1. 培养学生对工业机械臂及其相关领域的好奇心和探索精神;2. 培养学生具备严谨的科学态度,对技术问题进行客观分析;3. 增强学生的团队协作意识,培养合作共赢的价值观。

课程性质:本课程为理论与实践相结合的课程,旨在让学生在掌握基本理论知识的基础上,提高实际操作和解决问题的能力。

学生特点:本课程针对初中年级学生,他们具备一定的物理知识和动手能力,但需加强对工业机械臂相关知识的引导。

教学要求:教师需注重理论与实践相结合,通过生动的案例和实际操作,激发学生的学习兴趣,培养其创新思维和实际操作能力。

同时,将课程目标分解为具体的学习成果,便于教学设计和评估。

二、教学内容1. 工业机械臂的基本结构:介绍机械臂的组成部分,包括基座、关节、连杆、末端执行器等;教材章节:第一章 工业机械臂概述2. 工业机械臂的工作原理:讲解机械臂的运动原理,包括正运动学、逆运动学;教材章节:第二章 工业机械臂的运动学原理3. 工业机械臂的动力学:分析机械臂在运动过程中的力学特性,包括静力学和动力学;教材章节:第三章 工业机械臂的动力学原理4. 工业机械臂的编程与控制:介绍机械臂的编程方法和控制策略;教材章节:第四章 工业机械臂的编程与控制5. 工业机械臂的应用案例:分析工业机械臂在不同领域的实际应用;教材章节:第五章 工业机械臂的应用案例6. 工业机械臂的组装与调试:让学生动手实践,提高实际操作能力;教材章节:第六章 工业机械臂的组装与调试教学安排:本课程共分为六个课时,每个课时对应一个教学内容。

机械臂课程设计

机械臂课程设计

机械臂课程设计一、课程目标知识目标:1. 让学生掌握机械臂的基本结构、原理及功能,了解其在工业生产中的应用;2. 使学生了解机械臂的运动学及动力学基础知识,能够分析机械臂的运动特性;3. 帮助学生了解机械臂的控制原理,掌握基本的编程方法。

技能目标:1. 培养学生运用机械臂进行简单任务操作的能力,提高动手实践能力;2. 培养学生运用所学知识解决实际问题的能力,提高创新意识和团队协作能力;3. 提高学生对机械臂编程与控制技能的掌握,具备一定的实际操作经验。

情感态度价值观目标:1. 激发学生对机械臂技术及自动化领域的兴趣,培养探索精神和科学态度;2. 培养学生关注社会发展,认识到机械臂在现实生活中的应用价值;3. 引导学生树立正确的价值观,认识到科技发展对社会进步的重要作用。

课程性质分析:本课程为实践性较强的课程,结合理论知识与实际操作,培养学生对机械臂的全面认识。

学生特点分析:学生具备一定的物理知识和数学基础,对新鲜事物充满好奇心,喜欢动手实践。

教学要求:1. 注重理论知识与实践操作的相结合,提高学生的综合能力;2. 创设情境,引导学生主动探索,激发学习兴趣;3. 关注学生个体差异,因材施教,提高教学质量。

二、教学内容1. 机械臂的基本结构:介绍机械臂的组成部分,如基座、关节、连杆、末端执行器等,结合教材相关章节,分析各部分功能及相互关系。

2. 机械臂的运动学原理:讲解机械臂的运动学基础知识,包括正运动学、逆运动学以及运动轨迹规划,结合教材实例进行分析。

3. 机械臂的动力学原理:介绍机械臂的动力学基础知识,如牛顿-欧拉方程、拉格朗日方程等,分析机械臂在不同工况下的动力学特性。

4. 机械臂的控制原理:讲解机械臂的控制方法,包括开环控制、闭环控制以及PID控制等,结合教材相关章节,分析各控制方法的优缺点。

5. 机械臂编程与操作:学习机械臂的编程语言及编程方法,如示教编程、离线编程等,组织学生进行实际操作,提高动手能力。

基于某STM32的机械臂运动控制分析报告设计

基于某STM32的机械臂运动控制分析报告设计
(1)
其中:
得到各连杆之间的变换矩阵
(2)
(3)
(4)
式中:s1,s2,s3,s4;c1,c2,cs3,c4分别表示sinθ1,sinθ2,sinθ3,sinθ4; cosθ1, cosθ2, cosθ3, cosθ4以下同。由矩阵(1)可知:连杆变换 依赖于 四个参数和 ,其中只有一个参数是变化的,对于本文所研究的机器人,显然只有 为变量,其余三个参数为常量。
图3.1 STM32
3.3
该设计的主控制模块的硬件系统包括电源电路、复位电路、系统时钟电路以及JTAG调试电路四大组成部分。
3.3.1
在硬件电路的设计中,电源模块的设计是非常重要的,如果不能妥善处理,不但会使电路不能正常工作,严重的还可能烧毁电路。因此,在设计电源时务必要注意如下几点:
(1)交流输入和直流输出尽可能保持更大的距离;
关键词:四自由度机械臂,STM32,运动模型,脉冲宽度调制
第1章
1.1
机器人运动学描述了机器人关节与组成机器人的各刚体之间的运动关系。机器人在工作时,要通过空间中一系列的点组成的三维空间点域,这一系列空间点构成了机器人的工作范围,此工作范围可通过运动学正解求得。此外,根据机器人末端执行器的位置和姿态要求,通过运动学逆解求得各个关节转角,可以实现对机器人进行运动分析、离线编程、轨迹规划等工作。
机器人控制的目的就在于它能快速确定位置,这使得机器人的运动学正逆解问题变得更为重要。只有计算与运动学正逆解问题相关的变换关系在尽可能短时间内完成,才能达到快速准确的目的。在运动学方程正解过程中,只体现在矩阵相乘关系上,相对简单。
1.2
本文所研究的机器人由四个旋转关节和四个连杆组成,故为四自由度机器人,如图1.1所示。

基于STM的机械臂运动控制分析设计

基于STM的机械臂运动控制分析设计

机器人测控技术大作业课程设计课程设计名称:基于STM32的机械臂运动控制分析设计专业班级:自动1302学生姓名:张鹏涛学号:指导教师:曹毅课程设计时间:2016-4-28~2016-5-16指导教师意见:成绩:签名:年月日目录摘要 (II)第一章运动模型建立................................................................................................ I II1.1引言 ............................................................................................................... I II1.2机器人运动学模型的建立 ............................................................................. I II (IV)第二章机械臂控制系统的总体方案设计 (V)2.1机械臂的机械结构设计 (V)V错误!未定义书签。

2.2机械臂关节控制的总体方案 (VI)2.2.1机械臂控制器类型的确定 (VI)2.2.2机械臂控制系统结构 (VII)2.2.3关节控制系统的控制策略 (VII)第三章机械臂控制系统硬件设计 (VII)3.1机械臂控制系统概述 (VII)3.2微处理器选型 .............................................................................................. V III3.3主控制模块设计 .......................................................................................... V III错误!未定义书签。

ARM体系课程设计实验报告

ARM体系课程设计实验报告

目录1 绪论-------------------------------------------------------------12 课程设计的目标---------------------------------------------------23 课程设计的意义---------------------------------------------------24 需求分析---------------------------------------------------------35 概要设计---------------------------------------------------------35.1存储模块设计------------------------------------------------45.2音频解码模块设计--------------------------------------------45.3 液晶显示模块设计--------------------------------------------56 相关技术说明-----------------------------------------------------66.1 VS1003 的初始化--------------------------------------------66.2 MP3文件数据写入---------------------------------------------8 7详细设计---------------------------------------------------------107.1 SD模块-----------------------------------------------------107.2 VS1003模块-------------------------------------------------147.3 图形人机交互模块-------------------------------------------168.总结-------------------------------------------------------------16绪论随着消费类电子产业的蓬勃发展,越来越多的嵌入式电子产品走进了千家万户。

mearm机械臂实验报告

mearm机械臂实验报告

mearm机械臂实验报告篇一:摘要:本实验报告介绍了MeArm机械臂的设计、搭建和控制。

MeArm是一种简单且经济实惠的机械臂,适合初学者学习机械臂的基本原理和控制方法。

实验通过搭建MeArm机械臂的框架、安装电动机和控制器,并使用Arduino编程板控制机械臂的运动。

实验结果表明,MeArm机械臂能够准确地控制臂的运动,实现抓取和放置物体的功能。

本实验对机械臂的设计和控制提供了一个很好的实践平台。

引言:机械臂是一种能够模仿人体手臂和手的运动的机器装置,可以用于各种工业生产、医疗、科研和娱乐等领域。

随着科技的进步和成本的降低,机械臂的应用越来越广泛。

然而,传统的机械臂通常复杂、昂贵且难以控制,对于初学者来说学习起来较为困难。

MeArm机械臂是一种简单且经济实惠的机械臂,由英国工程师Ben Gray设计,旨在为初学者提供一个学习机械臂的入门平台。

MeArm机械臂由几个3D打印的零件组成,结构简单,易于搭建。

本实验旨在搭建MeArm机械臂并通过编程控制其运动,进一步探索机械臂的设计和控制。

方法:1. 搭建MeArm机械臂的框架: 使用3D打印的零件和螺丝将机械臂的框架组装起来。

2. 安装电动机和控制器: 将电动机安装到机械臂的各个关节上,并将控制器与电动机连接起来。

3. 连接Arduino编程板: 将Arduino编程板与控制器相连,以实现对机械臂的编程控制。

4. 编写控制程序: 使用Arduino编程语言编写控制程序,定义机械臂的运动轨迹和动作。

通过编程实现机械臂的抓取和放置功能。

5. 运行实验: 将编写好的控制程序上传到Arduino板上,通过控制程序控制机械臂的运动。

结果:实验结果表明,MeArm机械臂能够准确地控制臂的运动,实现抓取和放置物体的功能。

通过编程调整机械臂各个关节的角度和运动速度,可以实现不同的动作和抓取力度。

实验中使用的Arduino编程板提供了一个方便的编程环境,使得控制机械臂的编程相对简单。

基于STM32的机械臂运动控制分析设计

基于STM32的机械臂运动控制分析设计

机器人测控技术大作业课程设计课程设计名称:基于STM32的机械臂运动控制分析设计专业班级:自动1302学生姓名:张鹏涛学号: 2指导教师:曹毅课程设计时间: 2016-4-28~2016-5-16目录摘要 (III)第一章运动模型建立................................................................................................ I V1、1引言......................................................................................................... I V1、2机器人运动学模型的建立....................................................................... I V1、2、1运动学正解............................................................................... V I 第二章机械臂控制系统的总体方案设计.. (VII)2、1机械臂的机械结构设计 (VII)2、1、1臂部结构设计原则 (VII)2、1、2机械臂自由度的确定 (VIII)2、2机械臂关节控制的总体方案 (VIII)2、2、1机械臂控制器类型的确定 (VIII)2、2、2机械臂控制系统结构............................................................... I X2、2、3关节控制系统的控制策略....................................................... I X 第三章机械臂控制系统硬件设计.. (X)3、1机械臂控制系统概述 (X)3、2微处理器选型 (X)3、3主控制模块设计....................................................................................... X I3、3、1电源电路................................................................................... X I3、3、2复位电路 (XII)3、3、3时钟电路 (XII)3、3、4 JTAG调试电路 (XIII)3、4驱动模块设计 (XIII)3、5电源模块设计........................................................................................ X IV 第四章机械臂控制系统软件设计......................................................................... X VI4、1初始化模块设计.................................................................................... X VI4、1、1系统时钟控制........................................................................ X VI4、1、2 SysTick定时器 (XVII)4、1、3 TIM定时器 (XVIII)4、1、4通用输入输出接口GPIO ..................................................... X IX4、1、5超声波传感器模块................................................................ X IX 总结. (XX)参考文献................................................................................................................... X XI 附录A . (XXII)附录B (XXIII)设计要求:设计一个两连杆机械臂,具体参数自行设计,建立其运动学模型,然后在此基础上完成该机械臂两点间的路径规划,并给出仿真结果。

c++机械臂程序设计

c++机械臂程序设计

c++机械臂程序设计设计一个C++机械臂程序需要理解一些基本概念,包括:1.坐标系:机械臂可以在一个三维坐标系中移动。

每个关节都可以看作是在一个坐标系中的移动。

2.关节:关节是机械臂的移动部分。

每个关节都可以在一个坐标系中移动。

3.移动函数:这个函数负责计算关节的移动。

以下是一个简单的C++机械臂程序示例:cpp复制代码#include<iostream>#include<vector>class Joint {public:Joint(double initial_position) : position(initial_position) {}double move(double delta) {position += delta;return position;}private:double position;};class RobotArm {public:RobotArm(std::vector<Joint> joints) : joints(joints) {}void move_arm(std::vector<double> deltas) {for (size_t i = 0; i < deltas.size(); ++i) {joints[i].move(deltas[i]);}}private:std::vector<Joint> joints;};int main() {std::vector<Joint> joints = {Joint(0), Joint(0), Joint(0)}; // 三个关节,初始位置都是0RobotArm arm(joints);std::vector<double> deltas = {1, 2, 3}; // 每个关节移动1, 2, 3单位arm.move_arm(deltas);return0;}这个程序创建了一个有三个关节的机械臂,每个关节都可以在一个坐标系中移动。

基于单片机的机械臂控制系统设计与制作

基于单片机的机械臂控制系统设计与制作

目录课程设计题目及要求第一章绪论1.1 设计题目及要求1.2 设计内容第二章硬件设计2.1 硬件结构图2.2 各模块工作原理及设计2.2.1 控制模块2.2.2 显示模块2.2.3 按键模块2.2.4 舵机模块2.3 软件程序设计第三章硬件制作以及程序的下载调试3.1 电路板的制作3.2 元器件的焊接3.3 程序的下载与调试第四章总结4.1 课程设计体会4.2 奇瑞参观感受课程设计题目及要求题目:基于单片机的机械臂控制系统设计与制作实习内容:1,完成基于单片机的机械臂控制系统原理图和PCB的绘制,在基本要求的基础上自己可以作一定的扩展;2,利用热转印纸、三氯化铁腐蚀液等完成PCB板的制作;3,完成相应电路的焊接和调试;4,完成相应软件程序的编写;5,完成软、硬件的联调;6,交付实习报告。

实习要求:1,两人一组,自由搭配,但要遵循能力强弱搭配、男女搭配、考研和不考研的搭配;2,充分发挥主观能动性,遇到问题尽量自己解决,在基本要求基础上可自由发挥;3,第一次制作电路,电路不可追求复杂;4,注意安全!熨斗、烙铁。

第一章绪论单片机自20世纪70年代问世以来,以其极高的性价比,受到人们的重视和关注,应用广泛,发展迅速。

单片机集体积小、重量轻、抗干扰能力强、环境要求低、价格低廉、可靠性高、灵活性好、开发较为容易等众多优点,以广泛用于工业自动化控制、自动检测、智能仪器仪表、家用电器、电力电子、机电一体化设备等各个方面,无论在民间、商业、及军事领域单片机都发挥着十分重要的作用二十一世纪,随着机械化、自动化水平的不断提高,不仅减轻了劳动强度、提高生产率,而且把人类活动从危险、恶劣环境中替换出来。

而其中机器人技术,显示出极大的优越性;在宇宙探索、海洋开发以及军事应用上具有重要的实用价值。

大力发展机器人技术,一方面能让社会从劳动苦力型转换到福利休闲型,另一方面能极大的提高民众的幸福感。

在新时期的世界各国,随着应用日益广泛,机器人技术将不断发展并走向成熟。

华北电力大学科技学院arm课程设计92666895

华北电力大学科技学院arm课程设计92666895

课程设计(综合实验)报告( 2015-- 2016年度第一学期)名称:ARM课程设计题目:操作系统加采集电压显示院系:信息工程系班级13K2学号:31学生姓名:指导教师:张老师设计周数:2成绩:日期:2016年6月23日一、课程设计(综合实验)的目的与要求题目:根据上课已学内容和知识点设计:在带UC/OS-II操作时系统的基础上采集实验板上的电压值,显示电压。

要求:(1)用TFT、32*32液晶显示出采集的电压值的波形(需要显示有坐标轴、符合和对波形的说明)。

(2)液晶显示的同时要求ARM与PC有一条接口线,在PC上也显示采集的电压值(即串口显示电压值)。

(3)在液晶显示和PC显示的基础上同时要求采集的电压可以自动采集一次(即刷新一次)。

(4)当采集的电压值超过2V时,报警(即要有一个报警信号)。

二、设计(实验)正文1:设计思路(1)对于采集电压值可根据A/D转换使得电压值能在液晶上显示;用液晶显示采集电压的值可根据课内实验做的液晶显示实验来写;要在液晶上显示波形可以根据采集到的电压值与液晶屏的大小的采集点数的关系来写。

(2)在PC上显示可根据UART通信的知识点(异步串行通信)来进行设计。

(3)根据液晶屏的大小,判断是否到达最高数从而当采集完并显示出波形后可以自动再次刷新,重新采集并显示。

(4)报警可设计一个蜂鸣器,让其超过2V就报警(可利用课内做过的蜂鸣器实验来获得思路)。

(5)对于所有的操作系统,我是先在裸机下写程序,等到都测试好了再添加进来(分成四个任务)。

2:设计代码#include "lpc177x_8x.h"#include "includes.h"#include "../ADC/adc.h"#if ADC_DEBUG#include "../UART/uart.h"#endifextern volatile uint32_t ADCValue[ADC_NUM];extern volatile uint32_t ADCIntDone;#if ADC_DEBUGextern volatile uint32_t UART0Count;extern volatile uint8_t UART0Buffer[BUFSIZE];#endif#define BEEPON (LPC_GPIO3->CLR = 1ul << 30) //蜂鸣器工作#define BEEPOFF (LPC_GPIO3->SET = 1ul << 30) //蜂鸣器不工作/OS_EVENT *mbox;static OS_STK stkTaskA[256];static OS_STK stkTaskB[256];static OS_STK stkTaskC[256];static OS_STK stkTaskD[256];/********************************************************** ***********************************************宏定义*********************************************************** **********************************************/uint32_t x=0;//定义全局变量INT8U err;INT16U *pd;uint32_t ADCSum=0;uint32_t i;/********************************************************** ************************************************* 函数名称:myDelay** 函数描述:软件延时** 输入参数:ulTime** 返回值:无*********************************************************** **********************************************/void myDelay (uint32_t ulTime){uint32_t i;while (ulTime--) {for (i = 0; i < 19192; i++);}}void GPIOInit( void ){LPC_GPIO3->DIR |= 1<<30; //设置P3.30为输出LPC_GPIO3->SET |= 1<<30; //设置P3.30为高电平}/********************************************************** ************************************************* 函数名称:beepOperate** 函数描述:蜂鸣器工作** 输入参数:uiFrequency 蜂鸣器工作频率** 返回值:无*********************************************************** **********************************************/void beepOperate (void){BEEPON; // 蜂鸣器鸣叫OSTimeDly(OS_TICKS_PER_SEC / 2);BEEPOFF; // 蜂鸣器不鸣叫OSTimeDly(OS_TICKS_PER_SEC / 2);}void coordinate (void)//定义显示坐标及一些说明{lcd_Clear(LCD_WHITE); // 背景色为白色lcd_DrawHLine(0,320,230,LCD_BLACK);lcd_DrawLine(0,120,320,120,LCD_RED);lcd_DrawVLine(0,0,230,LCD_RED);GUI_SetColor(GREEN, RED);GUI_PutString8_8(10,5,"Y");GUI_SetColor(GREEN, RED);GUI_PutString8_8(310,230,"X");GUI_SetColor(BLUE, RED);GUI_PutString8_8(20,5,"bo xing tu");GUI_PutString8_8(150,230,"max voltage is 3V");}/*********************************************************************************************************** 函数名称:TaskD** 函数描述:任务D ,LCD显示** 输入参数:无** 返回值:无*********************************************************** **********************************************/void TaskD(void *pvData){pvData = pvData;while (1) {pd=(INT16U *)OSMboxPend(mbox,0,&err); // 等待消息//lcd_SetPixel(x,119-ADCSum/13,LCD_BLACK);也可以用这个函数GUI_Point(x,230-ADCSum*240/2500,BLACK); //描点函数,也就是坐标的开始(即从0,239位置为0位置),可以通过改变230-ADCSum*240/2500这个值来改变坐标的起始位置,也可以直接写230-ADCSum/10(自己定义,10表示2500/240,即满屏显示电压幅度值)x++;if(x==319){//描点函数自动刷新x=0;coordinate();}}}/********************************************************** ************************************************* 函数名称:TaskC** 函数描述:任务C ,蜂鸣器报警** 输入参数:无** 返回值:无*********************************************************** **********************************************/void TaskC(void *pvData){pvData = pvData;while (1) {pd=(INT16U *)OSMboxPend(mbox,0,&err); //等待消息if(ADCSum>=2000)//蜂鸣器报警条件{beepOperate();}}}/********************************************************** ************************************************* 函数名称:TaskB** 函数描述:任务B,串口显示** 输入参数:无** 返回值:无*********************************************************** **********************************************/void TaskB(void *pvData){unsigned int a=0;unsigned int b=0;unsigned int c=0;unsigned int d=0;pvData = pvData;while (1) {pd=(INT16U *)OSMboxPend(mbox,0,&err); //等待消息a=ADCSum/1000;//电压转换最高位b=(ADCSum-a*1000)/100; //电压转换第二位c=(ADCSum-a*1000-b*100)/10; //电压转换第三位d=ADCSum-a*1000-b*100-c*10; //电压转换第四位UART0Buffer[0] =(unsigned char)a+0x30;UART0Buffer[1] =(unsigned char)b+0x30;UART0Buffer[2] =(unsigned char)c+0x30;UART0Buffer[3] =(unsigned char)d+0x30;//转换成字符形式发送UART0Buffer[4] =(0x3D);UART0Buffer[5] =(a+48);UART0Buffer[6] =(0x2e);//小数点UART0Buffer[7] =(b+48);UART0Buffer[8] =(c+48);UART0Buffer[9] =(d+48);UART0Buffer[10] =(0x56);//“V”UART0Buffer[11] =(0xD);//回车UART0Buffer[12] =(0xA);//换行UARTSend( 0,(uint8_t*)UART0Buffer, 13);OSTimeDly(1);}}/********************************************************** ************************************************* 函数名称:TaskA** 函数描述:任务A , ADC采集电压** 输入参数:无** 返回值:无*********************************************************** **********************************************/void TaskA(void *pvData){pvData = pvData;mbox=OSMboxCreate(NULL); //创建消息邮箱,在优先级最高的任务创建while (1) {ADCSum=0;ADC_Start(0); //打开A/D转换while(ADC_GetStat(0)); //等待转换完成ADCSum=ADCRead(0); //读ADC通道0采集到的值ADCSum=(ADCSum*2500)/4096;//计算电压分辨率OSMboxPost(mbox,&ADCSum);//发送采集的电压OSTimeDly(1);}}/********************************************************** ************************************************* 函数名称:main** 函数描述:用户程序入口函数** 输入参数:无** 返回值:无*********************************************************** **********************************************/int main(void){ //一定要严格按照下面初始化顺序来做,液晶一定要在串口前面,否则很容易错SystemInit();LPC_SC->PCONP |= 0x00000800; //EMC上电GPIOInit(); // 通用I/O口初始化lcd_Init(); //初始化液晶#if ADC_DEBUG 如果定义了调试则编译串口初始化 UARTInit(0, 9600);#endifADCInit( ADC_CLK );coordinate ();//坐标轴初始化OSInit();OSTaskCreate(TaskA, (void *)0, &stkTaskA[sizeof(stkTaskA) / 4 - 1], 0);OSTaskCreate(TaskB, (void *)0, &stkTaskB[sizeof(stkTaskB) / 4 - 1], 1);OSTaskCreate(TaskC, (void *)0, &stkTaskC[sizeof(stkTaskC) / 4 - 1], 2);OSTaskCreate(TaskD, (void *)0, &stkTaskD[sizeof(stkTaskD) / 4 - 1], 3);OSStart();}说明:这里只显示主函数的内容,其余内容因为代码太多,在附录里截图显示,那些是根据课内实验移植的一些调用函数,在做的过程中经常出现例如“头文件找不到、目录不对应、大小太小等问题”,都是在这个移植的时候没添好造成。

机械臂控制代码

机械臂控制代码

##include <Servo.h> #include <math.h>#include <stdlib.h>#include "Wire.h"#include "WiiChuck.h"Servo servo1;// create servo object to control a servoServo servo2;Servo servo3;Servo servo4; // a maximum of eight servo objects can be createdServo servo5;Servo servo6;WiiChuck wii = WiiChuck();int pos1,pos2,pos3,pos4,pos5,pos6,x,y,z,c; // variable to store theservo positionvoid setup()// attaches the servo on pin 9 to the servo object servo1.attach(8);servo2.attach(9);servo3.attach(10);servo4.attach(11);servo5.attach(12);servo6.attach(13);pos1 = 60;pos2 = 50;pos3 = 100;pos4 =100;pos5 = 90;pos6 = 90;servo1.write(pos1); servo2.write(pos2); servo3.write(pos3); servo4.write(pos4); servo5.write(pos5); servo6.write(pos6); wii.initWithPower();void loop()if(true == wii.read() ){// 读取手柄值x=wii.getJoyAxisX(); y=wii.getJoyAxisY();c=wii.getButtonC(); z=wii.getButtonZ();}if(x==255&& y>120 && y<140&& c == 0 && z==1)//号舵机{ pos1 = pos1+10;delay (40);if(pos1>160){servo1.write(pos1);}}else if(x==255 && y>120 && y<140 && z==0 && c==1 ) { pos1 = pos1-10;servo1.write(pos1);delay(40);if(pos1<20)servo1.write(pos1);}}else if(x>220&& y==0&& c == 0 && z==1) //2号舵机{pos2 = pos2+10;servo2.write(pos2);delay (40);if(pos2>160){pos2=160;servo2.write(pos2);else if(x>220 && y==0&& z==0 && c==1 ) {pos2 = pos2-10;servo2.write(pos2);delay(40);if(pos2<90){pos2=90;servo2.write(pos2);}else if(x>110&& x<140&& y==0&& c == 0 && z==1) //3号舵机{pos3 = pos3+10; servo3.write(pos3);delay (40);if(pos3>160){pos3=160;servo3.write(pos3);} else if(x>110&& x<140&& y==0&& z==0 && c==1 )pos3 = pos3-10;servo3.write(pos3);delay(40);if(pos3<20){pos3=20;servo3.write(pos3);}}else if(x==0&& y==0&& c == 0 && z==1) //4号舵机{servo4.write(pos4);delay (40);if(pos4>160){pos4=160;servo4.write(pos4);}}else if(x==0 && y==0&& z==0 && c==1 ) {servo4.write(pos4);delay(40);if(pos4<20){pos4=20;servo4.write(pos4);}}else if(x==0&& y==128&& c == 0 && z==1) //5号舵机{servo5.write(pos5);pos5 = pos5+10;delay (40);if(pos5>170) {}}else if(x==0 && y==128&& z==0 && c==1 ) {servo5.write(pos5);pos5 = pos5-10;delay(40);}}else if(x==0 && y>240&& c == 0 && z==1) //6号舵机{servo6.write(pos6);pos6 = pos6+10;delay (40);if(pos6>120){}else if(x==0 && y>240&& z==0 && c==1 ) {servo6.write(pos6);pos6 = pos6-10;delay(40);if(pos6<45){pos6=41;}。

机械臂操控程序代码

机械臂操控程序代码

#include <Servo.h> //调用一些库文件#include <TimedAction.h>#include <SimpleTimer.h>#include <Wire.h>#include <LiquidCrystal_I2C.h>//定义舵机位置名称,并编号。

const int base = 0;const int shoulder = 1;const int elbow = 2;const int wristflex = 3;const int wristrot = 4;const int gripper = 5;const int stdDelay = 20; //舵机运动延时(单位ms)const int maxServos = 6; //舵机的数量const int centerPos = 90; //舵机中位位置unsigned long key_millis = 0;unsigned long button_millis = 0;int keyDelay = 100; //定义延时时间int buttonDelay = 50; //定义按键延时int thisServo = base; //定义起始电机typedef struct{ //数组框架结构byte neutral; //中位角度byte minPos; //最小角度byte maxPos; //最大角度byte delaySpeed; //延时时间byte curPos; //舵机当前角度} ServoPos; //结构体名称ServoPos servosPos[] = { //对舵机限位{ 90, 180, 10, stdDelay, 0 }, //中位90,最小角度180,最大角度10,范围0~180度。

{ 90, 180, 10, stdDelay, 0 },{ 90, 180, 60, stdDelay, 0 },{ 90, 170, 50, stdDelay, 0 },{ 90, 180, 10, 10, 0 },{ 90, 125, 55, 5, 0 }};byte serv = 90;int counter = 0;int curServo = 0;int sMove[] = {0, 90, 0};int sAttach[] = {0, 0};LiquidCrystal_I2C lcd(0x27,20,4); //0x27 D7~D0端口开关设置0x表示十六进制27转换成16进制数是00100111 1代表开,0代表关, 20列,4行,行号从零算起,第一行行号0,第二行行号1.Servo servos[maxServos];int destServoPos[maxServos];int currentServoPos[maxServos];TimedAction servoMove[maxServos] = TimedAction(100, doServoFunc); // 延时,延时时间为声明时间。

基于STM32的机械臂运动控制分析设计说明

基于STM32的机械臂运动控制分析设计说明

机器人测控技术大作业课程设计课程设计名称:基于STM32的机械臂运动控制分析设计专业班级:自动1302学生姓名:张鹏涛学号:201323020219指导教师:曹毅课程设计时间:2016-4-28~2016-5-16目录摘要 (IV)第一章运动模型建立 (V)1.1引言 (V)1.2机器人运动学模型的建立 (V)1.2.1运动学正解 ............................................................... V II 第二章机械臂控制系统的总体方案设计 ............................................... V III2.1机械臂的机械结构设计 ......................................................... V III2.1.1臂部结构设计原则..................................................... V III2.1.2机械臂自由度的确定.................................................... I X2.2机械臂关节控制的总体方案 (X)2.2.1机械臂控制器类型的确定 (X)2.2.2机械臂控制系统结构.................................................... X I2.2.3关节控制系统的控制策略 ............................................. X I 第三章机械臂控制系统硬件设计.......................................................... X II3.1机械臂控制系统概述 ............................................................. X II3.2微处理器选型...................................................................... X III3.3主控制模块设计................................................................... X III3.3.1电源电路 ................................................................. X IV3.3.2复位电路 ................................................................. X IV3.3.3时钟电路 ................................................................. X IV3.3.4 JTAG调试电路......................................................... X V3.4驱动模块设计....................................................................... X V3.5电源模块设计..................................................................... X VII 第四章机械臂控制系统软件设计 (XVIII)4.1初始化模块设计 (XVIII)4.1.1系统时钟控制 (XVIII)4.1.2 SysTick定时器......................................................... X X4.1.3 TIM定时器.............................................................. X XI4.1.4通用输入输出接口GPIO (XXII)4.1.5超声波传感器模块 (XXII)总结 (XXIV)参考文献 (XXV)附录A (XXVI)附录B (XXVII)设计要求:设计一个两连杆机械臂,具体参数自行设计,建立其运动学模型,然后在此基础上完成该机械臂两点间的路径规划,并给出仿真结果。

mearm机械臂实验报告

mearm机械臂实验报告

mearm机械臂实验报告MeArm机械臂实验报告引言:机械臂是一种能够模拟人类手臂运动的机械设备,广泛应用于工业生产、医疗手术等领域。

本实验以MeArm机械臂为研究对象,探究其基本动作控制原理和应用场景。

一、实验目的:1.了解机械臂的基本结构和工作原理;2.学习控制机械臂进行基本动作,如抓取、放置等;3.探究机械臂在实际应用中的潜力和局限性。

二、实验材料与方法:1.实验材料:一台MeArm机械臂、Arduino控制板、舵机等。

2.实验方法:1)搭建机械臂:按照说明书和指导视频,将各组件安装到MeArm机械臂上,确保其稳定性。

2)连接电路:将机械臂的舵机通过线缆连接到Arduino控制板上,确保电路连接正确。

3)编程控制:使用Arduino IDE软件编写控制程序,实现机械臂的基本动作,如旋转、抬起、放下等。

4)测试调试:将编写好的程序烧录到Arduino控制板上,通过调试和测试,验证机械臂的动作是否符合预期。

三、实验结果与分析:经过多次调试和测试,我们成功实现了MeArm机械臂的基本动作控制。

机械臂能够准确地旋转、抬起、放下等,且动作相对平稳。

实验结果符合预期,验证了机械臂的基本工作原理。

四、实验讨论:MeArm机械臂具有良好的灵活性和可控性,可广泛应用于模拟人工作业、进行医疗手术等领域。

然而,由于其结构和功能的限制,目前在承重能力和精确度等方面仍存在一定的局限性。

五、实验总结:通过本次实验,我们深入了解了MeArm机械臂的基本结构和工作原理。

通过编写控制程序,我们成功实现了机械臂的基本动作控制。

我们也发现了机械臂在实际应用中的一些潜力和局限性,这对我们进一步的研究和开发具有重要指导意义。

六:1. Magician Robot MeArm V1.6 Arduino版搭建指导手册;2. MeArm机械臂控制程序编写教程。

机械臂控制代码

机械臂控制代码

机械臂控制代码集团标准化小组:[VVOPPT-JOPP28-JPPTL98-LOPPNN]##include <Servo.h>#include <math.h>#include <stdlib.h>#include "Wire.h"#include "WiiChuck.h"Servo servo1;// create servo object to control a servoServo servo2;Servo servo3;Servo servo4; // a maximum of eight servo objects can be created Servo servo5;Servo servo6;WiiChuck wii = WiiChuck();int pos1,pos2,pos3,pos4,pos5,pos6,x,y,z,c; // variable to store the servo positionvoid setup(){// attaches the servo on pin 9 to the servo object servo1.attach(8);servo2.attach(9);servo3.attach(10);servo4.attach(11);servo5.attach(12);servo6.attach(13);pos1 = 60;pos2 = 50;pos3 = 100;pos4 =100;pos5 = 90;pos6 = 90;servo1.write(pos1); servo2.write(pos2); servo3.write(pos3); servo4.write(pos4); servo5.write(pos5); servo6.write(pos6);wii.initWithPower(); }void loop(){if(true == wii.read() ){//读取手柄值x=wii.getJoyAxisX();y=wii.getJoyAxisY();c=wii.getButtonC();z=wii.getButtonZ();}if(x==255&& y>120 && y<140&& c == 0 && z==1)//一号舵机 { pos1 = pos1+10;servo1.write(pos1);delay (40);if(pos1>160){pos1=160;servo1.write(pos1);}}else if(x==255 && y>120 && y<140 && z==0 && c==1 ) { pos1 = pos1-10;servo1.write(pos1);delay(40);if(pos1<20){pos1=20;servo1.write(pos1);}}else if(x>220&& y==0&& c == 0 && z==1) //2号舵机 {pos2 = pos2+10;servo2.write(pos2);delay (40);if(pos2>160){pos2=160;servo2.write(pos2);}}else if(x>220 && y==0&& z==0 && c==1 ) {pos2 = pos2-10;servo2.write(pos2);delay(40);if(pos2<90){pos2=90;servo2.write(pos2);}}else if(x>110&& x<140&& y==0&& c == 0 && z==1) //3号舵机 {pos3 = pos3+10;servo3.write(pos3);delay (40);if(pos3>160){pos3=160;servo3.write(pos3);}}else if(x>110&& x<140&& y==0&& z==0 && c==1 ){pos3 = pos3-10;servo3.write(pos3);delay(40);if(pos3<20){pos3=20;servo3.write(pos3);}}else if(x==0&& y==0&& c == 0 && z==1) //4号舵机 {pos4 = pos4+10;delay (40);if(pos4>160){pos4=160;servo4.write(pos4);}}else if(x==0 && y==0&& z==0 && c==1 ) {pos4 = pos4-10;delay(40);if(pos4<20){pos4=20;servo4.write(pos4);}}else if(x==0&& y==128&& c == 0 && z==1) //5号舵机 {servo5.write(pos5);pos5 = pos5+10;delay (40);if(pos5>170){pos5=160;}}else if(x==0 && y==128&& z==0 && c==1 ) {servo5.write(pos5);pos5 = pos5-10;delay(40);if(pos5<20)pos5=30;}}else if(x==0 && y>240&& c == 0 && z==1) //6号舵机 {servo6.write(pos6);pos6 = pos6+10;delay (40);if(pos6>120){pos6=119;}}else if(x==0 && y>240&& z==0 && c==1 ) {servo6.write(pos6);pos6 = pos6-10;delay(40);if(pos6<45){pos6=41;}}。

机器人大臂的参数化设计代码

机器人大臂的参数化设计代码

机器人大臂的参数化设计代码机器人大臂的参数化设计代码可以根据具体的机器人大臂结构和运动要求进行编写。

以下是一个示例代码,用于实现一个具有三个旋转关节和一个伸缩关节的机器人大臂的参数化设计:```pythonimport mathclass RobotArm:def __init__(self, length1, length2, length3):self.length1 = length1self.length2 = length2self.length3 = length3def forward_kinematics(self, theta1, theta2, theta3):x = self.length1 * math.cos(theta1) + self.length2 * math.cos(theta1 + theta2) + self.length3 * math.cos(theta1 + theta2 + theta3)y = self.length1 * math.sin(theta1) + self.length2 * math.sin(theta1 + theta2) + self.length3 * math.sin(theta1 + theta2 + theta3)return x, ydef inverse_kinematics(self, x, y):theta3 = math.acos((x**2 + y**2 - self.length1**2 - self.length2**2 -self.length3**2) / (2 * self.length2 * self.length3))theta2 = math.acos((x**2 + y**2 - self.length1**2 - self.length2**2) / (2 * self.length1 * self.length2)) - math.atan2(self.length3 * math.sin(theta3),self.length2 + self.length3 * math.cos(theta3))theta1 = math.atan2(y, x) - math.atan2(self.length2 * math.sin(theta2), self.length1 + self.length2 * math.cos(theta2))return theta1, theta2, theta3# 示例使用arm = RobotArm(1, 1, 1) # 设置机器人大臂的长度x, y = arm.forward_kinematics(math.pi/4, math.pi/4, math.pi/4) # 正运动学theta1, theta2, theta3 = arm.inverse_kinematics(x, y) # 逆运动学print("Forward kinematics result: x={}, y={}".format(x, y))print("Inverse kinematics result: theta1={}, theta2={}, theta3={}".format(theta1, theta2, theta3))```在上述代码中,`RobotArm` 类表示机器人大臂,构造函数 `__init__` 接受三个参数 `length1`、`length2` 和 `length3`,分别表示大臂的三个连杆的长度。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

成绩评定表课程设计任务书目录一、题目分析2二、总体设计 (2)三、详细设计6四、实现代码8五、相关图片20六、结束语21七、参考文献 (22)1、实验题目分析1.1 问题描述结合实时时钟,IIC(控制小键盘和数码管等)来做具备定期功能的实时时钟。

1.2功能分析至少完成以下功能:(1)能显示每秒的时刻(2)按下功能键能切换显示日期(3)能设置定时闹钟,定时到产生某种输出(4)可以扩展考虑加入外部中断,如停止闹钟功能等。

1.3 开发平台及工具介绍实验器材有:CITK2410开发板,JTAG连接线,RS-232直通连接线RVDS集成开发环境,超级终端工具,2、总体设计2.1 实验基本原理IIC总线:IIC总线的器件分为主器件和从器件。

主器件的功能是启动在总线上传送数据,并产生时钟脉冲,以允许与被寻址的器件进行数据传送。

SCL线为高电平期间,SDA线由高电平向低电平的变化表示起始信号;SCL线为高电平期间,SDA线由低电平向高电平的变化表示终止信号。

I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。

超始和停止信号图数据传送时序图IIC总线(IICSDA、IICSCL)经过VDD33的上拉后,进入ZLG7290数码管:实验使用的数码管是广州周立公司单片机发展有限公司自行设计的一款数码管显示驱动及键盘扫描管理芯片。

下面是介绍该数码管的特点还有电路图:1 I2C 串行接口提供键盘中断信号方便与处理器接口2 可驱动8 位共阴数码管或64 只独立LED 和64 个按键3 可控扫描位数可控任一数码管闪烁4 提供数据译码和循环移位段寻址等控制5 8 个功能键可检测任一键的连击次数6 无需外接元件即直接驱LED 可扩展驱动电流和驱动电压7 提供工业级器件多种封装形式PDIP24 SO24采用24 引脚封装引脚图如图所示其引脚功能分述如下:实时时钟(Real Time Clock):2410提供了一个实时时钟,该时钟使用独立的一路1.8V 供电,保证主电源切断时能正常维持RTC工作。

2410的RTC支持两个中断:Time Tick(固定在一个频率内发出的时钟中断)和Alarm中断(在某个时刻产生闹铃中断)。

利用这两个中断可以设置每一秒中断一次显示变化时间,用Alarm中断实现闹钟功能。

以下为S3C2410内部RTC模块结构图:2.2 实验电路图ZLG7290功能电路图:IIC总线接口电路图:2.3 实验主要步骤1.初始化配置(各种寄存器)。

2.编写各种相关的中断程序。

3.主函数调用这几个中断程序。

4.编译程序,在zoc串口工具进行测试。

5.使用zoc下载和调试。

3、详细设计3.1 具体实验过程和内容(1)实现实时时钟功能设置rRTCCON、rTICNT、rRTCALM寄存器TICNT[6:0]=127;可以设置rTICNT=(1<<7)|(127)实现每秒中断一次。

可以设置闹铃寄存器,例如每秒的第几秒中断一次,实现定时闹钟的功能。

要设置初始化当前时间。

这里还包括编写Time Tick中断和Alarm中断的中断服务程序。

(2)初始化IIC总线编写一个IIC的操作库。

包括发送和接受功能。

编写可以向ZLG7290发出指令的函数。

(3)编写键盘中断处理程序通过键盘中断,实现数码管显示日期和时间的切换,还有停止。

(4)使用RVDS集成开发环境编译调试程序(5)使用ZOV软件测试3.2 程序流程图3.3 实验和程序问题分析这次试验实际上是融合了三个实验的要求,要实验实时时钟的功能,包括显示当前时间,还有设置闹钟,主要使用到2410的RTC的两个中断:Time Tick和Alarm中断。

而要实现在数码管上显示当前时间,并且按键盘时实现时间与日期的切换,需要用到数码管和IIC总线的知识。

而实现的难处在于如何把几个内容融合在一起并且实现所需的功能,这也是实验要求做的。

4、实现程序#include "2410addr.h"#include "target.h"#include "2410lib.h"#include "iic.h"void iic_init(void){rGPEUP |= 0xc000; // 禁止上拉rGPECON |= 0xa00000; // 设置GPIO 为IIC 总线// Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16//rIICCON = (1<<7) | (0<<6) | (1<<5) | (0xf);//rIICADD = 0x10; // 2410 从设备地址//rIICSTAT = 0x10; // IIC 总线输出有效}void iic_send_master(unsigned char *buf, int size){// IIC 总线Master 模式数据发送函数int fc1;// ZLG7290要求IIC传输速率不大于32Kbit/s,即Tx clock不大于32KHz// 设置IICCLK=PCLK/512 Tx clock=IICCLK/4,则// 如果FLCK=200MHz,则最大Tx clock = 24kHz,处于可接受范围// 初始化IICrIICCON = (1<<7) | (1<<6) | (1<<5) | (0<<4) | (3<<0);rIICSTAT = 0xD0;// 发送从设备地址rIICDS = *(buf++) & 0xFE;size--;rIICSTAT = 0xF0;while(!(rIICCON & IIC_PENDING_BIT));while(size>0){// 发送buf 数据rIICDS=*(buf++);size--;// 等待IICSCL 到达触发沿for(fc1=0;fc1<10;fc1++){;}if(size!=0){rIICCON = rIICCON & IIC_PENDING_MASK;}else{// 最后发送不需要应答rIICCON = rIICCON & IIC_PENDING_MASK & IIC_ACK_MASK;}// 等待发送完成while(!(rIICCON & IIC_PENDING_BIT));}// 停止IICrIICSTAT = 0xD0;rIICCON = rIICCON & IIC_PENDING_MASK;Delay(10);}void iic_receive_master(unsigned char *cmdbuf, int cmdsize, unsigned char *buf, int size){// IIC 总线Master 模式数据接收函数int fc1;// ZLG7290要求IIC传输速率不大于32Kbit/s,即Tx clock不大于32KHz // 设置IICCLK=PCLK/512 Tx clock=IICCLK/4,则// 如果FLCK=200MHz,则最大Tx clock = 24kHz,处于可接受范围int slave_addr;rIICCON = (1<<7) | (1<<6) | (1<<5) | (0<<4) | (3<<0);rIICSTAT = 0xD0;// 发送从设备地址slave_addr = *(cmdbuf++);cmdsize--;rIICDS = slave_addr & 0xFE;rIICSTAT = 0xF0;while(!(rIICCON & IIC_PENDING_BIT));while(cmdsize>0){// 发送buf 数据rIICDS=*(cmdbuf++);cmdsize--;// 等待IICSCL 到达触发沿for(fc1=0;fc1<10;fc1++){;}rIICCON = rIICCON & IIC_PENDING_MASK;// 等待发送完成while(!(rIICCON & IIC_PENDING_BIT)){;}}rIICDS = slave_addr | 0x01;rIICSTAT = 0xB0;while(size>0){if(size>1){rIICCON = rIICCON & IIC_PENDING_MASK;}else{// 最后接收不需要应答rIICCON = rIICCON & IIC_PENDING_MASK & IIC_ACK_MASK;}// 等待接收完成while(!(rIICCON & IIC_PENDING_BIT)){;}// 取出数据*(buf++) = rIICDS;size--;}// 停止IICrIICSTAT = 0x90;rIICCON = rIICCON & IIC_PENDING_MASK;Delay(10);}void __irq isr_keyboard(void){unsigned char cmdbuf[4];unsigned char key[5];// 关闭1号外中断rINTMSK = rINTMSK | BIT_EINT1;// 清除中断位rINTPND = BIT_EINT1;rSRCPND = BIT_EINT1;// 等待IIC 总线空闲while(rIICCON & IIC_PENDING_BIT){;}// 读取键值cmdbuf[0]=IIC_ADDR_ZLG7290;cmdbuf[1]=IIC_ADDR_ZLG7290_KEY;iic_receive_master(cmdbuf,2,key,4);// 判断是否有效按键if(key[1] == 0x01){// 数字左移2位for(fc1=0;fc1<4;fc1++){cmdbuf[1]=IIC_ADDR_ZLG7290_DPM0+date[fc1];cmdbuf[2]=0xff;iic_send_master(cmdbuf,3);}}else if(key[1] == 0x02){// 数字左移2位for(fc1=0;fc1<4;fc1++){cmdbuf[1]=IIC_ADDR_ZLG7290_DPM0+time[fc1];cmdbuf[2]=0xff;iic_send_master(cmdbuf,3);}}// 打开1号外中断rINTMSK = rINTMSK & ~BIT_EINT1;}void __irq isr_alarm(void){rINTMSK = rINTMSK | BIT_RTC;Uart_Printf("This is a alarm interrupt occur at the 30th second every minute.\n");// 清除中断位rINTPND = BIT_RTC;rSRCPND = BIT_RTC;rINTMSK = rINTMSK & ~BIT_RTC;}void __irq isr_tick(void){public int tmpintmsk;public int year;public int month;public int day;public int date;public int hour;public int minute;public int second;public int readtime=0;public int date[3];public int time[3];// 在实际应用中,由于“嘀嗒”中断实时性要求较高,中断时间固定,而且处理时间不长// 所以需要屏蔽所有中断,并且清除中断位操作必须尽快执行// 屏蔽所有中断tmpintmsk = rINTMSK;rINTMSK = BIT_ALLMSK;// 清除中断位rINTPND = BIT_TICK;rSRCPND = BIT_TICK;// “嘀嗒”中断服务处理// 读时间// 由于读时间时可能跨越了年、月、日、时、分界限// 例如:本来时间是2000年12月31日23时59分59秒,但刚好读取到hour的时候,到达了2001年的0秒// 从而造成了读出的时间前后不一致性// 所以,如果遇到了秒读取是0的话,则需要再读一次。

相关文档
最新文档