标题:
C8051F411单片机产生PWM波
[打印本页]
作者:
xxmjamic
时间:
2016-3-19 23:28
标题:
C8051F411单片机产生PWM波
//-----------------------------------------------------------------------------
// F41x_PCA0_8Bit_PWM_Output.c
//-----------------------------------------------------------------------------
// Copyright 2006 Silicon Laboratories, Inc.
//
// Program Description:
//
// This program sends a PWM waveform out of an I/O pin, using the PCA's
// 8-bit PWM Output Mode. The duty cycle of the waveform is modified
// periodically within the main loop.
//
// In this example, PCA Module 0 is used to generate the waveform, and the 模块1
// crossbar is configured to send the CEX0 pin out on P0.0. P0.0端口输出PWM波
//
// How To Test:
//
// 1) Download code to a 'F41x device which has an oscilloscope monitoring P0.0
// 2) Run the program - the waveform should be visible on the oscilloscope.
// 3) Verify that the duty cycle of the waveform varies smoothly between
// minimum and maximum values. 占空比在在最大值和最小值间平滑变化
//
//
// FID: 41X000055
// Target: C8051F41x
// Tool chain: Keil C51 7.50 / Keil EVAL C51
// Command Line: None
//
//
// Release 1.0
// -Initial Revision (BD)
// -10 MAR 2006
//
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <c8051f410.h> // SFR declarations 头文件,单片机端口定义
//-----------------------------------------------------------------------------
// Global Constants
//-----------------------------------------------------------------------------
#define SYSCLK 24500000 // Internal oscillator frequency in Hz 单片机内部振荡频率
//-----------------------------------------------------------------------------
// Function Prototypes 振荡器初始化,端口初始化, PCA定时器初始化
//-----------------------------------------------------------------------------
void OSCILLATOR_Init (void);
void PORT_Init (void);
void PCA0_Init (void);
//-----------------------------------------------------------------------------
// main() Routine 主函数
//-----------------------------------------------------------------------------
void main (void)
{
unsigned int delay_count; // Used to implement a delay 延时函数
bit duty_direction = 0; // 0 = Decrease; 1 = Increase 定义占空比变化方向,0代表减小,1代表增大
PCA0MD = 0x00; // Disable watchdog timer 关闭看门狗,选择系统时钟的12分频作为时间基准
PORT_Init (); // Initialize crossbar and GPIO 端口初始化
OSCILLATOR_Init (); // Initialize oscillator 振荡器初始化
PCA0_Init (); // Initialize PCA0 PCA定时器初始化
while (1)
{
// Wait a little while
for (delay_count = 30000; delay_count > 0; delay_count--);
if (duty_direction == 1) // Direction = Increase
{
// First, check the ECOM0 bit ECOM0位是PCA模块的比较器功能的使能模块,等于1时有比较器功能
if ((PCA0CPM0 & 0x40) == 0x00) //与运算
{
PCA0CPM0 |= 0x40; // Set ECOM0 if it is '0' 如果ECOM0等于0则将其置位,b|=a等效于b=b|a,按位或,将ECOM0位置1
}
else // Increase duty cycle otherwise 否则增加占空比
{
PCA0CPH0--; // Increase duty cycle 增加占空比
if (PCA0CPH0 == 0x00)
{
duty_direction = 0; // Change direction for next time 占空比变化反向
}
}
}
else // Direction = Decrease
{
if (PCA0CPH0 == 0xFF)
{
PCA0CPM0 &= ~0x40; // Clear ECOM0
duty_direction = 1; // Change direction for next time
}
else
{
PCA0CPH0++; // Decrease duty cycle
}
}
};
}
//-----------------------------------------------------------------------------
// Initialization Subroutines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// OSCILLATOR_Init 振荡器时钟初始化程序
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This function initializes the system clock to use the internal oscillator
// at 24.5 MHz.
//
//-----------------------------------------------------------------------------
void OSCILLATOR_Init (void)
{
OSCICN = 0x87; // Set internal oscillator to run OSCICN是内部振荡器控制寄存器,将内部振荡器设为最大振荡频率
// at its maximum frequency
CLKSEL = 0x00; // Select the internal osc. as CLKSEL是时钟选择寄存器,选择内部振荡器为系统时钟源
// the SYSCLK source
}
//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This function configures the crossbar and GPIO ports.
//
// P0.0 digital push-pull PCA0 CEX0 端口初始化程序
//
//-----------------------------------------------------------------------------
void PORT_Init (void)
{
XBR0 = 0x00; //XBR0 端口I/O交叉控制开关0
XBR1 = 0x41; // Route CEX0 to P0.0, 交叉使能开关必须使能
// Enable crossbar and weak pull-ups 端口I/O交叉控制开关1,CEX0连接到端口引脚
P0MDOUT |= 0x01; // Set CEX0 (P0.0) to push-pull 设置P0.0口为推挽式输出,推挽式输出有较大的驱动电流
}
//-----------------------------------------------------------------------------
// PCA0_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This function configures the PCA time base, and sets up 8-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 256.
//
// The PCA time base in this example is configured to use SYSCLK, and SYSCLK
// is set up to use the internal oscillator running at 24.5 MHz. Therefore,
// the frequency of the PWM signal will be 24.5 MHz / 256 = 95.7 kHz.
// Using different PCA clock sources or a different processor clock will
// result in a different frequency for the PWM signal.
//
// -------------------------------------------------------------------------
// How "8-Bit PWM Mode" Works:
//
// The PCA's 8-bit PWM Mode works by setting an output pin low every
// time the main PCA counter low byte (PCA0L) overflows, and then setting
// the pin high whenever a specific match condition is met.
//
// Upon a PCA0L overflow (PCA0L incrementing from 0xFF to 0x00), two things
// happen:
//
// 1) The CEXn pin will be set low.
// 2) The contents of the PCA0CPHn register for the module are copied into
// the PCA0CPLn register for the module.
//
// When the PCA0L register increments and matches the PCA0CPLn 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
// PCA0CPHn register, the duty cycle of the waveform can also be varied.
//
// When ECOMn = '1', the duty cycle of the PWM waveform is:
//
// 8-bit PWM Duty Cycle = (256 - PCA0CPLn) / 256
//
// To set the duty cycle to 100%, a value of 0x00 should be loaded into the
// PCA0CPHn register for the module being used (with ECOMn set to '1').
// When the value of PCA0CPLn is equal to 0x00, 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 PCA0CPLn match from occuring,
// which results in the pin never being set high.
// -------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void PCA0_Init (void)
{
// Configure PCA time base; overflow interrupt disabled 配置PCA定时器时钟基准,关闭溢出中断
PCA0CN = 0x00; // Stop counter; clear all flags 关闭PCA计数器,清除所有标志位
PCA0MD = 0x08; // Use SYSCLK as time base 使用系统时钟作为PCA定时器的时钟源,关闭PCA定时器溢出中断
PCA0CPM0 = 0x42; // Module 0 = 8-bit PWM mode 设置为8位PWM输出模式
// Configure initial PWM duty cycle = 50%
PCA0CPH0 = 256 - (256 * 0.5); 设置初始的占空比为50%
// Start PCA counter 通过PCA0CN中的CR位打开PCA定时器
CR = 1;
}
//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------
复制代码
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1