目录
实现功能:用户通过指纹识别打开宿舍门锁
电子元件:
| 主控芯片 | stc12c60A | 供电方式 | USB供电 |
| 指纹模块 | AS608 | 电流、电压 | 5V、2A |
| 舵机 | MG995—180度 | 其它元件 | 1个蜂鸣器、2个LED、1个自锁开关 |
| 晶振 | 11.0529M | 其它元件 | 轻触开关 |
只需要接四根线(Vi TX RX GND)

2.1 首先安装USB转TTL的驱动,然后打开串口
将AS608与USB转TTL模块正确接线后 连接电脑。打开设备管理器找到串口号COMX
(为了避免差错,来回拔插一次,观察设备管理器中串口号的变化)

找到串口号后在AS608的上位机选择正确的串口号。
2.2 配置波特率 注意:AS608的波特率要与程序设计的波特率相同才能进行通讯

2.3添加指纹 在我的电脑操作时 ,AS608模块需要先预热 通电一会后才能录入指纹。
单片机波特率设置:
void Uart_Init(void)
{
SCON=0x50; //UART方式1:8位UART; REN=1:允许接收
PCON=0x80; //SMOD=0:波特率不加倍
TMOD=0x21; //T1方式2,用于UART波特率
TH1=0xFf; //UART波特率设置
TL1=0xFf;
TR1=1; //允许T1计数
EA=1;
}
波特率计算——THx与TLx
定时器工作模式是8位自动重装载,TH1和TL1赋的初值一样

SMOD:波特率选择位。当用软件置位SMOD,即SMOD=1,则使串行通信方式1、2、3的波特率加倍;SMOD=0,则各工作方式的波特率不加倍。复位时SMOD=0。
一般选择不加倍,所以SMOD为0,SYSclk是单片机时钟,也就是晶振的频率,11.0592MHz,运算时要转化为基本单位Hz,即11059200Hz
设置57600(波特率要加倍 SMOD=1):
I2T模式定时器1溢出率:
11059200Hz/12/(256-TH1) = 11059200Hz/12*(256-TH1) = 921600/(256-TH1)
57600 = 2^SMOD/32*(921600/(256-TH1)) = 2/32 * (921600/(256-TH1)) = 57600/(256-TH1)
256-TH1 = 57600/57600 = 1,TH1 = 256-1 = 255,255转为十六进制就是FF
所以TH1 = TL1 = FF

注意:MG995的舵机一定要用大于1a的电流驱动才能正常转动!!!(正常转动包括按照所写的代码转动90度而不是单纯的能转动)

舵机的输入线共有三条,红色中间,是电源正线,一根棕色(有些是黑色)是电源地线,这两根线给舵机提供最基本的能源保证,主要是电机的转动消耗。另外一根线是控制信号线,一般为桔黄色。
舵机的信号线是做为输入线就是接收PWM信号(定时器产生)。一般PWM的周期是20ms,那么对应的频率是50hz。那么改变不同的占空比就可以控制转动的角度。其中占空比从0.5-2.5ms,相对应的舵盘位置为0-180度,呈线性变化。

上图对应MG995的脉冲宽度与输出轴转角。
周期20ms 脉冲0.5ms 表示在20ms里有0.5ms是高电平,19.5ms是低电平。
用定时器计数100us,5us高电平 95us低电平就可以是舵机反方向转90度。
定时器有两种工作模式,分别为计数模式和定时模式。
定时器代码初始化
1.确定定时器的计数模式。
2.确定TLx与THx之间的搭配关系。
3.确定计数起点值。即TLx与THx的初值。
4.是否开始计数。TRx
TLx与THx之间256进制。即当TLx计到256个脉冲时,TLx归0同时THx进1。这也称为方式1。在方式1时,最多计65536个脉冲产生溢出。在主频为11.0592M时,每计一个脉冲为1.085us,所以溢出一次的时间为1.085usx65536=71.1ms
1和2可以由工作方式寄存器TMOD来设定,TMOD用于设置定时/计数器的工作方式,低四位用于T0,高四位用于T1。其格式如下:

定时器工作方式选择
定时器初始从0开始计数到65536然后溢出。要计数100us,所以初始计数要从(65536-100)计数到65536 然后溢出。
定时器初始化
TMOD=0X01; // 16位计数器
TH0=(65536-100)/256; // 高四位 100US定时
TL0=(65536-100)%256; //低四位
TR0= 1;
ET0= 1;
EA = 1;
void timer0( ) interrupt 1 \\ 5个中断源的排序:0代表外部中断0中断 ,1代表定时器/计数器0
中断 , 2代表外部中断1中断, 3代表定时器/计数器1,4代表串行中断的中断
中断 interrupt 1 数字一定一定要写对,对应设置的定时器/计数器
中断函数响应条件
1.中断源有中断请求;
2. 此中断源的中断允许位为1;
3.CPU开中断(即EA=1)。
驱动代码:
#include <STC12C5A60S2.H>
sbit Sevro_moto_pwm=P1^2; // 舵机信号线(橙色)
sbit Key=P2^1; //按键
sbit buzz = P1^4; //蜂鸣器
unsigned char pwm_val = 0;//变量定义
unsigned char push_val = 14;//舵机归中,产生约,1.5MS 信号
void delay1ms(unsigned int k) //延时1ms函数,k等于多少就延时多少ms
{
unsigned int a,b,c,d;
for(d=0;d<k;d++)
for(c=1;c>0;c--)
for(b=50;b>0;b--)
for(a=2;a>0;a--);
}
/**********************************************************************************************
** TIMER1中断服务子函数产生PWM信号
**********************************************************************************************/
void time1()interrupt 1 using 2
{
TH0=(65536-100)/256; //100US定时
TL0=(65536-100)%256;
pwm_val++;
if(pwm_val<=push_val)
Sevro_moto_pwm=1; //PWM信号高电平时间
else
Sevro_moto_pwm=0; //PWM信号高电平时间
if(pwm_val>=100)
pwm_val=0;
}
/**********************************************************************************************
** 主函数
**********************************************************************************************/
void main(void)
{
TMOD=0X21; //
TH0=(65536-100)/256; //100US定时
TL0=(65536-100)%256;
TR0= 1;
ET0= 1;
EA = 1;
push_val=13; //舵机归中
delay1ms(1000); //延时1S让舵机转到其位置,停留一下
while(1)
{
if(Key==0)
{
buzz=1;
push_val=4; //舵机向正转约90度
delay1ms(4000); //延时500MS让舵机转到其位置
buzz=0;
push_val=13;
delay1ms(500);
push_val=4; //舵机向反转约90
delay1ms(500);; //延时500MS让舵机转到其位置
}
else
{
push_val=13;
buzz=0;
}
}
}
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
我在开发的Rails3网站的一些搜索功能上遇到了一个小问题。我有一个简单的Post模型,如下所示:classPost我正在使用acts_as_taggable_on来更轻松地向我的帖子添加标签。当我有一个标记为“rails”的帖子并执行以下操作时,一切正常:@posts=Post.tagged_with("rails")问题是,我还想搜索帖子的标题。当我有一篇标题为“Helloworld”并标记为“rails”的帖子时,我希望能够通过搜索“hello”或“rails”来找到这篇帖子。因此,我希望标题列的LIKE语句与acts_as_taggable_on提供的tagged_with方法
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or
我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c
我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的
我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co
我有一个Controller,我想为这个Controller创建一个助手,我可以在不包含它的情况下使用它。我尝试像这样创建一个与Controller同名的助手classCars::EnginesController我创建的助手是moduleCars::EnginesHelperdefcheck_fuellogger.debug("chekingfuel")endend我得到的错误是undefinedlocalvariableormethod`check_fuel'for#有没有我遗漏的约定? 最佳答案 如果你真的想在Controll
我有这个代码File.open(file_name,'r'){|file|file.read}但是Rubocop发出警告:Offenses:Style/SymbolProc:Pass&:readasargumenttoopeninsteadofablock.你是怎么做到的? 最佳答案 我刚刚创建了一个名为“t.txt”的文件,其中包含“Hello,World\n”。我们可以按如下方式阅读。File.open('t.txt','r',&:read)#=>"Hello,World\n"顺便说一下,由于第二个参数的默认值是'r',所以这样