📄 main.asm.bak
字号:
////////////////////////////////////////////////////////////////////////////////////////////////////
//| 文件名:main.asm
//| 功 能:主文件模块,用来对各项功能进行集成。
//| 编码人:
//| 版 本:VAR 0.01
//| 时 间:2005.11.18
//| 修改历史:
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////
//| 头文件
.include SPT6608.inc
.include main.h
.include function.h
////////////////////////////////////////////////////
//| 全局定义
.public _main;
.public _BREAK;
.public _FIQ;
.public _IRQ0;
.public _IRQ1;
.public _IRQ2;
.public _IRQ3;
.public _IRQ4;
.public _IRQ5;
.public _IRQ6;
.public _IRQ7;
.external RW_Flag,RW_Address,RW_Temp1;
.external T_SACM_DVR1600_SpeechTable,SinTab1024
.external __RES_LING16K_ENC_sa
.ram
.var RW_Length
.var RW_CountAddr
.const B_RecordBeginAddr = 0x1000
////////////////////////////////////////////////////
//| 代码开始
.code
_main:
//初始化
INT OFF; //关闭中断
R1 = 0x55AA;
[P_Watchdog_Clr] = R1; //清看门狗
R2 = 0x0FFF;
SP = R2; //设置堆栈指针
// CALL F_Test1600; //test a1600
// jmp _main
// JMP ?_main_init //test
// CALL F_TestTTS
// jmp _main //test tts
CALL F_WakeUpCheck; //检测系统是否是从休眠中唤醒
CMP R1, C_True
JE ?_main_WakeUp;
//如果系统是冷启动
CALL F_CPUInit; //CPU硬件的一些初始化
CALL F_PlatInit; //软件的底层一些参数的初始化
CALL F_ClearPlayRam; //清除播放缓冲区
JMP ?_main_init; //调转到下一步处理
//系统是被从休眠中被唤醒的
?_main_WakeUp:
R1 = 0x0000;
[P_WakeUp] = R1;
R1 = 0xFFFF;
[P_WakeUpClr] = R1;
CALL F_Restore; //重新恢复休眠前的一些系统状态
//系统是被重新启动的
?_main_init:
INT FIQ, IRQ; //允许中断
R1 = 0x0080;
[P_SystemClock] = R1;
// CALL F_TimerBEnable //10s休眠处理
//消息循环
?_MsgLoop:
//test start
//test end
// CALL F_TestTTS
// JMP ?_MsgLoop
CALL F_GetMessage; //获取消息
R1 = [R_MessageType];
CMP R1, M_ComposePlay
JE ?_ComposePlay; //合成播放处理
CMP R1, M_PhrasePlay
JE ?_PhrasePlay; //短语播放处理
CMP R1, M_SoundPlay
JE ?_SoundPlay; //声音播放处理
// CMP R1, M_StopPlay
// JE ?_StopPlay; //停止消息处理
// CMP R1, M_VolumeSet
// JE ?_VolumeSet; //音量调节消息处理
// CMP R1, M_bMultiVoiceMode
// JE ?_bMultiVoiceMode; //姓名多音字消息处理
// CMP R1, M_SetSilenceTime
// JE ?_SetSilenceTime; //静音时间处理
// CMP R1, M_SetSpaceTime
// JE ?_SetSpaceTime; //字符间静音时间处理
// CMP R1, M_SetPlayTime
// JE ?_SetPlayTime;
CMP R1 , M_GoSleep
JE ?_CmdProc_GotoSleep
JMP ?_MsgLoop; //如果不是上述的几种消息
//重新取消息
//合成播放
?_ComposePlay:
CALL F_ComposePlay;
JMP ?_MsgLoop;
//短语播放
?_PhrasePlay:
CALL F_PhrasePlay;
JMP ?_MsgLoop;
//抬笔消息处理
?_SoundPlay:
CALL F_SoundPlay;
JMP ?_MsgLoop;
//停止消息处理
//?_StopPlay:
// CALL F_StopPlay;
// JMP ?_MsgLoop;
//命令消息处理
//?_VolumeSet:
// CALL F_VolumeSet;
// JMP ?_MsgLoop;
//姓氏多音字处理
//?_bMultiVoiceMode:
// CALL F_bMultiVoiceMode;
// JMP ?_MsgLoop;
//静音时间设置处理
//?_SetSilenceTime:
// CALL F_SetSilenceTime;
// JMP ?_MsgLoop;
//?_SetPlayTime:
// CALL F_SetPlayTime
// JMP ?_MsgLoop;
//字符间隔静音时间处理
//?_SetSpaceTime:
// CALL F_SetSpaceTime;
?_CmdProc_GotoSleep:
// CALL F_UARTGotoSleep;
JMP ?_MsgLoop;
///////////////////////////////////////////////////
F_TestTTS:
R1 = C_True
[R_PlayName] = R1
BP = UartPlayBuffer
R1 = 0x06
[BP++] = R1
R1 = 0x30
[BP++] = R1
R1 = 0x31
[BP++] = R1
R1 = 0x32
[BP++] = R1
R1 = 0x33
[BP++] = R1
R1 = 0x34
[BP++] = R1
R1 = 0x35
[BP++] = R1
CALL F_SPT6608_Init;
CALL F_ChNameInit;
// CALL F_VolumeSet
CALL F_SetSpaceTime
CALL F_SetSilenceTime
// R2 = [R_playnum]
// R3 = 65
// MR = R2 * R3
BP = UartPlayBuffer
// BP += R3
R1 = BP + 1 //播放缓冲区首地址
R2 = [BP]
R3 = 0
CALL F_ChNamePlay
// R1 = 5
// CALL F_ChPhrasePlay
?_ChNameWait:
CALL F_ChNameServiceLoop;
CALL F_ChNameGetStatus;
CMP R1 ,0x0
JNE ?_ChNameWait
RETF
/////////////////////////////////////////////////////
F_Test1600:
R1 = C_False
[R_PlayName] = R1
R1 = 0x0080;
[P_SystemClock] =R1;
R1 =B_8KHz+B_Enable32768+B_Strong32768+B_128Hz
[P_TimeBaseSet] = R1;
R1 = B_T128HzInt
[P_Int] = R1
R1 = 0;
[R_DAC] = R1;
[P_DAC] = R1;
INT IRQ,FIQ
R1 = 0
[RW_Flag] = R1
CALL F_SACM_DVR1600_Initial;
R1 = 0
[RW_Flag] = R1
CALL F_Play_Initial
r1 = 15;
call F_SACM_DVR1600_Volume; // set Volume ,15 max;
r1 = 0; //play recorded speech
LoopplaySpeed:
R3 = 0; //ramp down disable after speech over
call F_SACM_DVR1600_Play;
LoopAutoSpeed:
r1 = 0x55aa
[P_Watchdog_Clr] = r1 //Reset watchdog
call F_SACM_DVR1600_ServiceLoop; //write data from ADC to SDARM;
CALL F_SACM_DVR1600_Status
TEST R1,0x01
JNZ LoopAutoSpeed
ExitPlayLoop:
call F_SACM_DVR1600_Stop
RETF
//////////////////////////////////////////////////////////
F_Play_Initial:
R1 = 0x200
[P_DtmfTone] = R1
R1 = B_EnDAC
[P_AFECtrl] = R1
R1 = 0
[RW_CountAddr] = R1
R1 = B_RecordBeginAddr
R2 = [R1]
[RW_Length] = R2 //get data length for user
R1 +=1
[RW_Address] = R1
R1 = 0xD500;
[P_Tmr_Ctrl]=R1; // Enable TmrA
R1 = 0xfffE; // Select 16k
[P_TmrA_Data]=R1; //
[P_TmrA_Load] = R1;
r1 = [P_Int];
R1| = B_TmrAInt;
[P_Int]=R1;
r1 = 0x8000;
[R_Test_Counter] = R1;
RETF
////////////////////////////////////////////////////
//| 中断服务程序
.text
_BREAK:
RETI
////////////////////////////////////////////////////
//| UART接收程序
_FIQ:
PUSH R1, R5 TO [SP];
//清UART中断标志,以便允许下载中断
R1 = B_UARTInt;
[P_IntClr] = R1;
//检测是否有数据需要接收
R1 = [P_UARTCmd2];
TEST R1, B_RxRdy
JNZ ?_FIQ_HaveData
GOTO ?_FIQ_Quit1; //如果没有数据需要接收,直接跳出
?_FIQ_HaveData:
R1 = [P_UARTData]; //获取串口数据
R1 &= 0x00FF;
//test
nop
nop
nop
[P_UARTData] = R1
//test
CMP R1,0x02
JNE ?_FIQ_Data1;
R2 = [R_ValidFrame]
CMP R2 , C_True
JE ?_FIQ_Data1
R1 = C_True;
[R_ValidFrame] = R1
R1 = C_True; //初始化命令字为true
[R_IsCmd] = R1;
R1 = C_False; //初始化接收参数为false
[R_IsPara] = R1
?_FIQ_Quit1:
GOTO ?_FIQ_Quit; //如果接收到的数据是0xFF,唤醒指令
?_FIQ_Data1:
R2 = [R_ValidFrame];
CMP R2, C_True
JNE ?_FIQ_Quit1
?_FIQ_DataIsValid:
R2 = [R_IsCmd]
CMP R2 , C_True
JNE ?_FIQ_IsPara //如果命令为真,则接收命令
//接到的数据是命令
?_FIQ_DataIsCmd:
[R_CommandType] = R1; //将系统命令存放在R_CommandType中
CMP R1, M_StopPlay
JE ?_FIQ_DataIsCmdproc1
R1 = C_False;
[R_IsCmd] = R1; //下一次接收到的数据一定是命令参数,设置为C_False
R1 = C_True;
[R_IsPara] = R1
JMP ?_FIQ_Quit1;
?_FIQ_IsPara:
R2 = [R_IsPara];
CMP R2, C_True
JNE ?_FIQ_IsData; //数据是命令,跳转,退出
[R_CharNum] = R1 //备份数据长度
[R_CommandValue] = R1; //该数据为命令携带的参数,将其存放于R_CommandValue中
R1 = C_False;
[R_IsPara] = R1
R1 = 0
[R_CurrentPos] = R1 //初始化存储指针为数据区第一个字
JMP ?_FIQ_Quit1;
?_FIQ_IsData:
R2 = [R_CommandValue]
JZ ?_FIQ_Quit1;
R2 = [R_CharNum];
JNZ ?_FIQ_DataIsValid2
?_FIQ_DataIsCmdproc1:
GOTO ?_FIQ_DataIsCmdproc;
?_FIQ_DataIsValid2:
R2 = [R_CommandType];
R2 &= 0x00FF
CMP R2 , M_StopPlay
JNE ?_FIQ_DataNotStop
GOTO ?_FIQ_DataIsCmdproc
?_FIQ_DataNotStop:
R3 = R2 &0xF0; //保留低字节,即命令
CMP R3, 0x30
JNE ?_UARTProc_RecvVolume
R2 = [R_playnum]
CMP R2 , C_MaxPlayNum
JB ?_FIQ_DataGetPosition
GOTO ?_FIQ_Quit;
?_FIQ_DataGetPosition:
R2 = [R_playnumtail]
R3 = 65
MR = R2 * R3
BP = UartPlayBuffer
BP += R3
R2 = [R_CommandValue] //播放缓冲区首地址
[BP++] = R2 //首个字存放播放长度
JMP ?_UARTProc_Recv //接收合成命令参数
?_UARTProc_RecvVolume:
CMP R2, M_VolumeSet
JNE ?_UARTProc_RecvMultiVoice; //接收音量参数
BP = R_VolumeSet
JMP ?_UARTProc_Recv
?_UARTProc_RecvSetSilence:
CMP R2, M_SetSilenceTime
JNE ?_UARTProc_RecvSetSpace; //接收静音时间
BP = R_chartime
?_UARTProc_Recv5:
R3 = [R_CharNum]
CMP R3 , 2
JE ?_UARTProc_Recv4
R2 = [BP]
R2 = R2 LSL 4
R2 = R2 LSL 4
R2 |= R1
[BP] = R1
GOTO ?_FIQ_DataIsCmdproc
?_UARTProc_Recv4:
[BP] = R1
R2 = [R_CharNum]
R2 -= 1
[R_CharNum] = R2
?_FIQ_Quit2:
GOTO ?_FIQ_Quit;
?_UARTProc_RecvSetSpace:
CMP R2, M_SetSpaceTime
JNE ?_FIQ_Quit2; //接收间隔时间
BP = R_spacetime
JMP ?_UARTProc_Recv5
?_UARTProc_RecvMultiVoice:
CMP R2, M_bMultiVoiceMode
JNE ?_UARTProc_RecvSetSilence; //接收多音字参数
BP = R_MultiMode
// JMP ?_UARTProc_Recv
?_UARTProc_Recv:
R4 = BP
R3 = [R_CurrentPos]
BP += R3
CMP R1 , 0xA1
JB ?_UARTProc_Recv1
R2 = [BP]
CMP R2 , 0
JNE ?_UARTProc_Recv2
[BP] = R1
JMP ?_UARTProc_Recv3
?_UARTProc_Recv2:
R1 = R1 LSL 4
R1 = R1 LSL 4
R2 = [BP]
R1 |= R2
?_UARTProc_Recv1:
[BP] = R1
R3 += 1 //如果是ASCII码,直接保存,保存指针指向下一位置
[R_CurrentPos] = R3
?_UARTProc_Recv3:
R2 = [R_CharNum]
R2 -= 1
[R_CharNum] = R2 ; //该数据为命令携带的参数,将其存放于R_CommandValue中
CMP R2 , 0
JNE ?_FIQ_Quit
R2 = C_False;
[R_ValidFrame] = R2
R2 = [R_CommandType];
R2 &= 0xF0
CMP R2 , 0x30
JNE ?_FIQ_Quit
R2 = [R_playnum]
R2 += 1
[R_playnum] = R2
R2 = [R_playnumtail] //调整播放尾指针
R2 += 1
CMP R2 , C_MaxPlayNum
JE ?_UARTProc_Playtail
[R_playnumtail] = R2
JMP ?_FIQ_DataIsCmdproc
?_UARTProc_Playtail:
R2 = 0
[R_playnumtail] = R2 //循环保存要播放的数据
JMP ?_FIQ_DataIsCmdproc
?_FIQ_DataIsCmdproc:
//接收完了命令和命令参数,对其进行解析处理
CALL F_UARTProc;
// R1 = C_False;
/// [R_ValidFrame] = R1
JMP ?_FIQ_Quit; //对命令和命令参数解析完成后,退出中断处理程序
//下一个数据数据长度开始可以接收
?_FIQ_Quit:
POP R1, R5 FROM [SP];
RETI
_IRQ0:
RETI
_IRQ1:
PUSH R1, R5 TO [SP];
//清除ioa中断标志
R1 = B_IoaInt;
[P_IntClr] = R1;
R1 = [P_Int];
R1 |= B_Irq2; //开启时钟中断
R1 &= ~B_Irq1; //关闭IRQ1中断
[P_Int] = R1;
R1 = B_Irq2;
[P_IntClr] = R1;
POP R1, R5 FROM [SP];
RETI
//////////////////////////////////////////////////////
_IRQ7:
PUSH R1,R5 TO [SP]
R1 = [P_IntClr]
R1 |= B_T8HzInt
[P_IntClr] = R1
POP R1,R5 FROM [SP]
RETI
_IRQ2:
PUSH R1,R5 TO [SP]
R1 = [P_IntClr]
R1 |= B_Irq2
[P_IntClr] = R1
R1 = [R_PlayName]
CMP R1 , C_True
JE ?_IsChNameIrq2
r1 = [P_IOC_Buf];
r1 ^ = 0xFF0F;
[P_IOC_Data] = r1;
call F_ISR_Service_SACM_DVR1600_FG;
JMP ?_Irq2_Quit
?_IsChNameIrq2:
call F_ISR_Service_ChName;
?_Irq2_Quit:
POP R1,R5 FROM [SP]
RETI
_IRQ4:
PUSH R1,R5 TO [SP]
R1 = [R_PlayName]
CMP R1 , C_True
JE ?_IsChNameIrq4
R1 = [P_IntClr]
R1 |= B_Irq4
[P_IntClr] = R1
r1 = [P_IOC_Buf];
r1 ^ = 0xFFF0;
[P_IOC_Data] = r1;
JMP ?_Irq4_Quit
?_IsChNameIrq4:
R1 = [P_IntClr]
R1 |= B_Irq4
[P_IntClr]=r1;
?_Irq4_Quit:
POP R1,R5 FROM [SP]
RETI
_IRQ3:
PUSH R1,R5 TO [SP]
R1 = [P_IntClr]
R1 |= B_Irq3
[P_IntClr] = R1
R1 = [R_SleepAdd]
R1 += 1
[R_SleepAdd] = R1
CMP R1 , 10
JB ?_Irq3_Quit
R1 = 0
[R_SleepAdd] = R1
R1 = M_GoSleep
CALL F_PostMessage
// R1 = [P_Tmr_Ctrl]
// R1 &= 0xFF7F; //TimerB.En=0
// [P_Tmr_Ctrl] = R1;
CALL F_TimerBDisable
?_Irq3_Quit:
POP R1,R5 FROM [SP]
RETI
_IRQ5:
RETI
_IRQ6:
PUSH R1,R5 TO [SP]
R1 = [P_IntClr]
R1 |= B_Irq6
[P_IntClr] = R1
POP R1,R5 FROM [SP]
RETI
.END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -