Thông báo

Collapse
No announcement yet.

cần giúp về vấn đề PWM

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

  • cần giúp về vấn đề PWM

    mình đang tìm hiểu về vdk at89c51 và đang tìm hiểu về vấn đề tạo xung pwm. mình củng có đọc một số trang web nhưng không hiểu cách thức cho lắm. mình nghie ra một vấn đề về pwm như thế này nhưng chưa giải quyết được nên nhờ các cao thủ giúp giùm.
    1- chân out của vdk lớn nhất là xuất 5v để điều khiển led, vì thế để thay dổi độ sáng của led mình chia 0-5V ra làm 250 mức sáng khác nhau, như vậy là mổi mức sáng là 0,02V
    2- thời gian mình cho led sáng từ 0v đến 5v là 1S vì thế nên thời gian tăng số vol từ 0,02 lên 0,04 (mức 1 lên mức 2) là 4mS
    vấn đề minh cần giải quyết ở đây là làm sao để chia 0-5v thành 250 mức sáng được và làm sao để mức sáng đó thay đổi từ mức 1 lêd mức 2 lên.... lên mức 250, mổi lần thay như thế mất 4mS. bạn nào biết chỉ dùm mình với. thank nhiều

  • #2
    bạn dùng C hay asm ? nếu C thì mình có thể giúp được đôi chút.

    Comment


    • #3
      Nguyên văn bởi kervin Xem bài viết
      mình đang tìm hiểu về vdk at89c51 và đang tìm hiểu về vấn đề tạo xung pwm. mình củng có đọc một số trang web nhưng không hiểu cách thức cho lắm. mình nghie ra một vấn đề về pwm như thế này nhưng chưa giải quyết được nên nhờ các cao thủ giúp giùm.
      1- chân out của vdk lớn nhất là xuất 5v để điều khiển led, vì thế để thay dổi độ sáng của led mình chia 0-5V ra làm 250 mức sáng khác nhau, như vậy là mổi mức sáng là 0,02V
      2- thời gian mình cho led sáng từ 0v đến 5v là 1S vì thế nên thời gian tăng số vol từ 0,02 lên 0,04 (mức 1 lên mức 2) là 4mS
      vấn đề minh cần giải quyết ở đây là làm sao để chia 0-5v thành 250 mức sáng được và làm sao để mức sáng đó thay đổi từ mức 1 lêd mức 2 lên.... lên mức 250, mổi lần thay như thế mất 4mS. bạn nào biết chỉ dùm mình với. thank nhiều
      cách tính của bạn không áp dụng được đâu bạn. PWM là phương pháp điều chế độ rộng xung với tần số không đổi. Như vậy để tạo được pwm bạn cần xác định được :
      - Tần số PWM bạn mong muốn là bao nhiều?
      -Từ giá trị tần số => tính giá trị nạp cho timer của vi điều khiển( cái này bạn đọc về timer nhé).
      - So sánh trong timer để có độ rộng xung như mong muốn.
      Nguyễn Huy Biên - 01649 802 694
      gmail :

      Comment


      • #4
        Nguyên văn bởi dt3k4 Xem bài viết
        bạn dùng C hay asm ? nếu C thì mình có thể giúp được đôi chút.
        mình tìm hiểu cả 2 ngôn ngử. cảm ơn bạn trước nhé

        Nguyên văn bởi bienhou Xem bài viết
        cách tính của bạn không áp dụng được đâu bạn. PWM là phương pháp điều chế độ rộng xung với tần số không đổi. Như vậy để tạo được pwm bạn cần xác định được :
        - Tần số PWM bạn mong muốn là bao nhiều?
        -Từ giá trị tần số => tính giá trị nạp cho timer của vi điều khiển( cái này bạn đọc về timer nhé).
        - So sánh trong timer để có độ rộng xung như mong muốn.
        nhưng nếu tạo xung với 1 tần số không đổi nghỉa là chu kì xung vẩn không đổi. như vậy mình muốn led sáng từ 0v-5v trong vòng 2S thì phải tạo 1 xung có chu kì là 2S và tần số tương ứng sẻ là 0,5Hz phải không bạn. tất nhiên nếu xung thì sẻ có mức cao và mức thấp nên vấn đề ở đây là làm sao để thay dổi dộ rộng xung tăng lên theo thời gian mong muốn vậy bạn

        Comment


        • #5
          Code:
          #include <REGX51.H>
          sbit    PWM = P2^3;
          sbit    TANG = P1^2;
          sbit    GIAM = P1^5;
          unsigned char dem=0,tocdo=25;
          
          bit TANG1=1,TANG0=1,GIAM0=1,GIAM1=1;
          
          void timer0(void) interrupt 1
          {
          TR0 = 0;
          TF0 = 0;
          dem++;
          if(dem > 100)
          dem = 0;
          if(dem<tocdo)
          PWM = 1;
          else
          PWM = 0;
          TR0 = 1;
          }
          
          void phimnhan()
          {
          //////////////////////////
          TANG0=TANG1;TANG1=TANG;
          if((TANG0==1)&&(TANG1==0))
          tocdo=tocdo+5;
          if(tocdo==55)tocdo=50;
          
          /////////////////////////////////
          GIAM0=GIAM1;GIAM1=GIAM;
          if((GIAM0==1)&&(GIAM1==0))
          tocdo=tocdo-5;
          if(tocdo==-5)tocdo=0;
          }
          
          void main(void)
          {
          TMOD = 0X02;
          IE = 0X82;
          TH0=TL0=-50; // tao tan so 0.05 ms
          TR0 = 1;
          PWM=0;
          while(1)
          {
          phimnhan();
          }
          }
          bạn nghiên cứu nhé, ví dụ trong ctrinh này bạn chỉ cần tăng biến tocdo từ 0-100 trong 2s là ok
          Nguyễn Huy Biên - 01649 802 694
          gmail :

          Comment


          • #6
            Nguyên văn bởi bienhou Xem bài viết
            Code:
            #include <REGX51.H>
            sbit    PWM = P2^3;
            sbit    TANG = P1^2;
            sbit    GIAM = P1^5;
            unsigned char dem=0,tocdo=25;
            
            bit TANG1=1,TANG0=1,GIAM0=1,GIAM1=1;
            
            void timer0(void) interrupt 1
            {
            TR0 = 0;
            TF0 = 0;
            dem++;
            if(dem > 100)
            dem = 0;
            if(dem<tocdo)
            PWM = 1;
            else
            PWM = 0;
            TR0 = 1;
            }
            
            void phimnhan()
            {
            //////////////////////////
            TANG0=TANG1;TANG1=TANG;
            if((TANG0==1)&&(TANG1==0))
            tocdo=tocdo+5;
            if(tocdo==55)tocdo=50;
            
            /////////////////////////////////
            GIAM0=GIAM1;GIAM1=GIAM;
            if((GIAM0==1)&&(GIAM1==0))
            tocdo=tocdo-5;
            if(tocdo==-5)tocdo=0;
            }
            
            void main(void)
            {
            TMOD = 0X02;
            IE = 0X82;
            TH0=TL0=-50; // tao tan so 0.05 ms
            TR0 = 1;
            PWM=0;
            while(1)
            {
            phimnhan();
            }
            }
            bạn nghiên cứu nhé, ví dụ trong ctrinh này bạn chỉ cần tăng biến tocdo từ 0-100 trong 2s là ok
            bạn có thể gải thích quá một chút được không, mình còn mơ hồ quá, ví dụ nếu như ta muốn thay đổi độ rộng xung không dùng phím bấm thì pahir làm nhưu thế nào vậy

            Comment


            • #7
              dưới đây là đoạn code làm sáng dần và tối dần trên cổng P2.1. các bạn thử và góp ý nhé.
              Code:
               #include<regx52.h>
              
              sbit 	w11=P2^1;
              
              void delayus(int time)
              {	
              	int n;
              	unsigned char a;
              	for(n=0;n<time;n++)
              	{
              		a=0;
              	}
              }
              void up(unsigned char n1)
              {	
              	int n,time;
              	time=350;	
              	for(n=1;n<time;n++)
              	{
              		w11=0;delayus(time-n);
              		w11=n1;delayus(n);
              	}
              }
              void down(unsigned char n1)
              {	
              	int n,time;
              	time=350; 	
              	for(n=1;n<time;n++)
              	{
              		w11=0;delayus(n);
              		w11=n1;delayus(time-n);
              	}
              }
              void flash()
              {
              	up(1);           /// sáng dần
                      down(1);       /// tối dần
              }
              main()
              {	
              	for(;;)
              	{
                               flash();
              	}
              }
              chỉ có tâm hồn là nơi duy nhất: có thể biến thiên đường thành địa ngục và ngược lại có thể biến địa ngục hóa thiên đường
              Everything should be made as simple as possible, but not simpler

              Comment


              • #8
                Nguyên văn bởi daohuytien Xem bài viết
                dưới đây là đoạn code làm sáng dần và tối dần trên cổng P2.1. các bạn thử và góp ý nhé.
                Code:
                 #include<regx52.h>
                
                sbit 	w11=P2^1;
                
                void delayus(int time)
                {	
                	int n;
                	unsigned char a;
                	for(n=0;n<time;n++)
                	{
                		a=0;
                	}
                }
                void up(unsigned char n1)
                {	
                	int n,time;
                	time=350;	
                	for(n=1;n<time;n++)
                	{
                		w11=0;delayus(time-n);
                		w11=n1;delayus(n);
                	}
                }
                void down(unsigned char n1)
                {	
                	int n,time;
                	time=350; 	
                	for(n=1;n<time;n++)
                	{
                		w11=0;delayus(n);
                		w11=n1;delayus(time-n);
                	}
                }
                void flash()
                {
                	up(1);           /// sáng dần
                        down(1);       /// tối dần
                }
                main()
                {	
                	for(;;)
                	{
                                 flash();
                	}
                }
                ở 2 dòng màu đỏ đó là có phải mình liên tục tăng xung, đảo bit để tạo sóng vuông không bạn.
                bạn có thể hướng dẩn mình cách tình thời gian thực thi của 1 chu kì lệnh được không, giống bên asm dùng thạch anh 12mhz ta có thể tính được thòi gian 1 chu kì máy là 1uS thế, bên c mình không thấy nhắc đến, vd như lệnh for(i=0;i<50;i++) thì thời gian thực hiện là bao lâu. thank

                Comment


                • #9
                  Nguyên văn bởi kervin Xem bài viết
                  ở 2 dòng màu đỏ đó là có phải mình liên tục tăng xung, đảo bit để tạo sóng vuông không bạn.
                  bạn có thể hướng dẩn mình cách tình thời gian thực thi của 1 chu kì lệnh được không, giống bên asm dùng thạch anh 12mhz ta có thể tính được thòi gian 1 chu kì máy là 1uS thế, bên c mình không thấy nhắc đến, vd như lệnh for(i=0;i<50;i++) thì thời gian thực hiện là bao lâu. thank
                  thế này nhé bạn :
                  + hai dòng màu đỏ chỉ ra đó là khâu thay đổi độ rộng của xung. trong khi chu kỳ của xung không thay đổi là : ~ delayus(time).
                  khi n =1 chẳng hạn thì w11=0;( đèn tắt chẳng hạn ). được trễ trong thời gian là delayus(time-1), sau đó thì w111=1;(đèn sáng) được trễ trong delayus(1); tiếp tục tăng n lên thì thời gian tắt của đèn giảm, thời gian sáng tăng lên. ->>> thay đổi độ sáng ->>> ok
                  + còn cái ý thứ 2 là cách tính thời gian thực thi, bạn vào theo hình này mà xem.
                  Click image for larger version

