AVR C如何停止中断
我正在对 AVR MCU 进行编程。
它有一个可以读取模拟引脚的 POT。似乎中断被不断地调用,并且必须在 LCD_display 方法期间调用它,因为它弄乱了我的 LCD。
有没有办法在块运行之前停止中断?
int main(void)
{
/*Turn on ADC Interrupt */
ADCSRA |= (1 << ADIE);
/*Turn On GLobal Interrupts*/
sei();
/* Intalise LCD */
lcd_init(LCD_DISP_ON); /* initialize display, cursor off */
lcd_clrscr();
lcd_puts("READY");
DDRB &= ~(1 << PINB5); //set input direction
ADC_Init(128, 0); //initalize ADC
while (1)
{
if (!bit_is_clear(PINB, 5))
{
_delay_ms(500);
if (!pressed)
{
lcd_gotoxy(0,0);
lcd_clrscr();
lcd_puts("test"); //Doesnt work unless I dont comment out the last line of interrupt
pressed = 1;
}
}
/* INTERRUPTS */
//ADC INTERRUPT
ISR(ADC_vect)
{
char adcResult[4];
uint8_t theLowADC = ADCL;
uint16_t theTenBitResults = ADCH<<8 | theLowADC;
itoa(theTenBitResults, adcResult, 10);
ADCSRA |= (1 << ADSC); //next conversion *if i comment out this line it works*
}
I am programming a AVR MCU.
It has a POT that reads off an analogue pin. It seems that the interrupt is constantly called, and it must be called during a LCD_display method as it is messing with my LCD.
Is there a way to STOP the inturrupts until after the block is run?
int main(void)
{
/*Turn on ADC Interrupt */
ADCSRA |= (1 << ADIE);
/*Turn On GLobal Interrupts*/
sei();
/* Intalise LCD */
lcd_init(LCD_DISP_ON); /* initialize display, cursor off */
lcd_clrscr();
lcd_puts("READY");
DDRB &= ~(1 << PINB5); //set input direction
ADC_Init(128, 0); //initalize ADC
while (1)
{
if (!bit_is_clear(PINB, 5))
{
_delay_ms(500);
if (!pressed)
{
lcd_gotoxy(0,0);
lcd_clrscr();
lcd_puts("test"); //Doesnt work unless I dont comment out the last line of interrupt
pressed = 1;
}
}
/* INTERRUPTS */
//ADC INTERRUPT
ISR(ADC_vect)
{
char adcResult[4];
uint8_t theLowADC = ADCL;
uint16_t theTenBitResults = ADCH<<8 | theLowADC;
itoa(theTenBitResults, adcResult, 10);
ADCSRA |= (1 << ADSC); //next conversion *if i comment out this line it works*
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果中断处理程序对您的代码表现不佳,原因可能是您在中断处理程序中花费了太多时间。您应该只在中断处理程序中执行关键工作,而将不太关键的工作推迟到应用程序代码中;使用在处理程序和应用程序代码之间共享的 易失性 标志来让应用程序代码知道它是否有工作要做。在您的示例中,您应该推迟应用程序代码中的
itoa
调用。If the interrupt handler behaves bad with your code, the reason could be you spend too much time in the interrupt handler. You should only do critical work in the interrupt handler and defer the less critical work in the application code; use a
volatile
flag shared between the handler and the application code to let the application code know if it has work to do. In your example, you should defer theitoa
call in the application code.使用 cli();禁用中断和 sei();完成显示例程后再次启用它们。
您使用的是哪款 MCU?您应该使用计时器而不是 500 毫秒的延迟。
Use cli(); to disable interrupts and sei(); to enable them again after you finished the display routine.
Which MCU are you using? You should propably use a timer instead of a delay of 500ms.
我相信,我有点晚了,但我仍然遇到了同样的问题,我使用以下方法解决了它,
使用两个标志启用中断
1.全局中断标志
2.模块相关的中断标志(在您的情况下为ADC)
您可以控制模块相关的标志,在您的情况下,ADCSRA控制寄存器中有一个名为ADIE-ADC中断启用标志的标志,您可以使用它来控制中断。
例如,
在 main 函数中,您可以启用该标志,并在 ISR 中禁用该标志。
我希望这能解决您遇到的问题。
I believe, I am little late but still I had the same issue I solved it using the following method,
Interrupts are enabled using two flags
1.A global interrupt flag
2.A module related interrupt flag (in your case ADC)
You can have control over module related flag, in your case in the ADCSRA control register there is a flag named ADIE- ADC Interrupt Enable flag you can use that to control the Interrupts.
For example,
In main function you can enable the flag and in ISR disable the flag.
I hope this solves the issue you are having.