⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pwmn_1.c

📁 16位PWM调空 !请大家多多指教!请给点支持!谢谢大家了!
💻 C
字号:
//-----------------------------------------------------------------------------
// PWMn_1.c
//-----------------------------------------------------------------------------
//
// AUTH: BW
//
// Target: C8051F000, F001, F002, F005, F006, F010, F011, or F012
// Tool chain: KEIL C51
//
// Description:
//						Example source code for implementing an n-bit PWM.
//						The PCA is configured in high speed output mode using 
//						SYSCLK/4 as its time base.  <PWM_HIGH> holds the number of 
//						PCA cycles for the output waveform to remain high.
//						<PWM_LOW> holds the number of PCA cycles for the output
//						waveform to remain low.  The duty cycle of the output
//						is equal to PWM_HIGH / (PWM_HIGH + PWM_LOW).
//
//						Due to interrupt service times, there are minimum and
//						maximum values for PWM_HIGH and PWM_LOW, and therefore 
//						the duty cycle, depending on interrupt service times.
//						Regardless ofthe efficiency of the compiler, duty 
//						cycles between	1% and 99% should be very easy to achieve.
//
//						With the eval version of the Keil compiler, the minimum
//						high and low counts are 20 PCA cycles each (max frequency
//						is about 100kHz w/ 16MHz internal SYSCLK).  This assumes
//						no other interrupts being serviced, and PCA time base is
//						SYSCLK / 4.
//

//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------

#include <c8051f000.h>								// SFR declarations

//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------

#define PWM_START		0x8000						// starting value for the 
															// PWM_HIGH time and PWM_LOW time
sbit		PWM_OUT = P0^0;							// define PWM output port pin

//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------

void main (void);
void PCA_ISR (void);									// PCA Interrupt Service Routine

//-----------------------------------------------------------------------------
// Global VARIABLES
//-----------------------------------------------------------------------------
unsigned PWM_HIGH = PWM_START;					// Number of PCA clocks for
															// waveform to be high
unsigned PWM_LOW = ~PWM_START;					// Number of PCA clocks for 
															// waveform to be low
															// duty cycle = 
															// PWM_HIGH / (PWM_HIGH + PWM_LOW)

//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------

void main (void) {

	WDTCN = 0xde;										// Disable watchdog timer
	WDTCN = 0xad;

	OSCICN = 0x07;										// set SYSCLK to 16MHz,
															// internal osc.

	XBR0 = 0x08;										// enable CEX0 at P0.0
	XBR2 = 0x40;										// enable crossbar and weak 
															// pull-ups

	PRT0CF = 0x01;										// set P0.0 output mode to 
															// push-pull
	PRT1CF = 0x20;										// set P1.6 output to 
															// push-pull (LED)

	
	// configure the PCA
	PCA0MD = 0x02;										// disable CF interrupt
															// PCA time base = SYSCLK / 4
	PCA0CPL0 = (0xff & PWM_HIGH);					// initialize PCA compare value
	PCA0CPH0 = (0xff & (PWM_HIGH >> 8));
	PCA0CPM0 = 0x4d;									// CCM0 in High Speed output mode

	EIE1 |= 0x08;										// enable PCA interrupt

	EA = 1;												// Enable global interrupts

	PCA0CN = 0x40;										// enable PCA counter

	while (1) {
		PCON |= 0x01;									// set IDLE mode
	}
}

//-----------------------------------------------------------------------------
// PCA_ISR
//-----------------------------------------------------------------------------
//
// This ISR is called when the PCA CCM0 obtains a match
// PWM_OUT is the CEX0 port pin that holds the state of the current edge:
//  1 = rising edge; 0 = falling edge
// On the rising edge, the compare registers are updated to trigger for the
// next falling edge.
// On the falling edge, the compare registers are updated to trigger for the
// next rising edge.
//
void PCA_ISR (void) interrupt 9 
{
	unsigned temp;										// holding value for 16-bit math

	if (CCF0) {
		CCF0 = 0;										// clear compare indicator
		if (PWM_OUT) {									// process rising edge

			// update compare match for next falling edge
			temp = (PCA0CPH0 << 8) | PCA0CPL0;	// get current compare value
			temp += PWM_HIGH;							// add appropriate offset

			PCA0CPL0 = (0xff & temp);				// replace compare value
			PCA0CPH0 = (0xff & (temp >> 8));

		} else {											// process falling edge

			// update compare match for next rising edge
			temp = (PCA0CPH0 << 8) | PCA0CPL0;	// get current compare value
			temp += PWM_LOW;							// add appropriate offset

			PCA0CPL0 = (0xff & temp);				// replace compare value
			PCA0CPH0 = (0xff & (temp >> 8));

		}
	} else if (CCF1) {								// handle other PCA interrupt
		CCF1 = 0;										// sources
	} else if (CCF2) {
		CCF2 = 0;
	} else if (CCF3) {
		CCF3 = 0;
	} else if (CCF4) {
		CCF4 = 0;
	} else if (CF) {
		CF = 0;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -