⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hpi.c

📁 这个是录音琴的程序,用光电感应器来检测琴键的动作.并且将他记录下来,可以回放.
💻 C
字号:
/*******************************Copyright (c)***************************************

        人机接口程序.

************************************************************************************/

#include   	"common.h"
#include	"midi.h"
#include	"lcd.h"
#include	"hpi.h"

/*---------------------------------------------------------------------------------*/

bit		FlagRecRun			  = 0;			//录音器标记
bit		FlagRecEnd			  = 0;			//录音完成标记
bit		FlagPlayRun			  = 0;			//播放器标记
bit		FlagTimer			  = 0;			//定时器标记
bit		FlagTempo			  = 1;			//节拍器标记

bit		FlagInput			  = 0;			//输入端标记
bit		FlagOutput			  = 0;			//输出端标记
bit		FlagSaveSel			  = 0;			//存储选择标记


UBYTE	 data	ParamaTempo   = 120;	                //节拍器设定
UBYTE	 data	ParamaVolume  = 127;		        //音量设定

UBYTE	 data	KeyBoard      = 0;			//键盘数据
UBYTE	 data	SysWorkStatus = 0;			//系统状态

UBYTE	idata   InputNameLen  = 0;		        //输入名称长度
UBYTE	idata   InputFileName[8];			//输入文件名称
UBYTE	idata   InputTableRow = 0;			//输入名称纵坐标
UBYTE	idata   InputTableCol = 0;			//输入名称横坐标

UHWORD	idata	FileIndex     = 0;			//文件数据指针
UWORD	idata	DeltaTick     = 0;			//放音事件时间
UWORD	idata	RecEvtTick    = 0;			//录音事件时间

bit	FlagTxd		      = 0;			//发射标记
UBYTE 	idata 	TxdHead       = 0;			//发射缓存指针头
UBYTE 	idata 	TxdTail       = 0;			//发射缓存指针尾
UBYTE 	xdata 	TxdBuf[TXD_BUFFER_SIZE];	        //发射缓存区

UBYTE 	idata 	RxdHead       = 0;			//接收缓存指针头
UBYTE 	idata 	RxdTail       = 0;			//接收缓存指针尾
UBYTE 	xdata 	RxdBuf[RXD_BUFFER_SIZE];	        //接收缓存区

UBYTE 	xdata 	DBUF[512];				//公共缓存
UBYTE	xdata	InOutBuf[RAM_SIZE];			//进出缓存

struct	Rtc data SystemRtc;			        //系统时钟

/*-----------------------------------------------------------------------------------
名称: void SetSystemTimer0(void);
功能: 设定系统定时器0.
-----------------------------------------------------------------------------------*/
void SetSystemTimer0(void)
{
	TMOD &= 0xF0;
	TMOD |= 0x01;				//16位元定时器
	TL0 = TL0_RELOAD;    		        //定时器重载
	TH0 = TH0_RELOAD;
	ET0 = 1;        			//启动定时中断0
	TR0 = 1;
}

/*-----------------------------------------------------------------------------------
名称: void SetSystemUart(void);
功能: 设定串行端口.
-----------------------------------------------------------------------------------*/
void SetSystemUart(void)
{
    RCAP2H = (65536-(SYSTEM_FOSC/BAUD_RATE/32))/256;
    RCAP2L = (65536-(SYSTEM_FOSC/BAUD_RATE/32))%256;
    TH2 = RCAP2H;
    TL2 = RCAP2L;
    T2CON = 0x34;     		        //启动TR2

    SCON = 0x70;			//串口为模式1,REN=1
    IP   = 0x10;			//串口最高优先权
    ES   = 1;				//开启串口中断
}

/*-----------------------------------------------------------------------------------
名称: void IrqUartHandle(void) interrupt 4 using 3
功能: 串口中断处理.
-----------------------------------------------------------------------------------*/
void IrqUartHandle(void) interrupt 4 using 3
{
	UBYTE	RecvByte;
	UBYTE	TempHead;
	UBYTE	TempTail;

	if(_testbit_(TI))
	{
		if(TxdTail==TxdHead)
		{
			FlagTxd=false;
		}
		else
		{
			TempTail=(TxdTail+1)&TXD_BUFFER_MASK;
			TxdTail = TempTail;
			SBUF = TxdBuf[TempTail];
		}
	}

	if(_testbit_(RI))
	{
		RecvByte = SBUF;
		TempHead = (RxdHead+1)&RXD_BUFFER_MASK;
                RxdHead  = TempHead;
                RxdBuf[TempHead] = RecvByte;
	}
}

/*-----------------------------------------------------------------------------------
名称: void IrqTimer0Handle(void) interrupt 1 using 1
功能: 定时器0中断处理.
-----------------------------------------------------------------------------------*/
void IrqTimer0Handle(void) interrupt 1 using 1
{
	auto	UBYTE	KeyInput = P1&0x1F;
	static	UBYTE	KeySaves = 0;
	static	UBYTE	KeyStatu = 0;
	static	UBYTE	KeyTimer = 0;

	TH0 = TH0_RELOAD;          //5mS
	TL0 = TL0_RELOAD;

	FlagTimer = true;

	if(FlagTempo)
	{
		if(TempoTimer)
			TempoTimer --;
	}

	if(FlagRecRun)
	{
		RecEvtTick ++;
	}

	if(FlagPlayRun)
	{
		if(DeltaTick)
			DeltaTick--;
	}

	if(KeyStatu==0)
	{
		if(KeyInput!=0x1F)
		{
			KeySaves=KeyInput;
			KeyStatu=1;
		}
	}
	else if(KeyStatu==1)
	{
		if(KeyInput==KeySaves)
		{
			KeyStatu=2;
			KeyTimer=0;
			KeyBoard=KeySaves;
		}
		else
		{
			KeyBoard=0;
			KeyStatu=0;
		}
	}
	else if(KeyStatu==2)
	{
		if(KeyInput==0x1F)
		{
			KeyBoard=0;
			KeySaves=0;
			KeyStatu=0;
		}
		else
		{
			if(KeyInput==KeySaves)
				KeyTimer++;
			else
				KeyTimer=0;

			if(KeyTimer>50)
			{
				KeyTimer=0;
				KeyBoard=KeySaves|0x80;
			}
		}
	}
}

/*-----------------------------------------------------------------------------------
名称: void UartSendData(UBYTE Value);
功能: 串口数据传送.
-----------------------------------------------------------------------------------*/
void UartSendData(UBYTE Value)
{
	UBYTE	TempHead;

	TempHead = (TxdHead+1)&TXD_BUFFER_MASK;
	TxdBuf[TempHead] = Value;
	TxdHead = TempHead;

	if(!FlagTxd)
	{
		FlagTxd = true;
		TI = 1;
	}
}

/*-----------------------------------------------------------------------------------
名称: UBYTE GetKeyBoard(void);
功能: 获取键盘数据.
-----------------------------------------------------------------------------------*/
UBYTE GetKeyBoard(void)
{
	UBYTE	KeyValue = KeyBoard;
	KeyBoard = 0;

	return(KeyValue);
}

/*-----------------------------------------------------------------------------------
名称: UHWORD HexToBcd(UBYTE Hex);
功能: HEX转换BCD.
-----------------------------------------------------------------------------------*/
UHWORD HexToBcd(UBYTE Hex)
{
	return(((Hex/100)<<8)|(((Hex%100)/10)<<4)|((Hex%100)%10));
}

/*-----------------------------------------------------------------------------------
名称: void SystemRtcTask(void);
功能: 系统时钟任务.
-----------------------------------------------------------------------------------*/
void SystemRtcTask(void)
{
	if(_testbit_(FlagTimer))
	{
		if((FlagRecRun)||(FlagPlayRun))
		{
			SystemRtc.Millis++;

			if(SystemRtc.Millis>=148)
			{
				SystemRtc.Millis=0;
				SystemRtc.Second++;

				if(SystemRtc.Second>=60)
				{
					SystemRtc.Second = 0;
					SystemRtc.Minute ++;

					if(SystemRtc.Minute>=60)
						SystemRtc.Minute = 0;
				}
			}
		}
	}
}

/*-----------------------------------------------------------------------------------
名称: void ResetSystemRtc(void);
功能: 系统时钟复位.
-----------------------------------------------------------------------------------*/
void ResetSystemRtc(void)
{
	SystemRtc.Millis = 0;
	SystemRtc.Minute = 0;
	SystemRtc.Second = 0;
}

/*-----------------------------------------------------------------------------------
名称: UHWORD GetSystemRtc(void);
功能: 获取系统时钟.
-----------------------------------------------------------------------------------*/
UHWORD GetSystemRtc(void)
{
	return(((UBYTE)HexToBcd(SystemRtc.Minute)<<8)|(UBYTE)HexToBcd(SystemRtc.Second));
}

/*-----------------------------------------------------------------------------------
名称: void RamAreaSelect(UBYTE Select);
功能: RAM区域选择.
-----------------------------------------------------------------------------------*/
void RamAreaSelect(UBYTE Select)
{
	Select&=3;

	if(Select==1)
	{
		RAM_PAGE_LOW = 1;
		RAM_PAGE_HIG = 0;
	}
	else if(Select==2)
	{
		RAM_PAGE_LOW = 0;
		RAM_PAGE_HIG = 1;
	}
	else if(Select==3)
	{
		RAM_PAGE_LOW = 1;
		RAM_PAGE_HIG = 1;
	}
	else
	{
		RAM_PAGE_LOW = 0;
		RAM_PAGE_HIG = 0;
	}
}

