📄 function.asm
字号:
R2 = [R_playnumhead]
R2 += 1
CMP R2 ,C_MaxPlayNum
JB ?_ChNameAdjustHead
R2 = 0
?_ChNameAdjustHead:
[R_playnumhead] = R2 //头指针向下移动一位
R2 = [R_playnum]
R2 -= 1
[R_playnum] = R2 //播放条数减1
CMP R2 , 0x0
JNE ?_ChNameQuit
R1 = 0xFF02 //发送播放完
CALL F_UARTSendWord
?_ComposePlayEnd:
R2 = C_False;
[R_StopSign] = R2
R2 = 0x00FF;
[P_IOD_Dir] = R2; //设置IOD为输出状态(都设置为输出状态--低功耗)
R2 = 0x0000;
[P_IOD_Data] = R2;
CALL F_TimerBEnable
?_ChNameQuit:
CALL F_SetPlayTime
RETF
////////////////////////////////////////////////////
//| 函数名:F_PhrasePlay
//| 功 能:播放短语命令
//| 入 口:wu
//| 出 口:无
//| 影响的寄存器:无
////////////////////////////////////////////////////
F_PhrasePlay:
R2 = [R_playnumhead]
R3 = 65
MR = R2 * R3
BP = UartPlayBuffer
BP += R3
BP += 1 //播放缓冲区首地址
R1 = [BP] //短句序号
CMP R1 , B_PhraseNum
JAE ?_ChPhraseAdjust
?_PhrasePlay:
PUSH R1 TO [SP]
R2 = 0x00FF;
[P_IOD_Dir] = R2; //设置IOD为输出状态(都设置为输出状态--低功耗)
R2 = 0x0001;
[P_IOD_Data] = R2;
CALL F_TimerBDisable
R1 = C_True
[R_PlayName] = R1
CALL F_SPT6608_Init;
CALL F_ChNameInit; //TTS初始化
CALL F_VolumeSet //音量设置
POP R1 FROM [SP]
CALL F_ChPhrasePlay
?_ChPhraseWait:
CALL F_ChNameServiceLoop;
CALL F_ChNameGetStatus;
R2 = 0x55AA;
[P_Watchdog_Clr] = R2;
R2 = [R_StopSign]
CMP R2, C_True
JE ?_ChPhrasePlayEnd
CMP R1 , 0x0
JNE ?_ChPhraseWait
CALL F_ChNameStop
CALL F_TimerADisable
?_ChPhraseAdjust:
R2 = [R_playnumhead]
R2 += 1
CMP R2 ,C_MaxPlayNum
JB ?_ChPhraseAdjustHead
R2 = 0
?_ChPhraseAdjustHead:
[R_playnumhead] = R2 //头指针向下移动一位
R2 = [R_playnum]
R2 -= 1
[R_playnum] = R2 //播放条数减1
CMP R2 , 0x0
JNE ?_ChPhraseQuit
R1 = 0xFF02 //发送播放完
CALL F_UARTSendWord
?_ChPhrasePlayEnd:
R1 = C_False
[R_StopSign] = R1
R2 = 0x00FF;
[P_IOD_Dir] = R2; //设置IOD为输出状态(都设置为输出状态--低功耗)
R2 = 0x0000;
[P_IOD_Data] = R2;
CALL F_TimerBEnable
?_ChPhraseQuit:
CALL F_SetPlayTime
RETF
////////////////////////////////////////////////////
//| 函数名:F_SoundPlay
//| 功 能:播放声音
//| 入 口:无
//| 出 口:无
//| 影响的寄存器:无
////////////////////////////////////////////////////
F_SoundPlay:
R2 = [R_playnumhead]
R3 = 65
MR = R2 * R3
BP = UartPlayBuffer
BP += R3
BP += 1 //播放缓冲区首地址
R1 = [BP]
CMP R1 , B_SoundNum
JB ?_SoundPlay
GOTO ?_SoundPlayAdjust
// RETF
?_SoundPlay:
PUSH R1 TO [SP]
R2 = 0x00FF;
[P_IOD_Dir] = R2; //设置IOD为输出状态(都设置为输出状态--低功耗)
R2 = 0x0001;
[P_IOD_Data] = R2;
CALL F_TimerBDisable //无效定时器B
R1 = C_False
[R_PlayName] = R1 //播放声音
R1 = 0x8000;
[R_DAC] = R1;
[P_DAC] = R1;
nop
R1 = 0x55AA
R2 = 16
R4 =0
R3 = R1 ror 4
R3 = R1 ror 4
?_Loop2:
R3 = R3 LSL 1
R2 -=1
JNZ ?_Loop2
nop
R1 = 0
[RW_Flag] = R1
CALL F_SACM_DVR1600_Initial;
R1 = 0
[RW_Flag] = R1
CALL F_Play_Initial
CALL F_VolumeSet
?_SoundPlayNum:
POP R1 FROM [SP]
R3 = 0; //ramp down disable after speech over
CALL F_SACM_DVR1600_Play;
?_SoundLoop2:
R2 = 0x55AA;
[P_Watchdog_Clr] = R2;
CALL F_SACM_DVR1600_ServiceLoop; //A1600 Service loop;
CALL F_SACM_DVR1600_Status
R2 = [R_StopSign]
CMP R2, C_True
JE ?_SoundPlay_End
TEST R1,0x01
JNZ ?_SoundLoop2
call F_SACM_DVR1600_Stop
CALL F_TimerADisable
?_SoundPlayAdjust:
R2 = [R_playnumhead]
R2 += 1
CMP R2 ,C_MaxPlayNum
JB ?_ChSoundAdjustHead
R2 = 0
?_ChSoundAdjustHead:
[R_playnumhead] = R2 //头指针向下移动一位
R2 = [R_playnum]
R2 -= 1
[R_playnum] = R2 //播放条数减1
CMP R2 , 0x0
JNE ?_SoundQuit
R1 = 0xFF02 //发送播放完
CALL F_UARTSendWord
?_SoundPlay_End:
R2 = C_False
[R_StopSign] = R2
R2 = 0x00FF;
[P_IOD_Dir] = R2; //设置IOD为输出状态(都设置为输出状态--低功耗)
R2 = 0x0000;
[P_IOD_Data] = R2;
CALL F_TimerBEnable
?_SoundQuit:
CALL F_SetPlayTime
RETF
////////////////////////////////////////////////////
//| 函数名:F_VolumeSet
//| 功 能:设置音量0-15
//| 入 口:无
//| 出 口:无
//| 影响的寄存器:无
////////////////////////////////////////////////////
F_VolumeSet:
R1 = [R_VolumeSet]
CMP R1 , 0x0F
JA ?_VolumeSetVolume_End
R2 = [R_PlayName]
CMP R2 , C_True
JNE ?_VolumeSetVolume
CALL F_ChNameVolume;
JMP ?_VolumeSetVolume_End
?_VolumeSetVolume:
R1 = R1 LSR 1
CALL F_SACM_DVR1600_Volume;
?_VolumeSetVolume_End:
RETF
////////////////////////////////////////////////////
//| 函数名:F_bMultiVoiceMode
//| 功 能:设置多音字格式
//| 入 口:无
//| 出 口:无
//| 影响的寄存器:无
////////////////////////////////////////////////////
//F_bMultiVoiceMode:
// R1 = 1
// [R_MultiMode] = R1
// RETF
////////////////////////////////////////////////////
//| 函数名:F_SetSpaceTime
//| 功 能:设置两个字符间隔时间
//| 入 口:无
//| 出 口:无
//| 影响的寄存器:无
////////////////////////////////////////////////////
F_SetSpaceTime:
R1 = [R_spacetime]
CALL F_ChNameSetSpaceTime
RETF
////////////////////////////////////////////////////
//| 函数名:F_SetSilenceTime
//| 功 能:设置播放字符静音时间
//| 入 口:无
//| 出 口:无
//| 影响的寄存器:无
////////////////////////////////////////////////////
F_SetSilenceTime:
R1 = [R_chartime]
CALL F_ChNameSetCharTime
RETF
////////////////////////////////////////////////////
//| 函数名:F_SetPlayTime
//| 功 能:设置两个播放命令间的间隔时间
//| 入 口:无
//| 出 口:无
//| 影响的寄存器:无
////////////////////////////////////////////////////
F_SetPlayTime:
R1 = [R_playspacetime] //延时时间设置
?_SetPlayTime_Loop:
CMP R1 , 0
JE ?_SetPlayTime_Quit
// CALL F_Delay10ms //延时等待设置
CALL F_Delay
R1 -= 1
JNZ ?_SetPlayTime_Loop
?_SetPlayTime_Quit:
RETF
////////////////////////////////////////////////////
//| 函数名:F_StopPlay
//| 功 能:设置两个播放命令间的间隔时间
//| 入 口:无
//| 出 口:无
//| 影响的寄存器:无
////////////////////////////////////////////////////
F_StopPlay:
R1 = [R_PlayName]
CMP R1 , C_True
JE ?_StopPlayName
CALL F_SACM_DVR1600_Stop
JMP ?_StopPlayEnd
?_StopPlayName:
CALL F_ChNameStop
?_StopPlayEnd:
RETF
///////////////////////////////////////////////////////////////////////////
//| 函数名:F_ClearPlayRam
//| 功 能:设置两个播放命令间的间隔时间
//| 入 口:无
//| 出 口:无
//| 影响的寄存器:无
///////////////////////////////////////////////////////////////////////////////
F_ClearPlayRam:
R1 = 0x0
R2 = 520 //65*8
BP = UartPlayBuffer
?_ClearSram:
[BP++] = R1
R2 -= 1
JNZ ?_ClearSram
RETF
///////////////////////////////////////////////////////////////////////////
//| 函数名:F_ClearPlayRam
//| 功 能:设置两个播放命令间的间隔时间
//| 入 口:BP
//| 出 口:无
//| 影响的寄存器:无
///////////////////////////////////////////////////////////////////////////////
F_ClearOnePlayRam:
PUSH R1 ,R5 TO [SP]
R1 = 0x0
R2 = 65 //65*8
?_ClearOneSram:
[BP++] = R1
R2 -= 1
JNZ ?_ClearOneSram
POP R1 , R5 FROM [SP]
RETF
//////////////////////////////////////////////////////////////////
// Function: The partial code of hardware setting of ChNameInit()
//////////////////////////////////////////////////////////////////
F_SPT6608_Init:
push r1 to [sp];
//Enable TmrA for Int
R1 = B_UARTInt | B_T128HzInt;
R1 |= 0x0004;
[P_Int]=R1;
r1 = 0x0080;
[P_SystemClock]=r1; // Turn on CPU Speed to high Speed
R1 = 0xD5D0;
[P_Tmr_Ctrl]=R1; // Enable TmrA
R1 = 0xffff - 1;
[P_TmrA_Data]=R1; // Select 16 k sampling rate
R1 =0x0200;
[P_DtmfTone]=R1;
R1 = B_EnDAC //使能DAC输出
[P_AFECtrl] = R1
r1 = 0xFFFF;
[P_IntClr] = r1;
IRQ ON;
pop r1 from [sp];
RETF;
/////////////////////////////////////////////////////////////////
F_Play_Initial:
r1 = 0x0080;
[P_SystemClock]=r1; // Turn on CPU Speed to high Speed
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 = 0xD5D0;
[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
//***************************************************************/
//* 功能 : 延时10ms */
//* 入口 : 无 */
//* 出口 : 无 */
//* 影响寄存器 : 无 */
//* 说明 : 使用定时器A定时溢出,应用层延时:如两个播放命令的停顿时间 */
//***************************************************************/
.PUBLIC F_Delay10ms
F_Delay10ms:
PUSH R1 TO [SP]
//设置定时器
R1 = [P_Tmr_Ctrl]
R1 &= 0x00FF; //TimerA.En | counter | 32768Hz;
R1 |= 0xD500; // 1 10 10101
[P_Tmr_Ctrl] = R1
//清初值
R1 = 0
[P_TmrA_Data] = R1
[P_TmrA_Load] = R1
R1 = 0x55AA;
[P_Watchdog_Clr] = R1; //清看门狗
?_Delay10msLoop:
R1 = [P_TmrA_Data]
CMP R1,0xF5; //延时7.5ms
JLE ?_Delay10msLoop; //未溢出继续
R1 = [P_Tmr_Ctrl]
R1 &= 0x7FFF; //TimerA.En=0
[P_Tmr_Ctrl] = R1; //停止计数
POP R1 FROM [SP]
RETF
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
//--------------------------
//功能:将GB2312码解压缩成系统内码,将里面的ASCII码从单字节变成双字节
//入口:Str长度R1(字数单位:word),Str地址R2,存放的Wstr地址R3。
//出口:转换后的Wstr长度R1(单位:字数word)。
//影响寄存器:R1,R2,R3,R_StrLen。
//算法:取记录显示编辑时使用。解压缩时需注意最后一个字的低字节为空问题(碰到0xFF结束)。
// 剩下最后1字节为中文字符时,丢弃结束操作。
// 举例:0xA161,0xFFB0--->0x0061,0xB0A1
//--------------------------
.PUBLIC F_StrToWstr
F_StrToWstr:
PUSH R4,R5 TO [SP]
R5 =0
[R_StrLen] = R5 //转换后的Wstr长度
R5 = R1 //Str长度
JZ ?_StrToWstrRet
?_StrToWstrLoop:
R4 = [R2++] //Str DATA
R1 = R4 & 0x00FF
CMP R1,0x0080
JAE ?_StrToWstrWholeWord //中文字符(完整写入1WORD)
[R3++] = R1 //写入1个Wstr(低字节)
R1 = [R_StrLen]
R1 += 1
[R_StrLen] = R1 //转换后的Wstr长度 + 1
?_StrToWstrHighByte:
R4 = R4 LSR 4
R4 = R4 LSR 4
CMP R4,0x0080
JAE ?_StrToWstrChineseHigh ///Low //中文字符
JMP ?_StrToWstrASCII
?_StrToWstrWholeWord:
CMP R4,0xFF //高字节为0x00,结束退出。
JBE ?_StrToWstrOK
?_StrToWstrASCII:
[R3++] = R4 //写入1个Wstr
R1 = [R_StrLen]
R1 += 1
[R_StrLen] = R1 //转换后的Wstr长度 + 1
R5 -= 1
JZ ?_StrToWstrOK
JMP ?_StrToWstrLoop
?_StrToWstrChineseHigh://Low:
R5 -= 1
JZ ?_StrToWstrOK //这里有可能丢弃半个字的中文。
R1 = R4
R4 = [R2++] //Str DATA
PUSH R4 TO [SP]
R4 = R4 LSL 4
R4 = R4 LSL 4
R1 |= R4
[R3++] = R1 //写入1个Wstr
R1 = [R_StrLen]
R1 += 1
[R_StrLen] = R1 //转换后的Wstr长度 + 1
POP R4 FROM [SP]
JMP ?_StrToWstrHighByte
?_StrToWstrOK:
R1 = [R_StrLen]
?_StrToWstrRet:
POP R4,R5 FROM [SP]
RETF
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -