- 閱讀權限
- 20
- 最後登錄
- 11-7-2
- 精華
- 0
- UID
- 399136
- 帖子
- 16
- 積分
- 94
- 註冊時間
- 05-5-6
- 在線時間
- 16 小時
 
- UID
- 399136
- 帖子
- 16
- 積分
- 94
- Good
- 0
- 註冊時間
- 05-5-6
- 在線時間
- 16 小時
|
小弟要寫一個音樂發聲器既program
用4X3既鍵盤去彈音樂
用Keil uVision4去run佢
燒落粒8052度
基本program已經寫好
每一個制都發出唔同既音
但係我宜家想另外駁多一個制去8052度
寫多一個Function落個program度
一按個制就播歌
首歌既Musical notation codes 係:
64021,64103,64260,64400,64524,64580,64684,64777,64820,64898,64968,65030
請各位高手幫幫小弟
小弟萬分感謝各位~



程式如下: (有兩part)
MusInstru.h
#ifndef _MUSINSTRU_H // 防止MusInstru.h被重複引用
#define _MUSINSTRU_H
#include <reg52.h>
#include <absacc.h>
#include <stdio.h>
#include <math.h>
#define uchar unsigned char
#define uint unsigned int
/* 音符與計數值對應表 */
uint code tab[]={64021,64103,64260,
64400,64524,64580,
64684,64777,64820,
64898,64968,65030};
sbit P20 = P2^0; // 此引腳輸出脈波
uchar STH0;
uchar STL0;
#endif
MusInstru.c
#include "MusInstru.h"
/* 鍵消抖延時函數 */
void delay(void)
{
uchar i;
for (i=300;i>0;i--);
}
/* 鍵掃描函數 */
uchar getkey(void)
{
uchar scancode,tmpcode;
if ((P1&0xf0)==0xf0)
return(0);
scancode = 0xfe;
while((scancode&0x10)!=0) // 逐行掃描
{
P1 = scancode; // 輸出行掃描碼
if ((P1&0xf0)!=0xf0) // 本行有鍵按下
{
tmpcode = (P1&0xf0)|0x0f;
/* 返回特徵位元組碼,為1的位即對應於行和列 */
return((~scancode)+(~tmpcode));
}
else scancode = (scancode<<1)|0x01; // 行掃描碼左移一位
}
}
/* 定時器0中斷服務次程序 */
void time0_int(void) interrupt 1 using 0
{
/* 設定計數初值 */
TH0 = STH0;
TL0 = STL0;
P20=~P20; // 反相,產生輸出脈波
}
/* 主程式 */
void main()
{
uchar key,k;
TMOD = 0x01; // T0,工作模式1
ET0 = 1;
EA = 1;
while(1)
{
P1 = 0xf0; // 發全0行掃描碼
if ((P1&0xf0)!=0xf0) // 若有鍵按下
{
delay(); // 延時去抖動
if ((P1&0xf0)!=0xf0) // 延時後再判斷一次,去除抖動影響
{
key = getkey(); // 調用鍵盤掃描函數
// 根據獲取的按鍵位置得到k值
switch(key)
{
case 0x11: // 1行1列
k = 0;
break;
case 0x21: // 1行2列
k = 1;
break;
case 0x41: // 1行3列
k = 2;
break;
case 0x81: // 1行4列
k = 3;
break;
case 0x12: // 2行1列
k = 4;
break;
case 0x22: // 2行2列
k = 5;
break;
case 0x42: // 2行3列
k = 6;
break;
case 0x82: // 2行4列
k = 7;
break;
case 0x14: // 3行1列
k = 8;
break;
case 0x24: // 3行2列
k = 9;
break;
case 0x44: // 3行3列
k = 10;
break;
case 0x84: // 3行4列
k = 11;
break;
case 0x18: // 3行4列
k = 12;
break;
case 0x28: // 3行4列
k = 13;
break;
case 0x48: // 3行4列
k = 14;
break;
case 0x88: // 3行4列
k = 15;
break;
default:
break;
}
P20 = ~P20; // 反相
/* 根據所得的k值設定計數器1的計數初值 */
STH0 = tab[k]/256;
STL0 = tab[k]%256;
TR0 = 1; // 開始計數
P1 = 0xf0; // 發全0行掃描碼
while ((P1&0xf0)!=0xf0) // 若沒有鬆開按鍵
{
P1 = 0xf0;
}
TR1 = 0; // 若按鍵鬆開,則停止計數,不產生脈波輸出
}
}
}
}
 |
|