標題: 51單片機測量PWM脈沖寬度LCD1602顯示當前PWM占空比頻率 [打印本頁]

作者: MR_CHEN12    時間: 2018-12-26 12:22
標題: 51單片機測量PWM脈沖寬度LCD1602顯示當前PWM占空比頻率
此程序通過兩個定時器一個外部中斷,測量PWM高電平時間以及周期,計算并在1602顯示出占空比 周期 高電平時間,只需讓脈沖在P3^2口輸入即能測得數據。。

單片機源程序如下:
  1. #include <reg52.h>
  2. #include <LCD1602.h>

  3. typedef unsigned char uint8;
  4. typedef unsigned int  uint16;//數據類型重定義

  5. uint8 count = 0; //計進入外部中斷次數
  6. bit flag = 1;  //捕獲結束標志位
  7. long Pwm_All; //PWM的周期
  8. long Pwm_High; //PWM的高電平時間                   占空比=Pwm_High/Pwm_All
  9. void delay(long i)
  10. {
  11.         while(i--);
  12. }

  13. void Interrupt_Init()
  14. {
  15.         /*定時器1為工作模式1 16位計數器 由TR1直接啟動
  16.                 定時器0為工作模式1 16位計數器 由GATE和TR0共同啟動*/
  17.         TMOD = 0x19;
  18.         
  19.         TH1 = 0;
  20.         TL1 = 0;
  21.         TH0 = 0;
  22.         TL0 = 0;
  23.         
  24.         IT0 = 1;//下降沿觸發(fā)
  25.         IT1 = 1;
  26.         //TR0 = 1; //GATE高電平啟動
  27.         
  28.         EX0 = 1;
  29.         EA = 1;        
  30. }

  31. void main()
  32. {
  33.         uint16 Pwm_percentage; //PWM占空比
  34.         Interrupt_Init();
  35.         LCD1602_Initialize( );
  36.         LCD1602_PrintString(1,1,"ALL:");
  37.         LCD1602_PrintString(1,10,"us");
  38.         LCD1602_PrintString(2,1,"HIGH:");
  39.         LCD1602_PrintString(2,11,"us");
  40.         while(1)
  41.         {
  42.                
  43.                 if(flag)
  44.                 {
  45.                         Pwm_percentage = Pwm_High*1000 / Pwm_All;
  46.                         LCD1602_PrintChar(1,12,0x30+Pwm_percentage/100);
  47.                         LCD1602_PrintChar(1,13,0x30+Pwm_percentage%100/10);
  48.                         LCD1602_PrintChar(1,14,'.');
  49.                         LCD1602_PrintChar(1,15,0x30+Pwm_percentage%10);
  50.                         LCD1602_PrintChar(1,16,'%');
  51.                         
  52.                         LCD1602_PrintChar(1,5,0x30+Pwm_All/10000);
  53.                         LCD1602_PrintChar(1,6,0x30+Pwm_All%10000/1000);
  54.                         LCD1602_PrintChar(1,7,0x30+Pwm_All%1000/100);
  55.                         LCD1602_PrintChar(1,8,0x30+Pwm_All%100/10);
  56.                         LCD1602_PrintChar(1,9,0x30+Pwm_All%10);
  57.                         LCD1602_PrintChar(2,6,0x30+Pwm_High/10000);
  58.                         LCD1602_PrintChar(2,7,0x30+Pwm_High%10000/1000);
  59.                         LCD1602_PrintChar(2,8,0x30+Pwm_High%1000/100);
  60.                         LCD1602_PrintChar(2,9,0x30+Pwm_High%100/10);
  61.                         LCD1602_PrintChar(2,10,0x30+Pwm_High%10);
  62.                         flag = 0; //計算完一次清零
  63.                 }
  64.                 delay(70000);
  65.         }
  66.         
  67. }

  68. void EXTI0 () interrupt 0
  69. {
  70.                 count++;
  71.         if(count == 1) //第一次下降沿,啟動定時器1
  72.         {
  73.                 TR1 = 1;
  74.                 TR0 = 1;
  75.         }
  76.         if(count == 2) //第二次下降沿,一整個周期完畢
  77.         {
  78.                 EX0 = 0; //關閉外部中斷,防止被其他打斷計算
  79.                 TR1 = 0;        //周期停止計數
  80.                 TR0 = 0;        //高電平時間停止計數
  81.                 Pwm_All = TH1; //獲取數據
  82.                 Pwm_All = (Pwm_All<<8)+TL1;
  83.                 Pwm_High = TH0;
  84.                 Pwm_High = (Pwm_High<<8)+TL0;
  85.                 TH1 = 0; //清零為下一次做準備
  86.                 TL1 = 0;
  87.                 TH0 = 0;
  88.                 TL0 = 0;
  89.                 count = 0;
  90.                 flag = 1;        
  91.                 EX0 = 1; //開啟下一次計算
  92.                 TR1 = 0;
  93.                 TR0 = 0;
  94.         }
  95.         
  96. }
