求助STM8L进入halt休眠后外中断唤醒死机

求助STM8L进入halt休眠后外中断唤醒死机,第1张

你的uart_SendByte(REV);函数实现是不是等待发送完成才返回的,还是立即返回 如果是立即返回,那么后面的清除完标志之后,发送标志会在发送完成之后置位,然后会再进入中断,至于REV仍然存在数据1,大概是因为没有其它的 *** 作覆盖掉数据。

最后一句USART_ClearITPendingBit( USART1, USART_IT_RXNE);改为

USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);

itc_setsoftwarepriority(itc_irq_tim2_ovf,

itc_prioritylevel_0);//定时器tim2溢出中断

itc_setsoftwarepriority(itc_irq_adc2,

itc_prioritylevel_1);//adc2中断优先级为1,比tim2高

你确定有adc1?itc_setsoftwarepriority的中断源中,我没有看到adc1也。

望采纳~

手头一个项目对于成本要求颇高,所以选择了一款意法半导体的STM8L152。STM32市占率非常高,STM8来之其早前的ST7内核发展而来,处于对于该公司的充分信赖,毕竟这应该是比较成熟的内核了。结果踩了一个大大的深坑。

常见的串口收发中使用环形缓冲器,会用到临界区保护。而脉冲计数等也是如此,ISR计数器加一,需要主循环中临界保护,保存到EEPROM中,然后重置计数器。而大多数的临界区保护通过关闭全局中断使能来实现。偏偏在STM8L中撞鬼了。

在EXTI外部中断使能的脉冲计数中,会导致程序跑飞,而去掉了临界区保护,程序恢复正常。

追踪下来发现:RIM/SIM语句重置了中断优先级,且在同一个ISR中反复嵌套,只压栈不退栈,直接堆栈爆掉,程序跑飞。

在内部EEPROM初始化中关闭全局中断避免不可预测后果,这也是常见的做法。但是如果使用中断闭合,会导致外部中断变量不是增加一而是增加一个固定常数。

追踪下来发现:而关闭开放中断会重置中断,外部中断被定时中断嵌套后,而STM8L中所谓的虚拟寄存器没有压栈处理,直接被TIM4 ISR占用,导致虚拟寄存器指向外部中断的服务程序被改写。

在STM8相对应的错误报告中,的确将ITC部分的Bug列为“ 没有解决方案,也没有解决计划 ”的严重错误。

在STM8L上别使用RIM/SIM语句,即便要用也需要关闭对应IT_CONFIG,如果是EXTI中断,则自求多福。比较建议使用STM32L0XX,或者其他家的Cortex-M0+内核处理器,其实MSP430也可以用。

望周知,别踩坑。

/

STM8S105 TIM2 TIM3输出PWM PD0 PD3 TIM3输出PWM,/#include "STM8S105Kh"

#include "STM8S105_CLOCKh"

typedef unsigned char u8;

typedef unsigned int u16;u16 value;

/

函数名 : void SystemInit(void)

功能描述: 系统初始化

函数说明: 系统全局初始化

/

void SystemInit(void)

{ SystemClock_Init();

CLK_PCKENR1 |= 0x60; //使能TIM2与TIM3与主频连接

PD_CR2 |= 0x80; //使能PD7口外部中断

}

/

函数名 : void main(void)

功能描述: 主函数

函数说明:

/

void GPIO_init(void)

{

PD_DDR = 0x1F; //配置PD端口的方向寄存器全输出

PD_CR1 = 0x1F; //设置PD为推挽输出

PB_DDR|= 0x04; //PB2输出

PB_CR1|= 0x04; //PB2推挽输出

PB_ODR|= 0x04; //开5V电源

}

void TIM2_init(void) //TIM2 CH1 工作于模式1

{

// TIM2_CCMR2= 0x60; // PWM 模式 1

TIM2_CCMR1= 0x60; // PWM 模式 1,TIM2 CH1

TIM2_CCER1= 0x03; // CC1配置为输出

//TIM2_CCER2= 0x03; // CC3使能

TIM2_ARRH = 0x03; // 配置PWM分辨率为10位,ARR=0x3FF

TIM2_ARRL = 0xFF; // PWM频率=8M/0x03FF=7820Hz

TIM2_CR1 |= 0x01; // 计数器使能,开始计数

}

void TIM3_init(void) //TIM3 CH1 ch2工作于模式2,1

{

TIM3_CCMR1= 0x70; //PWM模式2

TIM3_CCMR2= 0x60; // PWM 模式 1

TIM3_CCER1= 0x33; // CC1 CC2配置为输出,CH1 CH2

TIM3_ARRH = 0x03; // 配置PWM分辨率为10位,ARR=0x3FF

TIM3_ARRL = 0xFF; // PWM频率=8M/0x03FF=7820Hz

TIM3_CR1 = 0x01; // 计数器使能,开始计数

} void Run(void)

{ //TIM2_CCR2H = (unsigned char)(value>>8); // 更新CC2比较寄存器

//TIM2_CCR2L = (unsigned char)(value);

TIM2_CCR1=value;

//TIM2_CCR3=value;

TIM3_CCR2=value;

TIM3_CCR1=value; //注意每个通道都要设CCR

} void init_devices(void)

{

_asm("sim");

SystemInit();

GPIO_init();

TIM2_init();

TIM3_init();

_asm("rim");

} void main( void )

{

init_devices();

while(1)

Run();

} /

函数名 : @near @interrupt void TLI_IRQHandler (void)

功能描述: 中断服务程序

函数说明:

/

@near @interrupt void TLI_IRQHandler (void) {

PD_CR2 &= 0x7F; //关PD7外部中断

value+=50;

while(value>1000)

value=0; PD_CR2 |= 0x80; //使能PD7口外部中断

return;

}

不能判断电平,会产生误导;如上升沿,下降沿边触发,是瞬态产生,可能在没有来得及判断时,中断就已经进行了;

举个例子,在PC口有的PC0和PC1两个信号都要求能够中断。而STM8S 对应PC口只有一个 中断向量,我要怎么才能够知道具体是有PC0引起的中断呢?还是PC1引起的中断呢?

我也看了坛子里面的一些相关的帖子,大致有这么一种方法,进入中断后读取IO口的电平状态 以判断是哪个IO口引起的中断。 但是我有个疑问,假定设置为下降沿触发中断。PC0先出现下降沿,系统进入中断,如果在这个时间段,PC1也出现下降沿,在中断里面再读PC0和PC1电平状态,仍然不能够判别是由PC0引起的中断,还是由PC1触发的中断啊!!

不建议这样用 最好一个PC,一个PD,每个口只开放一个中断;

那这样,一个PORT, 每个独立的中断口就没有意义了?

STM8S有5组IO端口,每组端口分别有若干引脚可以作为外部中断触发输入,分别为:

端口A: PA[6:2];端口B: PB[7:0];端口C: PC[7:0];端口D: PD[6:0];端口E: PE[7:0]。

以上就是关于求助STM8L进入halt休眠后外中断唤醒死机全部的内容,包括:求助STM8L进入halt休眠后外中断唤醒死机、STM8L的usart中断问题、stm8s 无法进入定时器中断程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9392232.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-27
下一篇 2023-04-27

发表评论

登录后才能评论

评论列表(0条)

保存