C8051F352中文手册上关于时钟乘法器的一个失误,(附源代码)。

2020-02-01 16:36发布

本帖最后由 liulangmao 于 2012-12-4 22:41 编辑

C8051F352的时钟管理还是很不错的,内部时钟比较准,不过这个中文手册还是有点瑕疵。
4.1.png (17.27 KB, 下载次数: 0) 下载附件 英文原版 2012-12-4 22:40 上传
源代码:


//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
}
//-----------------------------------------------------------------------------
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。