/*-----------------------------------------------------------------------------------
名称: void MidiPortSelect(void);
功能: Midi端口选择.
-----------------------------------------------------------------------------------*/
void MidiPortSelect(void)
{
	CTR_OUT_1    =  1;
	CTR_OUT_2    =  FlagOutput;
	MIDI_INP_SEL = ~FlagInput;
}

/*-----------------------------------------------------------------------------------
名称: void MidiOutChange(UBYTE Chane);
功能: Midi输出通道切换.
-----------------------------------------------------------------------------------*/
void MidiOutChange(UBYTE Chane)
{
	if(!Chane)
	{
		CTR_OUT_1 = 1;
		CTR_OUT_2 = 0;
	}
	else
	{
		CTR_OUT_1 = 0;
		CTR_OUT_2 = 0;
	}
}

/*-----------------------------------------------------------------------------------
名称: void MidiWaitSendEnd(void);
功能: 等待Midi输出完毕.
-----------------------------------------------------------------------------------*/
void MidiWaitSendEnd(void)
{
	while(TxdHead != TxdTail);
}

/*-----------------------------------------------------------------------------------
名称: void PianoSensorModify(void);
功能: 钢琴传感器调整.
-----------------------------------------------------------------------------------*/
void PianoSensorModify(void)
{
	UBYTE	key    = 0;
	UBYTE	sensor = 1;
	UBYTE	status = 0;
	UBYTE	TempTail = 0;

	while(1)
	{
		if(status==0)
		{
			key=P1&0x1F;
			if(key==KEY_ENT)
			{
				KeyBoard=0;
				break;
			}
			else if(key==0x10)
			{
				LcdClear();
				LcdDisplayAscii0816String(0,9,0,"Sensor Modify");
				LcdDisplayByte(2,45,sensor);
				LcdDisplayAscii0816(2, 0,0,'-');
				LcdDisplayAscii0816(2,113,0,'+');

				Led_Off();
				AUDIO_ON();
				MidiWaitSendEnd();
				MidiOutChange(0);
				SoundInital();
				SoundVolumeAdj();

				RxdHead = 0;
				RxdTail = 0;
				while((P1&0x1F)==0x10);
				status=1;
			}
		}
		if(status==1)
		{
			key = GetKeyBoard();
			if(key==KEY_ENT)
			{
				Led_Off();
				MidiWaitSendEnd();
				MidiOutChange(1);
				UartSendData(0xFE);
				UartSendData(0xFE);
				UartSendData(0xFE);
				MidiWaitSendEnd();
				MidiOutChange(0);
				SoundOff();
				AUDIO_OFF();
				break;
			}
			else if((key==KEY_DOWN)||(key==KEY_DOWN_ON))
			{
				if(sensor>1)
				{
					sensor--;
					LcdDisplayByte(2,45,sensor);
				}
			}
			else if((key==KEY_UP)||(key==KEY_UP_ON))
			{
				if(sensor<88)
				{
					sensor++;
					LcdDisplayByte(2,45,sensor);
				}
			}
			else if((key==KEY_LEFT)||(key==KEY_LEFT_ON))
			{
				Led_On();
				MidiWaitSendEnd();
				MidiOutChange(1);
				UartSendData(0xFE);
				UartSendData(sensor+20);
				UartSendData(0x55);
				MidiWaitSendEnd();
				MidiOutChange(0);
				Led_Off();
			}
			else if((key==KEY_RIGHT)||(key==KEY_RIGHT_ON))
			{
				Led_On();
				MidiWaitSendEnd();
				MidiOutChange(1);
				UartSendData(0xFE);
				UartSendData(sensor+20);
				UartSendData(0xAA);
				MidiWaitSendEnd();
				MidiOutChange(0);
				Led_Off();
			}

			if((P1&0x1F)==0x15)
			{
				Led_On();
				MidiWaitSendEnd();
				MidiOutChange(1);
				UartSendData(0xFE);
				UartSendData(0xFF);
				UartSendData(0xFF);
				MidiWaitSendEnd();
				MidiOutChange(0);

				sensor=0;
				LcdDisplayByte(2,45,sensor);
				while((P1&0x1F)==0x15);
				sensor=1;
				LcdDisplayByte(2,45,sensor);
				Led_Off();
			}

			if(RxdHead!=RxdTail)
			{
				TempTail = (RxdTail+1)&RXD_BUFFER_MASK;
				RxdTail  = TempTail;
				MidiWaitSendEnd();
				MidiOutChange(0);
				UartSendData(RxdBuf[TempTail]);
				MidiWaitSendEnd();
			}
		}
	}
}










⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -