STC – PWM輸出匯總

來源:互聯網
上載者:User

STC單片機PWM的實現方法與原理
一款單片機提供的pwm實現變頻輸出。程式將變頻pwm輸出到led上作測試。
#include<br />sfr CCON = 0xD8;<br />sfr CMOD = 0xD9;<br />sfr CL = 0xE9;<br />sfr CH = 0xF9;<br />sfr CCAP0L = 0xEA;<br />sfr CCAP0H = 0xFA;<br />sfr CCAPM0 = 0xDA;<br />sfr CCAPM1 = 0xDB;<br />sbit CR = 0xDE;<br />sbit led = P2^0;<br />unsigned char duty = 0x80;<br />unsigned int fre = 0xffff;<br />void timer0_int (void) interrupt 1 using 1<br />{<br />TH0 = fre >> 8;<br />TL0 = fre & 0xff;<br />led = ~led;<br />}<br />void timer0_init(void)<br />{<br />TMOD &= 0xf0;<br />TMOD |= 0x1;<br />TH0 = 0xff;<br />TL0 = 0xff;<br />TR0 = 1;<br />ET0 = 1;<br />}<br />void pwm_init(void)<br />{<br />CMOD = 0x4; // Use timer0<br />CL = 0x0;<br />CH = 0x0;<br />CCAP0H = duty; //Duty Cycle<br />CCAPM0 = 0x42; // PWM mode<br />CR = 1; //Start PCA Timer.<br />}<br />void soft_delay(unsigned int _1ms)<br />{<br />unsigned int tmp;<br />while(_1ms--!=0) {<br />for(tmp=0;tmp<144;tmp++);<br />}<br />}<br />void check_key(void)<br />{<br />unsigned char key1,key2;<br />key1 = P1 & 0xf;<br />soft_delay(20);<br />key2 = P1 & 0xf;<br />if(key1 == key2 && key1 != 0xf){<br />if(key1 == 0xe)<br />duty += 16;<br />else if(key1 == 0xd)<br />duty -= 16;<br />else if(key1 == 0xb)<br />fre += 0xff;<br />else if(key1 == 0x7)<br />fre -= 0xff;<br />while((P1 & 0xf) != 0xf);<br />}<br />}<br />void main (void)<br />{<br />pwm_init();<br />timer0_init();<br />EA = 1;<br />while(1){<br />CCAP0H = duty;<br />check_key();<br />}

 

-----------------------------------------------------------------------------------------

 

