在练习钢琴时,经常需要用到节拍器。
一般采用机械式的,上弦的,但有容易受潮而节拍不准的缺点。有时甚至向左和向右的节拍时长也不一样,令人无法练习。
电子的节拍器虽然音色不太好,但它工作稳定,用于家庭练习很合适。它有几种常用节拍
static unsignedchar buf[] ={ 60, 72, 84, 100, 120, 144, 160, 176, 192, 208 , 255 };
另外,有时隔几拍还需要一个重音,有以下几种节奏
static unsignedchar buf[] ={ 0, 2, 3, 4, 6, 8, 255 };
其中255表示数组结束。
采用STC15W型单片机,重音用一个有源蜂鸣器发音,节拍声音用3个继电器同时动作来发音。有点浪费继电器,不过这个试验板是以前做别的控制板留下的旧件,跳几根线,能派个用场倒也划算了。
软件设计采用了6个任务,其中main调度3个任务,分别是重音动作、节拍动作和键盘。
timer0实际上调度3个,但显式地只调度了2个任务,分别是显示任务和节拍运行任务,然后节拍运行任务内部调度了重音运行任务。因为显示采用4位数码管扫描式,试着放在main中调度发现4个位的亮度不一,很不美观,所以移到timer0中,亮度就一致了。
之所以把节拍动作和节拍运行显式地分为2个任务,是有原因的:继电器的声音太小了,为了听上去更响一些,所以一吸紧接着一放算作一次动作,这样听起来就更响一点点(其实是更吵一点)。由于一吸一放之间需要一定的时间,不然它根本来不及动作。至少需要给它30--50毫秒左右,所以,需要发生这个动作和这个动作的执行显然分别为生产者和消费者。其中消费者放在main里,这样可以避免把timer弄乱了。
调试中发现,74系列在供电是5V时,对于STC15W的3.3V的IO不认,造成不显示或显示错乱。最简单的办法就是降低74系列的供电电压为4.3V,这用一个2极管就能达到。
另外,修改了XPP中的代码,而未修改.c造成编译并没有真正扫描到变化的代码,造成怪现象,这也是搞了大半天才明白过来。因为一直是float运算有错,十分不解。
有时变量用data,idata,xdata修饰一下再编译可能能解决一点怪现象。
显示的第1位是重音,2表示2拍一个重音
后3位表示节拍速度,072表示每分钟72次。