|
发表于 2012-3-30 05:58:45
|
显示全部楼层
here is the single tmr version. much easier to implement and saves one timer/isr.- //pwm using one single timer (tmr0)
- #include <regx51.h>
- sbit PWM=P2^1;
- //unsigned char a=1,b,c;
- unsigned short pwm_dc=0; //pwm duty cycle
- unsigned short pwm_pr=0xff00; //pwm period, 16-bit
- /*************************************
- ???????PWM??,128???? ????????? ?????PWM
- *************************************/
- //for pwm period
- void T0zd(void) interrupt TF0_VECTOR
- {
- if (PWM == 1) { //pwm on period has finished
- PWM = 0; //clear pwm output pin
- TH0 += (-pwm_pr)>> 8; //set the msb
- TL0 += (-pwm_pr); //set the lsb
- } else {
- PWM = 1; //set pwm output pin
- TH0 += (-pwm_dc)>> 8; //set the msb
- TL0 += (-pwm_dc); //set the lsb
- }
- }
- //for dc
- /*
- void T1zd()interrupt TF1_VECTOR
- {
- PWM = 0; //clear pwm output pin
- TR1 = 0; //stop tmr1
- TH1 += (-pwm_dc) >> 8; //set the msb
- TL1 += (-pwm_dc); //set the lsb
- }
- */
- //set pwm parameters
- void pwm_init(unsigned short period, unsigned short dc)
- {
- pwm_pr = period - dc; //update pwm_pr
- pwm_dc = dc; //update pwm_dc
-
- TR0 = 0; //, TR1 = 0; //stop the timers
- TMOD= (TMOD & 0xf0) | 0x01; //use tmr0 in mode 1
- //IE =0x8A; //?????,???0??,???1??
-
- //tmr0 sets the priod
- TH0 = (-pwm_dc)>> 8; //get the msb
- TL0 = (-pwm_dc); //get the lsb
- ET0 = 1; //enable interrupt on tmr0
-
- //tmr1 sets the duty cycle
- //TH1 = (-pwm_dc) >> 8; //get the msb
- //TL1 = (-pwm_dc); //get the lsb
- //ET1 = 1; //enable interrupt on tmr1
- TR0 = 1; //turn on tmr0
- //TR1 = 1; //turn on tmr1
- PWM = 1; //pwm output pin starts high
- }
- void main(void)
- {
- //P3=0x80;
- pwm_init(2000, 1000); //initialize pwm to 1000 dc and 2000 period
- EA = 1; //enable interrupt
- while(1)
- {
- //if(TR1==0)PWM=1;
- //else PWM=0;
- }
- }
复制代码 again, the code is fully implemented in the isr so you are free to do whatever you want in the main loop. |
|