c8051单片机输出PWM波形的频率怎么设定

2024-12-04 06:38:13
推荐回答(1个)
回答(1):

具体可以使用三个方式,一个是通过DAC 进行对外输出PWM 或者通过PCA通过IO输出PWM的还可以直接用定时器来实现 程序我给你找找 我以前写过的
/*********************************************************************
* pca实现8位PWM
* * 编写环境KC3.0
* 作者:孔聆宇
***********************************************************************/
//--------------------------------------------------------------------
// PWM8_1.c
//--------------------------------------------------------------------
//
// AUTH: BW
//
//
//
// 说明
// 实现8位PWM的示例代码
// PCA被配置为8位PWM方式 使用SYSCLK/4作为时基信号
// 中保持着每256个计数周期内输出波形为低电平的PCA周期数
// 波形为高电平的时间占 256 - PWM 个周期
// 输出波形的占空度=(256 - PWM)/256
//
// 由于该8位PWM完全受硬件控制 不需要额外的CPU周期来维持固定的
// 占空度 在本例中 改变占空度只需要向模块的比较寄存器PCA0CP0H
// 的高字节写一个8位数
//
// 可以达到的占空度范围是0.38%(PCA0CP0H = 0xff)
// 到100%(PCA0CP0H = 0x00)
//

//--------------------------------------------------------------------

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

#include // SFR declarations

//-----------------------------------------------------------------------------
// Global Constants
//-----------------------------------------------------------------------------

#define SYSCLK 2211810 // Internal oscillator frequency in Hz

//-----------------------------------------------------------------------------
// Function Prototypes
//-----------------------------------------------------------------------------

void OSCILLATOR_Init (void);
void PORT_Init (void);
void PCA0_Init (void);

//-----------------------------------------------------------------------------
// main() Routine
//-----------------------------------------------------------------------------

void main (void)
{
unsigned int delay_count;
bit duty_direction = 0;

WDTCN = 0xde;
WDTCN = 0xad;

PORT_Init ();
OSCILLATOR_Init ();
PCA0_Init ();
SFRPAGE = PCA0_PAGE;

while (1)
{

for (delay_count = 30000; delay_count > 0; delay_count--);

if (duty_direction == 1)
{

if ((PCA0CPM0 & 0x40) == 0x00)
{
PCA0CPM0 |= 0x40;
}
else
{
PCA0CPH0--;

if (PCA0CPH0 == 0x00)
{
duty_direction = 0;
}
}
}
else
{
if (PCA0CPH0 == 0xFF)
{
PCA0CPM0 &= ~0x40;
duty_direction = 1;
}
else
{
PCA0CPH0++;
}
}

};
}

void OSCILLATOR_Init (void)
{
char SFRPAGE_save = SFRPAGE;

SFRPAGE = CONFIG_PAGE;

OSCICN = 0x83;

CLKSEL = 0x00;

SFRPAGE = SFRPAGE_save;
}

void PORT_Init (void)
{
char SFRPAGE_save = SFRPAGE;

SFRPAGE = CONFIG_PAGE;

XBR0 = 0x08;
XBR1 = 0x00;
XBR2 = 0x40;

P0MDOUT |= 0x01;

SFRPAGE = SFRPAGE_save;

}
void PCA0_Init (void)
{
char SFRPAGE_save = SFRPAGE;
SFRPAGE = PCA0_PAGE;

PCA0CN = 0x00;
PCA0MD = 0x08;

PCA0CPM0 = 0x42;

PCA0CPH0 = 256 - (256 * 0.5);

CR = 1;
SFRPAGE = SFRPAGE_save;
}

太多还有其他的写不下 这是比较简单的一种。