Thông báo

Collapse
No announcement yet.

Gặp chút vấn đề trong đồ án nhờ các bạn giúp, Timer với ADC

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

  • Gặp chút vấn đề trong đồ án nhờ các bạn giúp, Timer với ADC

    Tôi đang làm bài tập về bảo vệ quá áp và vượt tần, yêu cầu là khi tần số hay điện áp tăng bất thường thì sau khoảng 4s cắt điện. Tôi làm 2phần bv áp với bv tần riêng nhau thì mạch đã chạy nhưng giờ muốn ghép lại thì gặp vấn đề, không biết làm thế nào.
    Tôi dùng pp đếm xung để đo tần số, khi ghép 2 phần lại thì phần bv tần không hoạt động, tôi nghĩ do khi timer0 đếm chưa tràn thì đã đến phần ADC gặp delay nên làm sai các giá trị timer. Các bạn có cách nào giải quyết giúp với?

    Code:
    #include <at89x51.h>
    
    char ngat=0,w=0,f=0,ch=0;
    int vin=1,dem;
    sbit ADC_RD=P3^0;
    sbit ADC_WR=P3^1 ;
    sbit ADC_INTR=P3^2;
    
    void delay_ms(unsigned int ms)
    {
     unsigned int x,y;
     for(x=0;x<ms;x++)
     for(y=0;y<=125;y++);
    }
    
    void main (void)
    {
    P1=0x00;
    TMOD = 0x51;//Timer0 che do 1, Timer1 che do 1, counter
    EA = 1; 	//Cho phep ngat Timer0
    ET0 = 1; 	//Cho phep ngat
    TR0 = 1;	//Timer0 dem
    
    
    while(1)
    { //Bao ve qua tan so==============================
    if(ngat==21)
    	{
    	TR1 = 0;
    	dem = TH1*256+TL1;
    	TH1=TL1=0;
    	if(dem==50)	//Tan so an toan 50Hz
    		{		
    		P1_1=1; 
    		P1_0=0; 
    		w=0;
    		}
    		else{
    			P1_0=1; P1_1=0;//canh bao
    			w++;
    			if(w==2){
    				P1_2=1; //ngat relay
    				w=0;}
    				TR0=0;
    			delay_ms(3000);
    			TR0=1;			
    			}						
    	ngat=0;
    	}
    //================Bao ve qua ap===================
    //ADC_RD=1;
    ADC_WR=1;
    ADC_WR=0; //Tao suon thap len cao de bat dau chuyen doi ADC
    ADC_WR=1;
    while(ADC_INTR);//Cho cho ADC chuyen doi xong(INTR xuong muc thap)
    ADC_RD=0; //Doc du lieu ADC
    vin= P2;
    vin=vin*19.53125;
    if((vin<2960)|(vin>3040))// Gia su tin hieu V an toan la 3V
    {
    	f++;
    	P1_3=1;	P1_4=0;
    	if(f==2){
    		P1_2=1;	//ngat relay
    		f=0;}
    		//TR0=0;
    	delay_ms(3000);
    	//TR0=1;
    }
    else{
    	f=0;
    	P1_3=0;	
    	P1_4=1;
    	}	
    delay_ms(1000);
    ADC_RD=1;  
    }
    }
    void Interrupt (void) interrupt TF0_VECTOR
    {
    	TR0 = 0;	//Dung Timer0
    	TH0 = 0x3C; //Nap -50000 vao TH0TL0
    	TL0 = 0xB0;
    	ngat++;		//Tang ngat cho lap 20lan*50000 = 1s
    	TR0 = 1;	//Start Timer
    	TR1 = 1;
    } 
    //-----------------Bao ve qua ap---------------------
    Last edited by Zikx258; 18-09-2013, 22:40.

  • #2
    Mình chưa hiểu giải thuật mà bạn thực hiện trong bài này, bạn có thể nêu ngắn gọn bằng lời được không? Thực sự là mình thấy code bạn viết rối quá. Mà có thể tóm gọn là: chuơng trình của minhd sẽ liên tục kiểm tra cảm biến đo áp và tần số, nếu có 1 trong 2 hoặc cả 2 cùng xảy ra nếu hiện tượng đó kéo dài trong khoảng >=4s thì mình sẽ thực hiện ngắt điện? Nếu vậy sao bạn không thử đọc tín hiệu từ các cảm biến bằng timer? Và nếu bạn dùng timer để đọc thông tin thì trong hàm main chỗ while(1) ở cuối while đó bạn có thể đưa lệnh PCON=IDL_; thay cho delay(1000) chuơng trình sẽ chạy rất mượt mà ứng dụng vẫn đảm bảo tính thời gian thực.

    Comment


    • #3
      Mà theo mình đoán thì cậu sẽ lấy mẫu theo kiểu cứ cách 1s lại lấy mẫu 1 lần, nếu 4 lần lấy mẫu liên tiếp mà giá trị điện áp hoặc tần số đều cao quá mức thì sẽ thực hiện ngắt điện. Nếu cậu chuyển qua dùng timer để lấy mẫu thì có thể tính toán cho nó lẫy mẫu khoảng 20 lần trong 1s chẳng hạn thì tính chính xác cao hơn.

      Comment


      • #4
        Cảm ơn bạn, bạn nói đúng ý mình đó, nhưng giải thuật mình làm là nếu vượt 2 lần liên tiếp thì cho ngắt điện (delay 3s+1s lấy mẫu), không chính xác nhưng mình thấy chấp nhận được, nhưng chắc phải làm lại rồi. Bạn nói rõ hơn về đọc tín hiệu bằng timer được không, có phải là lấy mẫu trong thời gian nhất định vd 0.5s rồi kiểm tra nếu vượt liên tục trong 4s thì cắt điện đúng không?
        Bạn giải thích lệnh PCON=IDL_ giúp mình, vì mình học msp430 nay làm 8051 nên còn nhiều lệnh chưa rõ

        Comment


        • #5
          Nguyên văn bởi Zikx258 Xem bài viết
          Bạn giải thích lệnh PCON=IDL_ giúp mình, vì mình học msp430 nay làm 8051 nên còn nhiều lệnh chưa rõ
          Có 2 chỗ bạn có thể tra cứu: 1 là datasheet, 2 là header file (chủ yếu là khai báo register nằm ở vị trí nào, rồi từ đó xem datasheet xem nó có chức năng gì). Mình không rõ bạn dùng con gì mà có ADC, nhưng đoán mò IDL_ chắc là idle: đưa VĐK vào trạng thái nghỉ?

          Comment


          • #6
            Nguyên văn bởi spam12345 Xem bài viết
            Có 2 chỗ bạn có thể tra cứu: 1 là datasheet, 2 là header file (chủ yếu là khai báo register nằm ở vị trí nào, rồi từ đó xem datasheet xem nó có chức năng gì). Mình không rõ bạn dùng con gì mà có ADC, nhưng đoán mò IDL_ chắc là idle: đưa VĐK vào trạng thái nghỉ?
            Đúng rồi đó bạn ý mình là bạn lấy mẫu bằng timer, còn những khoảng thời gian rảnh rỗi khác cho VSL về trạng thái ngủ thay vì bạn delay để ứng ụng chạy với thời gian thực nhưng lại không phải vất vả cho VSL. Vì sau khi lấy mẫu xong thì timer sẽ gọi lại chương trình chính có nghĩa là sẽ wekup CPU từ ngủ sang trạng thái làm việc. như vậy là bạn không cần phải cho CPU làm "donothing" để làm trễ. nếu bạn không tin thì chuyển data sheet những linh kiện kia cho mình và hỗ trợ mình cái thẻ cào Viettel 20k mình sẽ code giúp bạn cái này đảm bảo thời gian thực mà độ chính xác cao nhưng lại không tiêu tốn sức mạnh VSL.

            Comment


            • #7
              Do mình đo tần số bằng pp đếm xung nên sau 1s mới lấy mẫu đc, mình có làm bằng pp đo độ rộng xung nhưng kq k ổn định, lâu lâu lại sai số 1hz. mình sẽ xem lại vđ này. Mình nghĩ tự viết sẽ dễ hiểu hơn và cũng không khó lắm
              Cảm ơn các bạn rất nhiều!

              Comment


              • #8
                Thực ra mình chả có ý muốn kiếm chác gì cả nhưng tại học xong mà chưa có việc đói quá đến tiền nạp điện thoại cũng không có nên mới nói vậy. Nói chung là nếu có mô tả phần cứng đầy đủ mình có thể viết cho bạn cái sườn đảm bảo chạy ổn hơn và dễ hiểu hơn của bạn. Vì mình là CNTT chứ không phải dân điện tử nên phần cứng mình mới chỉ đựoc làm quen với 1 số con thôi chứ chưa có đựoc nhiều.

                Comment


                • #9
                  Có lẽ thế này sẽ gần đúng với yêu cầu của bạn!

                  Thực ra mình không định làm giúp bài ai đó nhưng thấy mọi người làm khá máy móc, nên mình thử làm để phần nào đó thây đổi cách tư duy của mọi người. Nếu mình nổ quá thì mọi người cứ cho ít gạch đá nhé "can tội cái mồm hay chửi xằng".
                  Attached Files

                  Comment


                  • #10
                    Code của mình sửa lại, bỏ mấy chỗ delay và cho lấy mẫu mỗi 1s thì đã chạy ổn. Dân IT code có khác, mình lâu lâu mới đụng tới code nên viết lung tung. Code bạn viết chạy tốt nhưng ý mình muốn là khi có vượt tần hay quá áp thì cắt luôn relay chứ không mở lại vì nó cấp nguồn cho máy phát. Rất cảm ơn bạn vì sự nhiệt tình!

                    Comment


                    • #11
                      Nguyên văn bởi Zikx258 Xem bài viết
                      Code của mình sửa lại, bỏ mấy chỗ delay và cho lấy mẫu mỗi 1s thì đã chạy ổn. Dân IT code có khác, mình lâu lâu mới đụng tới code nên viết lung tung. Code bạn viết chạy tốt nhưng ý mình muốn là khi có vượt tần hay quá áp thì cắt luôn relay chứ không mở lại vì nó cấp nguồn cho máy phát. Rất cảm ơn bạn vì sự nhiệt tình!
                      Bạn chỉ cần đổi mở thành đóng, đóng thành mở là xong. Vì mình không biết mục đích của bài làm đó là gì, nên chỉ nghĩ là nếu những điều kiện đầu vào không ở mức an toàn thì không cấp điện còn khi ở điều kiện tiêu chuẩn thì cấp điện.

                      Comment

                      Về tác giả

                      Collapse

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

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

                      Collapse

                      Đang tải...
                      X