西北农林科技大学智能小车实习总结(完整版) - 图文

更新时间:2024-04-13 00:31:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

《机电一体化综合训练Ⅱ》总结

姓 名 学 号 实 验 组 指导教师

西北农林科技大学机械与电子工程学院

201 年 月

目录

1.舵机小车总结...........................................................................................................................- 1 -

1.1 舵机小车任务...............................................................................................................- 1 - 1.2 舵机小车控制原理 ......................................................................................................- 1 -

1.2.1舵机小车基本控制原理.....................................................................................- 1 - 1.2.2舵机小车的触觉导航控制原理.........................................................................- 2 - 1.2.3舵机小车的光敏电阻导航控制原理.................................................................- 2 - 1.2.4舵机小车的红外导航控制原理.........................................................................- 3 - 1.3舵机小车具体完成任务与改进....................................................................................- 3 -

1.3.1舵机小车的“U”字形行走任务实现 ..............................................................- 3 - 1.3.2舵机小车的触觉导航任务实现.........................................................................- 5 - 1.3.3舵机小车的光敏电阻导航任务实现.................................................................- 8 - 1.3.4舵机小车的红外导航任务实现(避让悬崖).................................................- 9 - 1.3.5舵机小车的方案改进.......................................................................................- 11 - 1.4舵机小车小结..............................................................................................................- 11 - 2.直流电机小车总结.................................................................................................................- 12 -

2.1直流电机小车任务......................................................................................................- 12 - 2.2 直流电机小车控制原理 ............................................................................................- 12 -

2.2.1直流电机小车基本运动控制原理...................................................................- 12 - 2.2.2直流电机小车测速控制原理...........................................................................- 13 - 2.2.3直流电机小车四路寻迹控制原理...................................................................- 14 - 2.2.4直流电机小车避障控制原理...........................................................................- 14 - 2.2.5直流电机小车红外遥控控制原理...................................................................- 15 - 2.3 直流电机小车具体完成任务与改进.........................................................................- 16 -

2.3.1直流电机小车的硬件组装任务实现...............................................................- 16 - 2.3.2直流电机小车基本运动任务实现...................................................................- 17 - 2.3.3直流电机小车测速任务实现...........................................................................- 18 - 2.3.4直流电机小车四路寻迹任务实现...................................................................- 18 - 2.3.5直流电机小车避障任务实现...........................................................................- 19 - 2.3.6直流电机小车红外遥控任务实现...................................................................- 20 - 2.3.7直流电机小车功能集成任务实现(改进)...................................................- 23 - 2.4直流小车小结 ............................................................................................................- 28 -

2.4.1思考题 ............................................................................................................- 28 -

2.4.2心得体会 .....................................................................................................- 29 -

3.步进电机小车总结 .............................................................................................................- 30 -

3.1 步进电机小车任务 .....................................................................................................- 30 - 3.2步进电机小车控制原理 .............................................................................................- 30 -

3.2.1步进电机小车基本控制原理

.....................................................................- 30 -

3.2.2步进电机小车的“T”字形行走控制原理 .....................................................- 32 - 3.2.3步进电机小车的遥控控制原理 .....................................................................- 33 - 3.2.4步进电机小车的寻迹控制原理 .....................................................................- 34 - 3.2.5步进电机小车的避障控制原理 .....................................................................- 36 - 3.3 步进电机小车具体完成任务与改进 .....................................................................- 37 -

3.3.1步进电机小车的硬件组装实现 .....................................................................- 37 - 3.3.2步进电机小车的“T”字形行走任务实现.....................................................- 38 - 3.3.3步进电机小车的遥控控制任务实现 .............................................................- 40 - 3.3.4步进电机小车的寻迹控制任务实现 .............................................................- 42 - 3.3.5步进电机小车的避障控制任务实现 .............................................................- 44 - 3.3.6步进电机小车的任务集成控制实现(改进) .............................................- 47 - 3.4步进小车小结 .............................................................................................................- 51 -

3.4.1思考题 .............................................................................................................- 51 - 3.4.2心得体会

.....................................................................................................- 52 -

4.机电系统创新设计 .............................................................................................................- 53 -

4.1创新题目简介 .............................................................................................................- 53 - 4.2解决的问题 4.3采用的方法

.............................................................................................................- 53 - .............................................................................................................- 53 -

4.4设计原理 .....................................................................................................................- 54 - 4.5机械图与电路图

.....................................................................................................- 55 -

4.6创新设计小结 .............................................................................................................- 56 - 5.个人体会与总结 .....................................................................................................................- 56 -

5.1有关基础知识认知 .....................................................................................................- 56 - 5.2有关知识实践结合 .....................................................................................................- 57 - 5.3有关拓展创新能力 .....................................................................................................- 57 - 5.4有关团队沟通合作.......................................................................................................- 57 - 5.5有关解决发现问题 .....................................................................................................- 58 -

《机电一体化综合训练Ⅱ》实习总结

1.舵机小车总结

1.1 舵机小车任务

1.1.1完成舵机小车的硬件组装;

1.1.2通过软件和硬件的结合,程序的编写,实现舵机小车的前进、后退,并可以实现左转弯、右转弯,并在允许范围内可调节速度; 1.1.3实现舵机小车的“U”字形行走;

1.1.4基于单片机的步进小车系统,就是在单片机最小系统的基础上,增加触觉导航模块,光敏电阻导航模块,红外导航模块使单片机正常驱动步进电机,根据传感器模块的反馈不断修正,实现带动小车执行蔽障、寻迹、触觉导航、趋光行走的任务。

1.2 舵机小车控制原理

1.2.1舵机小车基本控制原理

舵机小车的主控制板或接收机发出的控制信息给舵机,电路板上的IC判断转动方向,再驱动直流电机开始转动,通过减速齿轮将动力传至输出轴。同时,位置检测器送回电机转动位置的反馈信号,判断电机的转动角度是否已经达到既定的位置。位置检测器其实就是可变的电位器,当舵机转动时电阻值也随之改变,检测电阻值的大小,便可获得电机转动的角度。此处以180°和360°旋转角度舵机的控制原理为例。

舵机是一个微型的伺服控制系统,180度旋转角的舵机控制原理可以用图1-1所示,控制电路接收信号源的控制脉冲,并驱动电机转动;齿轮组将电机的速度呈大倍数缩小,并将电机的输出扭矩放大响应倍数,然后输出;电位器和齿轮组的末级一起转动,测量舵机转动角度;电路板检测并根据电位器判断舵机转动角度,然后控制舵机转动到目标角度或保持在目标角度。

