دوستان من از وقفه خارجی شماره یک در میکروکنترلر ATmega8 می خواهم استفاده کنم.
یک برنامه برای تست وقفه با کامپایلر اتمل استودیو نوشتم و یک برنامه هم به زبان بیسیک. به این شکل که میکروکنترلر در حالت عادی یک عدد را یک ثانیه به یک ثانیه اضافه بکند و سپس به پورت سریال ارسال کند. در این بین اگر وقفه خارجی اتفاق افتاد به زیر برنامه وقفه برود و کلمه INT را به پورت سریال ارسال کند.
مشکل در اینجا است که برنامه بیسیک کاملا درست کار می کند ولی برنامه ای که به زبان C نوشتم اصلا درست کار نمی کند به این شکل که: با روشن کردن میکروکنترلر اعداد شمارنده به پورت سریال ارسال و نمایش داده می شود ولی به محض وقوع چند وقفه پشت سر هم دیگر برنامه نوشه شده در تابع main کار نمی کند . انگار که برنامه از خط خارج میشه ولی دفعات بعد با قوع وقفه دوباره داخل تابع وفقه میره.
یک مشکل دیگر هم وجود دارد این هست که وقتی وقفه رو حساس به لبه پایین رونده یا بالا رونده قرار میدم، و در عمل پین وقفه میکروکنترلر رو به زمین متصل می کنم. وقفه به صورت پشت سرهم اتفاق میافتد در صورتی که در برنامه بیسیک اصلا به این شکل نیست.
برنامه زبان C:
[code=c]#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include "uart.h"
int main(void)
{
char buffer[200];
char x=0;
uart_init();
DDRD |= (1<<PIND2);
PORTD |= (1<<PIND2);
MCUCSR |= (1 << ISC11); //Set ISC11 in MCUCSR register -> falling edge
MCUCSR &= ~(1 << ISC10); //Reset ISC10 in MCUCSR register -> falling edge
//MCUCSR |= (1 << ISC11); //Set ISC11 in MCUCSR register -> rising edge
//MCUCSR |= (1 << ISC10); //Set ISC10 in MCUCSR register -> rising edge
GICR |= (1<<INT1); //Enable interrupt 1 in GICR register
sei();
while (1)
{
x++;
sprintf(buffer,"X=%i\r\n",x);
uart_puts(buffer);
_delay_ms(1000);
}
}
ISR(INT1_vect)
{
uart_puts("INT\r\n"
;
}
[/code]
برنامه بیسیک:
[code=vb]$regfile = "m8def.dat"
$crystal = 16000000
$baud = 9600
Config Portd.2 = Output
Portd.2 = 1
Config Int1 = Rising
Enable Int1
On Int1 Ext_int1
Enable Interrupts
Dim X As Byte
Do
Print X
Incr X
Wait 1
Loop
Ext_int1:
Print "INT"
Return[/code]
اضافه شده در تاریخ :
دوباره یک برنامه جدید نوشتم زمانی که وقفه وارد زیر برنامه وقفه می شود یک LED روشن شود و با بازگشت به حلقه while خاموش شود.
برنامه در شبیه سازی درست کار می کند ولی در عمل بعد از پروگرام کردن، با اتصال پایه وقفه به زمین برنامه از زیربرنامه وقفه خارج نمیشه (وقفه حساس به لبه تنظیم کردم نه به سطح صفر) اگر سطح صفر بود این اتفاق طبیعی بود.
دو تا میکروکنترلر عوض کردم و مطمئن هستم که سخت افزار مشکل ندارد چون برنامه با بسکام کاملا درست کار می کند. :angry: :angry: :angry: :angry:
واقعا مغزم هنگ کرده. اصلا نمیدونم مشکل کجاست! تمام رجیستر ها مقدار دهی هاشون مطمئن هستم که درست هست.
[code=c]#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 16000000UL
#include <util/delay.h>
int main(void)
{
DDRD |= (1<<PIND2);
DDRB |= (1<<PINB1);
PORTD |= (1<<PIND2);
//MCUCSR |= (1 << ISC11); //Set ISC11 in MCUCSR register -> falling edge
//MCUCSR &= ~(1 << ISC10); //Reset ISC10 in MCUCSR register -> falling edge
MCUCSR = 0x0F;
//MCUCSR |= (1 << ISC11); //Set ISC11 in MCUCSR register -> rising edge
//MCUCSR |= (1 << ISC10); //Set ISC10 in MCUCSR register -> rising edge
GICR |= (1<<INT1); //Enable interrupt 1 in GICR register
sei();
while (1)
{
PORTB &= ~(1 << PINB1);
_delay_ms(200);
}
}
ISR(INT1_vect)
{
//uart_puts("INT\r\n"
;
//reti();
//PORTB ^= (1 << PINB1);
PORTB |= (1 << PINB1);
}
[/code]
یک برنامه برای تست وقفه با کامپایلر اتمل استودیو نوشتم و یک برنامه هم به زبان بیسیک. به این شکل که میکروکنترلر در حالت عادی یک عدد را یک ثانیه به یک ثانیه اضافه بکند و سپس به پورت سریال ارسال کند. در این بین اگر وقفه خارجی اتفاق افتاد به زیر برنامه وقفه برود و کلمه INT را به پورت سریال ارسال کند.
مشکل در اینجا است که برنامه بیسیک کاملا درست کار می کند ولی برنامه ای که به زبان C نوشتم اصلا درست کار نمی کند به این شکل که: با روشن کردن میکروکنترلر اعداد شمارنده به پورت سریال ارسال و نمایش داده می شود ولی به محض وقوع چند وقفه پشت سر هم دیگر برنامه نوشه شده در تابع main کار نمی کند . انگار که برنامه از خط خارج میشه ولی دفعات بعد با قوع وقفه دوباره داخل تابع وفقه میره.
یک مشکل دیگر هم وجود دارد این هست که وقتی وقفه رو حساس به لبه پایین رونده یا بالا رونده قرار میدم، و در عمل پین وقفه میکروکنترلر رو به زمین متصل می کنم. وقفه به صورت پشت سرهم اتفاق میافتد در صورتی که در برنامه بیسیک اصلا به این شکل نیست.
برنامه زبان C:
[code=c]#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include "uart.h"
int main(void)
{
char buffer[200];
char x=0;
uart_init();
DDRD |= (1<<PIND2);
PORTD |= (1<<PIND2);
MCUCSR |= (1 << ISC11); //Set ISC11 in MCUCSR register -> falling edge
MCUCSR &= ~(1 << ISC10); //Reset ISC10 in MCUCSR register -> falling edge
//MCUCSR |= (1 << ISC11); //Set ISC11 in MCUCSR register -> rising edge
//MCUCSR |= (1 << ISC10); //Set ISC10 in MCUCSR register -> rising edge
GICR |= (1<<INT1); //Enable interrupt 1 in GICR register
sei();
while (1)
{
x++;
sprintf(buffer,"X=%i\r\n",x);
uart_puts(buffer);
_delay_ms(1000);
}
}
ISR(INT1_vect)
{
uart_puts("INT\r\n"

}
[/code]
برنامه بیسیک:
[code=vb]$regfile = "m8def.dat"
$crystal = 16000000
$baud = 9600
Config Portd.2 = Output
Portd.2 = 1
Config Int1 = Rising
Enable Int1
On Int1 Ext_int1
Enable Interrupts
Dim X As Byte
Do
Print X
Incr X
Wait 1
Loop
Ext_int1:
Print "INT"
Return[/code]
اضافه شده در تاریخ :
دوباره یک برنامه جدید نوشتم زمانی که وقفه وارد زیر برنامه وقفه می شود یک LED روشن شود و با بازگشت به حلقه while خاموش شود.
برنامه در شبیه سازی درست کار می کند ولی در عمل بعد از پروگرام کردن، با اتصال پایه وقفه به زمین برنامه از زیربرنامه وقفه خارج نمیشه (وقفه حساس به لبه تنظیم کردم نه به سطح صفر) اگر سطح صفر بود این اتفاق طبیعی بود.
دو تا میکروکنترلر عوض کردم و مطمئن هستم که سخت افزار مشکل ندارد چون برنامه با بسکام کاملا درست کار می کند. :angry: :angry: :angry: :angry:
واقعا مغزم هنگ کرده. اصلا نمیدونم مشکل کجاست! تمام رجیستر ها مقدار دهی هاشون مطمئن هستم که درست هست.
[code=c]#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 16000000UL
#include <util/delay.h>
int main(void)
{
DDRD |= (1<<PIND2);
DDRB |= (1<<PINB1);
PORTD |= (1<<PIND2);
//MCUCSR |= (1 << ISC11); //Set ISC11 in MCUCSR register -> falling edge
//MCUCSR &= ~(1 << ISC10); //Reset ISC10 in MCUCSR register -> falling edge
MCUCSR = 0x0F;
//MCUCSR |= (1 << ISC11); //Set ISC11 in MCUCSR register -> rising edge
//MCUCSR |= (1 << ISC10); //Set ISC10 in MCUCSR register -> rising edge
GICR |= (1<<INT1); //Enable interrupt 1 in GICR register
sei();
while (1)
{
PORTB &= ~(1 << PINB1);
_delay_ms(200);
}
}
ISR(INT1_vect)
{
//uart_puts("INT\r\n"

//reti();
//PORTB ^= (1 << PINB1);
PORTB |= (1 << PINB1);
}
[/code]
دیدگاه