Name:	debug.jpg
Views:	1
Size:	85.7 KB
ID:	1384021
                  chỉ có tâm hồn là nơi duy nhất: có thể biến thiên đường thành địa ngục và ngược lại có thể biến địa ngục hóa thiên đường
                  Everything should be made as simple as possible, but not simpler

                  Comment


                  • #10
                    Nguyên văn bởi daohuytien Xem bài viết
                    thế này nhé bạn :
                    + hai dòng màu đỏ chỉ ra đó là khâu thay đổi độ rộng của xung. trong khi chu kỳ của xung không thay đổi là : ~ delayus(time).
                    khi n =1 chẳng hạn thì w11=0;( đèn tắt chẳng hạn ). được trễ trong thời gian là delayus(time-1), sau đó thì w111=1;(đèn sáng) được trễ trong delayus(1); tiếp tục tăng n lên thì thời gian tắt của đèn giảm, thời gian sáng tăng lên. ->>> thay đổi độ sáng ->>> ok
                    + còn cái ý thứ 2 là cách tính thời gian thực thi, bạn vào theo hình này mà xem.
                    [ATTACH=CONFIG]72773[/ATTACH]
                    nếu nói vậy thì 1 led tắt hẳn cần 1 thời gian nhất định mới làm led sáng 100%. ta lợi dụng điểm này của led làm cho nó sáng lên vài mS rồi cho nó tắt vài mS và cho nó sáng lên tiếp bằng cách tăng thời gian sáng và giảm thời gian tối lại. cách này là không dùng ngắt timer phải không bác. tần số củng như chu kì xung trong code trên tính như thế nào vậy bác.

                    Comment


                    • #11
                      Nguyên văn bởi kervin Xem bài viết
                      tần số củng như chu kì xung trong code trên tính như thế nào vậy bác.
                      kiểu này không dùng đến timer, còn chu kỳ của xung được tính theo : hàm delayus( time ) với time là tham số . còn hàm delayus() thì bạn lại thử debug xem nó hết khoảng bao nhiêu us.
                      cái này mình lập trình sau đó cho chạy thử thấy nó sáng theo ý mình thì thôi. chứ không qua tâm nhiều đến chu kỳ hay tần số xung là bn .
                      chỉ có tâm hồn là nơi duy nhất: có thể biến thiên đường thành địa ngục và ngược lại có thể biến địa ngục hóa thiên đường
                      Everything should be made as simple as possible, but not simpler

                      Comment


                      • #12
                        Nguyên văn bởi daohuytien Xem bài viết
                        kiểu này không dùng đến timer, còn chu kỳ của xung được tính theo : hàm delayus( time ) với time là tham số . còn hàm delayus() thì bạn lại thử debug xem nó hết khoảng bao nhiêu us.
                        cái này mình lập trình sau đó cho chạy thử thấy nó sáng theo ý mình thì thôi. chứ không qua tâm nhiều đến chu kỳ hay tần số xung là bn .
                        tình thời gian chu kì của xung suy ra tần số. mà nếu như vậy thì mình nghỉ viêc chọn tần số càng lớn ( chu kì 1 xung càng nhỏ) và băm xung càng nhỏ thì xung càng mịn đúng không ạ. thank bác đẳ giúp đở, em sẻ tìm thêm về vấn đề này

                        Comment


                        • #13
                          nếu chọn chu kỳ xung càng nhỏ thì đèn sáng lên rất nhanh và tắt đi cũng rất nhanh. Khi đó ta phải cho thêm 1 chút này : dòng màu đỏ.
                          Code:
                          void up(unsigned char n1)
                          {	
                          	unsigned char n,time,m;
                          	time=200;	
                          	for(n=1;n<time;n++)
                          	{
                          		for(m=0;m<3;m++)
                          		{
                          			w11=0;delayus(time-n);
                          			w11=n1;delayus(n);
                          		}
                          	}
                          }
                          void down(unsigned char n1)
                          {	
                          	unsigned char n,time,m;
                          	time=200;	
                          	for(n=1;n<time;n++)
                          	{
                          		for(m=0;m<3;m++)
                          		{
                          			w11=0;delayus(n);
                          			w11=n1;delayus(time-n);
                          		}
                          	}
                          }
                          ờ mà khi nào làm được rồi up video lên cho ae xem nhé.
                          chỉ có tâm hồn là nơi duy nhất: có thể biến thiên đường thành địa ngục và ngược lại có thể biến địa ngục hóa thiên đường
                          Everything should be made as simple as possible, but not simpler

                          Comment


                          • #14
                            Nguyên văn bởi daohuytien Xem bài viết
                            nếu chọn chu kỳ xung càng nhỏ thì đèn sáng lên rất nhanh và tắt đi cũng rất nhanh. Khi đó ta phải cho thêm 1 chút này : dòng màu đỏ.
                            Code:
                            void up(unsigned char n1)
                            {	
                            	unsigned char n,time,m;
                            	time=200;	
                            	for(n=1;n<time;n++)
                            	{
                            		for(m=0;m<3;m++)
                            		{
                            			w11=0;delayus(time-n);
                            			w11=n1;delayus(n);
                            		}
                            	}
                            }
                            void down(unsigned char n1)
                            {	
                            	unsigned char n,time,m;
                            	time=200;	
                            	for(n=1;n<time;n++)
                            	{
                            		for(m=0;m<3;m++)
                            		{
                            			w11=0;delayus(n);
                            			w11=n1;delayus(time-n);
                            		}
                            	}
                            }
                            ờ mà khi nào làm được rồi up video lên cho ae xem nhé.
                            ok. thank bác. đưa video lên thì ở dạng test led thôi. em mới ngồi hàn cái boar test led 32 cổng xài 89c51 xong.

                            Comment


                            • #15
                              Nguyên văn bởi kervin Xem bài viết
                              bạn có thể gải thích quá một chút được không, mình còn mơ hồ quá, ví dụ nếu như ta muốn thay đổi độ rộng xung không dùng phím bấm thì pahir làm nhưu thế nào vậy
                              thì bạn cứ cho cái biến tốc độ nó tự tăng lên trong while thôi.
                              Nguyễn Huy Biên - 01649 802 694
                              gmail :

                              Comment

                              Về tác giả

                              Collapse

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

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

                              Collapse

                              Đang tải...
                              X