图1-1 舵机控制原理

本次实习的舵机小车,其控制方法为:

- 1 -

①舵机顺时针全速:控制器连续给舵机发送1.3ms的脉冲,间隔20ms,舵

机将全速顺时针旋转,全速的范围是从50到60RPM。

②舵机逆时针旋转:控制器连续给舵机发送1.7ms的脉冲,间隔20ms,舵

机将全速逆时针旋转。全速范围是50到60RPM。

③舵机不动:控制器连续给舵机发送1500us的脉冲,间隔20ms,舵机将

静止不动。

1.2.2舵机小车的触觉导航控制原理

每条胡须都是一个常开开关。连接到每个胡须电路的I/O引脚监视着10k

上拉电阻上的电压变化。当胡须没有被触动时,连接胡须的I/O管脚的电压是5V,当胡须被触动,I/O短接到地,所以I/O管脚的电压是0V。微控制器启动或者复位时,所有的I/O插脚缺省为输入。如果I/O脚上的电压为5V(胡须没有被触动),则其相应的寄存器中的相应位存储1;如果电压为0V(胡须被触动),则存储0。

单片机可以读入相应的数据,进行分析、处理、控制机器人运动。在进行

胡须测试之前需将串口电缆连接好,需用到调试终端以显示左右胡须状态,调用相关程序进行测试。触须导航的电路原理如图1-2所示。

图1-2 触须导航电路原理

1.2.3舵机小车的光敏电阻导航控制原理

舵机小车的光敏电阻,用来探测可见光,并且可以检测不同的光亮度水平。使小车识别周围环境的明暗,报告探测到的明暗水平,并且可以寻找手电筒光束或从门口射进黑暗的屋子的光这样的光源。图1-3是光敏探测电路。

任何大于1.5V的电压,都会使单片机的I/O口的输入寄存器的值为1,任何小于1.5V的电压都会使其寄存器的值为0.

如果光特别亮,光敏电阻的阻值非常小,在完全黑暗的环境中,电阻值接近50千欧。在带荧光天花板,光线好的屋子里,光敏电阻的阻值可能小到1千欧

- 2 -

(光线没有任何遮挡)或大到25千欧(阴影遮住光敏电阻)。图1-4是其等效电路,由于光敏电阻的阻值随光照强弱而改变,Vo点的输出电压也随之改变:当R增大时Vo会减小;当R减小时Vo会增大。Vo正是单片机I/O的输入电压。如果输入电路接到P1.5,当Vo的值大于1.5V时,P1寄存器的第6位为1,当Vo的值小于1.5V时,P1寄存器的第6位为0.

图1-3 光敏探测电路 图1-4 等效电路 1.2.4舵机小车的红外导航控制原理

舵机小车使用红外传感器探测物体是通过红外线二极管LED发射红外光,在有障碍的情况下,红外线从物体反射折回,红外检测器检测到从物体反射回的红外线后传送给主控制器,主控制器据此判断,舵机作出相应的动作来实现的。

1.3舵机小车具体完成任务与改进

1.3.1舵机小车的“U”字形行走任务实现 ①舵机小车的“U”字形行走程序:

#include #include int i;

int P1_5state(void) { }

int P2_3state(void) { }

- 3 -

void Forward(void) { }

void Left_Turn(void

P1_1=1;

delay_nus(1700); P1_1=0; P1_0=1;

delay_nus(1300); P1_0=0; delay_nms(20);

return (P1&0x20)?1:0;

return (P2&0x08)?1:0;

) { for(i=1;i<=26;i++) { P1_1=1;

delay_nus(1300); P1_1=0; P1_0=1;

delay_nus(1300); P1_0=0; delay_nms(20);

}

}

void Right_Turn(void) { for(i=1;i<=26;i++) { P1_1=1;

delay_nus(1700); P1_1=0; P1_0=1;

delay_nus(1700); P1_0=0; delay_nms(20);

}

}

void Backward(void) { for(i=1;i<=65;i++) { P1_1=1;

delay_nus(1300); P1_1=0; P1_0=1;

delay_nus(1700);

P1_0=0;

delay_nms(20);

}

}

int main(void) { int counter; int old2=1; int old3=0;

for(counter=1;counter<=1000;counter++)

{ P1_4=1;

delay_nus(1000); P1_4=0;

delay_nus(1000);

}

counter=1; while(1) {

if(P1_5state()!=P2_3state()

)

{

if((old2!=P1_5state())&&(ol

d3!=P2_3state))

{

counter=counter+1;

old2=P1_5state();

old3=P2_3state();

- 4 -

}

} else

} {

}

}

}

Backward(); Left_Turn(); Left_Turn();

if(counter>4)

counter=1; Backward(); Left_Turn(); Left_Turn();

else { } else { } else

Forward(); Backward(); Left_Turn(); Backward(); Right_Turn();

if(P1_5state()==0)

if(P2_3state()==0)

counter=1;

if((P1_5state==0)&&(P2_3sta

{

te==0))

②程序解释:三个变量用于探测墙角。Int型变量counter用来存储交替探测次数。以上程序设定交替探测次数的最大值为4.用Int型变量old2\\old3存储胡须旧的状态值。Counter设为1,当舵机小车在此墙角累积到4时,counter复位为1.假如触须被触动,接着检查当前状态是否与上次状态不同。及判断old2不等于P1_5state(),old3不等于P2_3state(),如果是,就在触须触动计数器上加1,同时记下当前的状态,设置old2等于当前的P1_5state(),old5等于当前的P2_3state(),若触须连续4次被触动,则计数器置1,并且进行“U”型转弯。

1.3.2舵机小车的触觉导航任务实现 ①舵机小车的触觉导航程序:

#include #include int P1_5state(void) {

- 5 -

return(P1&0x20)?1:0; }

int P2_2state(void) {

return(P2&0x08)?1:0; }

void Forward(void) {

P1_1=1;

delay_nus(1700);

P1_1=0; P1_0=1;

delay_nus(1300); P1_0=0; delay_nms(20);

}

void Left_Turn(void) { int i;

for(i=1;i<=26;i++) {

P1_1=1;

delay_nus(1300);

P1_1=0; P1_0=1;

delay_nus(1300); P1_0=0; delay_nms(20);

}

}

