|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区
您需要 登录 才可以下载或查看,没有账号?立即注册
×
C8051F320 10KHzPWM,占空比可调代码生成
#include "c8051f320.h"
#include <stdio.h>
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
typedef unsigned char u8;
typedef unsigned short int u16;
void SYSCLK_Init (void);
void CLKMUL_Init (void);
void Port_Init (void);
void PCA0_Init (void);
void UART0_Init (void);
void ReadState(void);
void Flash_erasure_and_Store(void);
unsigned int CEX0_Compare_Value;
unsigned char test = 0 ; //?????????
/****************for reading******************/
unsigned char code test_c _at_ 0x3A00;
/****************for writing******************/
unsigned char xdata test_x _at_ 0x3A00;
extern unsigned char Key_num;
void ReadState(void)
{
Key_num = test_c;
}
//-----------------------------------------------------------------------------
// SYSCLK_Init ()
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This routine initializes the system clock to use the internal 12 MHz
// oscillator as its clock source. Also enables missing clock detector reset.
//
//-----------------------------------------------------------------------------
void SYSCLK_Init (void)
{
OSCICN = 0x83; // Configure internal oscillator for
// its highest frequency (12 MHz)
RSTSRC = 0x04; // Enable missing clock detector
CLKSEL = 0x00; // Switch SYSCLK to the IntOsc output
}
//-----------------------------------------------------------------------------
// CLKMUL_Init ()
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This routine initializes the Clock Multiplier using the Internal Oscillator
// as the source.
//
//-----------------------------------------------------------------------------
void CLKMUL_Init (void)
{
char i;
CLKMUL = 0x00; // Reset the Multiplier by writing 0x00
// to register CLKMUL.
CLKMUL |= 0x00; // Select the Multiplier input source
// via the MULSEL bits.
// '00'b = Internal Oscillator
CLKMUL |= 0x80; // Enable the Multiplier with the MULEN
// bit (CLKMUL | = 0x80).
for (i = 35; i > 0; i--); // Delay for >5 ?s.
// At 12 MHz SYSCLK ~ 80 ns, so 5 us is
// 61 SYSCLK counts. DJNZ = 2 clocks.
CLKMUL |= 0xC0; // Initialize the Multiplier with the
// MULINIT bit (CLKMUL | = 0xC0).
while ((CLKMUL & 0x20) != 0x20); // Poll for MULRDY => ??
CLKSEL = 0x02; // Switch SYSCLK to the CLKMUL output
}
//-----------------------------------------------------------------------------
// Port_Init ()
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// Configure the Crossbar and GPIO ports.
//
// P2.0 digital open-drain SW (switch)
// P2.2 digital push-pull LED
//
//-----------------------------------------------------------------------------
void PORT_Init (void)
{
P0MDOUT |= 0x17;
P2SKIP = 0xff;
P0SKIP = 0xfc;
XBR0 = 0x01; // TX0, RX0???????????P0.4??P0.5
XBR1 = 0x42; // CEX0??CEX1??CEX2???????????
}
//-----------------------------------------------------------------------------
// PCA0_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This function configures the PCA time base, and sets up 16-bit PWM output
// mode for Module 0 (CEX0 pin).
//
// The frequency of the PWM signal generated at the CEX0 pin is equal to the
// PCA main timebase frequency divided by 65536.
//
// The PCA time base in this example is configured to use SYSCLK, and SYSCLK
// is set up to use the internal oscillator running at 12 MHz. Therefore,
// the frequency of the PWM signal will be 12 MHz / 65536 = 183.1 Hz.
// Using different PCA clock sources or a different processor clock will
// result in a different frequency for the PWM signal.
//
// -------------------------------------------------------------------------
// How "16-Bit PWM Mode" Works:
//
// The PCA's 16-bit PWM Mode works by setting an output pin low every
// time the main 16-bit PCA counter (PCA0H) overflows, and then setting
// the pin high whenever a specific match condition is met.
//
// Upon a PCA0 overflow (PCA0 incrementing from 0xFFFF to 0x0000), the
// CEXn pin will be set low.
//
// When the PCA0 register increments and matches the PCA0CPn register for
// the selected module, the CEXn pin will be set high, except when the
// ECOMn bit in PCA0CPMn is cleared to '0'. By varying the value of the
// PCA0CPn register, the duty cycle of the waveform can also be varied.
//
// When ECOMn = '1', the duty cycle of the PWM waveform is:
//
// 16-bit PWM Duty Cycle = (65536 - PCA0CPn) / 65536
//
// To set the duty cycle to 100%, a value of 0x0000 should be loaded into
// the PCA0CPn register for the module being used (with ECOMn set to '1').
// When the value of PCA0CPn is equal to 0x0000, the pin will never be
// set low.
//
// To set the duty cycle to 0%, the ECOMn bit in the PCA0CPMn register
// should be cleared to 0. This prevents the PCA0CPn match from occuring,
// which results in the pin never being set high.
//
// When adjusting the PWM duty cycle, the low byte of the PCA0CPn register
// (PCA0CPLn) should be written first, followed by the high byte (PCA0CPHn).
// Writing the low byte clears the ECOMn bit, and writing the high byte will
// restore it. This ensures that a match does not occur until the full
// 16-bit value has been written to the compare register. Writing the high
// byte first will result in the ECOMn bit being set to '0' after the 16-bit
// write, and the duty cycle will also go to 0%.
//
// It is also advisable to wait until just after a match occurs before
// updating the PWM duty cycle. This will help ensure that the ECOMn
// bit is not cleared (by writing PCA0CPLn) at the time when a match was
// supposed to happen. This code implements the compare register update in
// the PCA ISR upon a match interrupt.
// -------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void PCA0_Init (void)
{
// Configure PCA time base; overflow interrupt disabled
PCA0CN = 0x00; // Stop counter; clear all flags
PCA0MD = 0x08; // Use SYSCLK as time base
PCA0CPM0 = 0x42; // Module 0 = 8-bit PWM mode
// Configure initial PWM duty cycle = 50%
PCA0CPH0 = 256 - (256 * 0.5);
// Start PCA counter
CR = 1;
/*
PCA0CPM0 = 0xCB; // Module 0 = 16-bit PWM mode and
// enable Module 0 Match and Interrupt
// Flags
// Configure initial PWM duty cycle = 50%
CEX0_Compare_Value = 65536 - (65536 * 0.5);
PCA0CPL0 = (CEX0_Compare_Value & 0x00FF);
PCA0CPH0 = (CEX0_Compare_Value & 0xFF00)>>8;
EIE1 |= 0x10; // Enable PCA interrupts
// Start PCA counter
CR = 1;
*/
}
//-----------------------------------------------------------------------------
// PCA0_ISR
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This is the ISR for the PCA. It handles the case when a match occurs on
// channel 0, and updates the PCA0CPn compare register with the value held in
// the global variable "CEX0_Compare_Value".
//
//-----------------------------------------------------------------------------
/*
void PCA0_ISR (void) interrupt 11
{
CCF0 = 0; // Clear module 0 interrupt flag.
PCA0CPL0 = (CEX0_Compare_Value & 0x00FF);
PCA0CPH0 = (CEX0_Compare_Value & 0xFF00)>>8;
}
*/
void Delay_us(unsigned int i)
{
unsigned int k = 0;
for(k = 0;k < i;k++);
}
void Delay_ms(unsigned int i)
{
unsigned int j = 0;
unsigned int k = 0;
for(k = 0;k < i;k++)
for(j = 0;j < 1000;j++);
}
void Flash_erasure_and_Store(void)
{
//EA = 0; //disable interrupt
FLKEY = 0xA5;
FLKEY = 0xF1;
PSCTL |= 0x03; //allow to erase or write
test_x = 0; //erase
FLKEY = 0xA5;
FLKEY = 0xF1;
PSCTL &= 0xFD; //clear PSEE AND PSWE
test_x = Key_num;
PSCTL = 0;
//EA=1;
} |
|