ghostfire 发表于 2014-9-4 14:04:03

【重量级别】TWR(塔)系统的总线时钟控制和串口测试程序编写


昨天下午开始熟悉飞思卡尔的TWR(塔)系统,MCU是CodeFire V1 核的MCF51CN。TWR系统碟所附带的lab均是搭载了MQX,而且网络上的资源少之又少。为了学习这款MCU,决定还是看datasheet然后编写各个模块的代码。由于时间紧张,详细寄存器定义和使用方法以后再添上。
1、MCG
MCF51CN的时钟比较复杂,与以往的16位MCU不用,MCF51CN的多用途时钟生成模块(Multipurpose Clock Generator, MCG) 比以往的MCU时钟控制更为复杂、精细,带来的是更多的选择和更低的功耗(在我看来是更为麻烦的编程……)。
MCG模块图
http://pic002.cnblogs.com/images/2012/204306/2012031721025030.jpg
时钟源(Reference clock)主要来自外部的晶振(TWR51 上是25MHz)和片内时钟。为了更稳定的时钟输出,除了用来倍频的PLL外,还有一个FLL,就是“锁频环”。
MCU复位后,各种寄存器的默认值是在FEI(FLL Engaged Internal, 内部时钟参考FLL)模式下,默认输出是16Mhz。根据手册上的公式,FLL的倍频系数为512,Bus Divider 为2,这样可以推断出Internal Clock的频率为31.25KHz。
http://pic002.cnblogs.com/images/2012/204306/2012031721121021.jpg
MCG给定了模块工作的几个模式,各个模式之间转换图如下
http://pic002.cnblogs.com/images/2012/204306/2012031721232922.jpg
红线所示的就是如何从默认的FEI转到PEE(外部锁相环)。
TWR自带的外部晶振为25MHz,如果想把总线频率倍频到50MHz,可以通过以下的方式
http://common.cnblogs.com/images/copycode.gif