void Right_Turn(void) { int i;

for(i=1;i<=26;i++) {

P1_1=1;

delay_nus(1700);

P1_1=0;

P1_0=1;

delay_nus(1700); P1_0=0; delay_nms(20);

}

}

void Bcckward(void) {

int i;

for(i=1;i<=65;i++) { P1_1=1;

delay_nus(1300);

P1_1=0; P1_0=1;

delay_nus(1700); P1_0=0; delay_nms(20);

}

}

int main(void) {

uart_Init(); printf(\

Running!\\n\

int counter;

for(counter=1;counter<=1000;counter++)

{ P1_4=1; delay_nus(1000);

P1_4=0;

delay_nms(1000); } while(1)

- 6 -

{

if((P1_5state()==0)& &(P2_3state()==0)) {

Backward(); Left_Turn();

Right_Turn(); }

else if(P1_5state()==0) {

Backward();

Right_Turn();

}

else if(P2_3state()==0) Backward(); Left_Turn(); } else Forward(); } }

②程序解释:舵机小车触须导航程序流程图如图1-5所示:

图1-5 舵机小车触须导航程序流程图

- 7 -

1.3.3舵机小车的光敏电阻导航任务实现 ①舵机小车的光敏电阻导航程序

#include #include int counter;

int P1_5state(void) /*获

取P1_5口的状态*/

{

return(P1&0x20)?1:0; }

int P2_3state(void) /*获

取P2_3口的状态*/

{

return(P2&0x08)?1:0; }

int main(void) {

uart_Init(); /*串口初

始化*/

printf(\

Running!\\n\

for(counter=1;counter<=1000;counter++) /*开始复位信号*/

{

P1_4=1; delay_nus(1000);

P1_4=0;

delay_nus(1000); } while(1) {

if((P1_5state()==0)&&(P2_3state()==0)) /*都探到阴影,向前运动

*/

{ P1_1=1;

delay_nus(1700); P1_1=0;

P1_0=1;

delay_nus(1300); P1_0=0;

}

else

if(P1_5state()==0) /*只有左边的探测到阴影,向左转*/

{ P1_1=1;

delay_nus(1500); P1_1=0;

P1_0=1;

delay_nus(1300); P1_0=0; }

else if(P2_3state()==0)/*只有右边的探测到阴影,向右转*/

{ P1_1=1;

delay_nus(1700); P1_1=0;

P1_0=1;

delay_nus(1500);

- 8 -

P1_0=0; }

else /*没有探测到阴{

P1_0=1;

delay_nus(1500);

P1_0=0; }

影,静止不动*/

P1_1=1; delay_nus(1500);

P1_1=0;

delay_nms(20); } }

②程序解释:将光敏电阻与P1.5和P2.3相连,分别获取P1_5口和P2_3口的状态,然后将信号复位。若光敏电阻两侧都探到阴影,向前运动;只有左边的探测到阴影,向左转 ;没有探测到阴影,静止不动。

1.3.4舵机小车的红外导航任务实现(避让悬崖) ①舵机小车的红外导航程序

#include #include #include #define RightIR #define

P1_4

#define P3_5

void IRLaunch(unsigned char IR)

{

unsigned int counter; if(IR=='L')

for(counter=0;counter<1000;coun

{

LeftLaunch=1; _nop_();

_nop_(); _nop_(); _nop_();

LeftLaunch=0;

P3_6

} else

_nop_(); _nop_();

#define LeftIR P1_5 _nop_(); _nop_(); _nop_(); _nop_();

LeftLaunch RightLaunch for(counter=0;counter<1000;counter

++)

{

RightLaunch=1;

_nop_();

_nop_();

_nop_(); _nop_(); _nop_(); _nop_();

_nop_(); _nop_();

_nop_(); _nop_(); _nop_();

RightLaunch=0; } }

void Forward(void) {

_nop_(); _nop_();

_nop_(); _nop_(); _nop_(); _nop_();

_nop_(); ter++)

_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); - 9 -

P1_1 = 1; delay_nus(1700); P1_1 = 0; P1_0 = 1; delay_nus(1370); P1_0 = 0;

delay_nms(20);

}

void Left_Turn(void) {

int i;

for( i=1;i<=23;i++) { P1_1=1;

delay_nus(1300); P1_1=0; P1_0=1;

delay_nus(1370);

P1_0=0; delay_nms(20);

} }

void Right_Turn(void) {

int i;

for( i=1;i<=23;i++) { P1_1=1;

delay_nus(1700); P1_1=0; P1_0=1;

delay_nus(1700); P1_0=0; delay_nms(20);

}

}

void Backward(void) {

int i;

for( i=1;i<=65;i++) { P1_1=1;

delay_nus(1300); P1_1=0; P1_0=1;

delay_nus(1700); P1_0=0; delay_nms(20);

} }

int main(void) { int

irDetectLeft,irDetectRight;

int counter;

uart_Init();

for(counter=1;counter<=1000;counter++)

{ P1_3=1; delay_nus(1000); P1_3=0;

delay_nus(1000);

}

do {

- 10 -

IRLaunch('R'); irDetectRight IRLaunch('L'); irDetectLeft

{

Backward(); Right_Turn();

= RightIR;

}

else

if((irDetectRight==0)&&(irDetectLeft==1))

{ } else

Backward(); Left_Turn();

= LeftIR;

if((irDetectLeft==0)& &(irDetectRight==0))

{ }

Backward(); Left_Turn(); Left_Turn();

} }

Forward();

while(1);

else

if((irDetectLeft==0)&

&(irDetectRight==1)) 1.3.5舵机小车的方案改进

将触须避障与红外蔽障程序融合,流程图如图1-6所示:

图1-6 触须避障与红外蔽障程序融合流程图

1.4舵机小车小结

这次的小车是舵机小车,对于舵机以前没有接触过,所以要先看舵机的原理。通过此次的舵机小车实习,我认识到基本实习的流程,掌握了舵机小车的组装,以及舵机小车的基本工作原理,掌握了舵机小车的基本编程,并加强了团队

- 11 -

合作意识。

舵机小车要先进行舵机的调零,调零之后我们又进行了小车的组装,在组装的时候接触了面包板,了解了面包板的接线方法。由于前面进行过步进小车的实习,所以这个小车的组装连线很快就弄好了。

下面就是舵机基本运动的调试(前进、后退、左右转弯),因为每个舵机的转速不同,当前进的时候不走直线,因此我们要不断地改写延迟的时间,在不断的实验下最后终于完成了小车的基本运动。

然后进行触须导航的程序调试,我们遇到了触须导航不灵敏的问题,后来发现是两个触须接触短路造成的。

接下来是驱光导航的任务实现,我们遇到了光敏电路单方向不灵敏的问题,但是不清楚是单片机接线错误还是传感器失灵。在老师的指导下,我们将两个光敏电阻对调接入,发现另一边出现问题而原来的一边可以实现驱光导航,所以我们确定了是传感器的损坏影响了驱光导航,随后就完成了此次项任务。

随后就是避障,我们仔细看了电路图,明白了原理,开始程序的调试,在实验过程中,我们的红外蔽障起初没有成功,原因在于接线太多,导致短路。由于小车是靠碰到快要接触到墙壁的时候有红外反射信号,使小车转动,所以要有后退的过程,所以我们在红外接收器检测到信号的时候后退并且右转。旋转角度是90°。避让悬崖的程序调试类似。

最后是舵机小车的寻迹,按照上次步进小车的寻迹经验,很快编号程序。可是转弯的时候由于转弯延迟太大,小车不稳,只有改变小车转弯的延迟,经过几次实验完成了寻迹。

由于舵机小车的面包板容量有限,我们没有实现舵机小车的任务集成。

2.直流电机小车总结

2.1直流电机小车任务

2.1.1熟练掌握单一传感器、单电机在控制器作用下实现具体机械构件的控制; 2.1.2熟练掌握控制器采集多类型、多数量传感器信息并通过复杂电路控制多电机实现对多机械构件的控制;

2.1.3熟练掌握直流电机在控制器作用下,驱动机械构件实现复杂运动。

2.2 直流电机小车控制原理

2.2.1直流电机小车基本运动控制原理

每个直流电机需要三个控制信号EN1、IN1、IN2。EN1是使能信号。选用一路PWM连接EN1引脚,通过调整PWM的占空比可以调整电机的转速,IN1、IN2为电机转动方向控制信号。IN1、IN2分别为1,0时,电机正转;反之电机反转。为节省单片机引脚,可只用一路I/O口,经反向器74HC14分别接IN1和IN2引脚,

- 12 -

} }

2.3.3直流电机小车测速任务实现 ①直流电机小车测速任务实现程序:

void timer0()interrupt 1

using 2

{

2.3.4直流电机小车四路寻迹任务实现 ①直流电机小车四路寻迹任务实现程序 #include #define Left_1_led P3_4 #define Left_2_led P3_5 #define Right_1_led P3_6 #define Right_2_led P3_7 #define #define #define #define #define #define

disbuff[1]=V00/100;

disbuff[2]=V000/10;

disbuff[3]=V000;

} void

}

TH0=(65536-2000)/256; TL0=(65536-2000)%6; time++; Display_SMG(); if(time>=250) {

time=0; V=count1*2; count1=0;

disbuff[0]=V/1000;

intersvr1(void)interrupt 0 using 1000

{ }

count1++

{P1_4=0,P1_5=0,P1_6=0,P1_7=0;}

void delay(unsigned int k) { }

//全速前进 void run(void) { }

//全速后退

void backrun(void) {

- 18 -

unsigned int x,y; for(x=0;x

for(y=0;y<125;y++);

Left_moto_go Left_moto_back Left_moto_Stop Right_moto_go Right_moto_back Right_moto_Stop {P1_0=1,P1_1=0,P1_2=1,P1_3=0;} {P1_0=0,P1_1=0,P1_2=0,P1_3=1;} {P1_0=0,P1_1=0,P1_2=0,P1_3=0;} {P1_4=1,P1_5=0,P1_6=1,P1_7=0;} {P1_4=0,P1_5=1,P1_6=0,P1_7=1;}

Left_moto_go; Right_moto_go;

}

Left_moto_back Right_moto_back

}

/*--主函数--*/ void main(void) {

动状态

} }

delay(100); run(); while(1) {

run();//将run()改成

//左转

void leftrun(void) { } //右转

void rightrun(void) {

Left_moto_go; Right_moto_back; Left_moto_back; Right_moto_go;

其他三种运动状态即可实现其他三种运

2.3.5直流电机小车避障任务实现 ①直流电机小车避障任务实现程序: #include #define Left_1_led P3_4 #define Left_2_led P3_5 #define Right_1_led P3_6 #define Right_2_led P3_7 #define #define #define #define #define #define

Left_moto_go Left_moto_back Left_moto_Stop Right_moto_go Right_moto_back Right_moto_Stop {P1_0=1,P1_1=0,P1_2=1,P1_3=0;} {P1_0=0,P1_1=0,P1_2=0,P1_3=1;} {P1_0=0,P1_1=0,P1_2=0,P1_3=0;} {P1_4=1,P1_5=0,P1_6=1,P1_7=0;} {P1_4=0,P1_5=1,P1_6=0,P1_7=1;} {P1_4=0,P1_5=0,P1_6=0,P1_7=0;}

void delay(unsigned int k) {

- 19 -

}

unsigned int x,y; for(x=0;x

for(y=0;y<125;y++);

//全速前进 void run(void) { }

//全速后退

void backrun(void) { } //左转

void leftrun(void) {

Left_moto_back Right_moto_back Left_moto_go; Right_moto_go;

}

Left_moto_back; Right_moto_go;

{

2_led==1)

1)

} }

{

backrun(); rightrun(); } else { } else { }

backrun(); backrun(); leftrun();

}

if(Left_1_led==0&&Right_2_led==

{ } else {

run();

if(Left_1_led==1&&Right_

//右转

void rightrun(void) { }

/*--主函数--*/ void main(void) {

动状态

}

void main(void) { while(1)

2.3.6直流电机小车红外遥控任务实现 ①直流电机小车红外遥控任务实现程序: #include #define Left_1_led P3_4 #define Left_2_led P3_5 #define Right_1_led P3_6

- 20 -

Left_moto_go; Right_moto_back;

delay(100); run(); while(1) {

run();//将run()改成if(Right_2_led==0&&Left_1_led==1)

其他三种运动状态即可实现其他三种运

}

if(Left_1_led==0&&Right_2_led==0)

delay(100); { }

run();

#define Right_2_led P3_7 #define #define

Left_moto_go Left_moto_back

{P1_0=1,P1_1=0,P1_2=1,P1_3=0;}

{P1_0=0,P1_1=0,P1_2=0,P1_3=1;}

#define #define #define #define

{P1_0=0,P1_1=0,P1_2=0,P1_3=0;}

Right_moto_go Right_moto_back Right_moto_Stop {P1_4=1,P1_5=0,P1_6=1,P1_7=0;} {P1_4=0,P1_5=1,P1_6=0,P1_7=1;} {P1_4=0,P1_5=0,P1_6=0,P1_7=0;}

#define Imax 14000 #define Imin 8000 #define Inum1 1450 #define Inum2 700 #define Inum3 3000 unsigned char f=0; unsigned

Im[4]={0x00,0x00,0x00,0x00};

unsigned char show [2] = {0,0};

unsigned long m,Tc; unsigned char IrOK; //延时

void delay(unsigned int k) { }

//外部中断解码程序 void

intersvr1(void)interrupt 2 using 1

{

TL0=0; if(Tc>Imin)&&(Tc

m=0; f=1; return;

Left_moto_Stop //定时中断重新置零

} if(f==1) {

//找到起始码

if(Tc>Inum1&&Tc

}

m++; {

char Im[m/8]=Im[m/8]>>1|0x80;

if(Tc>Inum2&&Tc

}

if(m==32) {

m=0; f=0;

if(Im[2]==~Im[3]) { } {

Im[m/8]=Im[m/8]>>1;

m++;

unsigned int x,y; for(x=0;x

for(y=0;y<125;y++);

//取码

Tc=TH0*256+TL0TH0=0;

; IrOK = 1;

- 21 -

//提取中断时间间隔时长

else IrOK = 0;

//取码完成后判断读码是否正确

/*--主函数--*/ } void main(void)

//准备读下一码

}

}

//全速前进 void run(void) { Left_moto_go; Right_moto_go;

}

//全速后退

void backrun(void) { Left_moto_back Right_moto_back

} //左转

void leftrun(void) { Left_moto_back; Right_moto_go;

} //右转

void rightrun(void) { Left_moto_go; Right_moto_back;

} //停转

void stoprun(void) { Left_moto_Stop; Right_moto_Stop;

}

{ m = 0; f = 0; IT1 = 1; EX1 = 1;

TMOD = 0x11; TH0 = 0; TL0 = 0; TR0 = 1; EA = 1;

delay(100); while(1)

{

if(IrOK==1) { switch(Im[2]) { case 0x0e:run(); break;

case 0x1a:backrun();

break; case 0x0a:leftrun();

break;

case 0x1e:rightrun();

break;

case

- 22 -

0x05:stoprun();

break; default:break;

}

} IrOK=0;}

2.3.7直流电机小车功能集成任务实现(改进) ①直流电机小车功能集成任务实现程序:

#include #define Left_1_led P3_4 #define Left_2_led P3_5 #define Right_1_led P3_6 #define Right_2_led P3_7 #define Left_moto_go

{P1_0=1,P1_1=0,P1_2=1,P1_3=0;}

#define Left_moto_back

{P1_0=0,P1_1=1,P1_2=0,P1_3=1;}

#define Left_moto_stop

{P1_0=0,P1_1=0,P1_2=0,P1_3=0;}

#define Right_moto_go

{P1_4=1,P1_5=0,P1_6=1,P1_7=0;}

#define Right_moto_back

{P1_4=0,P1_5=1,P1_6=0,P1_7=1;}

#define Right_moto_stop

{P1_4=0,P1_5=0,P1_6=0,P1_7=0;}

#define Imax 14000 #define Imin 8000 #define Inum1 1450 #define Inum2 700 #define Inum3 3000 void stoprun(); sbit led1=P2^0; sbit led2=P2^1; sbit led3=P2^2; sbit led4=P2^3; sbit ir_left=P0^1; sbit ir_right=P0^0; unsigned code

table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

unsigned code

dis[]={0xfe,0xfd,0xfb,0xf7};

unsigned char

disbuff[5]={0};

unsigned char time=0; unsigned char i=0; unsigned int count1=0; unsigned int V=0; unsigned char f=0; unsigned char

Im[4]={0x00,0x00,0x00,0x00};

unsigned char show[2]={0,0}; unsigned long m,Tc; unsigned char IrOK; void delay(unsigned int k) {

unsigned int x,y; for(x=0;x

void Display_SMG() {

if(++i>=4) i=0; P0=table[disbuff[i]]; P2=dis[i]; } void

intersvrl(void)interrupt 2 using 3

- 23 -

{

Tc=TH1*256+TL1; TH1=0; TL1=0;

if((Tc>Imin)&&(Tc

if(Tc>Inum1&&Tc

Im[m/8]=Im[m/8]>>1|0x80;m++

;

}

if(Tc>Inum2&&Tc

Im[m/8]=Im[m/8]>>1;m++; } if(m==32) { m=0; f=0;

if(Im[2]==~Im[3]) { IrOK=1; }

else IrOK=0; } } }

void timer0() interrupt 1

using 2

- 24 -

{

TH0=(65536-2000)/256; TL0=(65536-2000)%6; time++; Display_SMG(); if(time>=250) { time=0; V=count1*4; count1=0;

disbuff[0]=V/1000; disbuff[1]=V00/100; disbuff[2]=V000/10; disbuff[3]=V000; }}

void intersvr1() interrupt 0

using 1

{count1++;} void run() {

Left_moto_go; Right_moto_go; }

void lowrun() { run(); delay(3); stoprun(); delay(3); }

void backrun() {

Left_moto_back; Right_moto_back; }

void lowback() { run:

backrun();

delay(2); stoprun(); delay(3); goto run; }

void leftrun() {

Left_moto_go; Right_moto_back; }

void lowleft() {

leftrun(); delay(5); stoprun(); delay(2); }

void rightrun() {

Left_moto_back; Right_moto_go; }

void lowright() {

rightrun(); delay(5); stoprun(); delay(2); }

void stoprun() {

Left_moto_stop;

Right_moto_stop; }

void main() { m=0; f=0; IT1=1; EX1=1; TMOD=0x11; TH1=0; TL1=0; TR1=1; EA=1;

TH0=(65536-2000)/256; TL0=(65536-2000)%6; TR0=1; ET0=1; EX0=1; IT0=1; IE0=0; delay(100); while(1) {

if(IrOK==1) { loop: switch(Im[2]) {

case 0x0d:

while(1)

{

switch(Im[2]) {

case 0x0e:run();

- 25 -

} else

if(Left_2_led==0&&Right_1_led==1)

{

backrun(); delay(500); rightrun(); delay(500); } else

if(Right_1_led==0&&Left_2_led==1)

{

backrun(); delay(500); leftrun(); delay(500); } else { run(); }

if(Im[2]==0x16) {

stoprun(); goto loop;

break;

case 0x1a:backrun();

break;

case

0x0a:leftrun();delay(5);stoprun();delay(2);

case

0x1e:rightrun();delay(5);stoprun();delay(2);

{

break;

case 0x05:stoprun();

break;

break;

case 0x16:

stoprun(); goto loop; } } }break;

case 0x19:

{

}}} break; case 0x1b:

{

delay(100); run(); while(1) {

if(Left_2_led==0&&Right_1_l

ed==0)

{ run();

delay(100); lowrun(); while(1)

{ if(Left_1_led==1&&Right_

2_led ==0)

{

- 26 -

backrun(); delay(90); rightrun(); delay(90); } else

if(Left_1_led==0&&Right_2_led ==1)

{

backrun(); delay(90); leftrun();

delay(90); } else

{ lowrun();} if(Im[2]==0x16) {

stoprun(); goto loop; } }break;} }}}}

②程序解释:系统整体设计流程图如图2-1所示。

图2-6 系统整体设计流程图

- 27 -

图3-3 小车“T”字型行走路线图

3.2.3步进电机小车的遥控控制原理

四键无线遥控器包括四键遥控模块PT2262-IR和接收模块PT2272-M4,遥控器的四位数码对应模块的四路输出,程序实现简单,但可开发性差。步进电机小车需要实现的控制方式有限,而四建无线遥控器的四路输出可以有15种组合方式,足够我们使用,并且编程简单,所以选用四键无线遥控器作为本步进电机小车的遥控模块。

接收模块PT2272-M4,与单片机电路连接。接收模块有自锁、非锁、互锁三种型号,本模块采用非锁型。

接收模块管脚功能表如表3-4所示。接收模块的七根脚引分别为D3、D2、D1、D0、GND、VT、VCC。其中VCC为DC5V的供电端,GND为接地端,VT端为解码有效输出端,只要发射器的数据码有输出,VT都能同步输出高电平;D3、D2、D1、D0是2262解码芯片的四位数据输出端,有信号时能输出5V左右的高电平,驱动电流约2mA,与发射器四位数码一一对应。接收模块不焊接天线也能接收信号,为提高接受灵敏度,可以用一根长度约为23厘米的软导线直接焊接到天线孔处,接收模块和发射器的震荡电阻需要匹配才能工作。

表3-4接收模块管脚功能表 管脚 1 2 3 4 5 6 7 8 名称 VT D3 D2 D1 D0 5V GND ANT 管脚功能 输出状态指示 输出状态 输出状态 输出状态 输出状态 输入电源 接地 接天线 对应接线关系D0-B键;D1-D键;D2-A键;D3-C键。

其工作原理是:遥控器将控制信号编码、调制后转换为无线电波发送出去,然后接收模块将接收到的无线电波放大、解码为相应的电信号,放大输出,有遥控信号时数据脚为高电平,遥控信号消失,数据脚为低电平。

四建无线遥控的编程,比较简单,将输出状态D3、D2、D1、D0作为小车不同运行方式的标志,单片机接受到相应的信号键后,发出控制指令给驱动模块,驱动小车运行。程序流程图如图3-4所示

- 33 -

图3-4四键无线遥控程序流程图

3.2.4步进电机小车的寻迹控制原理

寻迹功能是步进电机小车沿着一条黑色的固定轨迹前进的功能,小车跟随轨迹就要用到光电传感器。光电传感器是利用被检测的物体对光束的遮挡或者反射,由同步回路选通电路,从而检测物体的有无的。

光电传感器由三部分组成:发射器、接收器和检测电路。

发送器对准目标发射光束,发射的光束一般来源于半导体光源,发光二级管(LED)、激光二极管及红外发射二极管。光束不间断的发射,或者改变脉冲宽度。接收器有光电二极、光电三极管、光电池组成。在接收器的前面,装有光学元件。在其后面是检测电路,它滤出有效信号和应用该信号。

光电传感器TCRT5000,如图3-5所示,左右对称安装在车底前部,发射头的

- 34 -

红外光,经白色地面反射后,被接收管接收,输出端输出低电平;当遇到黑线时,由于黑色对光吸收强,接收管接收到红外线光少,接收管没有导通,输出高电平;设高电平为0,低电平为1,小车的转向选择如表3-5所示,小车的寻迹过程流程图如图3-6所示。

图3-5光电传感器TCRT5000

表3-5 小车转向表 光电左 1 1 0 0

光电右 1 0 1 0 左光电 黑 浅 黑 黑 右光电 黑 黑 浅 黑 寻迹动作 前进 右转 左转 右转 - 35 -

图3-6 小车的寻迹过程流程图。

3.2.5步进电机小车的避障控制原理

避障功能是步进电机小车在进行的过程中自动躲避障碍并前进的功能,实现避障功能的传感器主要是红外传感器。

红外反射式传感器是集发射与接收于一体的光电传感器,具有探测距离远(最远可达到80cm)、受可见光干扰小、体积小、功耗低、应用方便等特点。而且它检测障碍物的距离,可以根据实际要求,通过尾部的电位器旋钮,进行调节,非常适用于小车避障。

三个红外传感器,分别放置在车身的正前方、左前方和右前方,水平互成60°角。当三个中的一个或多个(障碍物较大)接收部分的传感器,就能根据反射回来的红外线进行自动调整,从而使小车的运行轨迹达到自动避障的目的。 小车避障时,需要转弯,转弯过程需要消耗一定的时间,在程序中加入了延时程序delay(),延时越长,转弯角度越大。delay(1800)转180°,delay(800)

- 36 -

转90°,在连续转弯后就可达到要求了。避障子程序一个简单的流程,如图3-6所示。

图3-6 避障子程序流程图

3.3 步进电机小车具体完成任务与改进

3.3.1步进电机小车的硬件组装实现

①连接电机和电机固定座,然后把电机的四根线,从电机固定座的圆孔中穿过。

②把组装好的电机安装到底板上,为了方便安装底板上的安装孔为长孔,电机固定座有一定的活动余量,安装时注=注意调节两个电机在同一直线上,这样才能保证小车运动的精确性。

- 37 -

③安装电机驱动、联轴器。注意联轴器的顶丝要装上。

④安欧装轮胎、牛眼,把一根30mm和两根8mm的铜柱拼接起来,两条铜柱要平行,固定牛眼的螺母安装在驱动的下方。

⑤安装光电开关、寻迹传感器。注意两侧安装光电开关的安装角度;注意调整寻迹传感器的安装角,适合寻线的宽度。然后插上线,注意区分Vcc、GND、OUT三根线不要弄混。最后接上电机电源。安装好的步进电机小车如图3-7所示。

图3-7 安装好的步进电机小车实物图

3.3.2步进电机小车的“T”字形行走任务实现 ①步进电机小车的“T”字形行走程序如下:

#include \定义头文件

#include \#include #include

#define uchar unsigned char #define uint unsigned int sbit en_left = P1^0;

- 38 -

sbit cw_left = P1^1; sbit clk_left = P1^2; sbit en_right = P1^3; sbit cw_right = P1^4; sbit clk_right = P1^5; void timer_init(); void

move_left(uint

speed_l,uchar cw,uchar en);

void move_right(uint {en_left=1;} else {en_left=0;} } void

函数

{

speed=speed_r; if(cw==1) {cw_right=1;} else

{cw_right=0;} if(en==1) {en_right=1;} else

{en_right=0;} }

void main (void)//“T”字形行

走主程序

{

delay(10); timer1_init(); while(1)

move_right(uint

speed_r,uchar cw,uchar en);

void delay(unsigned int k); void stop(); uint n; uint speed; 延时函数

{

unsigned int i,j; for(i=0;i

void timer1_init()//中断服务子函数

{

TMOD=0x10; ET1=1; EA=1;

TH1=(65536-100)/256; TL1=(65536-100)%6; TR1=1; } void 函数

{

speed=speed_l; if(cw==1) {cw_left=1;} else

{cw_left=0;} if(en==1)

- 39 -

void delay(unsigned int k)//speed_r,uchar cw,uchar en)//右转子

{;}}

move_left(uint 4s

{

2s

move_right(20,0,1); delay(2000);

move_left(20,1,1);//左转move_left(20,0,1);//前进move_right(20,1,1); delay(4000);

move_left(20,1,1);//后退

speed_l,uchar cw,uchar en)//左转子

0.9s

5s

} }

void stop() {TR1=0;} “T”字形行走。

move_right(20,1,1); delay(5000); stop();//停止 move_right(20,1,1); delay(900);

move_left(20,0,1);//直行

void timer1_serve() interrupt

3//中断定时复位程序

{

TH1=(65536-100)/256; TL1=(65536-100)%6; n=n+1; if(n==speed) { } }

clk_left=~clk_left; clk_right=~clk_right; n=0;

②程序解释:小车先前进4秒,再后退2秒,左转前进4秒后停止,完成 3.3.3步进电机小车的遥控控制任务实现 ①步进电机小车的遥控控制程序如下:

#include \#include \#include #include

#define uchar unsigned char #define uint unsigned int sbit en_left = P1^0; sbit cw_left = P1^1; sbit clk_left = P1^2; sbit en_right = P1^3; sbit cw_right = P1^4; sbit clk_right = P1^5; sbit B_key=P2^0; sbit D_key=P2^1; sbit A_key=P2^2;

sbit C_key=P2^6;//接口定义 void timer_init(); void

speed_l,uchar cw,uchar en);

void

move_right(uint

speed_r,uchar cw,uchar en);

void delay(unsigned int k); uint n; uint speed;

void delay(unsigned int k)//

时间延时

{ }

void timer1_init()//定时中断

初始化

{

TMOD=0x10;

- 40 -

unsigned int i,j; for(i=0;i

{;}}

move_left(uint }

ET1=1; EA=1;

TH1=(65536-100)/256; TL1=(65536-100)%6; TR1=1;

}

void main (void)//主函数 {

move_left(uint

delay(10);//延时 timer1_init(); while(1)//等待中断 {

void

义子函数

{ } void

义子函数

{

speed_l,uchar cw,uchar en)//左转定

if(A_key==1&&B_key==0&&C_key==0&&D_key==0)//设置按键A为前进

speed=speed_l; if(cw==1) {cw_left=1;} else

{cw_left=0;} if(en==1) {en_left=1;} else

{en_left=0;}

} else {

EA=1;

move_left(20,0,1); move_right(20,1,1);

if(A_key==0&&B_key==1&&C_key==0&&D_key==0) 设置按键B为右转

move_right(uint

{

EA=1;

speed_r,uchar cw,uchar en)//右转定

move_left(20,0,1);

move_right(20,0,1);

} else

speed=speed_r; if(cw==1) {cw_right=1;} else

{cw_right=0;} if(en==1) {en_right=1;} else

{en_right=0;}

- 41 -

if(A_key==0&&B_key==0&&C_key==1&&D_key==0) 设置按键C为左转

{

EA=1;

} else

}

}

move_left(20,1,1); move_right(20,1,1);

void

interrupt 3

{

EA=1;

timer1_serve()

if(A_key==0&&B_key==0&&C_key==0&&D_key==1) 设置按键D为后退

} else {EA=0;} {

TH1=(65536-100)/256; TL1=(65536-100)%6; n=n+1; if(n==speed) {

clk_left=~clk_left;

move_left(20,1,1); move_right(20,0,1);

clk_right=~clk_right;

}

}

n=0;

②程序解释:设置定时中断,按下遥控按钮触发高电平,执行相应程序,并设置设置按键A为前进、设置按键B为右转、设置按键C为左转、设置按键D为后退。

3.3.4步进电机小车的寻迹控制任务实现 ①步进电机小车的寻迹控制程序如下:

#include \#include \#include #include

#define uchar unsigned char #define uint unsigned int sbit en_left = P1^0;//管脚定

sbit cw_left = P1^1; sbit clk_left = P1^2; sbit en_right = P1^3; sbit cw_right = P1^4;

- 42 -

sbit clk_right = P1^5; sbit ir_left=P2^5; sbit ir_right=P2^4;

void timer1_init();//函数声

void void

move_left(uint move_right(uint

speed_l,uchar cw,uchar en); speed_r,uchar cw,uchar en);

void delay(unsigned int k); uint n;

uint speed;

延时函数

{ }

void timer1_init()//启动中断 { } void

转子函数

{ } void

speed_r,uchar cw,uchar en)//小车右

{

speed=speed_r; if(cw==1) {cw_right=1;} else

{cw_right=0;} if(en==1) {en_right=1;} else

{en_right=0;}

void delay(unsigned int k)//转子函数

unsigned int i,j; for(i=0;i

{;}}

}

TMOD=0x10; ET1=1; EA=1;

TH1=(65536-100)/256; TL1=(65536-100)%6; TR1=1;

void main (void)//主函数 {

delay(10); timer1_init(); while(1) {

move_left(uint

speed_l,uchar cw,uchar en)//小车左

if(ir_left==0&&ir_right==0)//左

} {

右全为黑,右转

speed=speed_l; if(cw==1) {cw_left=1;} else

{cw_left=0;} if(en==1) {en_left=1;} else

{en_left=0;}

move_left(20,0,0);

if(ir_left==0&&ir_right==1)//左

{

move_right(20,0,0);

黑,右浅,左转

move_right(uint

- 43 -

move_left(20,1,1);

}

delay(100);

}

}

}

delay(40);

move_right(20,1,1);

if(ir_left==1&&ir_right==0)//左

}

delay(100); {

浅,右黑,右转

void {

timer1_serve()

interrupt 3//中断恢复

TH1=(65536-100)/256; TL1=(65536-100)%6; n=n+1; if(n==speed) {

clk_left=~clk_left;

move_left(20,0,1);

move_right(20,0,1);

if(ir_left==1&&ir_right==1)//左

{

右全黑,前进

clk_right=~clk_right;

}

}

n=0;

move_left(20,0,1);

move_right(20,1,1);

②程序解释:定义中断主函数按照表2-5执行

3.3.5步进电机小车的避障控制任务实现 ①步进电机小车的避障控制程序如下:

#include \#include \#include #include

#define uchar unsigned char #define uint unsigned int sbit en_left = P1^0; sbit cw_left = P1^1; sbit clk_left = P1^2;

- 44 -

sbit en_right = P1^3; sbit cw_right = P1^4; sbit clk_right = P1^5; sbit ir_left=P1^6; sbit ir_right=P1^7; sbit ir_mid=P2^3;

void timer1_init(); void

move_left(uint

speed_l,uchar cw,uchar en);

void

move_right(uint speed_r,uchar cw,uchar en);

uint n; uint speed;

void delay(unsigned int k) { }

void timer1_init() { } void {

} void { }

void main (void) {

delay(10); timer1_init();

while(1)//中断:三个红外{

speed=speed_r; if(cw==1) {cw_right=1;} else

{cw_right=0;} if(en==1) {en_right=1;} else

{en_right=0;}

move_right(uint

void delay(unsigned int k); speed_r,uchar cw,uchar en)

unsigned int i,j; for(i=0;i

{;}}

TMOD=0x10; ET1=1; EA=1;

TH1=(65536-100)/256; TL1=(65536-100)%6; TR1=1;

传感器的八种状态和对应的运动方式

move_left(uint

if(ir_left==1&&ir_mid==1&&ir_ri

- 45 -

speed_l,uchar cw,uchar en)

speed=speed_l; if(cw==1) {cw_left=1;} else

{cw_left=0;} if(en==1) {en_left=1;} else

{en_left=0;}

ght==1)

}

delay(800); {

move_left(15,1,1); move_right(15,0,1);

if(ir_left==1&&ir_mid==1&&ir_ri

ght==0)

if(ir_left==1&&ir_mid==0&&ir_right==1)

if(ir_left==1&&ir_mid==0&&ir_right==0)

if(ir_left==0&&ir_mid==1&&ir_right==1)

}

}

}

- 46 -

move_right(15,1,1);

}

delay(400);

{

move_left(15,0,1);

delay(400);

move_right(15,0,1);

if(ir_left==0&&ir_mid==1&&ir_ri

}

delay(800); {

ght==0)

move_left(15,0,1); move_right(15,0,1);

{

move_left(15,0,1);

delay(800);

move_right(15,0,1);

if(ir_left==0&&ir_mid==0&&ir_ri

}

delay(400); {

ght==1)

move_left(15,1,1); move_right(15,1,1);

{

move_left(15,0,1);

delay(400);

move_right(15,0,1);

if(ir_left==0&&ir_mid==0&&ir_ri

}

}

} {

ght==0)

move_left(15,1,1); move_right(15,1,1);

{

move_left(15,1,1);

void

interrupt 3

{

timer1_serve()

{

clk_left=~clk_left;

TH1=(65536-100)/256; TL1=(65536-100)%6; n=n+1; if(n==speed)

clk_right=~clk_right;

}

}

n=0;

3.3.6步进电机小车的任务集成控制实现(改进) ①步进电机小车的任务集成控制程序如下:

#include \#include \#include #include

#define uchar unsigned char #define uint unsigned int sbit en_left = P1^0; sbit cw_left = P1^1; sbit clk_left = P1^2; sbit en_right = P1^3; sbit cw_right = P1^4; sbit clk_right = P1^5; sbit B_key=P2^0; sbit D_key=P2^1; sbit A_key=P2^2; sbit C_key=P2^6; sbit ir_left=P2^5; sbit ir_right=P2^4; void timer_init(); void void

move_left(uint move_right(uint speed_l,uchar cw,uchar en); speed_r,uchar cw,uchar en);

void delay(unsigned int k); uint nl; uint nr;

- 47 -

uint speedl; uint speedr;

void delay(unsigned int k) { }

void timer1_init() { } void {

speedl=speed_l; if(cw==1) {cw_left=1;} else

move_left(uint

speed_l,uchar cw,uchar en)

TMOD=0x10; ET1=1; EA=1;

TH1=(65536-100)/256; TL1=(65536-100)%6; TR1=1;

unsigned int i,j; for(i=0;i

{;}}

本文来源:https://www.bwwdw.com/article/4f0p.html

Top