C8051F352中文手册上关于时钟乘法器的一个失误,(附源代码)。
本帖最后由 liulangmao 于 2012-12-4 22:41 编辑C8051F352的时钟管理还是很不错的,内部时钟比较准,不过这个中文手册还是有点瑕疵。
源代码:
//OSC_EX
//外部振荡器倍频实验
//外部12MHz晶振
//已完成
#include <c8051f350.h>
//-----------------------------------------------------------------------------
// 端口声明
//-----------------------------------------------------------------------------
sbit LED1 = P0^6;
sbit LED2 = P0^7;
//-----------------------------------------------------------------------------
// 函数声明
//-----------------------------------------------------------------------------
void OSCILLATOR_Init (void);
void CLKMUL_Init (void);
void Port_Init (void); // Port initialization routine
void Timer2_Init (void); // Timer2 initialization routine
//-----------------------------------------------------------------------------
// 主函数
//-----------------------------------------------------------------------------
void main (void)
{
PCA0MD &= ~0x40; // Disable Watchdog timer
Port_Init ();
OSCILLATOR_Init (); // Initialize oscillator
CLKMUL_Init ();
Timer2_Init ();
EA = 1; // Enable global interrupts
while(1)
{
LED2 = 0;
LED2 = 1; //使用贴片LED串330R做负载,IO翻转有效操作时间约需要40ns
LED2 = 0;
}
}
//-----------------------------------------------------------------------------
// 振荡器初始化
//-----------------------------------------------------------------------------
void OSCILLATOR_Init (void)
{
unsigned int i;
OSCXCN = 0x67;//晶体振荡器不分频,12MHz补偿
for (i=0; i < 256; i++); // Wait for crystal osc. to start
for (i=0; i < 256; i++); // Add 1ms delay
for (i=0; i < 256; i++); // Add 1ms delay
while (!(OSCXCN & 0x80)); // Wait for crystal osc. to settle
RSTSRC = 0x06; // Enable missing clock detector and
// VDD Monitor reset
CLKSEL = 0x01;//使能外部振荡器
OSCICN = 0x00; // 禁用内部24.5MHz振荡器。
}
//-----------------------------------------------------------------------------
// 时钟倍频函数
//-----------------------------------------------------------------------------
void CLKMUL_Init (void)
{
unsigned int i;
CLKMUL = 0x00; //复位乘法器
CLKMUL |= 0x01; //选择外部时钟输入,4倍输出
CLKMUL |= 0x80; //使能乘法器
for (i=0; i < 256; i++); //
for (i=0; i < 256; i++); //
for (i=0; i < 256; i++); //
CLKMUL |= 0xC0; //
while (!(CLKMUL & 0x20));
CLKSEL = 0x02;
OSCICN = 0x00; // 禁用内部24.5MHz振荡器。
}
//-----------------------------------------------------------------------------
// 端口初始化
//-----------------------------------------------------------------------------
void Port_Init (void)
{
// P2MDIN |= 0x07;
P1MDOUT = 0x07; // 设置P1^0,P1^1,P1^2,推挽输出模式
// 外部振荡器引脚
P0MDIN &= ~0x1C; // P0.2, P0.3, P0.4 are analog
P0SKIP |=0x1C; // P0.2, P0.3, P0.4 skipped in the Crossbar
XBR0 = 0x08; // Route /SYSCLK to first available pin
XBR1 = 0x40; // 开启交叉开关
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Timer2_Init
//-----------------------------------------------------------------------------
void Timer2_Init(void)
{
CKCON &= ~0x60; // Timer2 uses SYSCLK/12 ?
TMR2CN &= ~0x01;
TMR2L = 0x5F; // 1ms翻转一次,显示500Hz方波
TMR2H = 0xF0; // 48 000 000/1000/12=4000 = 0xFA0
// 0xFFFF - 0xFA0 = 0xF05F
TMR2RLL = 0x5F;
TMR2RLH = 0xF0;
TMR2CN = 0x04; // Enable Timer2 in auto-reload mode
ET2 = 1; // Timer2 interrupt enabled
}
//-----------------------------------------------------------------------------
// Timer2_ISR
//-----------------------------------------------------------------------------
void Timer2_ISR (void) interrupt 5
{
LED1 = !LED1;
TF2H = 0; // Reset Interrupt
}
//-----------------------------------------------------------------------------
收拾收拾
页:
[1]