復制代碼

所有資料51hei提供下載:
PWM捕獲占空比.zip (45 KB, 下載次數: 406)




作者: MR_CHEN12    時間: 2018-12-26 18:33
里面注釋詳細,不懂的歡迎提問
作者: 1179839709    時間: 2019-1-1 18:38
呢能不能改成在4位的led數碼管上顯示脈沖寬度的,不知道代碼怎么改
作者: zycable    時間: 2019-3-11 21:39
初學菜鳥,謝謝!學習了!
作者: Lucky_Dog    時間: 2019-4-27 10:58
可以只用一個定時器來實現嗎,大佬有空看一下我的求助
http://www.torrancerestoration.com/bbs/dpj-157890-1.html
作者: 1975966580    時間: 2019-5-27 22:36
如果要用定時中斷測頻率為100hz的方波的周期并在LCD1602上表示出來,程序應該怎么改呢
作者: zhanyouyuyuni    時間: 2019-6-22 09:17
1179839709 發(fā)表于 2019-1-1 18:38
呢能不能改成在4位的led數碼管上顯示脈沖寬度的,不知道代碼怎么改

可以更改 P0口接上拉電阻接數碼管更改數碼管對應的顯示就可以
作者: 懶惰的家伙    時間: 2019-7-5 16:24
請問如何改變占空比,剛剛接觸PWM,不是很明白
作者: leiluo    時間: 2019-7-5 16:46
請問老哥,這個硬件原理圖您用哪個軟件做的呢?請問是 3D MAX嗎?
作者: 周濤1331    時間: 2019-7-21 21:45
懶惰的家伙 發(fā)表于 2019-7-5 16:24
請問如何改變占空比,剛剛接觸PWM,不是很明白

#include <AT89X52.h>

#define MAX 0x50   //定時上限定義       占空比上限         下面通過定時器改變占空比
#define MIN 0x00   //定時下限定義       占空比下限
#define TIMELINE 11         //時間分頻常數
#define TRUE  1
#define FALSE 0             //標志位常數

unsigned int TimeCounter;
bit ArrowFlg = 0;         //方向標志位
unsigned char upCounter,downCounter;    //增加計數器和減少計數器

sbit LED=P0^0;

//T0的中斷服務子函數
void T0Deal() interrupt 1 using 0
{
        TH0=0xf1;
        TL0=0xf1;
        TR0=1;
        TimeCounter++;  //定時計數器增加
        if(TimeCounter == TIMELINE)
        {
                if((upCounter == MAX)&&(downCounter == MIN))  //計數方向標志位切換
    {
      ArrowFlg = FALSE;
    }
                if((upCounter == MIN)&&(downCounter == MAX))
    {
      ArrowFlg= TRUE;
    }
                if(ArrowFlg == 1)   //如果是增加計數
    {
      upCounter++;
      downCounter--;
    }
                else               //如果是減少計數
    {
      upCounter--;
      downCounter++;
    }
                TimeCounter=0;
        }
}
//延時函數
void Delay(unsigned int i)
{
        unsigned int j;
        while(i--)
        {
                for(j=0;j<32;j++);     //延時
        }
}

void main()
{
        upCounter = MIN;
        downCounter = MAX;     //計數器初始化
        TMOD = 0x01;          //設置定時器工作方式
        TH0 = 0xF0;
        TL0 = 0xF0 ;          //T0初始化值
        EA = 1;
        ET0 = 1;              //開中斷
        TR0 = 1;              //啟動T0
        while(1)
        {
                LED=0;            //輸出變化的PWM波形
                Delay(downCounter);   
                LED=1;
                Delay(upCounter);
        }
}