/*==============================================================<br />at12c2052所帶的PWM功能示範,內部公用了一個定時器,當啟動PWM時PCA<br />定時器只工作在8位元模式,匹配比較子也是按8位的。本程式示範了PWM啟動<br />的設定和調節。<br /> 改用在tasking c51下面編譯,並嘗試了tasking 方便的線上彙編方式<br /> ------- 曉奇 2006.01.12<br /> ===============================================================*/<br />#include "STC12C2052AD.h"<br />/*#include<INTRINS.h>*/<br />#define uint unsigned int<br />#define uchar unsigned char</p><p>uint i;<br />uchar upordn; /* 升降標誌,1=上升 */<br />void initall(void);<br />_interrupt(1) void timers0(void);<br />_interrupt (6) void PCA_LVD(void);<br />void initall(void)<br />{<br /> TMOD= 0x11; /* 0000 0001 T0作為16位計數器 */<br /> TH0 = 0xc0; /* 定時器0初始值裝入 */<br /> TL0 = 0x00;<br /> ET0 = 1; //開中斷<br /> IE |= 0x40; /* 使能PCA定時功能 */<br /> EA = 1;<br /> AUXR = 0x80;<br /> /* 1000 0000<br /> |||| ||++-保留<br /> |||| |+---低電壓中斷允許:0=禁止,1=允許,5V..3.7V,3V..2.4V以下<br /> |||| +----SPI中斷允許位:0=禁止,1=允許<br /> |||+------ADC中斷允許位:0=禁止,1=允許<br /> ||+-------串口模式0時時鐘設定:0=傳統1/12, 1=1/2 2分頻;<br /> |+--------定時器ct1時鐘源設定:0=傳統1/12,1=1:1不分頻;<br /> +---------定時器ct0時鐘源設定:0=傳統1/12,1=1:1不分頻;<br /> */<br /> P1 = 0xff;<br /> P1M0 = 0x00; /* P1口用傳統51准雙向口模式 */<br /> P1M1 = 0x00;<br /> CMOD = 0x03; /* 內部時鐘,Fosc/2, PCA計數溢出中斷使能*/<br /> /* 0000 0011 PCA 模式寄存器<br /> |||| |||+--ECF...PCA計數溢出中斷使能:ECF=1時,使能寄存器CCON CF位的<br /> |||| ||| 中斷。ECF=0時,禁止該功能。<br /> |||| |++---CPS1,CPS0 選擇PCA 時鐘源輸入(PCA計數脈衝選擇)<br /> |||| | 0 0 0,內部時鐘,Fosc/12<br /> |||| | 0 1 1,內部時鐘,Fosc/2<br /> |||| | 1 0 2,定時器0溢出,由於定時器0可以工作在1T方式,<br /> |||| | 所以可以達到計一個時鐘就溢出, 頻率反而<br /> |||| | 是最高的,可達到Fosc<br /> |||| | 1 1 3,ECI/P3.4腳的外部時鐘輸入(最大速率=Fosc/2)<br /> |+++-+-----保留<br /> +----------CIDL...計數器陣列空閑控制:CIDL=0時,空閑模式下PCA計數器<br /> 繼續工作。CIDL=1時,空閑模式下PCA計數器停止工作。<br /> */</p><p> CH = 0x00; /* PCA計數器初始值高8位 */<br /> CL = 0x00; /* PCA計數器初始值低8位 */<br /> CCAP0H = 0x00; /* 當出現捕獲或比較時,它們用來儲存16 位的計數值。<br /> 當PCA 模組用在PWM 模式中時,它們用來控制輸出的<br /> 占空比。CCAP0H.CCAP0L分別為高低8位,組合使用<br /> */<br /> CCAP0L = 0x00;</p><p> CCAP1H = 0x00; /* 當出現捕獲或比較時,它們用來儲存16 位的計數值。<br /> 當PCA 模組用在PWM 模式中時,它們用來控制輸出的<br /> 占空比。CCAP1H.CCAP1L分別為高低8位,組合使用<br /> */<br /> CCAP1L = 0x00;</p><p> CCAPM1 = 0x4c; /* PCA 比較/捕獲模組寄存器1作為16位軟體定時器。使能<br /> 比較子,PCA計數值與模組的比較/捕獲寄存器的值的匹配將<br /> 置位CCON寄存器的中斷標誌位CCF1,使能CCF1中斷 */<br />/*<br /> 0100 1100 功能說明<br /> |||| |||+---ECCF1.. 使能CCF1中斷。使能寄存器CCON的比較/捕獲標誌CCF1,<br /> |||| ||| 用來產生中斷。<br /> |||| ||+----PWM1... 脈寬調節模式。當PWMn=1時,使能CEXn腳用作脈寬調節輸出。<br /> |||| |+-----TOG1... 翻轉。當TOG1= 1時, PCA計數值與模組的比較/捕獲寄存<br /> |||| | 器的值的匹配將使CEXn腳翻轉。(CEX1/P3.5)<br /> |||| +------MAT1... 匹配。當=1時, PCA計數值與模組的比較/捕獲寄存器的值<br /> |||| 的匹配將置位CCON寄存器的中斷標誌位CCF1。<br /> |||+--------CAPN1.. 負捕獲。CAPN1= 1時使能下降沿捕獲。<br /> ||+---------CAPP1.. 正捕獲。CAPP1= 1時使能上升沿捕獲。<br /> |+----------ECOM1.. 使能比較子。ECOM1= 1時使能比較子功能。<br /> +-----------CCAPM1^7保留</p><p>使用的機種基本模式組合:<br /> ECOM1 CAPP1 CAPN1 MAT1 TOG1 PWM1 ECCF1 模組功能<br /> 0 0 0 0 0 0 0 無此操作<br /> X 1 0 0 0 0 X 16位捕獲模式,由CEX1的上升沿觸發<br /> X 0 1 0 0 0 X 16位捕獲模式,由CEX1的下降沿觸發<br /> X 1 1 0 0 0 X 16位捕獲模式,由CEX1的跳變觸發<br /> 1 0 0 1 0 0 X 16位軟體定時器<br /> 1 0 0 1 1 0 X 16位高速輸出<br /> 1 0 0 0 0 1 0 8位PWM<br />*/</p><p> CCAPM0 = 0x42; /* PCA 比較/捕獲模組寄存器0作為16位軟體定時器。使能<br /> 比較子,PCA計數值與模組的比較/捕獲寄存器的值的匹配將<br /> 置位CCON寄存器的中斷標誌位CCF0,使能CCF0中斷 寄存器<br /> 位功能同上*/<br /> CR = 1; //Start PCA Timer.<br /> TR0 = 1; //啟動計時<br /> i = 0;<br /> upordn = 1;<br />}</p><p>/* ------------- 定時器0用來定時調節PWM的輸出占空比 ------------- */<br />_interrupt(1) void timers0(void)<br />{<br /> TL0 = 0x00;<br /> TH0 = 0xc0;</p><p> CCAP0H = i>>8; /* CCAP0L不用賦值,他不參與工作 */<br /> if(upordn) /* 逐步加寬PWM、加快脈衝輸出 */<br /> {<br /> if(++i==65535) /* 到頭 */<br /> {<br /> upordn=0; /* 調頭 */<br /> }<br /> }<br /> else /* 逐步減窄PWM、減慢脈衝輸出 */<br /> {<br /> if(--i==0) /* 到頭 */<br /> {<br /> upordn=1; /* 調頭 */<br /> }<br /> }</p><p> P1 = ~(i>>8); /* 高8位輸出LED指示,作監視用 */<br />}</p><p>/* ------------ PCA 定時中斷,負責清除溢出標誌並賦初值 ------------- */<br />/* 搖晃編程板可以看到P3.5串連的led閃亮頻率的緩慢變化,虛線在變長變短 */<br />_interrupt (6) void PCA_LVD(void)<br />{<br /> CH = i>>8;<br /> CL = i&0xff;<br /> CF = 0;<br /> CCF0 = 0;<br />// LedPCA ^= 1; /* 頻率要求不高的時候這裡可以插入使用者代碼 */<br />}</p><p>void main(void)<br />{<br /> initall();</p><p>// 測試tasking c51的線上彙編功能<br />#pragma asm<br /> mov r0,#0f0h<br /> v1: nop<br /> nop<br /> djnz r0,v1<br /> nop<br />#pragma endasm<br />// 編譯很順利通過,不用作任何附加的設定<br /> while(1){};<br />}<br />

 

 