1 // CLK初始化,默认是FEI mode, 调整到PEE
2 // BUS CLK = 50M
3 void CLK_init_50MHz(void)
4 {
5
6   //1. First, FEI must transition to FBE mode:
7 //a) MCGC2 = 0x36 (%00110110)
8 // BDIV (bits 7 and 6) set to %00, or divide-by-1
9 // RANGE (bit 5) set to 1 because the frequency of 8 MHz is within the high frequency range
10 // HGO (bit 4) set to 1 to configure the crystal oscillator for high gain operation
11 // EREFS (bit 2) set to 1, because a crystal is being used
12 // ERCLKEN (bit 1) set to 1 to ensure the external reference clock is active
13   MCGC2 = MCGC2_EREFS_MASK | MCGC2_ERCLKEN_MASK | MCGC2_RANGE_MASK | MCGC2_HGO_MASK;      
14
15
16   //b) Loop until OSCINIT (bit 1) in MCGSC is 1, indicating the crystal selected by the EREFS bit
17 //has been initialized.
18   while (!(MCGSC & MCGSC_OSCINIT_MASK))      
19   ;
20   
21   //c) Because RANGE = 1, set DIV32 (bit 4) in MCGC3 to allow access to the proper RDIV bits
22 //while in an FLL external mode.
23    MCGC3 |=MCGC3_DIV32_MASK;
24
25   //d) MCGC1 = 0x98 (%10011000)
26 // CLKS (bits 7 and 6) set to %10 to select external reference clock as system clock source
27 // RDIV (bits 5-3) set to %011, or divide-by-256 because 8MHz / 256 = 31.25 kHz that is in
28 //the 31.25 kHz to 39.0625 kHz range required by the FLL
29 // IREFS (bit 2) cleared to 0, selecting the external reference clock
30    MCGC1 = (0b10// CLKS = 10 -> external reference clock
31                      | (0b100 // RDIV = 2^4 -> 25MHz/16 = 1.5625 MHz for PLL
32
33
34
35 // wait for Reference Status bit to update
36   while (!( MCGSC &MCGSC_IREFST_MASK))
37   ;
38
39   // and for clock status bits to update
40   while (( MCGSC &MCGSC_CLKST_MASK) != (0b10 41   ;
42
43
44   // switch from FBE to PBE (PLL bypassed internal) mode
45 // set PLL multi 50MHz amd select PLL      
46    MCGC3 = (0b100047               
48   // wait for PLL status bit and LOCK bit
49   while (!( MCGSC &MCGSC_PLLST_MASK) && !( MCGSC &MCGSC_LOCK_MASK))
50    ;
51   
52   //switch from PBE to PEE (PLL enabled external mode)                                    
53    MCGC1 &= ~(0b11 54
55   /* Wait for clock status bits to update */
56   while (( MCGSC &MCGSC_CLKST_MASK )!= (0b1157   ;
58   // FEE mode entered
59 }
http://common.cnblogs.com/images/copycode.gif

1、SCI
(1) 设置GPIO复用,将PTD2改为TXD2,PTD3改RXD3。因为TWR系统将顶板MCF51CN的SCI2通过PCI接口接到底板的RS232上,所以可以需要设置但是SCI2。
(2) 设置波特率。总线时钟为50M,将SBR设置为651,可以得到近似的9600b/s的波特率。8位数据模式,不使用校验位
(3) 中断设置。不使用中断,因为只是简单测试串口发送只需查询方式即可。
http://common.cnblogs.com/images/copycode.gif

1 void SCI_init(void)
2 {
3   //RXD2_DIR    = 0;//in
4 //TXD2_DIR    = 1;//out
5   PTDPF2_D2   = 2;//PTD_PTD2 as TXD2
6   PTDPF2_D3   = 2;//PTD_PTD2 as RXD2
7   
8 //SCI baud rate equals SCI module clock/(16 × BR)
9 //50000000/(326*16) = 96150x146
10 //50000000/(651*16) = 48000x28b
11   SCI2BDH = 0x01;//000-00010
12   SCI2BDL = 0x46;
13   
14   SCI2C1= 0x00;//0000 0010:not Loop mode or single-wire mode, start + 8 data bits (lsb first) + stop, No Parity enabled, even
15   SCI2C2= 0x00;//disable transmit & receive interrupt; not start transmi:SCI2C2_TE=0;
16   SCI3C3= 0x00;
17   
18 }
http://common.cnblogs.com/images/copycode.gif

发送单个字符函数
http://common.cnblogs.com/images/copycode.gif

1 void SCI_send(unsigned char sendchar)
2 {
3   while(SCI2S1_TC==0)//transmission doesnt end
4   ;
5   SCI2D = sendchar;
6   SCI2C2_TE = 1;//send
7 }
http://common.cnblogs.com/images/copycode.gif

发送字符串函数
http://common.cnblogs.com/images/copycode.gif

1 void SCI_sendmsg(unsigned char * msg,unsigned char cnt)
2 {
3   unsigned char count=0;
4   for(count=0;count5   {
6         SCI_send(*(msg+count));
7   }
8 }
http://common.cnblogs.com/images/copycode.gif

最后main函数,记得要在for循环里面喂看门狗,防止程序跑飞
http://common.cnblogs.com/images/copycode.gif

1 void main(void)
2 {
3   DisableInterrupts;
4   //variable
5   unsigned char msg1 ={"hello! rcq!\n"};
6   unsigned char msg2 ={"abcedfghigklmnopqrstvuwxyz\n"};
7   unsigned char msg3 ={"这是SCI 测试超群天晴2012年 3月17日20:52:41\n"};
8   // sys init
9   CLK_init_50MHz();
10   LED_init();
11   SCI_init();
12   //function body
13   SCI_sendmsg(msg1,12);   
14   delay();
15   SCI_sendmsg(msg2,27);   
16   delay();
17   SCI_sendmsg(msg3,49);   
18   delay();
19   SCI_test();   
20   delay();
21   for(;;)
22   {
23         __RESET_WATCHDOG(); /* feeds the dog */
24   }
25 }
http://common.cnblogs.com/images/copycode.gif

连上串口调试助手,显示结果
http://pic002.cnblogs.com/images/2012/204306/2012031721434697.jpg

湛泸骏驰 发表于 2014-9-4 14:08:30

好重哦。。。承受不住了。。。

ghostfire 发表于 2014-9-4 14:11:15

湛泸骏驰 发表于 2014-9-4 14:08
好重哦。。。承受不住了。。。

是大家梦寐以求的塔系统

sdlibin007 发表于 2014-9-4 14:27:57

梦寐以求,但是很难梦想成真!!

wanstrive 发表于 2014-9-4 14:35:29

梦寐以求啊!我是没希望了感觉。

湛泸骏驰 发表于 2014-9-4 14:39:56

时钟确实是这样的mcu最难啃的地方之一。。。没有去弄过这块,图都看不太懂。。。。唉

fbestwish 发表于 2014-9-4 14:51:13

看的不是很懂,只能支持楼主了

ghostfire 发表于 2014-9-4 14:58:37

湛泸骏驰 发表于 2014-9-4 14:39
时钟确实是这样的mcu最难啃的地方之一。。。没有去弄过这块,图都看不太懂。。。。唉 ...

多看手册和代码。

wxfje 发表于 2014-9-4 15:02:23

好多代码,默默帮顶

彼岸花开@ 发表于 2014-9-4 15:03:34

代码可以和图结合看了。。

霸气侧漏 发表于 2014-9-4 15:03:40

多看看资料就行

dragon19809200 发表于 2014-9-4 15:07:52

帮顶      

abszy 发表于 2014-9-4 15:32:53

感谢楼主分享了
如果是转载 麻烦注明原链接

shawn_bu 发表于 2014-9-4 15:35:27

博客园转载过来的也不标准一下出处。LZ这是不尊重别人的劳动成果。

Jmhh247 发表于 2014-9-4 15:44:28

看图上,这时钟的确更复杂的,这也应该能说明其更具灵活性{:smile:}

rockyyangyang 发表于 2014-9-4 15:51:08

mark了。                     

laotui 发表于 2014-9-4 16:27:58

学习了。

ghostfire 发表于 2014-9-4 16:37:37

自己顶一下

huangdog 发表于 2014-9-4 16:51:20

有了tower,又可以发出很多精华帖子出来,是不是又能换个tower了呢~
页: [1]
查看完整版本: 【重量级别】TWR(塔)系统的总线时钟控制和串口测试程序编写