应广单片机 PMS150G 161 171 基础例子 GPC 比较器 内部参考电压

本文介绍了如何在嵌入式系统中使用比较器,通过PA.3脚与内部参考电压的9/32比例进行对比,并利用GPC_out输出结果。当PA.3电压高于阈值时,GPC_out输出0,反之输出1。讲解了相关的设置步骤和关键函数调用。
//==================================================//
//					比较器的设置
//案例为:
//输入脚PA.3与内部参考电压的9/32进行比较
//比较的结果通过GPC_out输出
//当PA.3大于内部参考电压的9/32时GPC_out为0
//当PA.3小于内部参考电压的9/32时GPC_out为1
//==================================================//
#include	"extern.h"

void	Comparator(void)
{
	//设置比较器的输入脚需要停用上拉、下拉、数字输入使能
	PAC.3 = 0;
	PAPH.3 = 0;
	PADIER = 0b1111_0001;		//注:其他脚默认为1,需要关闭的请手动修改
	$ GPCC Enable,N_PA3,P_R;	//是否启用比较器;选择比较器结果是否有TM2_CLK采样输出(写Sync_TM2为选择,不写为不选);选择是否反极性(写为选择,不写为不选);选择负输入来源;选择正输入来源。
								//是否启用比较器:Enable为启用,Disable为停用
								//选择负输入来源:N_PA3, N_PA4, BANDGAP, N_R(内部参考电压), N_PA6, N_PA7(PA6、PA7不能仿真)
								//选择正输入来源:P_R(内部参考电压), P_PA4
	$ GPCS VDD*9/32;			//比较器输出启用到PA0(写output启用,不写停用);选择比较器参考电压范围
								//注:在仿真器上,输出到 PA0 也会造成 PA3 输出不良,请避开此问题
								//比较器参考电压范围:共有四种分别为
								//	VDD*(9~24)/32		对应GPCS[5:4]=00;	GPCS[3:0]=0000~1111;
								//	VDD*(1~16)/24		对应GPCS[5:4]=01;	GPCS[3:0]=0000~1111;
								//	VDD*(9~24)/40		对应GPCS[5:4]=10;	GPCS[3:0]=0000~1111;
								
#include "extern.h" BIT LED : PA.3; // OUT 电机控制 (正极) BIT LED2 : PA.7; // OUT LED负极 (高电平熄灭,低电亮点亮) BIT KEY : PA.5; // IN 按键 BYTE mode; //0休眠 1工作 BIT lowVoltageFlag; //低电压标志(1=电压低于2V) BYTE lowVoltageCnt; //低电压计数 WORD batCheckTimer; //电池检测计时器(单位ms) void Io_init(void) { pa = 0b0000_0000; pac = 0b1000_1000; // PA.3和PA.7设为输出 paph = 0b1010_0000; padier = 0b0010_0000; // 初始化LED2为高电平(熄灭) LED2 = 1; } WORD t16_cnt; //初始装载值 void T16_INIT(void) { T16M = 0b00000101; // IHRC, /64, 16-bit mode t16_cnt = 32768-250; // 250*4us = 1ms stt16 t16_cnt; } void T16IRQ_INIT(void) { INTEN.T16 = 1; //打开T16中断 INTRQ.T16 = 0; //清除T16中断请求 ENGINT; //打开全局中断4 } void Gpc_init(void) { GPCS = 0b00011000; // VDD*(24)/40 GPCC = 0b10000010; // enable,BANDGAP,P_R } void CheckBattery(void) // 改为void函数,通过全局变量传递结果 { if(GPC_out == 0) // VDD < 2V { lowVoltageCnt++; if(lowVoltageCnt >= 10) { lowVoltageFlag = 1; } } else { lowVoltageCnt = 0; lowVoltageFlag = 0; } } BIT key_on; WORD key_cnt; BIT key_state; void Keyscan(void) { if(KEY == 0) { key_cnt++; if(key_cnt >= 29 && key_state == 0) { key_cnt = 29; key_on = 1; key_state = 1; } } else { key_on = 0; key_cnt = 0; key_state = 0; } } BYTE g8SleepClkmdBK; void Sleep_init(void) { g8SleepClkmdBK = CLKMD; $ CLKMD ILRC/1,En_IHRC,En_ILRC; nop; CLKMD.En_IHRC = 0; nop; stopexe; $ CLKMD ILRC/1,EN_IHRC,EN_ILRC; nop; CLKMD = g8SleepClkmdBK; key_on = 1; key_state = 1; } void Work(void) { if(key_on == 1) { key_on = 0; if(mode == 1) { mode = 0; } else if(lowVoltageFlag == 0) // 只有电压正常才允许切换到工作模式 { mode = 1; } } if(mode == 1) // 工作模式 { if(lowVoltageFlag) { LED = 0; // 关闭电机/LED正极 LED2 = 1; // LED负极高电平(熄灭) mode = 0; // 强制切换到睡眠模式 } else { LED = 1; // 打开电机/LED正极 LED2 = 0; // LED负极低电平(点亮) } } else // 睡眠模式 { LED = 0; // 关闭电机/LED正极 LED2 = 1; // LED负极高电平(熄灭) if(lowVoltageFlag == 0) { Sleep_init(); } } } void FPPA0(void) { .ADJUST_IC SYSCLK=IHRC/8, IHRC=16MHz, VDD=3V, Init_RAM; Io_init(); T16_INIT(); T16IRQ_INIT(); Gpc_init(); // 开机先检测一次电压 // CheckBattery(); // if(lowVoltageFlag == 1) // { // mode = 0; // 直接进入睡眠模式 // } while (1) { wdreset; // 每500ms检测一次电池电压 batCheckTimer++; if(batCheckTimer >= 500) { batCheckTimer = 0; CheckBattery(); } Keyscan(); Work(); } } void Interrupt(void) { pushaf; if (Intrq.T16 == 1 && INTEN.T16 == 1) { Intrq.T16 = 0; stt16 t16_cnt; } popaf; }帮我优化下
08-01
你好,如下代码中,没有给出输出 的 IO 指令,是否可以补充完善?://*******product model:RGB 7 彩灯 .CHIP PMS132B ;SOP16 //.CHIP PFC154 ;SOP14 //.CHIP PMC153 ;SOP14 //{{PADAUK_CODE_OPTION .Code_Option LVR 3.5V .Code_Option Security Enable // Security 7/8 words Enable .Code_Option Comparator_Edge All_Edge .Code_Option Bootup_Time Slow .Code_Option PWM_Source 16MHz .Code_Option GPC_PWM Disable .Code_Option Interrupt_Src1 PB.0 .Code_Option Interrupt_Src0 PA.0 .Code_Option PB4_PB7_Drive Strong //}}PADAUK_CODE_OPTION .INCLUDE "HEAD.H" ;----------- 常量定义 ----------- SYNC_MIN EQU 80 ; 同步头最小(8ms)32 SYNC_MAX EQU 140 ; 同步头最大(14ms)56 DATA_0_MIN EQU 2 ; 数据0最小(0.2ms) DATA_0_MAX EQU 6 ; 数据0最大(0.6ms) DATA_1_MIN EQU 8 ; 数据1最小(0.8ms) DATA_1_MAX EQU 14 ; 数据1最大(1.4ms) RF EQU PA.0 ;RF_IN_Size => 3 ;MAX_BRIGHTNESS EQU 6 ;6级亮度 ;********************************************************* .ROMADR 0X001 ;; GOTO FPPA0 ;******************************************************** .ROMADR 0X10 ;INTERR IN address ;====================== 中断服务程序 ====================== INTERRUPT: PUSHAF ; 保存现场 T1SN INTRQ.2;T16 GOTO TM2_INT ;------------------------------------------- TM16_INT: SET0 INTRQ.2 SET1 TIME_T16_INT_1MS_FLAG ; 处理T16中断 INC T16_TIEMS_COUNTER_TIME_R ; 每次进入中断时,递增一个计时器变量,用于累计时间 ; 检查是否达到40ms MOV A, T16_TIEMS_COUNTER_TIME_R ; 将计时器值加载到累加器A中 CEQSN A, 40 ; 如果A等于40,则跳转到UPDATE_GRADIENT执行颜色更新逻辑 GOTO ISR_EXIT; ; 否则直接退出中断 GOTO UPDATE_GRADIENT UPDATE_GRADIENT: ; 更新渐变步进 INC STEP_A ; 增加STEP_A,表示A路LED的色相步进 DZSN STEP_A;, RESET_STEP_A ; 如果STEP_A溢出(即超过255),则跳转到RESET_STEP_A重置为0 GOTO $+2 GOTO RESET_STEP_A INC STEP_B ; 增加STEP_B,表示B路LED的色相步进 DZSN STEP_B;, RESET_STEP_B ; 如果STEP_B溢出(即超过255),则跳转到RESET_STEP_B重置为0 GOTO ISR_EXIT GOTO RESET_STEP_B ; 跳回中断退出点 RESET_STEP_A: MOV A,0 MOV STEP_A,A; 0; ; 将STEP_A重置为0,重新开始下一个颜色循环 GOTO ISR_EXIT; ; 返回中断退出点 RESET_STEP_B: MOV A,0 MOV STEP_B,A; 0; ; 将STEP_B重置为0,重新开始下一个颜色循环 GOTO ISR_EXIT; ; 返回中断退出点 ;------------------------------------------ TM2_INT: ; TM2中断处理 (250us周期) T1SN INTRQ.TM2 ; 检测TM2中断标志 GOTO CHECK_RF ;PA0 中断检查 INC Timer_250us ; 专用TM2计数器 SET0 INTRQ.TM2 ; 清除中断标志 MOV A, 170;72;80;Timer_250us ; 加载计数器值 SUB A, Timer_250us ; 18ms超时检测 T1SN FC ; 检查是否超时 GOTO ISR_Exit ; 未超时继续 SET0 RF_Start ; 超时复位接收状态 CLEAR Timer_250us ; 重置计时器 GOTO ISR_Exit; CHECK_RF: T1SN INTRQ. RF ; 检测RF中断标志 GOTO ISR_Exit ;ISR_END T1SN PA.0 ; 检测PA0当前电平(1=高电平) GOTO RF_Clear;RF_Low ; 低电平处理分支 T1SN RF_Start ; 检查是否已经开始接收 GOTO Check_Start ; 起始码检测分支 ; 数据位 ;------ 1码检测-------------------- ;----- 0:----0.3ms-0.6mS H + 0.8mS-1.4ms L ;------1:----0.8-1.4ms H + 0.3-1.4ms L ;结束位:-----0.3-0.6ms H + 10-14ms L ;(Timer_250us>=3 && Timer_250us<=5) //0.75~1.25ms INC Icnt ; 位计数器加1 MOV A, Timer_250us ; 加载计时器值 SUB A,DATA_1_MIN; 3 ; 1码检测下限(0.75ms) T0SN FC ; 检查是否大于下限 GOTO Check_Zero ; 跳转0码检测 MOV A,DATA_1_MAX; 5 ; 1码检测上限(1.25ms) SUB A, Timer_250us ; 计算时间差 T0SN FC ; 检查是否小于上限 GOTO Check_Zero ; 跳转0码检测 SET0 CF ; 设置进位标志为1 SLC Data_In$0 ; 数据左移并带进位 SLC Data_In$1 ; 数据左移并带进位 SLC Data_In$2 ; 数据左移并带进位 GOTO Check_Complete ; 跳转完成检测 Check_Zero: ; ------0码检测------- ;(Timer_250us>=1 && Timer_250us<=2)//0.25~0.5ms MOV A, Timer_250us ; 加载计时器值 SUB A,DATA_0_MIN; 1 ; 0码下限(0.25ms) T0SN FC ; 检查是否大于下限 GOTO Data_Error ; 错误处理 MOV A,DATA_0_MAX; 2 ; 0码上限(0.5ms) SUB A, Timer_250us ; 计算时间差 T0SN FC ; 检查是否小于上限 GOTO Data_Error ; 错误处理 SET1 FC ; 设置进位标志为0 SLC Data_In$0 ; 数据左移并带进位 SLC Data_In$1 ; 数据左移并带进位 SLC Data_In$2 ; 数据左移并带进位 Check_Complete: ; 完成检测 MOV A, 24 ; 加载位计数器 XOR A, Icnt ; 检查是否满24位 T1SN FZ ; 判断是否完成 GOTO RF_Clear ; 未完成继续接收 ; SET1 RF_End ; 设置接收完成标志 SET0 RF_Start ; 清除接收开始标志 ; 数据存储与校验 current_RF_ID_R0 = Data_In$0; ;.0-7 ; 存储低8位 current_RF_ID_R1 = Data_In$1; current_RF_ID_R2 = Data_In$2; T0SN FIRST_ID_SVAE_FLAG GOTO SVAE_ID ; DTAT_SAVE_R0=current_RF_ID_R0; DTAT_SAVE_R1=current_RF_ID_R1; DTAT_SAVE_R2=current_RF_ID_R2; SET1 FIRST_ID_SVAE_FLAG SVAE_ID: SET1 RF_END GOTO RF_Clear ; 跳转中断清除 Check_Start: ; 起始码检测 ;----(Timer_250us>=32 && Timer_250us<=48) //用8-12ms低电平做起始码 MOV A, Timer_250us ; 加载计时器值 SUB A,SYNC_MIN; 32 ; 起始码下限(8.75ms) T0SN FC ; 检查是否大于下限 GOTO RF_Clear ; 无效起始码 MOV A,SYNC_MAX; 56;48 ; 起始码上限(11.25ms) SUB A, Timer_250us ; 计算时间差 T0SN FC ; 检查是否小于上限 GOTO RF_Clear ; 无效起始码 SET1 RF_Start ; 设置接收开始标志 Data_In = 0 ; ; 清空数据缓存 CLEAR Icnt ; 复位位计数器 CLEAR Timer_250us ; 重置250us计时器 GOTO RF_Clear Data_Error: ; 错误处理 CLEAR Icnt ; 复位位计数器 SET0 RF_Start ; 清除接收开始标志 Data_In = 0 ; ; 清空数据缓存 CLEAR Timer_250us ; 重置250us计时器 RF_Clear: ; RF中断清除 SET0 INTRQ.RF ; 清除RF中断标志 CLEAR Timer_250us ; 重置250us计时器 GOTO ISR_Exit ; 跳转中断退出 TM2_Clear: ; 定时器中断清除 SET0 INTRQ.TM2 ; 清除定时器中断标志 GOTO ISR_EXIT ISR_Exit: ; 中断退出 POPAF ; 恢复A和FLAG寄存器 RETI ; 中断返回 ;-------------------------------------------- //======================================================= FPPA0: .ADJUST_IC SYSCLK=IHRC/4, IHRC=16MHz, VDD=5.0V; // WatchDog Disable, RAM 0 ~ 0xF temporary be used //You can add the follow code : CLKMD.En_WatchDog=0; // WatchDog Enable SP=STACK0 ;//--------------CLRRAM ---------------------- Initialize: ; CALL DELAY_1SUP; MOV A,_SYS(RAM_SIZE)-1 MOV LB@RAM_POINTER,A CLEAR HB@RAM_POINTER L_CLRRAMLP: MOV A,0X00 IDXM RAM_POINTER,A DZSN LB@RAM_POINTER GOTO L_CLRRAMLP ;//--------------INITIAL IO---------------------- IO_Initialize: PA = 0B_0000_0000; PAC = 0B_0111_1000; ; //0:input;1:output; PAPH = 0B_1111_1001; ;1=ENABLED PULL UP PADIER=0B_1111_1111; PB=0B_1000_0000; PBC=0B_0111_1001; ; //0:input;1:output; PBPH=0B_1111_1001; ;1=ENABLED PULL UP PBDIER=0B_1111_1111; ;--------TM2 100uS ------------------- ; TM2CT=0; ; 清零定时器计数器 ; MOV A,9 ; MOV TM2B, A ; 设置预分频值为9 ; $ TM2C IHRC,Period ; 配置时钟源为内部高速RC ; $ TM2S 8BIT,/16,/25 ; 设置8位模式,16分频,25周期 ;100US tm2ct = 0; tm2b = 4; $ TM2C IHRC,Disable,Period; $ TM2S 8bit,/64,/5; SET0 INTRQ.TM2; ; 清除定时器中断标志 SET1 INTEN.TM2; ; 使能定时器中断 ;-----------PA0 IN_INT --------------------------- //设置PA0引脚输入模式,根据情况选择是否需要上拉 $ PA.0 in,pull; $ INTEGS PA0_B; //PA0中断边缘选择,上升缘和下降缘上升缘都请求中断PA0_B,上升缘请求中断为PA0_R,下降缘请求中断为PA0_F。 SET1 INTEN.PA0; = 1; //中断允许寄存器,开PA0中断 SET0 INTRQ.PA0; = 0; //中断请求寄存器,清零INTRQ寄存器。 ;-------------1MS--------------------------------------- Reload_T16 = 32768 - 16000; stt16 Reload_T16; $ T16M IHRC,/1,bit15; $ INTEGS BIT_R; INTRQ.T16 = 0; INTEN.T16 = 1; Engint; ;************************************************************* START: ;PG2PWM=>PB.3 => RED_A;//A路红色,使用内部 PG2PWM资源,8位; ;PG1PWM=>,PA.4 => BLU_A;//A路蓝色,使用内部 PG1PWM资源,8位; ;PA.3 => GRE_A;//A路绿色,用IO口模拟 输出PWM ;PB.6 => RED_B;B路红色,用IO口模拟 输出PWM ;PB.5 => GRE_B;//B路绿色,用IO口模拟 输出PWM ;PB.4 => BLU_B;//B路蓝色,用IO口模拟 输出PWM MOV A,0 ; 清除累加器 A SET1 POWER_RUN_FALG; 设置初始状态为开启 MOV A,6 MOV CUR_MODE,A; 7 ; 设置当前模式为7 MOV A,2 MOV BRIGHT_LEVEL,A; 3 ; 设置初始亮度等级为中间值 MOV A,128 MOV HUE_A,A;A路色相值 MOV HUE_B,A;B路色相值 CLEAR T16_TIEMS_COUNTER_TIME_R; 清除计时器 Data_In = 0 ; ; 清空数据缓存 ;------------PWMG1--PA4---/A路蓝色-------------------------------- START_LOOP: $ PWMG1C Enable,PA4,IHRC; PA4 OUT PWM $ PWMG1S /4,/1; PWMG1DTL = 0b010_00000; PWMG1DTH = 0b0100_0111; PWMG1CUBL = 0b10_000000; PWMG1CUBH = 0b1000_1110; ;------------PWMG2----A路红色--------------------------------- $ PWMG2C Enable,PB3,IHRC; PB3 OUT PWM $ PWMG2S /4,/1; PWMG2DTL = 0b010_00000; PWMG2DTH = 0b0100_0111; PWMG2CUBL = 0b10_000000; PWMG2CUBH = 0b1000_1110; ;--------------PA3 A-----A路绿色---------------------------- T1SN TIME_T16_INT_1MS_FLAG; 1mS 中断标志 GOTO MAIN SET0 TIME_T16_INT_1MS_FLAG ; 请补充 PA3 输出 PWM ; 初始化定时器 T16 GOTO MAIN; 跳转到主循环 ;********************************************************* ;暖白-红-绿-蓝-紫-青-粉-白光-黄光 MAIN: CALL COMPLETE_RF_ID CALL Power_Control_ON_OFF CALL MODE_DECIDE NOP GOTO MAIN ;***************************************************************** COMPLETE_RF_ID: T1SN RF_End ; 设置接收完成标志 RET current_ID_COMPLETE: MOV A,current_RF_ID_R1; CEQSN A,DTAT_SAVE_R1 GOTO ID_EEROR MOV A,current_RF_ID_R2 CEQSN A,DTAT_SAVE_R2 RET SET1 ID_COMPLETE_OK_FLAG;ID 正确 SET0 RF_End ; 设置接收完成标志 current_RF_ID_R0 = Data_In$0; RET ID_EEROR: SET0 ID_COMPLETE_OK_FLAG;ID 正确 SET0 RF_End ; 设置接收完成标志 RET ;**************************************************************** Power_Control_ON_OFF: MOV A,02H ; 将按键值加载到ACC中 XOR A,current_RF_ID_R0 ; 检查是否为02H(开/关机) T1SN FZ RET CLEAR current_RF_ID_R0 T0SN POWER_RUN_FALG GOTO Power_Control_OFF;$+3 SET1 POWER_RUN_FALG GOTO Power_Control_ON Power_Control_ON: CALL UPDATE_MODE ; 开机时更新模式 RET Power_Control_OFF: ;关闭全部PWM PWMG2C=0; PWMG1C=0; PA.3=0; PA.4=0; PB.3=0; PB.4=0; PB.5=0; PB.6=0; SET0 POWER_RUN_FALG RET ;**************************************************************** MODE_DECIDE: ;CEQSN A, 4, INCREASE_BRIGHTNESS; 如果等于 04H,则增加亮度 T1SN POWER_RUN_FALG RET MOV A, 04H ; 检查是否为04H(亮度增加) CEQSN A,current_RF_ID_R0 GOTO $+2 GOTO Brightness_Up_Handler ; 如果是04H,跳转到亮度增加处理 ;CEQSN A, 10, DECREASE_BRIGHTNESS; 如果等于 0AH,则减少亮度 MOV A,0AH CEQSN A,current_RF_ID_R0 GOTO $+2 GOTO Brightness_Down_Handler ; CEQSN A, 6, NEXT_MODE; 如果等于 06H,则进入下一个模式 MOV A,06H CEQSN A,current_RF_ID_R0 GOTO $+2 GOTO NEXT_MODE ; CEQSN A, 12, PREV_MODE; 如果等于 0CH,则进入上一个模式 MOV A,0CH CEQSN A,current_RF_ID_R0 GOTO $+2 GOTO PREV_MODE ; 如果没有按键操作,继续执行当前模式 GOTO UPDATE_PWM; POWER_TOGGLE: ; 切换电源状态 T1SN POWER_RUN_FALG; POWER_ON_FLAG, 1; 反转电源标志 GOTO MAIN;_LOOP; RET ;***************************************** Brightness_Up_Handler: ; 增加亮度等级 INC BRIGHT_LEVEL ; DZSN BRIGHT_LEVEL, MAX_BRIGHTNESS; 如果超过最大值,回到最小值 ; GOTO UPDATE_PWM; MOV A,5 SUB A,BRIGHT_LEVEL T1SN FC GOTO UPDATE_PWM; ;DECREASE_BRIGHTNESS: Brightness_Down_Handler: ; 减少亮度等级 DEC BRIGHT_LEVEL ; DZSN BRIGHT_LEVEL, MIN_BRIGHTNESS; 如果低于最小值,回到最大值 ; GOTO UPDATE_PWM; MOV A,0 CEQSN A,BRIGHT_LEVEL GOTO UPDATE_PWM; GOTO Brightness_Up_Handler ;--------------切换模式-------------------- NEXT_MODE: ; 切换到下一个模式 INC CUR_MODE ; DZSN CUR_MODE, MAX_MODE; 如果超过最大模式,回到第一个模式 ; GOTO UPDATE_PWM; MOV A,7 SUB A,CUR_MODE T1SN FC GOTO UPDATE_PWM; GOTO PREV_MODE PREV_MODE: ; 切换到上一个模式 ; DEC CUR_MODE ; DZSN CUR_MODE, MIN_MODE; 如果低于最小模式,回到最后一个模式 ; GOTO UPDATE_PWM; DZSN CUR_MODE;, MIN_MODE; 如果低于最小模式,回到最后一个模式 GOTO UPDATE_PWM; GOTO NEXT_MODE ;-------亮度调整----------- ;MAX_BRIGHTNESS: ; MOV BRIGHT_LEVEL, 6; 最大亮度等级 ; GOTO UPDATE_PWM; ;MIN_BRIGHTNESS: ; MOV BRIGHT_LEVEL, 1; 最小亮度等级 ; GOTO UPDATE_PWM; ;MAX_MODE: ; MOV CUR_MODE, 1; 最大模式 ; GOTO UPDATE_PWM; ;MIN_MODE: ; MOV CUR_MODE, 7; 最小模式 ; GOTO UPDATE_PWM; ;****************************************************************** UPDATE_PWM: ; 根据当前模式更新PWM占空比 MOV A,0 CEQSN A,CUR_MODE GOTO $+2 GOTO MODE_1 MOV A,1 CEQSN A,CUR_MODE GOTO $+2 GOTO MODE_2 MOV A,2 CEQSN A,CUR_MODE GOTO $+2 GOTO MODE_3 MOV A,3 CEQSN A,CUR_MODE GOTO $+2 GOTO MODE_4 MOV A,4 CEQSN A,CUR_MODE GOTO $+2 GOTO MODE_5 MOV A,5 CEQSN A,CUR_MODE GOTO $+2 GOTO MODE_6 MOV A,6 CEQSN A,CUR_MODE GOTO $+2 GOTO MODE_7 RET ;****************************************************************** ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; UPDATE_MODE: ; 关机时不更新模式 T1SN POWER_RUN_FALG RET MODE_1: ; 模式1:A路红色,B路绿色 CALL GET_BRIGHTNESS; 获取当前亮度值 MOV Duty_R_RGB_A, A; A路红色 MOV A, 0; A路绿色 MOV Duty_G_RGB_A, A MOV A, 0; A路蓝色 MOV Duty_B_RGB_A, A MOV A, 0; B路红色 MOV Duty_R_RGB_B, A MOV Duty_G_RGB_B, A; B路绿色 MOV A, 0; B路蓝色 MOV Duty_B_RGB_B, A GOTO END_UPDATE; MODE_2: ; 模式2:A路粉色,B路黄色 CALL GET_BRIGHTNESS; 获取当前亮度值 MOV Duty_R_RGB_A, A; A路红色 MOV A, 128; A路绿色 MOV Duty_G_RGB_A, A MOV A, 0; A路蓝色 MOV Duty_B_RGB_A, A MOV A, 128; B路红色 MOV Duty_R_RGB_B, A MOV Duty_G_RGB_B, A; B路绿色 MOV A, 128; B路蓝色 MOV Duty_B_RGB_B, A GOTO END_UPDATE; MODE_3: ; 模式3:A路绿色,B路蓝色 CALL GET_BRIGHTNESS; 获取当前亮度值 MOV A, 0; A路红色 MOV Duty_R_RGB_A, A MOV Duty_G_RGB_A, A; A路绿色 MOV A, 0; A路蓝色 MOV Duty_B_RGB_A, A MOV A, 0; B路红色 MOV Duty_R_RGB_B, A MOV A, 0; B路绿色 MOV Duty_G_RGB_B, A MOV Duty_B_RGB_B, A; B路蓝色 GOTO END_UPDATE; MODE_4: ; 模式4:A路紫色,B路白色 CALL GET_BRIGHTNESS; 获取当前亮度值 MOV Duty_R_RGB_A, A; A路红色 MOV A, 0; A路绿色 MOV Duty_G_RGB_A, A MOV Duty_B_RGB_A, A; A路蓝色 MOV Duty_R_RGB_B, A; B路红色 MOV Duty_G_RGB_B, A; B路绿色 MOV Duty_B_RGB_B, A; B路蓝色 GOTO END_UPDATE; MODE_5: ; 模式5:A路蓝色,B路粉色 CALL GET_BRIGHTNESS; 获取当前亮度值 MOV A, 0; A路红色 MOV Duty_R_RGB_A, A MOV A, 0; A路绿色 MOV Duty_G_RGB_A, A MOV Duty_B_RGB_A, A; A路蓝色 MOV Duty_R_RGB_B, A; B路红色 MOV Duty_G_RGB_B, A; B路绿色 MOV A, 128; B路蓝色 MOV Duty_B_RGB_B, A GOTO END_UPDATE; MODE_6: ; 模ode6:A路蓝色,B路橙色 CALL GET_BRIGHTNESS; 获取当前亮度值 MOV A, 0; A路红色 MOV Duty_R_RGB_A, A MOV A, 0; A路绿色 MOV Duty_G_RGB_A, A MOV Duty_B_RGB_A, A; A路蓝色 MOV Duty_R_RGB_B, A; B路红色 MOV Duty_G_RGB_B, A; B路绿色 MOV A, 128; B路蓝色 MOV Duty_B_RGB_B, A GOTO END_UPDATE; ;************************************************************* END_UPDATE: ; 更新PWM占空比 MOV A,Duty_R_RGB_A; 更新A路红色PWM MOV PWMG2DTL,A MOV A,Duty_R_RGB_A; MOV PWMG2DTH,A MOV A,Duty_G_RGB_A; 更新A路绿色PWM MOV PWMG1DTL,A MOV A,Duty_G_RGB_A; MOV PWMG1DTH,A ; 这里需要添加B路PWM的更新代码 MOV A,Duty_R_RGB_B; 更新A路红色PWM MOV PWMG1DTL,A MOV A,Duty_R_RGB_B; MOV PWMG1DTH,A MOV A,Duty_G_RGB_B; 更新A路绿色PWM MOV PWMG2DTL,A MOV A,Duty_G_RGB_B; MOV PWMG2DTH,A ;GOTO MAIN ;_LOOP; RET ;************************************************************ GET_BRIGHTNESS: ; 获取当前亮度值 ; MOV A, BRIGHT_LEVEL ; MOV PC, BRIGHT_TABLE; 查找亮度表 ; RET; A = BRIGHT_LEVEL+1 _PCADD { RET 51; 20%, RET 89; 35%, RET 128; 50%, RET 166; 65%, RET 204; 80%, RET 255; 100%, } ;************************************************************* MODE_7: ; 更新A路颜色 ; 更新A路颜色 MOV A, HUE_A ; 将当前A路色相值加载到累加器A CALL HSV_TO_RGB ; 调用HSV转RGB子程序,得到R、G、B三通道值(R_VAL, G_VAL, B_VAL) CALL GET_BRIGHTNESS ; 获取当前亮度值(存入A) ; 计算红色通道 × 亮度值 MOV A, R_VAL ; 第一个乘数 → A MOV MULOP, A ; 复制A中的值到 MULOP MOV A, BRIGHT ; 第二个乘数 → A MUL ; 执行乘法:R_VAL × BRIGHT MOV Duty_R_RGB_A, A ; 存低字节到PWM寄存器 MOV A, MULRH ; 读取高字节 MOV Duty_R_RGB_H_A, A ; 存高字节备用 ; 计算绿色通道 × 亮度值 MOV A, G_VAL ; 第一个乘数 → A MOV MULOP, A ; 复制A中的值到 MULOP MOV A, BRIGHT ; 第二个乘数 → A MUL ; 执行乘法:G_VAL × BRIGHT MOV Duty_G_RGB_A, A ; 存低字节到PWM寄存器 MOV A, MULRH ; 读取高字节 MOV Duty_G_RGB_H_A, A ; 存高字节备用 ; 计算蓝色通道 × 亮度值 MOV A, B_VAL ; 第一个乘数 → A MOV MULOP, A ; 复制A中的值到 MULOP MOV A, BRIGHT ; 第二个乘数 → A MUL ; 执行乘法:B_VAL × BRIGHT MOV Duty_B_RGB_A, A ; 存低字节到PWM寄存器 MOV A, MULRH ; 读取高字节 MOV Duty_B_RGB_H_A, A ; 存高字节备用 ;----------------------------------------------------- ; 更新B路颜色 MOV A, HUE_B ; 将当前B路色相值加载到累加器A CALL HSV_TO_RGB ; 调用HSV转RGB子程序,得到B路的R、G、B值 CALL GET_BRIGHTNESS ; 获取当前亮度值(存入A) ; 计算B路红色通道 × 亮度值 MOV A, R_VAL ; 第一个乘数 → A MOV MULOP, A ; 复制A中的值到 MULOP MOV A, BRIGHT ; 第二个乘数 → A MUL ; 执行乘法:R_VAL × BRIGHT MOV Duty_R_RGB_B, A ; 存低字节到PWM寄存器 MOV A, MULRH ; 读取高字节 MOV Duty_R_RGB_H_B, A ; 存高字节备用 ; 计算B路绿色通道 × 亮度值 MOV A, G_VAL ; 第一个乘数 → A MOV MULOP, A ; 复制A中的值到 MULOP MOV A, BRIGHT ; 第二个乘数 → A MUL ; 执行乘法:G_VAL × BRIGHT MOV Duty_G_RGB_B, A ; 存低字节到PWM寄存器 MOV A, MULRH ; 读取高字节 MOV Duty_G_RGB_H_B, A ; 存高字节备用 ; 计算B路蓝色通道 × 亮度值 MOV A, B_VAL ; 第一个乘数 → A MOV MULOP, A ; 复制A中的值到 MULOP MOV A, BRIGHT ; 第二个乘数 → A MUL ; 执行乘法:B_VAL × BRIGHT MOV Duty_B_RGB_B, A ; 存低字节到PWM寄存器 MOV A, MULRH ; 读取高字节 MOV Duty_B_RGB_H_B, A ; 存高字节备用 RET ;***************************************************** ; ----------------------------- ; 子程序:HSV_TO_RGB ; 功能:将HSV颜色值转换为RGB颜色值 ; 输入:A = 色相值(0-255) ; 输出:R_VAL, G_VAL, B_VAL(8位RGB通道值) ; 说明:本子程序假设饱和度和亮度已为最大值(255),适用于全彩LED控制 ; 特别注意:所有数据传送必须通过累加器 A 完成(无 # 符号) ; ----------------------------- HSV_TO_RGB: ; 将输入的色相值保存到 SEGMENT 寄存器中 MOV A, HUE_A ; 将当前色相值加载到 A MOV SEGMENT, A ; 将 A 中的值复制到 SEGMENT ; 右移3位,得到色相区段编号(0~5,共6个区段) ; MOV A, SEGMENT ; 将 SEGMENT 的值加载到 A ; SR A, 3 ; 右移3位,相当于除以8,得到整数部分 SR SEGMENT MOV SEGMENT,A MOV SEGMENT, A ; 将结果存回 SEGMENT ; 计算色相的小数部分 ; MOV A, SEGMENT ; 将整数部分加载到 A ; SL A, 3 ; 左移3位,相当于乘以8,恢复整数部分的8倍 SL SEGMENT MOV FRACTION, A ; 将整数部分的8倍存入 FRACTION MOV A, HUE_B ; 重新加载原始色相值到 A SUB A, FRACTION ; 原色相值 - 整数部分的8倍 = 小数部分 MOV FRACTION, A ; 将小数部分存入 FRACTION ; 根据区段跳转到对的RGB计算分支 ; MOV A, SEGMENT ; 将区段编号加载到 A ; CEQSN A, 0, RED_SEGMENT ; 区段0 → 红色区间 MOV A,0 CEQSN A,SEGMENT GOTO $+2 GOTO RED_SEGMENT ; CEQSN A, 1, GREEN_SEGMENT ; 区段1 → 绿色区间 MOV A,1 CEQSN A,SEGMENT GOTO $+2 GOTO GREEN_SEGMENT ; CEQSN A, 2, BLUE_SEGMENT ; 区段2 → 蓝色区间 MOV A,2 CEQSN A,SEGMENT GOTO $+2 GOTO BLUE_SEGMENT ; CEQSN A, 3, MAGENTA_SEGMENT ; 区段3 → 品红区间 MOV A,3 CEQSN A,SEGMENT GOTO $+2 GOTO MAGENTA_SEGMENT ; CEQSN A, 4, CYAN_SEGMENT ; 区段4 → 青色区间 MOV A,4 CEQSN A,SEGMENT GOTO $+2 GOTO CYAN_SEGMENT ; CEQSN A, 5, YELLOW_SEGMENT ; 区段5 → 黄色区间 MOV A,5 CEQSN A,SEGMENT GOTO $+2 GOTO YELLOW_SEGMENT ; 区段0 - 红色区间 (Red to Yellow) RED_SEGMENT: MOV A, 255 ; 加载红色通道最大值 255 到 A MOV R_VAL, A ; 将 A 中的值写入 R_VAL(红色通道满) MOV A, FRACTION ; 将小数部分加载到 A MOV G_VAL, A ; 将 A 中的值写入 G_VAL(绿色通道从小到大变化) MOV A, 0 ; 加载蓝色通道最小值 0 到 A MOV B_VAL, A ; 将 A 中的值写入 B_VAL(蓝色通道不变) RET ; 返回主程序 ; 区段1 - 绿色区间 (Green to Cyan) GREEN_SEGMENT: MOV A, 255 ; 加载 255 到 A SUB A, FRACTION ; A = 255 - FRACTION(红色通道从255递减) MOV R_VAL, A ; 将结果写入 R_VAL MOV A, 255 ; 加载 255 到 A MOV G_VAL, A ; 将 A 中的值写入 G_VAL(绿色通道满) MOV A, 0 ; 加载 0 到 A MOV B_VAL, A ; 将 A 中的值写入 B_VAL(蓝色通道不变) RET ; 返回主程序 ; 区段2 - 蓝色区间 (Blue to Magenta) BLUE_SEGMENT: MOV A, 0 ; 加载 0 到 A MOV R_VAL, A ; 将 A 中的值写入 R_VAL(红色通道不变) MOV A, 255 ; 加载 255 到 A MOV G_VAL, A ; 将 A 中的值写入 G_VAL(绿色通道满) MOV A, FRACTION ; 将小数部分加载到 A MOV B_VAL, A ; 将 A 中的值写入 B_VAL(蓝色通道从小到大变化) RET ; 返回主程序 ; 区段3 - 品红区间 (Magenta to Red) MAGENTA_SEGMENT: MOV A, 0 ; 加载 0 到 A MOV R_VAL, A ; 将 A 中的值写入 R_VAL(红色通道不变) MOV A, 255 ; 加载 255 到 A SUB A, FRACTION ; A = 255 - FRACTION(绿色通道从255递减) MOV G_VAL, A ; 将结果写入 G_VAL MOV A, 255 ; 加载 255 到 A MOV B_VAL, A ; 将 A 中的值写入 B_VAL(蓝色通道满) RET ; 返回主程序 ; 区段4 - 青色区间 (Cyan to Green) CYAN_SEGMENT: MOV A, FRACTION ; 将小数部分加载到 A MOV R_VAL, A ; 将 A 中的值写入 R_VAL(红色通道从小到大变化) MOV A, 0 ; 加载 0 到 A MOV G_VAL, A ; 将 A 中的值写入 G_VAL(绿色通道不变) MOV A, 255 ; 加载 255 到 A MOV B_VAL, A ; 将 A 中的值写入 B_VAL(蓝色通道满) RET ; 返回主程序 ; 区段5 - 黄色区间 (Yellow to Magenta) YELLOW_SEGMENT: MOV A, 255 ; 加载 255 到 A MOV R_VAL, A ; 将 A 中的值写入 R_VAL(红色通道满) MOV A, 0 ; 加载 0 到 A MOV G_VAL, A ; 将 A 中的值写入 G_VAL(绿色通道不变) MOV A, 255 ; 加载 255 到 A SUB A, FRACTION ; A = 255 - FRACTION(蓝色通道从255递减) MOV B_VAL, A ; 将结果写入 B_VAL RET ; 返回主程序
09-12
如面这个程序代码存在单片机 IO 外部中断 读取RF433数据时,主程序中的数据处理也中断了的问题是否可以帮我优化程序结构,解决上述问题,谢谢!====//*******product model:RGB 7 彩灯 .CHIP PMS132B ;SOP16 //.CHIP PFC154 ;SOP14 //.CHIP PMC153 ;SOP14 //{{PADAUK_CODE_OPTION .Code_Option LVR 3.5V .Code_Option Security Enable // Security 7/8 words Enable .Code_Option Comparator_Edge All_Edge .Code_Option Bootup_Time Slow .Code_Option PWM_Source 16MHz .Code_Option GPC_PWM Disable .Code_Option Interrupt_Src1 PB.0 .Code_Option Interrupt_Src0 PA.0 .Code_Option PB4_PB7_Drive Normal //}}PADAUK_CODE_OPTION .INCLUDE "HEAD.H" ;----------- 常量定义 ----------- SYNC_MIN EQU 80;32 ; 同步头最小(8ms)32;80 SYNC_MAX EQU 140 ; 同步头最大(14ms)56 DATA_0_MIN EQU 2 ; 数据0最小(0.2ms) DATA_0_MAX EQU 6 ; 数据0最大(0.6ms) DATA_1_MIN EQU 8 ; 数据1最小(0.8ms) DATA_1_MAX EQU 14 ; 数据1最大(1.4ms) GRE_A EQU PB.3;A路绿色, BLU_A EQU PA.4;A路蓝色, RED_A EQU PA.3;A路红色, GRE_B EQU PB.6;B路绿色, RED_B EQU PB.5;B路红色, BLU_B EQU PB.4;B路蓝色, RF EQU PA.0 ;********************************************************* .ROMADR 0X001 ;; GOTO FPPA0 ;******************************************************** .ROMADR 0X10 ;INTERR IN address ;====================== 中断服务程序 ====================== INTERRUPT: PUSHAF ; 保存现场 T1SN INTRQ.TM3 GOTO TM16_INT SET0 INTRQ.TM3 ;10uS K: T0SN H_L_LEVEL_FLAG GOTO DDD INC TEMP_COUNT_4R;控制PWM占空比频率 MOV A,128 SUB A,TEMP_COUNT_4R T1SN FC GOTO ISR_EXIT; SET1 H_L_LEVEL_FLAG DDD: DZSN TEMP_COUNT_4R GOTO ISR_EXIT; SET0 H_L_LEVEL_FLAG GOTO ISR_EXIT; TM16_INT: T1SN INTRQ.2;T16 GOTO TM2_INT SET0 INTRQ.2 stt16 Reload_T16; ; $ PA.7 Toggle; INC T16_TIEMS_COUNTER_TIME_R GOTO ISR_EXIT; ;------------------------------------------ TM2_INT: ; TM2中断处理 (100us周期) T1SN INTRQ.TM2 ; 检测TM2中断标志 GOTO CHECK_RF;ISR_Exit SET0 INTRQ.TM2 ; 清除定时器中断标志 INC Timer_250us ; 专用TM2计数器 INC TM2_TIME_H_LVEVL_R ;同步计时 MOV A, 16;140;72;80;Timer_250us ; 加载计数器值 SUB A, Timer_250us ; 18ms超时检测 T1SN FC ; 检查是否超时 GOTO SYNC_MIM_TIME_CHECK; ; 同步头超时检查 SET0 RF_Start ; 超时复位接收状态 CLEAR Timer_250us ; 重置计时器 ; GOTO ISR_Exit; SYNC_MIM_TIME_CHECK: MOV A,150; SUB A,TM2_TIME_H_LVEVL_R T1SN FC GOTO ISR_Exit; CLEAR TM2_TIME_H_LVEVL_R GOTO ISR_Exit; ;**************************************************** CHECK_RF: T1SN INTRQ. RF ; 检测RF中断标志 GOTO ISR_Exit ;ISR_END SET0 INTRQ.RF ; 清除RF中断标志 T1SN PA.0 ; 检测PA0当前电平(1=高电平) GOTO RF_Clear;RF_Low ; 低电平处理分支 T1SN RF_Start ; 检查是否已经开始接收 GOTO RF_Clear;RF_Low $ PB.0 out,LOW NOP NOP $ PB.0 out,HIGH ; 数据位 ;------ 1码检测-------------------- ;----- 0:----0.3ms-0.6mS H + 0.8mS-1.4ms L ;------1:----0.8-1.4ms H + 0.3-1.4ms L ;结束位:-----0.3-0.6ms H + 10-14ms L ;(Timer_100us>=8 && Timer_100us<=14) //0.8~1.4ms INC Icnt ; 位计数器加1 MOV A, Timer_250us ; 加载计时器值 SUB A,DATA_1_MIN; 3 ; 1码检测下限(0.8ms) T0SN FC ; 检查是否大于下限 GOTO Check_Zero ; 跳转0码检测 MOV A,DATA_1_MAX; 5 ; 1码检测上限(1.4ms) SUB A, Timer_250us ; 计算时间差 T0SN FC ; 检查是否小于上限 GOTO Check_Zero ; 跳转0码检测 SET0 CF ; 设置进位标志为1 SLC Data_In$0 ; 数据左移并带进位 SLC Data_In$1 ; 数据左移并带进位 SLC Data_In$2 ; 数据左移并带进位 GOTO Check_Complete ; 跳转完成检测 Check_Zero: ; ------0码检测------- ;(Timer_100us>=2 && Timer_100us<=6)//0.2~0.6ms MOV A, Timer_250us ; 加载计时器值 SUB A,DATA_0_MIN; 1 ; 0码下限(0.2ms) T0SN FC ; 检查是否大于下限 GOTO Data_Error ; 错误处理 MOV A,DATA_0_MAX; 2 ; 0码上限(0.6ms) SUB A, Timer_250us ; 计算时间差 T0SN FC ; 检查是否小于上限 GOTO Data_Error ; 错误处理 SET1 FC ; 设置进位标志为0 SLC Data_In$0 ; 数据左移并带进位 SLC Data_In$1 ; 数据左移并带进位 SLC Data_In$2 ; 数据左移并带进位 Check_Complete: ; 完成检测 MOV A, 24 ; 加载位计数器 XOR A, Icnt ; 检查是否满24位 T1SN FZ ; 判断是否完成 GOTO RF_Clear ; 未完成继续接收 T0SN RF_END GOTO RF_Clear SET0 INTEN.PA0; = 1; //中断允许寄存器,开PA0中断 SET0 INTRQ.PA0; = 0 ; 数据存储与校验 CALL DELAY_40MS current_RF_ID_R0 = Data_In$0; ;.0-7 ; 存储低8位 current_RF_ID_R1 = Data_In$1; current_RF_ID_R2 = Data_In$2; T0SN FIRST_ID_SVAE_FLAG GOTO SVAE_ID DTAT_SAVE_R0=current_RF_ID_R0; DTAT_SAVE_R1=current_RF_ID_R1; DTAT_SAVE_R2=current_RF_ID_R2; SET1 FIRST_ID_SVAE_FLAG SVAE_ID: ; .delay 2500; //等待 3.9622=1 us ,汇编中最大延时2500约630US SET1 RF_END SET0 RF_Start ; 清除接收开始标志 GOTO RF_Clear ; 跳转中断清除 Data_Error: ; 错误处理 CLEAR Icnt ; 复位位计数器 SET0 RF_Start ; 清除接收开始标志 Data_In = 0 ; ; 清空数据缓存 CLEAR current_RF_ID_R0 CLEAR current_RF_ID_R1 CLEAR current_RF_ID_R2 CLEAR Timer_250us ; 重置250us计时器 CLEAR CYCLE_TIME_COUNT_R SET0 INTEN.PA0; = 1; //中断允许寄存器,开PA0中断 SET0 INTRQ.PA0; = 0 RF_Clear: ; RF中断清除 SET0 INTRQ.RF ; 清除RF中断标志 CLEAR Timer_250us ; 重置250us计时器 GOTO ISR_Exit ; 跳转中断退出 TM2_Clear: ; 定时器中断清除 SET0 INTRQ.TM2 ; 清除定时器中断标志 ISR_Exit: ; 中断退出 POPAF ; 恢复A和FLAG寄存器 RETI ; 中断返回 ;-------------------------------------------- //======================================================= FPPA0: .ADJUST_IC SYSCLK=IHRC/2, IHRC=16MHz, VDD=5.0V; // WatchDog Disable, RAM 0 ~ 0xF temporary be used //You can add the follow code : CLKMD.En_WatchDog=1; // WatchDog Enable SP=STACK0 ;//--------------CLRRAM ---------------------- Initialize: ; CALL DELAY_1SUP; MOV A,_SYS(RAM_SIZE)-1 MOV LB@RAM_POINTER,A CLEAR HB@RAM_POINTER L_CLRRAMLP: MOV A,0X00 IDXM RAM_POINTER,A DZSN LB@RAM_POINTER GOTO L_CLRRAMLP ;//--------------INITIAL IO---------------------- IO_Initialize: PA = 0B_0000_0000; PAC = 0B_1001_1000; ; //0:input;1:output; PAPH = 0B_1111_1001; ;1=ENABLED PULL UP PADIER=0B_1111_1111; PB = 0B_1000_0000; PBC = 0B_0111_1001; ; //0:input;1:output; PBPH = 0B_1111_1001; ;1=ENABLED PULL UP PBDIER=0B_1111_1111; ;-------TM2 100US----------- tm2ct = 0; tm2b = 4; $ TM2C IHRC,Disable,Period; $ TM2S 8bit,/64,/5; SET0 INTRQ.TM2; ; 清除定时器中断标志 SET1 INTEN.TM2; ; 使能定时器中断 ;----------TM3---10US-------------------------------------- tm3ct = 0; tm3b = 1; $ TM3C IHRC,Disable,Period; $ TM3S 8bit,/16,/5; SET0 INTRQ.TM3; = 0; SET1 INTEN.TM3; ;-----------PA0 IN_INT --------------------------- $ PA.0 in,pull; $ INTEGS PA0_B; //PA0中断边缘选择,上升缘和下降缘上升缘都请求中断PA0_B,上升缘请求中断为PA0_R,下降缘请求中断为PA0_F。 // SET1 INTEN.PA0; = 1; //中断允许寄存器,开PA0中断 SET0 INTRQ.PA0; = 0; //中断请求寄存器,清零INTRQ寄存器。 ;-------------5MS--------------------------------------- Reload_T16 = 32768 - 20000; stt16 Reload_T16; $ T16M IHRC,/4,bit15; $ INTEGS BIT_R; INTRQ.T16 = 0; INTEN.T16 = 1; Engint; ; 堆栈寄存器寄不够用,时会影响读数据的正确性 ;************************************************************* START: Data_In = 0 ; ; 清空数据缓存 Duty_B_RGB_A=1;255;上电亮度 Duty_B_RGB_B=1;255; Duty_R_RGB_A=1;255; Duty_R_RGB_B=1;255; Duty_G_RGB_A=1;255; Duty_G_RGB_B=1;255; SET1 POWER_RUN_FALG CUR_MODE=0; BRIGHT_LEVEL=2;5; ;********************************************************* ;暖白-红-绿-蓝-紫-青-粉-白光-黄光 MAIN: .WDRESET CALL RF_IN_DATA_LEVEL CALL COMPLETE_RF_ID CALL Power_Control_ON_OFF CALL KEY_VALUE_DECIDE ;模式断定 ; CALL shine_MODE_SEPARATION ;发光模式选择 NOP GOTO MAIN ;***************************************************************** ;****************************************************************** RF_IN_DATA_LEVEL: T1SN PA.0 ; 检测PA0当前电平(1=高电平) RET ;GOTO TIME_Clear ; T1SN RF_Start ; 检查是否已经开始接收 GOTO Check_Start ; 起始码检测分支 RET ; 起始码检测 Check_Start: ;----(Timer_250us>=32 && Timer_250us<=48) //用8-12ms低电平做起始码 T0SN RF_End RET MOV A, TM2_TIME_H_LVEVL_R;Timer_250us ; 加载计时器值 SUB A,SYNC_MIN; 32;9 ; 起始码下限(9ms) T0SN FC ; 检查是否大于下限 GOTO TIME_Clear;RF_Clear ; 无效起始码 MOV A,SYNC_MAX; 56;140 ; 起始码上限(14ms) SUB A, TM2_TIME_H_LVEVL_R;Timer_250us ; 计算时间差 T0SN FC ; 检查是否小于上限 GOTO TIME_Clear INC CYCLE_TIME_COUNT_R MOV A,CYCLE_TIME_COUNT_R;2 SUB A,7;8;7;5;4;3; T1SN FC GOTO TIME_Clear CLEAR CYCLE_TIME_COUNT_R SET1 RF_Start ; 设置接收开始标志 SET1 INTEN.PA0; SET0 INTRQ.PA0; Data_In = 0 ; ; 清空数据缓存 CLEAR Icnt ; 复位位计数器 CLEAR TM2_TIME_H_LVEVL_R;Timer_250us ; 重置250us计时器 GOTO TIME_Clear CLEAR Timer_250us ; 重置计时器 TIME_Clear: ; RF中断清除 NOP CLEAR TM2_TIME_H_LVEVL_R;Timer_250us ; 重置250us计时器 RET ;***************************************************************** ;***************************************************************** COMPLETE_RF_ID: T1SN RF_End RET current_ID_COMPLETE: T1SN FIRST_ID_SVAE_FLAG RET MOV A,current_RF_ID_R1; CEQSN A,DTAT_SAVE_R1 GOTO ID_EEROR MOV A,current_RF_ID_R2 CEQSN A,DTAT_SAVE_R2 RET SET1 ID_COMPLETE_OK_FLAG;ID 正确 ; SET0 RF_End ; 设置接收完成标志 current_RF_ID_R0 = Data_In$0; RET ID_EEROR: SET0 ID_COMPLETE_OK_FLAG;ID不正确 SET0 RF_End ; 设置接收完成标志 RET ;**************************************************************** ;**************************************************************** Power_Control_ON_OFF: T1SN ID_COMPLETE_OK_FLAG RET SET0 ID_COMPLETE_OK_FLAG;ID不正确 MOV A,02H ; 将按键值加载到ACC中 XOR A,current_RF_ID_R0 ; 检查是否为02H(开/关机) T1SN FZ RET CLEAR current_RF_ID_R0 SET0 RF_End T0SN POWER_RUN_FALG GOTO Power_Control_OFF;$+3 SET1 POWER_RUN_FALG ; 切换电源状态 RET Power_Control_OFF: ;关闭全部PWM PA.3=0; .delay 12; PA.4=0; PB.3=0; PB.4=0; PB.5=0; .delay 12; PB.6=0; SET0 POWER_RUN_FALG ; 切换电源状态 RET ;**************************************************************** ;**************************************************************** KEY_VALUE_DECIDE: ;;按键值断定 T1SN POWER_RUN_FALG RET T1SN RF_End RET MOV A, 04H ; //检查是否为04H(亮度增加) CEQSN A,current_RF_ID_R0 GOTO $+2 GOTO Brightness_Up_Handler ; 如果是04H,跳转到亮度增加处理 MOV A,0AH ;亮度减小 CEQSN A,current_RF_ID_R0 GOTO $+2 GOTO Brightness_Down_Handler ;----------------模式切换------------------------------------ MOV A,06H ;上一个模式 CEQSN A,current_RF_ID_R0 GOTO $+2 GOTO MODE_UP MOV A,0CH ;下一个模式 CEQSN A,current_RF_ID_R0 GOTO $+2 GOTO PREV_MODE RET ;***************************************** Brightness_Up_Handler: ; ; 增加亮度等级 T1SN RF_End RET SET0 RF_End INC BRIGHT_LEVEL CLEAR current_RF_ID_R0 CLEAR TEMP_COUNT_4R MOV A,5 SUB A,BRIGHT_LEVEL T1SN FC RET ; BRIGHT_LEVEL=5; RET Brightness_Down_Handler: ; ; 减少亮度等级 T1SN RF_End RET SET0 RF_End MOV A,0 XOR A,BRIGHT_LEVEL T0SN FZ GOTO DDDS DEC BRIGHT_LEVEL CLEAR current_RF_ID_R0 CLEAR TEMP_COUNT_4R RET DDDS: BRIGHT_LEVEL=0; RET ;--------------切换模式-------------------- MODE_UP: ; 切换到下一个模式 T1SN RF_End ; 设置接收完成标志 RET SET0 RF_End ; 设置接收完成标志 CLEAR current_RF_ID_R0 INC CUR_MODE MOV A,CUR_MODE;6 SUB A,6 T0SN FC RET CUR_MODE=6; RET PREV_MODE: ; 切换到上一个模式 T1SN RF_End ; 设置接收完成标志 RET SET0 RF_End ; 设置接收完成标志 CLEAR current_RF_ID_R0 MOV A,0 XOR A,CUR_MODE T1SN FZ GOTO PPP CLEAR CUR_MODE RET PPP: DEC CUR_MODE; RET
最新发布
09-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值