作者: six666666666666    時間: 2019-7-23 23:48
求電路原理圖
作者: odiwuano    時間: 2019-8-16 12:21
學習一下哈
作者: zhang21    時間: 2019-10-31 23:43
我是新手看不懂
作者: shenyuqiu    時間: 2019-11-1 15:16
有點沒搞明白這個占空比是怎么計算的,頻率就可以計算,兩個下降沿就一個完整周期,看你程序TR0與TR1都是同時開同時關的,那計時的時間不是都一樣嗎,怎么計算出占空比?
作者: 劉十一    時間: 2019-11-1 18:16
Pwm_All = (Pwm_All<<8)+TL1;這是什么意思?有什么作用嗎?
作者: sunlei058378    時間: 2019-12-17 23:46
有哪位編譯通過的嗎。交流一下。編譯一直無法通過
作者: kevintang    時間: 2020-2-12 09:24
學習一下,謝謝分享。
作者: kevintang    時間: 2020-2-15 21:10
學習一下,謝謝分享。
作者: wzjhuohua    時間: 2020-4-11 16:13
你這個能讀出來嗎?
作者: 星辰大海aa    時間: 2021-6-15 14:06
請問LCD1602的頭文件能給出來嗎 編譯的時候報錯了
作者: 星辰大海aa    時間: 2021-6-15 17:13
頭文件怎么寫呀 樓主 求救!
作者: sd3114336    時間: 2021-8-27 17:29
看看謝分享啦,學習中如何捕獲PWM然后轉換PWM或者驅動MOS
作者: 續(xù)我心弦    時間: 2022-7-20 15:19
定時器工作模式 TMOD = 0x19什么意思?
作者: mick32    時間: 2022-7-20 20:48
TMOD(Timer Mode) is an SFR. The address of this register is 89H. This is not bit-addressable.

TMOD.jpg (191.21 KB, 下載次數: 102)

TMOD.jpg

作者: 續(xù)我心弦    時間: 2022-7-21 16:28
脈沖輸入的口為什么是P32,我想弄個八路測脈沖寬度
作者: 續(xù)我心弦    時間: 2022-7-21 16:36
mick32 發(fā)表于 2022-7-20 20:48
TMOD(Timer Mode) is an SFR. The address of this register is 89H. This is not bit-addressable.

I'm going to have another question on the next floor and if you could help me, I will sincerely appreciate you
作者: mick32    時間: 2022-7-21 22:52
本帖最后由 mick32 于 2022-7-21 23:20 編輯

"This is not bit-addressable"
If you want to change lets say only 89.0 bit you can change that bit and rest of bits in byte keep the same
Then you can send new byte to 89H register
information is byte wide xxxxxxxx (8 bits)
hope this is of help...
TMOD EQU 089H ; TMOD register

bit addressable

CLR IE.7 or SETB 20H.2

byte addressable

MOV TMOD,#00100010B ;22H


作者: mick32    時間: 2022-7-21 23:10

"Why is the pulse input port P32, I want to get an eight-way test pulse width"
P3.2 (INT0) and P3.3 (INT1) are hardware specific inputs...
8051 can't follow eight inputs with hardware
You try with software pooling but with big chance to loose real data...
作者: mick32    時間: 2022-7-21 23:30
"This is not bit-addressable"

TMOD EQU 089H ; TMOD register

bit addressable example

CLR IE.7 or
SETB 20H.2

byte addressable example

MOV TMOD,#00100010B ;22H
作者: 1940178371    時間: 2023-5-22 16:07
shenyuqiu 發(fā)表于 2019-11-1 15:16
有點沒搞明白這個占空比是怎么計算的,頻率就可以計算,兩個下降沿就一個完整周期,看你程序TR0與TR1都是同 ...

因為定時器0博主設置的帶門控位GATE,當INT0高電平時,定時器0才啟動;中斷第一次下降沿開啟TR0=1不會立刻啟動定時器1,上升沿之后才啟動

作者: 18355449194    時間: 2023-5-22 19:22
這個有點復雜了




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1