各位前辈大佬号,小弟遇到一个2次唤醒的情况
小弟使用ADXL345+STC8H1K实现一个简易的小项目,思路流程是:当ADXL345静止以后触发一个ADXL345高电平中断,这个ADXL345高电平中断引脚连接到STC8H1K的INT0 P32引脚上。当中断被触发以后,唤醒休眠状态的STC8H1K单片机。STC8H1K处理完相关任务以后写ADXL345的一个一个寄存器,这个中断引脚恢复为低电平。 ST 8H1K进入休眠等待下一次的ADXL345静止唤醒。
在实际编写程序中遇到问题。 查阅手册和资料 STC8H1K08 只能把INT0设置为上升沿和下降沿触发。不能单独设置为上升沿触发。似乎是这个原因导致 每次ADXL345唤醒 STC8H1K都会唤醒两次、
我也按照论坛大佬的思路编写了以下代码,依旧会两次触发中断,请问我的问题在哪里?谢谢各位大佬了。
////INT0相关
sbit INT0_PIN = P3^2; // 定义INT0对应的引脚
bit lastState = 0; // 用于存储上一次的引脚状态
bit currentState ; // 用于当前的引脚状态
IT0=0;//设置 INT0 上升沿和下降沿中断
EX0=1; //启动INT0中断
voidINT0_P32() interrupt 0// 使用INT3 P32引脚唤醒休眠的单片机 启用外部中断以后必须给引脚明确的电平 如果处于高阻态悬空 就会导致死机状态。
{
// 记录当前状态
currentState = INT0_PIN;
// 判断是上升沿还是下降沿
if(lastState == 0 && currentState == 1) // 上升沿
{
ADXL345_wakeup = 1; // 设置唤醒标志
}
lastState = currentState;
}
我还进一步尝试了 在STC8H1K休眠前打开总中断 休眠唤醒后立刻关闭总中断后果就是 无法唤醒了
EA=1;//开总中断
PCON=0x02;
//MCU进入掉电模式 进行休眠
_nop_();
_nop_();
_nop_();
_nop_();
EA=0;//开总中断
请问各位大佬 我得问题到底是什么原因导致得 谢谢各位。
这个上下沿唤醒是肯定会唤醒的,,
我觉得你应该转换一下思维,不要想着怎么去掉一次中断,应该想一想哪一次唤醒是要我单片机进行操作的,然后不需要操作的那次中断就什么都不做直接睡觉。。 _奶咖君_ 发表于 2025-3-17 10:11
这个上下沿唤醒是肯定会唤醒的,,
我觉得你应该转换一下思维,不要想着怎么去掉一次中断,应该想一想哪一 ...
谢谢大佬 你好 现在是 我在外部中断内判断是否上升沿。。。可是上升沿似乎读取不到?或者是别得原因,现在是每次休眠会唤醒2次 给串口发送2次数据。。。 帕拉丁 发表于 2025-3-17 10:15
谢谢大佬 你好 现在是 我在外部中断内判断是否上升沿。。。可是上升沿似乎读取不到?或者是别得原因, ...
边沿触发,进中断后读IO为1就是上升沿,反之是下降沿
IO高阻需要读外部状态的,禁止悬空,外部电路必须是明确的高低电平,开漏必须要有上拉 DebugLab 发表于 2025-3-17 11:06
边沿触发,进中断后读IO为1就是上升沿,反之是下降沿
IO高阻需要读外部状态的,禁止悬空,外部电路必须是 ...
谢谢大佬 我设置为双向口状态了并且按照你的指点改进程序在中断里读IO如果高电平改变标志位。 现在中断稳定了 但是依旧是触发两次间隔一秒我用示波器看 是一个方波 。程序如下
voidINT0_P32() interrupt 0// 使用INT3 P32引脚唤醒休眠的单片机 启用外部中断以后必须给引脚明确的电平 如果处于高阻态悬空 就会导致死机状态。
{
if (INT0_PIN==1)
{ADXL345_wakeup = 1; // 设置唤醒标志
}
} void main()
{
float x_angle, y_angle, z_angle;
IO_init();//io初始化
Uart1_Init(); // 串口初始化
iic_init(); //IIC 初始化
EA=1;//开总中断
UART_Send_String("start......");
//setup_adxl345_continuous_read() ;// 设置ADXL345为一直工作模式 调试用
setup_adxl345_auto_sleep();// 设置ADXL345为震动唤醒 然后静止后休眠的模式
UART_Send_String("set adxl345--ok\r\n");
while (1)
{
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
//EX0=1; //启动INT0中断
nop_();
_nop_();
_nop_();
_nop_();
PCON=0x02;
//MCU进入掉电模式 进行休眠
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
////唤醒后执行的工作
//Uart1_Init(); //唤醒后串口初始化?
//delay(6000);
UART_Send_Hex_txt(0xee); //发送数据给串口
UART_Send_HEX(INT0_PIN);// 串口HEX格式发HEX函数
UART_Send_HEX(INT0_PIN);// 串口HEX格式发HEX函数
UART_Send_HEX(INT0_PIN);// 串口HEX格式发HEX函数
UART_Send_HEX(INT0_PIN);// 串口HEX格式发HEX函数
UART_Send_HEX(INT0_PIN);// 串口HEX格式发HEX函数
UART_Send_Hex_txt(0xee); //发送数据给串口
if (ADXL345_wakeup == 1)//
{
UART_Send_String("testweakup=1 ...\r\n");// 串口发送数据 已经唤醒
ADXL345_wakeup=0;// 中断内的唤醒标志位归零
adxl345_read_data();//读取ADXL345的数据
Determine_ADXL345_Orientation();// 判断哪一面向上
UART_Send_NewLine() ;// 串口发送换行
UART_Send_Hex_txt(number); //发送色子面数据给串口
UART_Send_NewLine();//串口发送换行
int_source= Single_Read_ADXL345(0x30); // 读取标志位 用于清除标志位 恢复中端口低电平
delay(4000);
}
}这段程序很清晰明了啊按说不应该唤醒两次 也不应该给电脑发送2次信息 唤醒是硬件决定的,设置双边沿触发,电平变化就一定会唤醒,这是正常的
但只有上升沿执行ADXL345_wakeup = 1
唤醒后继续执行程序(从哪睡眠的就从哪继续)
外部电路如果是推挽输出或有上拉接单片机IO,单片机IO就不用设置准双向或打开4K上拉,高阻就行
如果需要进入省电模式,IO需要设置为高阻或与外部状态相同的电平,不让IO有电流,否则会耗电 DebugLab 发表于 2025-3-17 14:12
唤醒是硬件决定的,设置双边沿触发,电平变化就一定会唤醒,这是正常的
但只有上升沿执行ADXL345_wakeup =...
谢谢大佬 我继续找找 到底是什么原因导致了一个波形两次唤醒。谢谢大佬 有没有示波器抓波形看下是否真的一个波形~ ercircle 发表于 2025-3-17 15:50
有没有示波器抓波形看下是否真的一个波形~
谢谢大佬昨天下午捣鼓了一下午示波器看波形很多时候 ADXL345 触发了2次波形导致 谢谢大佬 正在深入研究。 INT0设置为仅下降沿触发。( IT0=1 )
ADXL345静止后输出高还是低,是你自己定义的吗?
如果是你定义的,你改成输出低。
如果不是你定义的,你把ADXL345输出信号取反再接单片机。
页:
[1]
2