Thông báo

Collapse
No announcement yet.

LPC2103 - Gặp vấn đề với giá trị trả về khi dùng ngắt EINT

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • LPC2103 - Gặp vấn đề với giá trị trả về khi dùng ngắt EINT

    Mình dùng LPC2103 để hiển thị dữ liệu lên LCD 16x2. Trong đó, mình đặt EINT1 cho P0.14, dùng biến đếm count để xác định số lần nhấn nút và hiển thị trên LCD là "chẵn" hoặc "lẻ".
    Khi test bằng Proteus thì đôi khi nhấn ăn (dữ liệu hiển thị trên LCD thay đổi), nhưng có khi nhấn tới 2, 3 lần thì mới ăn. Không biết có phải do biến count trả về giá trị không đúng không?

    Code file main.c:
    Code:
    #include "lcd.h"
    #include "lpc2103.h"
    unsigned int i=0;
    /* ========== KHAI BAO INTERUPT EINT1 (P0.14) ========== */
    // void EINT __ irq: Khai bao lenh khi xay ra interrupt
    void EINT1 (void) __irq
    {
        i++;
    	EXTINT = 0;
    	//VICVectAddr0 = 0x00;	
    }
    
    // void intrp: Khai bao EINT1 o Port 14
    void intrp()
    {
    	EXTMODE = 2;
    	EXTPOLAR = 2;
    	
    	PINSEL0=0x10000000;	// P0.14 -> EINT1
    	VICIntEnable = 1 << 15;
    	VICVectCntl0 = 0x20 | 15;
    	VICVectAddr0 = (unsigned ) EINT1;	
    }
    
    int main()
    {
    	intrp();
    	lcd_int();
    	
    	while(1)
    	{
    		lcd_com(0x80);
    		if (i%2==0)
    		{
    			lcd_string("chan");	
    		}		
    		else
    		{
    			lcd_string(" le ");
    		}
    	}
    }
    Code file lcd.h: file này mình lấy từ 1 nguồn trên mạng, có chỉnh sưả cho phù hợp với file mô phỏng của Proteus
    Code:
    #include "lpc2103.h"
    
    
    #define OUTPORT 0x038003FC //Port 2,3,4,5,6,7,8,9,23,24,25
    #define E       0x00800000 //Port 23
    #define RW      0x01000000 //Port 24
    #define RS      0x02000000 //Port 25
    /* ========================== */
    
    void delay(long time)
    {
    	while(time-->0);
    }
    
    void lcd_com(int command)
    {
    	IODIR=OUTPORT;			
    	IOCLR=OUTPORT;
    	IOSET=E+4*command;		  // Bat Port E
    	IOCLR=E;		          // Tat Port E
    	delay(5200);
    }
    
    void lcd_int()
    {	
    	
    	lcd_com(0x38);			  // 2 Dong, 5*7 font
    	lcd_com(0x0C);			  // Bat hien thi, tat con tro
    }
    
    void lcd_write(char *data)
    {	
    	IODIR=OUTPORT;	
    	IOCLR=OUTPORT;
    	IOSET=E|RS + 4*(*data);		//Bat E RS
    	IOCLR=E;			        //Tat E
    	delay(5200);
    }
    
    void lcd_string(char *sentence)
    {		  
    	while(*sentence!='\0')	  	
    	{						   
    		lcd_write(sentence);
    		sentence++;
    	}
    }
    Mình đính kèm file Proteus bên dưới:
    Attached Files

  • #2
    Mình đã tìm được cách giải quyết, có lẽ mình chưa hiểu kĩ về Interrupt cũng như về cách trả về giá trị nên mới phát sinh lỗi này.
    Cách giải quyết:
    -- Mình đặt thêm 2 biến: int n, char j
    ---- n: dùng để biết được số lần nhấn button là chẵn hay lẻ.
    ---- j: dùng nó làm điều kiện trong vòng lặp while của main. Nếu không dùng thêm biến j này thì khi đó chưa kịp nhấn nút thì dữ liệu đã hiển thị trên LCD và thay đổi liên tục.

    Code:
    Code:
    unsigned int i,n;
    unsigned char j;
    
    /* ========== KHAI BAO INTERUPT EINT1 (P0.14) ========== */
    // void EINT __ irq: Khai bao lenh khi xay ra interrupt
    void EINT1 (void) __irq
    {
            i++;
            if (i==1)
            {
                   i=0;
                   j=0;
    	}
            EXTINT = 0;
    	//VICVectAddr0 = 0x00;	
    }
    
    int main()
    {
    	intrp();
    	
    	while(1)
    	{
                    if (j==0)
                    {
                            j=1;
    		        n++;
                
    		        if (n%2==0)
    		        {
                                    lcd_int();lcd_com(0x80);
    			        lcd_string("chan");	
    		        }		
    		        else
    		        {
                                    lcd_int();lcd_com(0x80);
    			        lcd_string(" le ");
    		        } 
    	        }
            }
    }

    Comment


    • #3
      Mình cũng gặp vấn đề tương tự như bạn. Khi mình thiết lập ngắt cạnh xuống (falling edge) ở chân EINT1, ISR thì cũng chỉ có 1 biến i đếm số lần nhấn nút. trong hàm main hiển thị số này lên lcd. Nhưng khi dùng proteus mình có thể khẳng định đây vẫn là ngắt kiểu level sensivity vì khi minh ấn button, i đã nhảy rất xa (Có lẽ Proteus chạy sai chăng ?). Không hiểu nguyên nhân ở đâu???

      P/S: mình thấy câu lệnh: EXTINT = 0; của bạn trong isr có vẻ không ổn thì phải. mình nghĩ nên sửa lại thành EXTINT = 2. Không biết ý kiến của mình có đúng không, vì mình cũng vừa mới làm quen với lpc2103. Mong bạn giúp đỡ

      Comment

      Về tác giả

      Collapse

      newbielpc03 Tìm hiểu thêm về newbielpc03

      Bài viết mới nhất

      Collapse

      Đang tải...
      X