大家好,我是最帅的廖先生,今天给大家分享一个指尖POV陀螺。
首先大家会问什么是POV?即视觉暂留(POV)即视觉的短暂停留。人眼观看物体时,物体的像会成到视网膜上。视网膜上的光感细胞将光信号转换为生物电信号通过视神经传给大脑。然而,当物体移去后,视神经对物体的印象不会立刻消失,画面完整的被大脑接受,大家所知道的摇摇棒就是根据相同原理。
指尖POV陀螺就是控制LED的亮灭,通过旋转来开关LED,从而出现视觉停留,显示各种图案文字。
先来看下原理图:
我们来看看单片机,我这边选用的是STC15W404AS,SOP16封装,内置晶振。
供电方面使用的是两颗CR2032电池并联,正极接一颗IN4148到VCC,负极接一个拨动开关到GND。
LED灯采用0603封装的,限流电阻也是0603的阻值1K,LED正极连接一颗1K电阻到VCC,负极接单片机IO口,单片机IO口低电平灯亮,高电平灭。
光电感应方面我使用的是亿光的ITR8307,电路比较简单,在之前使用霍尔的还比较麻烦才切换这个ITR8307。
最后就是现实切换按键电路,轻触按键。
电路方面是不是感觉很简单。啊哈哈哈哈
PCB板设计方面,2层板设计,板型打了3板,前面的板型都太丑,前几天抽出时间又画了一版,如下图:
程序方面:
//晶振评率选6M,字模11*11(或者自己调试合适)黑体,低位先,从左至右,0为亮灯
#include
<STC15F2K60S2.H>
#include"liao.h"
#define uchar unsigned char
#define uint unsigned int
uchar i,s,b,zz;
uchar JS,ss,zz,xuanze;
uint ZS; //累计转数
sbit k1=P3^2;
sbit k2=P5^5;
sbit LED=P3^7;
sbit LED_H=P5^4; //光电
sbit D7=P3^0;
sbit D8=P3^1;
sbit D9=P3^3;
sbit D10=P3^6;
sbit D11=P3^7;
/**************************/
uchar code table0[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
uchar code huamian0[]={
//画满显示0:电子芯吧客
0xFF,0xFF,0x03,0xFF,0x6B,0xFF,
0x6B,0xFF,0x00,0xFC,0x6B,0xFD,
0x6B,0xFD,0x83,0xFD,0xFF,0xFD,
0xFF,0xFE,/*"电",0*/
/* (10 X 11 , 黑体 ) */
0xFF,0xFF,0xDF,0xFF,0xDF,0xFF,
0xDD,0xFD,0x05,0xFC,0xD9,0xFF,
0xD9,0xFF,0xDD,0xFF,0xDF,0xFF,
0xEF,0xFF,/*"子",1*/
/* (10 X 11 , 黑体 ) */
0xFF,0xFF,0x1D,0xFF,0xFD,0xFF,
0x10,0xFC,0xED,0xFD,0xCD,0xFD,
0xF0,0xFD,0xDD,0xFE,0xBD,0xFF,
0xFF,0xFF,/*"芯",2*/
/* (10 X 11 , 黑体 ) */
0xFF,0xFF,0x01,0xFE,0x81,0xFF,
0xFF,0xFF,0x01,0xFE,0xDD,0xFD,
0xC1,0xFD,0xDD,0xFD,0xC1,0xFD,
0xFF,0xFE,/*"吧",3*/
/* (10 X 11 , 黑体 ) */
0xBF,0xFF,0xA9,0xFF,0x2D,0xFC,
0x21,0xFD,0x45,0xFD,0x54,0xFD,
0x25,0xFD,0x35,0xFC,0xB9,0xFF,
0xFF,0xFF,/*"客",4*/
/* (10 X 11 , 黑体 ) */
};
uchar code huamian1[]=
{
//画面显示1,这里添加字模代码
};
uchar code huamian2[]={
//画面显示2,这里添加字模代码
};
uchar code huamian3[]={
//画面显示3,这里添加字模代码
};
void delay(uint a) //延时
{
uchar x;
while(a--)
{
for(x=0;x<150;x++);
}
}
//////////////////////////////
void delayus(uint b)
{
while(b--);
}
/**************************/
void Timer0Init(void) //1毫秒@6.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x0C; //设置定时初值
TH0 = 0xFE; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //定时器T0中断允许
}
/**********************************************/
/*开机显示*/
void kaijiss() //开机最外面LED闪烁三次
{
uchar i;
for(i=0;i<6;i++)
{
P10=~P10;
delay(100);
}
P10=1;
}
/********************************************/
/*测试程序,按住按键再开机,LED流水*/
void ceshi()
{
uchar i;
P1=P2=0xff;
for(i=0;i<8;i++)
{
P1=table0[i];
P30=P16;
P31=P17;
delay(100);
}
P31=1;
for(i=0;i<8;i++)
{
P2=table0[i];
P33=P20;
P36=P21;
P37=P22;
delay(100);
}
P2=0xff;
}
void tuan(uchar *p)
{
uchar i;
delayus(ss*100+3100); //延时一个时间后
for(i=0;i<72;i++)
{
P1=p[i*2];
P2=p[i*2+1];
if(i==71)P2=0xff; //修复防止个别改字后,第11个LED常亮问题
P30=P16;
P31=P17;
P33=P20;
P36=P21;
P37=P22;
delayus(ss+22);
//显示延时
}
P1=P2=0xff; //清除LED显示
}
/***********************************/
/* 比较器中断 */
void cmp_isr()interrupt 21 //
{
CMPCR1&=~CMPIF; //清除完成标志
JS=!!(CMPCR1&CMPRES);
if(JS==0)
{
/**/
switch(xuanze)
{
case(0):tuan(huamian0);break;
case(1):tuan(huamian1);break;
case(2):tuan(huamian2);break;
case(3):tuan(huamian3);break;
}
ZS++; //转数累加
}
}
/**************************************/
/**************************************/
/*定时器T0中断服务*/
void Timer0(void) interrupt 1
{
uchar c;
b++;
if(b==40/4) //一直检测每10ms内当前转数
{ b=0;
c++;
if(c==20)
{
P11=~P11;
}
ss=ZS+1;
ZS=0;
//清零
}
TL0 = 0x0C; //设置定时初值
TH0 = 0xFE; //设置定时初值
}
/**************************************/
/*外中断0服务程序*/
void zhongduan(void) interrupt 0
{
if(k1==0)
{
delay(15);
if(k1==0)
{
xuanze++;
if(xuanze>=4)xuanze=0; //
LED=0;
}
while(!k1);
LED=1;
}
}
void main()
{
uchar cs=0;
EA=1; //开总中断
EX0=1; //允许使用外中断
IT0=1; //负跳变触发方式(下降沿)
Timer0Init(); //1毫秒@6.000MHz
msgl();
//单片机工作模式
fenpin(); //单片机主频设置
bjq();
//比较器设置
ioshezhi(); //io口设置
////
if(k1==0)
{
cs=1;
}
while(cs)
{
ceshi();
}
////
kaijiss(); //开机最外面LED闪烁三次
////////////////////////////////////////////
while(1)
{
LED_H=0;
//红外发射LED
}
}
liao.h代码如下:
#ifndef
__liao_H__
#define __liao_H__
#include <STC15F2K60S2.H>
#define uchar unsigned char
#define uint unsigned int
#define CMPEN 0x80
//比较器使能
#define CMPIF 0x40 //比较器中断位
#define PIE 0x20
//比较器上升沿中断使能
#define NIE 0x10
//比较器下降沿中断使能
#define PIS
0x08 //比较器正极选择
#define NIS
0x04 //比较器负极选择
#define CMPOE 0x02
//比较器结果输出控制
#define CMPRES 0x01
//比较器比较结果标志
#define INVCMPO 0x80
//比较器结果反向输出控制位
#define DISFLT 0x40
//比较器输出滤波使能控制位
#define LCDTY 0x3f
//比较器输出的去抖时间控制
void msgl()
{
}
void fenpin()//分频
{
CLK_DIV =0x02; //主时钟频率/4
}
void bjq()//比较器
{
CMPCR1=0; //初始化比较器控制寄存器1
CMPCR2=0; //初始化比较器控制寄存器2
CMPCR1|=CMPEN; //使能比较器
CMPCR1|=NIE; //使能比较器的下降沿中断
CMPCR1&=~PIS; //选择外部管脚P5.5(CMP+)为比较器的正极输入源
CMPCR1&=~NIS; //选择内部BandGap电压BGV为比较器的负极输入源
CMPCR1&=~CMPOE;
//禁用比较器的比较结果输出
CMPCR2&=~INVCMPO; //比较器的比较结果正常输出到P1.2
CMPCR2&=~DISFLT; //不禁用(使能)比较器输出端的0.1us滤波电路
CMPCR2&=~LCDTY;
//比较器结果不去抖,直接输出
}
void ioshezhi() //io口设置
{
P5M1|=0x20;
P5M0|=0x00;
/*
//P54强推挽
P5M1|=0x00;
P5M0|=0x10;
*/
//P32高阻
P3M1=0x04;
P3M1=0x00;
}
#endif
可以显示4组文字图案,可以通过字模软件取模更换,按轻触按键可以切换。
视频演示:http://v.youku.com/v_show/id_XNDA3MTYyNzY0NA==.html?spm=a2h3j.8428770.3416059.1
文笔不好不要嫌弃,看看就行哈。
原创作品,未经权利人授权禁止转载。详情见转载须知。 举报文章
我要举报该内容理由
×