---------------------------------------------------------------------------------------------

 

/******************************************************************************<br />* *<br />*關於頻率和占空比的確定,對於12M晶振,假定PWM輸出頻率為1KHZ,這樣定時中斷次數 *<br />*設定為C=10,即0.01MS中斷一次,則TH0=FF,TL0=F6;由於設定停機時間為0.01ms,這樣*<br />*可以設定占空比可從1-100變化。即0.01ms*100=1ms *<br />******************************************************************************/<br />#include <REGX51.H><br />#define uchar unsigned char<br />/*****************************************************************************<br />* TH0和TL0是計數器0的高8位和低8位計數器,計算辦法:TL0=(65536-C)%256; *<br />* TH0=(65536-C)/256,其中C為所要計數的次數即多長時間產生一次中斷;TMOD是計數器*<br />* 工作模式選擇,0X01表示選用模式1,它有16位計數器,最大計數脈衝為65536,最長時 *<br />* 間為1ms*65536=65.536ms *<br />******************************************************************************/<br />#define V_TH0 0XFF<br />#define V_TL0 0XF6<br />#define V_TMOD 0X01 </p><p>void init_sys(void); /*系統初始化函數*/<br />void Delay5Ms(void); </p><p>unsigned char ZKB1,ZKB2; </p><p>void main (void)<br />{<br />init_sys();<br /> ZKB1=40; /*占空比初始值設定*/<br /> ZKB2=70; /*占空比初始值設定*/<br /> while(1)<br /> {<br /> if (!P1_4) //如果按了+鍵,增加占空比<br /> {<br /> Delay5Ms();<br /> if (!P1_4)<br /> {<br /> ZKB1++;<br /> ZKB2=100-ZKB1;<br /> }<br /> } </p><p> if (!P1_5) //如果按了-鍵,減少佔空比<br /> {<br /> Delay5Ms();<br /> if (!P1_5)<br /> {<br /> ZKB1--;<br /> ZKB2=100-ZKB1;<br /> }<br /> }<br />/*對占空比值限定範圍*/<br />if (ZKB1>99) ZKB1=1;<br />if (ZKB1<1) ZKB1=99; </p><p> }</p><p>} </p><p>/******************************************************<br />*函數功能:對系統進行初始化,包括定時器初始化和變數初始化*/<br />void init_sys(void) /*系統初始化函數*/<br />{<br /> /*定時器初始化*/<br /> TMOD=V_TMOD;<br /> TH0=V_TH0;<br /> TL0=V_TL0;<br /> TR0=1;<br /> ET0=1;<br /> EA=1;<br />} </p><p>//延時<br />void Delay5Ms(void)<br />{<br />unsigned int TempCyc = 1000;<br />while(TempCyc--);<br />} </p><p>/*中斷函數*/<br />void timer0(void) interrupt 1 using 2<br />{<br />static uchar click=0; /*中斷次數計數器變數*/<br />TH0=V_TH0; /*恢複定時器初始值*/<br />TL0=V_TL0;<br />++click;<br />if (click>=100) click=0; </p><p>if (click<=ZKB1) /*當小於占空比值時輸出低電平,高於時是高電平,從而實現占空比的調整*/<br /> P1_0=0;<br />else<br /> P1_0=1; </p><p>if (click<=ZKB2)<br /> P1_1=0;<br />else<br /> P1_1=1; </p><p>}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.