📄 main.asm
字号:
;CPU时钟用RC 4.0MHz,WDT:enable;LVR:enable;LVR range:low;=================================================================;6月27日的版本修改以下的项目:;1:调节MODE键直接可以调频道 ;已调整,待确认;2:两个版本的:其中一个上电后即PLAY, 另外一个要压下按键后才开始播放 ;现在还是PLAY中,待改;3:LED指示灯指示工作状态,如果是在PLAY中,则LED闪烁,停止时LED常亮 ;;4:遥控,暂时不加;5:对于不同的存储器(MP3与U盘),上电后可以开始的时间不一样,如何更好的处理?;增加上电后声音的记忆功能;LIST P=69P20CROMSIZE=0x03FF;=================================================================;================================================================= ORG 0000H JMP RESET JMP RESET JMP RESET ;T0中断用查询的方式,用于显示刷新与定时 JMP RESET JMP RESET;================================================================= ORG 0005HRESET: NOP NOP;=================================================================;=================================================================;================================================================= INT_SYS_SYSTEM:; LDI PFCNT ,1101B ;PF.0为输出;PF.1为输入(为状态HST_STS输入脚); LDI PECNT ,1111B ;PE.0~PE.3为输出 LDI PDCNT ,0001B ;PD.2为输出 LDI PCCNT ,1111B ;PC3,PC2为输出;PC1,PC0外接晶振 LDI PBCNT ,0000B ;PB.0,PB1,PB.2为输出,PB.3为按键输入脚 LDI PACNT ,1111B ;PA.0~PA.3都为输出 LDI PA ,1111B LDI PB ,1111B LDI PC ,1011B LDI PD ,1111B LDI PULL ,1100B ;上拉电阻打开,下降沿中断INT_T0_REG: ;T0为2MS定时器,用于LED的刷新 LDI T0MODE ,0101B ANDIM IRQ ,1011B LDI TL0 ,06H ;06H LDI TH0 ,00H ;中断为500uS;=================================================================CLR_RAM: ;RAM清零:RAM范围是030H-BFH的所有RAM全部清零,这个;***************************************************************** LDI DPL ,00H ;清除RAM从030H开始 LDI DPM ,02H LDI DPH ,00HRAM_CLEAR_1: LDI INX ,00H SBI DPM ,07H BNZ $+3 SBI DPL ,0FH BAZ INT_PORT ADIM DPL ,01H BNZ RAM_CLEAR_1 ADIM DPM ,01H BNz RAM_CLEAR_1INT_PORT: ;初始化IO,将LCD与背光LED关闭 LDI PA_TMP ,1111B ; STA PA LDI PB_TMP ,1111B ; STA PB LDI PC_TMP ,1011B STA PC LDI PD_TMP ,1111B STA PD LDI IRQ,0000B LDI IE,0000B ;;上电后,先不开端口中断,T0中断用查询的方法.端口中断需等上电稳定后(100MS后);发送一个波形,通知外设测试治具已准备好,同时打开端口中断;================================================================= LDI IRQ ,0000B LDI IE ,0000B ;开机显示步步高小写的标志 LDI WDT ,08H;=================================================================MAIN_START: ;开机的主程式;1:先发出命令关掉MP3;2:接下来再发出读命令读24C02相应的位置;3;读出值的判定:先判断以前是否常写过24C02(如果写入过,特定的值是C5);4:如果以前写入过24C02,根据此值设定发身频率; ;再调用命令将以前的文件夹编号与文件编号送给M ;然后再发送命令读M的状态,如果M的状态不是ERRO,则发送命令PLAY ;如果以前没有写入过24C02 ;初始化24C02,设发射频率为默认的频率,文件为头一个,然后写入 ;24C02 ;发送命令PLAY;24C02 EEPROM内部的说明:00H------对应的是有无写入的识别码,如果写入,此值为C4; 01H------发射频率码; 02H------文件夹的编号; 03H------文件的编号; 04H------音阶 CALL DELAY_20MS LDI DATA_ADDRH,00H LDI DATA_ADDRL,00H CALL READ_DATA ;读出识别写入码 LDA I2C_ERRO_CNT,00H BAZ $+4 SBI I2C_ERRO_CNT,03H BNC $-6 JMP I2C_NO_WRITE SBI READ_DATAL,04H BNZ I2C_NO_WRITE ;如果读的第1位不是C4,则认为没有写入 SBI READ_DATAH,0CH BNZ I2C_NO_WRITE ;是新机,还没有用过的测试方法 JMP I2C_NO_WRITE I2C_WRITE: ;以前24C02写入过;4:如果以前写入过24C02,根据此值设定发身频率; ;再调用命令将以前的文件夹编号与文件编号送给M ;然后再发送命令读M的状态,如果M的状态不是ERRO,则发送命令PLAY LDI DATA_ADDRH,00H LDI DATA_ADDRL,01H CALL READ_DATA ;读出发射频率码 LDA I2C_ERRO_CNT,00H BAZ $+4 SBI I2C_ERRO_CNT,03H BNC $-6 ;如果读发生错误的次数小于三次,再读 JMP I2C_FRE_CHANGE ;如果连续三次读错,则使用默认频道 SBI READ_DATAL,07H LDI R0 ,00H SBC READ_DATAH,00H BC I2C_FRE_CHANGE ;如果存入的频道值大于8,则认为频道错,用默认频道 ;如果以前存入的频率值合法,则设定发射频率 LDA READ_DATAL ;频率值没有改变,则将此值改为默认的 STA FRE_MODE ;将发射码的值保存 STA PC_TMP ORIM PC_TMP ,1000B STA PC CALL DELAY_5S LDI SEND_COM,03H CALL SEND_COMMAND ;先发送一个停止的指令给BU9432 JMP I2C_WJ_CHECK I2C_FRE_CHANGE:;如果以前存入的频率值不合法,则设定频率为默认的频率 LDI FRE_MODE,03H LDI DATA_L,03H LDI DATA_H,00H ;设定写入I2C的值 LDI DATA_ADDRL,01H LDI DATA_ADDRH,00H ;写入频率的位置为01H CALL WRITE_DATA ;将默认诉频率值写入给I2C,以便记忆 CALL DELAY_5MS LDI PC_TMP ,1011B STA PC CALL DELAY_5S LDI SEND_COM,03H CALL SEND_COMMAND ;先发送一个停止的指令给BU9432 LDI DATA_ADDRH,00H LDI DATA_ADDRL,02H LDI DATA_H ,00H LDI DATA_L ,01H CALL WRITE_DATA ;写入初始文件夹的编号,为01H CALL DELAY_5MS LDI DATA_ADDRH,00H LDI DATA_ADDRL,03H LDI DATA_H ,00H LDI DATA_L ,01H CALL WRITE_DATA ;写入初始文件的编号,为01H CALL DELAY_5MS ;延时5MS的子程式I2C_WJ_CHECK: LDI SEND_COM,01H CALL SEND_COMMAND ;发送命令01H(开始的命令) CALL DELAY_5MS ;每写完1位延时5MS CALL DELAY_5MS ;每写完1位延时5MS CALL DELAY_5MS ;每写完1位延时5MS CALL DELAY_20MS ;每写完1位延时5MS LDI DATA_ADDRL,02H LDI DATA_ADDRH,00H CALL READ_DATA ;先读文件夹的编号,再读文件的编号 LDA I2C_ERRO_CNT,00H BAZ $+4 SBI I2C_ERRO_CNT,03H BNC $-6 JMP SEND_START ;如果连续三次读错误文件,则取消记忆 LDA READ_DATAL,00H STA DIR_L,00H STA DIR_BACK_L,00H ;备份文件夹的编号 LDA READ_DATAH,00H STA DIR_H,00H ;文件夹的编号高位 STA DIR_BACK_H,00H SEND_DIR_NO: ;发送命令确定文件夹的编号 LDA DIR_H ,00H BNZ SEND_DIR_1 SBI DIR_L ,01H BAZ SEND_FILE_CHECKSEND_DIR_1: SBIM DIR_L,01H LDI R0,00H SBCM DIR_H,00H ;如果文件夹的编号为0,则发送文件的编号 LDI SEND_COM,06H CALL SEND_COMMAND ;如果文件夹的编号还没有减到0,则再发送一个 CALL DELAY_20MS ;每写完1位延时5MS CALL DELAY_20MS ;每写完1位延时5MS CALL DELAY_20MS ;每写完1位延时5MS CALL DELAY_20MS ;每写完1位延时5MS CALL DELAY_5MS ;每写完1位延时5MS CALL DELAY_5MS ;每写完1位延时5MS JMP SEND_DIR_NOSEND_FILE_CHECK: CALL DELAY_5MS ;每写完1位延时5MS LDI DATA_ADDRL,03H LDI DATA_ADDRH,00H CALL READ_DATA ;再读文件的编号 LDA I2C_ERRO_CNT,00H BAZ $+4 SBI I2C_ERRO_CNT,03H BNC $-6 JMP SEND_START ;如果连续三次读错误文件,则取消记忆 LDA READ_DATAL,00H STA FILE_L,00H STA FILE_BACK_L,00H ;备份文件的编号 LDA READ_DATAH,00H ;文件的编号高位 STA FILE_H,00H STA FILE_BACK_H,00H ;备份文件的编号 CALL DELAY_5MS ;每写完1位延时5MS;'; CALL DELAY_5MS ;每写完1位延时5MS; call DELAY_20MSSEND_FILE_NO: ;发送命令确定文件的编号 LDA FILE_H ,00H ;如果文件编号为0,则发送文件的编号 BNZ SEND_FILE_1 ;如果文件夹的编号为0,则发送文件的编号 SBI FILE_L,01H BAZ SEND_STARTSEND_FILE_1: SBIM FILE_L,01H LDI R0,00H SBCM FILE_H,00H LDI SEND_COM,04H CALL SEND_COMMAND ;如果文件夹的编号还没有减到0,则再发送一个 CALL DELAY_20MS ;每写完1位延时5MS CALL DELAY_20MS ;每写完1位延时5MS CALL DELAY_20MS ;每写完1位延时5MS CALL DELAY_20MS ;每写完1位延时5MS CALL DELAY_5MS ;每写完1位延时5MS CALL DELAY_5MS ;每写完1位延时5MS JMP SEND_FILE_NOSEND_START:; LDI SEND_COM,01H; CALL SEND_COMMAND ;发送命令01H LDI SEND_COM,09H CALL SEND_COMMAND ;发送完文件编号后,再送一个PLAY命令,再读状态 CALL DELAY_5MS LDA RD_STATUS14 ;如果状态错误,则返回原程式的地方再次执行 BA3 MAIN1; BA3 READ_ERRO ;如果错误位为1,则说明读错; JMP MAIN1 ;如果没有错误,则进入主程式开始循环READ_ERRO:; LDI SEND_COM,03H; CALL SEND_COMMAND ;先发送一个停止的命令 CALL DELAY_5MS LDI SEND_COM,01H CALL SEND_COMMAND ;再发送一个重新开始的命令 CALL DELAY_5MS JMP MAIN1 ;如果没有错误,进入主程式开始循环 I2C_NO_WRITE: ;以前24C02没有写入过; LDI DATA_ADDRH,00H; LDI DATA_ADDRL,00H; LDI DATA_H ,0CH; LDI DATA_L ,04H; CALL WRITE_DATA ;读出识别写入码; CALL DELAY_5MS ;延时5MS的子程式 LDI FRE_MODE,03H ;将频率开始置为3档 LDI DATA_L,03H LDI DATA_H,00H ;设定写入I2C的值 LDI DATA_ADDRL,01H LDI DATA_ADDRH,00H ;写入频率的位置为01H CALL WRITE_DATA ;将默认诉频率值写入给I2C,以便记忆 CALL DELAY_5MS LDI PC_TMP ,1011B STA PC CALL DELAY_5S LDI SEND_COM,03H CALL SEND_COMMAND ;先发送一个停止的指令给BU9432 LDI DATA_L ,01H LDI DATA_H ,00H ;设定写入I2C的值(初始文件夹编号) LDI DATA_ADDRL,02H LDI DATA_ADDRH,00H ;写入频率的位置为00H CALL WRITE_DATA CALL DELAY_5MS ;每写完一位延时5MS LDI DATA_L ,01H LDI DATA_H ,00H ;设定写入I2C的值(初始文件编号为01) LDI DATA_ADDRL,03H LDI DATA_ADDRH,00H ;写入频率的位置为01H CALL WRITE_DATA; CALL DELAY_5MS ;每写完1位延时5MS; CALL DELAY_5MS ;确定完频率后再发送一个开始命令就可以了; CALL DELAY_5MS; CALL DELAY_5MS; CALL DELAY_5MS ;确定完频率后再发送一个开始命令就可以了; CALL DELAY_5MS; CALL DELAY_5MS ;确定完频率后再发送一个开始命令就可以了; CALL DELAY_5MS; CALL DELAY_5MS ;确定完频率后再发送一个开始命令就可以了; CALL DELAY_5MS; CALL DELAY_5MS ;确定完频率后再发送一个开始命令就可以了; CALL DELAY_5MS CALL DELAY_20MS CALL DELAY_20MS CALL DELAY_20MS LDI SEND_COM,01H CALL SEND_COMMAND ;发送一个一始命令 CALL DELAY_20MS CALL DELAY_20MS LDI DATA_ADDRH,00H LDI DATA_ADDRL,00H LDI DATA_H ,0CH LDI DATA_L ,04H CALL WRITE_DATA ;读出识别写入码 CALL DELAY_5MS ;延时5MS的子程式 CALL DELAY_5MS LDI WORK_FLAG,0001B ;说明上电初始化后是在工作中 ; JMP MAIN1 ;进入主程式开始循环;=================================================================MAIN1: ;上电后不开始,先关断再说 NOP NOP; ORIM WORK_FLAG,0001B ANDIM WORK_FLAG,1110B LDI SEND_COM,02H CALL SEND_COMMAND CALL DELAY_5MSMAIN: LDI WDT ,08H LDA WORK_FLAG,00H BA0 $+2 ;如果是在工作中,则调整声音 JMP $+2 JMP VOICE ;调整声音的子程序MAIN_VOICE: LDI WDT ,08H JMP KEY_SCAN ;按键扫描的子程式MAIN_KEY_SCAN: LDI WDT ,08H JMP INT_TIMER0 ;调用时间的查询子程式MAIN_INT_TIMER0: LDI WDT ,08H; CALL SEND_COMMAND ;发送命令的子程式 JMP MAIN;=================================================================VOICE: ;如果是在工作中,检查声音是否已调整过,如果调整过,则结束 LDA WORK_FLAG,00H BA3 VOICE_EXIT ORIM WORK_FLAG,1000B ;设置已调整过的标志 LDI DATA_ADDRH,00H LDI DATA_ADDRL,04H CALL READ_DATA ;读出音阶 LDA I2C_ERRO_CNT,00H BAZ $+4 SBI I2C_ERRO_CNT,03H BNC $-6 JMP VOICE_NO_CHANGE ;如果连续三次读错误文件,则取消记忆 SBI READ_DATAL,0AH ;如果是大于32,则音阶不合法,用28D LDI R0 ,02H SBC READ_DATAH,00H BC VOICE_NO_CHANGE ;使用80%音阶VOICE_CHANGE: LDA READ_DATAL,00H STA VOICE_BACK_L,00H STA VOICE_CNT_L ,00H LDA READ_DATAH,00H STA VOICE_BACK_H,00H STA VOICE_CNT_H ,00H SBI VOICE_BACK_L,00H LDI R0 ,01H SBC VOICE_BACK_H,00H BC VOICE_CHANGE_ADD SBI VOICE_BACK_L,0FH LDI R0 ,00H SBC VOICE_BACK_H,00H BNC VOICE_CHANGE_DEC JMP VOICE_EXIT ;如果存入的音量为10,则不改变VOICE_CHANGE_DEC: LDI R0 ,0FH LDA VOICE_BACK_L,00H SUBM R0 ,00H STA VOICE_BACK_L,00H LDI VOICE_BACK_H,00HVOICE_DEC: LDA VOICE_BACK_H ,00H BNZ VOICE_ADJUST_ING LDA VOICE_BACK_L ,00H BAZ VOICE_EXIT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -