资源描述
课程设计总结报告书
设计项目: 手势控制点阵实验
课程名称: 创新课程设计
指导老师: 周山雪
班 级: 院拓一班
组 员: 黄进发 熊启强 王仁浩
2016年11月29日—2016年12月1日
16 / 19
目录
一 、项目介绍 1
1.1 摘要 1
1.2 设计内容 1
1.3 系统主要功能 1
二、硬件设计 1
2.1 原理电路图 1
2.2 主要元件功能说明 2
2.3 硬件工作原理阐述 4
2.4 元件清单 5
三、系统软件设计 5
3.1 程序流程图 6
3.2 源程序清单 7
3,3调试和检修·······························································8
四、参考文献 9
一 、项目介绍
1.1 摘要
本作品实现手势控制led阵列的功能,它由两个独立部分组成,分别为led阵列显示部分(下称led阵列模块)、捕捉手势部分(下称手持模块)它们分别采用了51级和stm32级芯片作为本作品的主控器,并通过2.4G无线模块作为模块的通信桥梁。实现了“手动,led阵列有感应。”本作品经反复试验,响应延时均保持0.5Ms内。
关键词:手势识别 led阵列 无线 算法
1.2 设计内容
我们组所设计的是一个8×8点阵显示模块,期间包括软件程序的编写和调试 ,PCB板子的制作,电路的仿真以及硬件的焊接和调试,最后做实训总结报告。
1.3 系统主要功能
1.实现功能,功能是在一块板子上用户晃动板子。板子8*8LED点阵四个亮点会随角度的变化而移动且每个点都可以显示到.
二、硬件设计
2.1 电路原理图
(2)8*8点阵工作原理
由于是8*8点阵屏设计,需要端口16个,可采用静态显示模式,用P0口和P2口驱动LED点阵芯片块,通过软件编程,即可实现汉字的显示,并可上移下移,左移,右移,动态流动显示。
(3)最小系统功能说明
MCS--52系列单片机是美国Intel公司在1980年推出的8位单片 微型计算机 ,包含51和52两个子系列。51子系列的典型产品有8031,8051和8751三种机型 52子系列包括8032,8052二种主要机型。 52子系列的配置如下:
(1)8位CPU;
(2)振荡频率1.2~12MHZ;
(3)128个字节的片内数据存储器(片内RAM);
(4)21个专用寄存器;
(5)4KB的片内程序存储器(8031无);
(6)8位并行I/O口P0,P1,P2,P3;
(7)一个全双工串行I/O口;
(8)2个16位定时器/计数器;
(9)5个中断源,分为2个优先级;
本系统选用STC89C52系列单片机,由于它的模块化设计为适应具体的应用提供了极大的灵活性,便于扩展功能,有效的提高了系统的经济性。AT89C52是一种低工耗、高性能的片内含有4KB快闪可编程/擦除只读存储器的八位CMOS微控制器,使用高密度、非易失存储编程器对程序存储器重复编程。
STC89C52具有以下特点:
(1)片内有4KB可在线重复编程的快闪擦写存储器。
(2)32条可编程I/O线。
(3)程序存储器具有三级加密保护。
(4)可编程全全双工串行通道。
(5)空闲状态维持低功耗和掉电状态保存存储内容。
最小系统可以通过编写程序,杜邦线和执行程序的点阵模块的连接,将执行信号通过杜邦线输送到点阵模块,使点阵显示模块显示编写程序中的一系列命令,已完成点阵显示的功能。
(5)最小系统工作原理
最小系统的核心是STC89C52单片机,其内部带有8KB的FLASH ROM,256B片内RAM,基本上能满足最小系统的设计要求。如接上时钟电路、复位电路即可加电工作。单片机结构见下图:
2.3 硬件工作原理阐述
点阵LED一般采用扫描式显示,实际运用分为三种方式:
(1)点扫描;
(2)行扫描;
(3)列扫描。
若使用第一种方式,其扫描频率必须大于16×64=1024Hz,周期小于1ms即可。若使用第二和第三种方式,则频率必须大于16×8=128Hz,周期小于7.8ms即可符合视觉暂留要求。此外一次驱动一列或一行(8颗LED)时需外加驱动电路提高电流,否则LED亮度会不足。
最小系统主要写入程序,通过和点阵的连接,执行相应的程序。
2.4 元件清单
51单片机一个
8*8点阵模块一个
Mpu6050模块一个
杜邦线若干根
火牛一个
电容一个
插针若干
。3.1流程图
3.2 源程序清单
#include <reg52.h>
#include "suanfa.h"
#include "all.h"
//uchar fron[]="fron";
//uchar base[]="base";
//uchar left[]="left";
//uchar right[]="right";
int _Y=0,_Z=0,_X=0;
int mode_x_y_node = 44; //个位是x轴
uchar fron[]="fron";
uchar base[]
uchar left[]="left";
uchar right[]= right
uchar midd[]="middle";
void judge(int _X_, int _Y_) ;
int judge_run(int X__,int Y__);
void check()
{
show_angle();
}
/***************************
判断函数.***************************/
void judge(int _X_, int _Y_)
{
int mode;
// int i;
// /*********************中间************************/
// if(_X_<20&&_X_>-20 &&_Y_<20&&_Y_>-20)
// {
// for(i=0;i<6;i++)
// {
// SeriPushSend(midd[i]);
// }
// SeriPushSend(0x0a);
// show_dot(myself,1);
// }
// /*******************上面****************************/
// if(_X_<20&&_X_>-20 &&_Y_<-20)
// {
// /*if(_Y_<-50) //最上
// {
// for(i=0;i<4;i++)
// {
// SeriPushSend(fron[i]);
// }
// run(4,4, 4,7,myself_af ,1);
// }
// if(_Y_>-50 && _Y_<-30) //中间
// {
// for(i=0;i<4;i++)
// {
// SeriPushSend(fron[i]);
// }
// run(4,4, 4,6,myself_af ,1);
// }
// if(_Y_>-30 && _Y_<-20) //下面
// {
// for(i=0;i<4;i++)
// {
// SeriPushSend(fron[i]);
// }
// run(4,4, 4,5,myself_af ,1);
// }
// */
// }
// SeriPushSend(0x0a);
// // run_fron(3, 6, myself_af ,1);
//
//
// /************************下面***************************/
// if(_X_<20&&_X_>-20 &&_Y_>20)
// {
// for(i=0;i<4;i++)
// SeriPushSend(base[i]);
// SeriPushSend(0x0a);
// // run_down(4, 1, myself_af ,1);
// run(4,4, 4,1,myself_af ,1);
// }
// /*****************************左面**************************/
// if(_X_>20 &&_Y_>-20&&_Y_<20)
// {
// for(i=0;i<4;i++)
// SeriPushSend(left[i]);
// SeriPushSend(0x0a);
// //run_left (3, 7, myself_af ,1);
// run(4,4, 7,4,myself_af ,1);
// }
// /*****************************右面****************************/
// if(_X_<-20 &&_Y_>-20&&_Y_<20)
// {
// for(i=0;i<4;i++)
// SeriPushSend(right[i]);
// SeriPushSend(0x0a);
// //run_right(4, 1, myself_af ,1);
// run(4,4, 1,4,myself_af ,1);
// }
mode = judge_run(_X_,_Y_);
run(4,4, mode%10,mode/10,myself_af ,1);}
/*
上面、下面、左面、右面 是以十为分辨率
左上、 左下、右上、右下 是以五为分辨率
mode_x_y_node 个位是x轴.
*/
int judge_run(int X__,int Y__) //传入x轴、y轴的数据... 返回一个两位数 x轴、y轴坐标
{
if(X__<10&&X__>-10 &&Y__<10&&Y__>-10)
{
// for(i=0;i<6;i++)
// {
// SeriPushSend(midd[i]);
// }
//SeriPushSend(0x0a);
// show_dot(myself,1);
mode_x_y_node = 44;
}
else
{
/*******************上面****************************/
if(X__<20&&X__>-20 &&Y__<-20)
{
if(Y__>-50) //控制角度.
{
mode_x_y_node = 10*((-Y__/10)+3) + 1*4 ; // 当-Y__/10 为2时,进位 个位不变
}
if(Y__<-50) //超过界限,最极限显示.
{
mode_x_y_node = 10*7 + 1*4;
}
}
/************************下面***************************/
if(X__<20&&X__>-20 &&Y__>20)
{
if(Y__<50)
{
mode_x_y_node = 10*(5-(Y__/10)) + 1*4 ; // 当Y__为4时,十位为一 个位不变
}
if(Y__>50) //超过界限,最极限显示.
{
mode_x_y_node = 10*1 + 1*4 ;
}
}
/*****************************左面**************************/
if(X__>20 &&Y__>-20&&Y__<20)
{
if(X__<50)
{
mode_x_y_node = 10*4 + 1*((X__/10)+3) ; // 当X__/10为3时,进位. 十位不变
}
if(X__>50) //超过界限,最极限显示.
{
mode_x_y_node = 10*4 + 1*7 ;
}
}
/*****************************右面****************************/
if(X__<-20 &&Y__>-20&&Y__<20)
{
if(X__>-50)
{
mode_x_y_node = 10*4 + 1*(5-(-X__/10)) ; //当-X__/10 为2时,进位. 十位不变.
}
if(X__<-50) //超过界限,最极限显示.
{
mode_x_y_node = 10*4 + 1*1 ;
}
}
/********************左上*****************************/
if(X__>10 && Y__<-10) //以5为分辨率.
{
if(X__<25 && Y__>-25)
{
mode_x_y_node = 10*((-Y__/5)+3) + 1*((X__/5)+3) ; //
}
if(X__>=25 || Y__<=-25) //超过界限,最极限显示.
{
mode_x_y_node = 10*7 + 1*7 ;
}
}
/****************右上****************************/
if(X__<-10 && Y__<-10)
{
if(X__>-25 && Y__>-25)
{
mode_x_y_node = 10*((-Y__/5)+3) + 1*(5-(-X__/5)) ;
}
if(X__<=-25 || Y__<=-25) //超过界限,最极限显示.
{
mode_x_y_node = 10*7 + 1*1;
}
}
/***********************左下****************************/
if(X__>10 && Y__>10)
{
if(X__<25 && Y__<25)
{
mode_x_y_node = 10*(5-(Y__/5)) + 1*((X__/5)+3);
}
if(X__>=25 || Y__>=25) //超过界限,最极限显示.
{
mode_x_y_node = 10*1 + 1*7;
}
}
/*******************右下**************************/
if(X__<-10 && Y__>10)
{
if(X__>-25 && Y__<25)
{
mode_x_y_node = 10*(5-(Y__/5)) + 1*(5-(-X__/5));
}
if(X__<=-25 || Y__>=25) //超过界限,最极限显示.
{
mode_x_y_node = 10*1 + 1*1;
}
}
return mode_x_y_node;
}
3.3调试和检修
1. 检修
1. 第一次:
在用厂家示例程序时接线正常无误的情况下没有出现想要的效果,后面修改相应的管脚(P0->P1)现象正常.
2. 第二次:
在调试程序时靠近中心位置的若干亮点显示不正常,后面通过特殊处理算法解决了显示不正常的问题.
2. 调试
1. 调试用到的方法:
1. 最小程序体法,即通过写一段简单的小程序让点阵显示出我们想要的现象,然后一步一步地将程序扩大.如不能正常显示则通过程序流程仿真的方法找BUG.
2. 最难调试的部分:
1. 在和六轴模块(测试偏移角度用)联合调试时如何能够使程序快速反应?
2. 如何使亮点正常地显示?
3. 如何地使六轴模块测试出最佳的数据?
最难调试的部分三点的解决方法有两步:
1. 用串口在电脑上看六轴模块回来的数据、按照数据的变化情况设定界限值.
2. 在有第一步的资料后对六轴模块传回来的数据进行运算然后不断地改变公式算法使其达到正常显示的效果.
四、参考文献
1. 《单片机基础》 李广弟 北京航空航天大学出版社 1992
2. 《单片微机控制应用技术—实操指导书》 张大明 刘振鹏 机械工业出版社
3 《单片机原理技术和应用技术》 李全钊
4.LED点阵显示和C语言编程(基础篇)
展开阅读全文