【重量级别】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
好重哦。。。承受不住了。。。
是大家梦寐以求的塔系统 梦寐以求,但是很难梦想成真!! 梦寐以求啊!我是没希望了感觉。 时钟确实是这样的mcu最难啃的地方之一。。。没有去弄过这块,图都看不太懂。。。。唉 看的不是很懂,只能支持楼主了 湛泸骏驰 发表于 2014-9-4 14:39
时钟确实是这样的mcu最难啃的地方之一。。。没有去弄过这块,图都看不太懂。。。。唉 ...
多看手册和代码。 好多代码,默默帮顶 代码可以和图结合看了。。 多看看资料就行 帮顶 感谢楼主分享了
如果是转载 麻烦注明原链接 博客园转载过来的也不标准一下出处。LZ这是不尊重别人的劳动成果。 看图上,这时钟的确更复杂的,这也应该能说明其更具灵活性{:smile:} mark了。 学习了。 自己顶一下 有了tower,又可以发出很多精华帖子出来,是不是又能换个tower了呢~
页:
[1]