|
发表于 2025-3-30 12:58:32
|
显示全部楼层
你所碰到的这种逐步执行正常,但直接执行时数值异常的状况,一般是由硬件响应速度、时序问题或者代码执行速度过快等因素造成的。下面为你详细分析可能的原因以及对应的解决办法:
可能的原因
硬件响应速度:指拨开关在电路里有一定的机械延迟与电气延迟,当代码直接执行时,可能在硬件还未完全响应的情况下就进行了下一次操作,从而造成读取数值异常。
时序问题:代码里的 NOP 指令也许不足以让硬件有足够的时间响应。NOP 指令只是让 CPU 空转一个指令周期,若硬件响应时间较长,就会出现问题。
代码执行速度:PIC16F873A 运行速度较快,直接执行时代码可能会迅速跳过读取操作,导致读取到错误的数值。
解决办法
增加延时:在 PORTA 输出和读取 return2、return3 之间添加适当的延时,以此确保硬件有足够的时间响应。
软件滤波:对读取到的数值进行多次采样,然后取平均值或者进行逻辑判断,以此减少误读的可能性。
修改后的代码示例
c
#include <xc.h>
#include <delay.h> // 假设你使用的编译器支持这个延时库
#define DELAY_TIME 10 // 延时时间,可根据实际情况调整
void SCAN_DIP_SET(){
unsigned char scan_mark, scan_cnt;
asm("NOP");
scan_dip_buf = 0;
PORTA = 0x00; // 清所有scan输出PORTA bit3~b0
// 读取4位DIP_SW
for(scan_cnt = 1; scan_cnt <= 8; scan_cnt <<= 1){ // 8421左移4次,故范围=8
PORTA = scan_cnt; // 输出"高态"供读取
__delay_ms(DELAY_TIME); // 增加延时
if(return2) // 取回=RETURN2
scan_mark = 1; // 若有ON则移入"1"
else
scan_mark = 0;
scan_dip_buf <<= 1; // 结果变量=往MSB左移1位=空出bit0
scan_dip_buf |= scan_mark; // 映入bit0
asm("Nop");
}
// 承接上_读取2位DIP_SW
for(scan_cnt = 1; scan_cnt <= 2; scan_cnt <<= 1){ // 32_16左移2次,相同SCAN1~2
PORTA = scan_cnt;
__delay_ms(DELAY_TIME); // 增加延时
if(return3) // 取回=RETURN3
scan_mark = 1; // 若有ON则移入"1"
else
scan_mark = 0;
scan_dip_buf <<= 1; // 结果变量=左移1位=空出bit0
scan_dip_buf |= scan_mark; // 映入bit0
asm("Nop");
}
}
说明
延时函数:__delay_ms(DELAY_TIME) 是一个延时函数,DELAY_TIME 能够依据实际情况进行调整,以此保证硬件有足够的时间响应。
延时库:要保证你的编译器支持 delay.h 库,若不支持,你可以自行编写延时函数。
你可以尝试使用修改后的代码,看是否能够解决直接执行时读取数值异常的问题。 |
|