Thông báo

Collapse
No announcement yet.

Ngắt ngoài 8051 không chính xác

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

  • Ngắt ngoài 8051 không chính xác

    Chào các bác, em đang làm mạch đếm hiển thị ra LCD có sử dụng ngắt ngoài của 8051. Em dùng ngắt kích hoạt bằng sườn của xung. Nhưng khổ nỗi là nó không chính xác cho lắm. Em bấm 1 lần thả ra mà nó nhảy đi mấy số. Cho delay vào thì được, nhưng do đây là mạch đếm cần chính xác cao nên không thể để delay cao quá được, mà để delay bé quá hoặc ko để thì bị lỗi như trên. Sơ đồ mạch cũng ko có gì cả, chỉ là dùng 1 công tắc nối với cổng INT thôi. Test thử thì là vậy, sau ngoài đời cái ấy sẽ nối với hệ đếm sensor. Các bác giúp em với nhé. Em cảm ơn nhiều. Code của em đây
    Code:
    #include <REGX52.H>
    #include "string.h"
    sfr lcddata=0xA0;
    sbit bf=0xA7;
    sbit rs=P3^0;
    sbit rw=P3^1;
    sbit en=P3^2;
    int i=0;
    void wait(void)
    {
    	//long n=0;
    	
    	en=1;
    	rs=0;
    	rw=1;
    	lcddata=0xff;
    	while(bf)
    	{
    		//n++;
    		//if(n>100)break;
    	}
    	en=0;
    	rw=0;	
    
    }
    void lcdcontrol(unsigned char x)
    {
    	rs=0;
    	rw=0;
    	lcddata=x;
    	en=1;
    	en=0;
    	wait();
    }
    void lcdinit(void)
    {
    	lcdcontrol(0x30); //Phai co cai nay thi moi chay 2 dong duoc
    	
    	lcdcontrol(0x38);
    	
    	lcdcontrol(0x0e);
    	lcdcontrol(0x01);
    }
    void lcdwrite(unsigned char c)
    {
    	rs=1;
    	rw=0;
    	lcddata=c;
    	en=1;
    	en=0;
    	wait();
    }
    void lcdwrites(unsigned char *s)
    {
    	unsigned char data lens, count;
    	lens=strlen(s);
    	for(count=0;count<lens;count++)
    	{
    		lcdwrite(*(s+count));
    	}
    }
    void delay(long time)
    {
    	while(time--);
    }
    void number(unsigned int i)
    {
    	unsigned char a,b,c,d,e;
    	e=i%10;
    	i=i/10;
    	d=i%10;
    	i=i/10;
    	c=i%10;
    	i=i/10;
    	b=i%10;
    	a=i/10;
    	lcdwrite(a+48);
    	lcdwrite(b+48);
    	lcdwrite(c+48);
    	lcdwrite(d+48);
    	lcdwrite(e+48);
    }
    void dem(void) interrupt 2
    {
    	
    	
    	lcdcontrol(0x87);
    	
    	
    	i++;
    	
    	number(i);
    	
    	
    }
    void main(void)
    {
    	EA=1;
    	EX1=1;
    	IT1=1;
    	lcdinit();
    	lcdcontrol(0x80);
    	lcdwrites("Counts:");
    	lcdcontrol(0xc0);
    	lcdwrites("     HUS-VNU");
    	
    	while(1);
    	
    
    	}

  • #2
    Bạn đã nghe đến "chống nhiễu phím bấm" bao giờ chưa? Thử Google search đi.

    Khi bấm phím (nút bấm), gặt công tắc... thì, do đặc tính cơ học, sẽ không có một sự chuyển mức logic đơn lẻ 0->1, 1->0 như ta vẫn nghĩ mà nó có thêm một số xung nhiễu. Phải xử lý cái đó thì mới đếm chính xác.

    Comment


    • #3
      Trước tiên nối cho nút bấm 1 con led treo trở 10k lên VCC, khi ta bấm thì led sáng lên.
      Tại sao bạn lại để hàm điều khiển LCD trong chương trình con phục vụ ngắt ngoài ?
      /////delay
      Code:
      void delay(unsigned int time){
      while (time--);
      continue;
      }
      ////Trong chương trình con phục vụ ngắt thì chỉ nên cho tăng biến i thôi.

      Code:
      void dem(void) interrupt 2
      {	
      	
      	i++;	
      	
      }
      Main thì khởi tạo ngắt ngoài, cho phép ngắt toàn cục, khởi tạo LCD.
      rồi trong vòng lặp while(1) bạn chỉ việc hiển thị lcd
      Code:
      while(1){
      number(i);
      ////đặt code hiển thị LCD ở đây
      ///ví dụ  lcd_putnum(number,0,0); 
      
      }

      Comment


      • #4
        Nguyên văn bởi qwerty68 Xem bài viết
        Chào các bác, em đang làm mạch đếm hiển thị ra LCD có sử dụng ngắt ngoài của 8051. Em dùng ngắt kích hoạt bằng sườn của xung. Nhưng khổ nỗi là nó không chính xác cho lắm. Em bấm 1 lần thả ra mà nó nhảy đi mấy số. Cho delay vào thì được, nhưng do đây là mạch đếm cần chính xác cao nên không thể để delay cao quá được, mà để delay bé quá hoặc ko để thì bị lỗi như trên. Sơ đồ mạch cũng ko có gì cả, chỉ là dùng 1 công tắc nối với cổng INT thôi. Test thử thì là vậy, sau ngoài đời cái ấy sẽ nối với hệ đếm sensor. Các bác giúp em với nhé. Em cảm ơn nhiều. Code của em đây
        Code:
        #include <REGX52.H>
        #include "string.h"
        sfr lcddata=0xA0;
        sbit bf=0xA7;
        sbit rs=P3^0;
        sbit rw=P3^1;
        sbit en=P3^2;
        int i=0;
        void wait(void)
        {
        	//long n=0;
        	
        	en=1;
        	rs=0;
        	rw=1;
        	lcddata=0xff;
        	while(bf)
        	{
        		//n++;
        		//if(n>100)break;
        	}
        	en=0;
        	rw=0;	
        
        }
        void lcdcontrol(unsigned char x)
        {
        	rs=0;
        	rw=0;
        	lcddata=x;
        	en=1;
        	en=0;
        	wait();
        }
        void lcdinit(void)
        {
        	lcdcontrol(0x30); //Phai co cai nay thi moi chay 2 dong duoc
        	
        	lcdcontrol(0x38);
        	
        	lcdcontrol(0x0e);
        	lcdcontrol(0x01);
        }
        void lcdwrite(unsigned char c)
        {
        	rs=1;
        	rw=0;
        	lcddata=c;
        	en=1;
        	en=0;
        	wait();
        }
        void lcdwrites(unsigned char *s)
        {
        	unsigned char data lens, count;
        	lens=strlen(s);
        	for(count=0;count<lens;count++)
        	{
        		lcdwrite(*(s+count));
        	}
        }
        void delay(long time)
        {
        	while(time--);
        }
        void number(unsigned int i)
        {
        	unsigned char a,b,c,d,e;
        	e=i%10;
        	i=i/10;
        	d=i%10;
        	i=i/10;
        	c=i%10;
        	i=i/10;
        	b=i%10;
        	a=i/10;
        	lcdwrite(a+48);
        	lcdwrite(b+48);
        	lcdwrite(c+48);
        	lcdwrite(d+48);
        	lcdwrite(e+48);
        }
        void dem(void) interrupt 2
        {
        	
        	
        	lcdcontrol(0x87);
        	
        	
        	i++;
        	
        	number(i);
        	
        	
        }
        void main(void)
        {
        	EA=1;
        	EX1=1;
        	IT1=1;
        	lcdinit();
        	lcdcontrol(0x80);
        	lcdwrites("Counts:");
        	lcdcontrol(0xc0);
        	lcdwrites("     HUS-VNU");
        	
        	while(1);
        	
        
        	}
        bạn bấm 1 cái mà nó nhảy vài số là ít vì trong hàm ngắt có thêm cái lcdcontrol nó hãm bớt, thử chỉ có 1 lệnh ++ xem nó nhảy mấy chục số cho coi. Dùng ngắt ngoài, nếu là phục vụ phím bấm thì phải chống nảy phím (debouncing) còn nếu ngắt ngoài nối với sensor thì ko cần debounce vì trạng thái logic đầu ra của sensor ko bị nảy. Nhưng đếm sự kiện thì nên dùng timer/counter

        Comment


        • #5
          Cảm ơn các bác ạ, để tí em thử xem sao.

          Comment

          Về tác giả

          Collapse

          qwerty68 Trịnh Ngọc Duy Tìm hiểu thêm về qwerty68

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

          Collapse

          Đang tải...
          X