|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
近日工作中又涉及到了DSP28335的应用,看来TI的芯片还是得到了公司领导的认可,也直接丢了一份DSP28335的FOC程序给我理解。以前读书阶段较为简单的接触过一段时间,对DSP28335的基础功能部分有了一些浅显的了解,现在工作中要实际开始用了,开始发现之前学习的程度还是不够,因此要更加深入的探究一遍。可能非常基础,希望大家也不要见笑,人真是年龄越大忘东西越快。8 e" z2 R: f9 e# t' T; U8 t/ J6 G
5 ?; h% s0 K6 k0 R/ C$ f! c, H系统初始化
/ m; j& O* H$ O- x' x |0 ]首先从系统的初始化开始,系统初始化主要是系统时钟、看门狗等功能模块的基础配置,TI官方配置的系统初始化函数如下:) W5 q, c7 |% L
2 d, H" d F* S* f0 W* o3 Ivoid InitSysCtrl(void)
$ F7 W* E5 B8 t! t7 ] O4 Q{
3 q& m2 W ]& V% \ : [# L9 x+ r9 U3 Z' X! O
// Disable the watchdog
( D+ h% y5 U, N: U) j- J- M: ` DisableDog();3 h- v" k; n1 v2 u
6 A# t( p1 D0 `0 q+ k // Initialize the PLL control: PLLCR and DIVSEL
/ a$ G% f6 {( u& b1 J // DSP28_PLLCR and DSP28_DIVSEL are defined in DSP2833x_Examples.h
. `4 k$ k, f9 X% E2 h/ Y InitPll(DSP28_PLLCR,DSP28_DIVSEL);
& `6 k. F+ q. v% ]
6 G# `' G8 j, ^+ h3 {! | // Initialize the peripheral clocks
6 d1 X0 o8 ^. C8 @: b2 M) [ S InitPeripheralClocks();
+ d E6 V# D3 f: C! B$ O. }5 S l}
* L. P* T: `, Z4 Q. K! O上面代码主要由3个子函数构成,分别为 DisableDog();、InitPll(DSP28_PLLCR,DSP28_DIVSEL);、 InitPeripheralClocks();这三个子函数的功能我们也来一一分析。
/ E4 G: G/ x+ Y* P+ z$ k
9 U& \2 o4 I. s: Z9 m- Y看门狗配置函数DisableDog()/ {: @. n1 R2 J. b) Q: x: [( D1 i! K
首先是开门狗初始化函数DisableDog(),函数代码如下:, x: i E- P: {, E0 E) }
}6 D; V* O7 D, x2 dvoid DisableDog(void)# B3 Z8 J# y- p& L1 f
{
6 g- e- r. E6 l) R! B6 v EALLOW;# Q0 C) S! s0 O
SysCtrlRegs.WDCR= 0x0068; A! h7 |( Q" Z9 j, I7 z; E! |
EDIS;
; o% w! L0 Y+ _; M7 B% ]% o$ v}
7 i+ c$ P" L! t& k# H2 K8 d代码解释:
x" S, C C8 N0 c) U* [
9 T6 P3 F4 R( e3 G1、EALLOW /EDIS 打开/关闭状态寄存器保护。EALLOW/EDIS 是DSP为了防止杂散代码或指针破坏关键寄存器的状态宏定义指令,关键寄存器包括ePWM、Flash、器件仿真寄存器、FLASH寄存器、CSM寄存器、PIE矢量表、系统控制寄存器、GPIOMux寄存器等,这些寄存器的状态决定DSP是否稳定运行,因此需要修改之前应用EALLOW打开保护,修改完后必须用EDIS关闭。
7 v( e# K' Q$ A7 a3 ]
3 a4 u6 {" ]# N! r2 c" b2、配置SysCtrlRegs.WDCR寄存器为0x0068。关闭看门狗,也可以戏称为把狗杀了,好残忍,看门狗的实际作用就是防止CPU跑飞或者其他故障导致系统出现不可挽回的故障,如果一段时间收不到CPU稳定运行的信号就会复位CPU,从而保证CPU的稳定性。打开WDCR寄存器表可知,寄存器后8位起到实际作用,0x0068 = 0110 1000 ,第7位置0看门狗不满足复位条件,第6位置1禁止看门狗模块,第5~3位写101强制写,第2~0位写000配置看门狗时钟。关键为第6位置1禁止看门狗模块。
9 ?: N3 v+ Q' ^! l4 c/ l u( W2 _& U' p6 b V% x' }
7 }3 m' \( B+ Z3 x. F6 [, _" q0 f
* O/ |; ?4 Y2 `' i; Z锁相环初始化函数 InitPll(DSP28_PLLCR,DSP28_DIVSEL)- h6 z/ Q; l0 M6 X$ K
其次是锁相环初始化函数,在DSP中锁相环函数主要是用在时钟的分频上,将晶振产生的震荡进行分频和倍频操作,是整个芯片心脏——时钟能够起作用的关键之处,因此必须在程序开头对其进行配置。其代码如下:
9 {. X+ @8 z9 r1 X: Z2 Y( f1 W2 U+ f! b1 S5 |( X5 ?% W
void InitPll(Uint16 val, Uint16 divsel)
" F; m4 j7 X& Q{
& ]) \3 N( v" l/ K. m
& f! E( w8 T7 M1 Q | // Make sure the PLL is not running in limp mode 确保PLL没有运行在故障状态
" Y4 U3 A- y# x0 u: W. o if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0)( ~* x* ~1 \" I7 @& c
{
2 [$ f$ A* a0 @ c- A // Missing external clock has been detected4 A" u" s" O, O% a1 F* m6 N( ~
// Replace this line with a call to an appropriate
# c8 Q) d; j9 _, U/ T& s // SystemShutdown(); function.' Z' d' W1 A: \
// 若检测到系统失去外部时钟,则关闭系统& |7 [2 p6 q* U/ _1 R
asm(" ESTOP0");: w" g3 [% d7 e' f3 s
}1 _* H( r) y9 t! F
$ J5 g9 j$ |6 T
// DIVSEL MUST be 0 before PLLCR can be changed from 在PLLCR可以从更改前,DIVSEL必须为07 q, h7 T9 X6 j
// 0x0000. It is set to 0 by an external reset XRSn 通过外部重置XRSn将其设置为04 q( u( N- M5 G. {5 P% N7 F: I
// This puts us in 1/4
7 f4 x# ?+ N- {4 [2 s if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0)
6 C E; }% w# R2 N2 j: W. K) Z5 X {
4 ^" k# g' Y& C EALLOW;& n- j& @2 L$ z6 f8 w) o" Q% @9 [
SysCtrlRegs.PLLSTS.bit.DIVSEL = 0;* D1 X- z y- W5 h/ D+ `
EDIS;
. K) y7 V9 o( [$ k5 ?8 [" ~6 a9 I# c }
; V' [% G3 M) x; A1 N; _ : k3 t7 d6 U2 w# _
// Change the PLLCR 更改PLLCR
) a$ b% i( Y- m" h if (SysCtrlRegs.PLLCR.bit.DIV != val)8 b3 x# X1 q: Z3 i: A" `! M' D
{
& ]. y- p5 H( @ i, D- h
! ]+ B9 [+ _3 f, F0 Z& O EALLOW;4 r: s& S( p2 A' n& g
// Before setting PLLCR turn off missing clock detect logic 在设置PLLCR之前,关闭缺失时钟检测逻辑: T8 B6 j6 H# W0 }; P2 \
SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1;; @$ P( D3 p- w) d) I
SysCtrlRegs.PLLCR.bit.DIV = val;
& ?4 N" z. c3 t* l6 ? EDIS;1 E0 Q' q& L& F( l. H+ r
$ s: t6 ^. _8 X& e4 b; L6 l
DisableDog();
8 k* V& k8 l" g/ E' \ H4 F" l7 F
! x1 ~" [8 M) b ~6 b- } while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1)3 ^# I% |6 J1 g5 P" t
{
; ~4 S: v ]) ~. G. r/ _( p, L // Uncomment to service the watchdog( F; |) s% M8 l! n7 m
// ServiceDog();
0 W+ q+ G+ o) R* U6 A$ } }# u" S9 i* N3 g! z
8 U5 k' S* {8 M8 o! I2 `
EALLOW;. N8 _0 ], w& \3 Y( A1 ]
SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0;
: w6 v/ {6 S; _6 J EDIS;2 g( g( E* @/ I& k+ ?# ^" @
}) S: x( [8 Y5 p+ V5 x0 l) V( C% X$ c
$ B) V5 R0 `! d9 d6 C% A
// If switching to 1/2 如果切换至1/2
e1 `1 L4 B5 f8 }+ n% F if((divsel == 1)||(divsel == 2))! r: x0 o- B7 w/ W2 O. ]
{% L! w- J I: W$ s* @
EALLOW;! r/ Y% Y* R9 C& m+ T
SysCtrlRegs.PLLSTS.bit.DIVSEL = divsel;6 Y( s- g1 K; g4 i9 X' F8 y; D) Y
EDIS;4 a6 F8 _$ U, {* X) t
}
5 m& `3 E5 B, h. B$ W0 J 1 H2 t! Y( v2 \# U4 \
// NOTE: ONLY USE THIS SETTING IF PLL IS BYPASSED (I.E. PLLCR = 0) OR OFF
% J2 j, |3 z4 n P# Z6 L; Y // If switching to 1/1 如果切换至 1/1
4 \" }' \% o8 R2 M // * First go to 1/2 and let the power settle6 {8 Y" q5 M& D. }. J0 a
// The time required will depend on the system, this is only an example
+ m f$ k" S! S1 c B! M9 o // * Then switch to 1/16 \/ f0 H( q5 \* ]! u. n
if(divsel == 3)9 y! @3 G1 w( X m, I+ V" X( |
{
0 p! ?6 ^: g& K, P8 C EALLOW;) o/ i- U' S. B! H7 n% H
SysCtrlRegs.PLLSTS.bit.DIVSEL = 2;
6 J6 H6 j' i: Q9 s3 s- S% s* ? DELAY_US(50L);8 i+ u7 _) N9 ]" }, E( K+ r
SysCtrlRegs.PLLSTS.bit.DIVSEL = 3;" x8 }9 O5 z6 A% H
EDIS;
0 n" X7 Z; V# u$ d2 x$ ]. x }
' R) J s" b: V' @+ C}
5 ~) G9 |4 h. T + x Z7 q& v: n. f$ N X- _" i
void InitPll(Uint16 val, Uint16 divsel)
$ R6 @, Z! i8 x% k+ ^{
5 S; O! a, d s' O ! B) v0 F: |- l% o& t3 `$ \
// Make sure the PLL is not running in limp mode
- V" ]+ r& d0 @% v. y if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0)4 J' G. u( R5 C" O1 l
{
' u! E4 j. C& `) j3 a Y) W // Missing external clock has been detected
( N8 U1 S% q2 r5 r9 _% w" n1 K // Replace this line with a call to an appropriate5 f3 c8 f) i; n5 E5 V+ V7 ?
// SystemShutdown(); function.: K) |8 l: |; M& f! w( V, P- Y
asm(" ESTOP0");
. t0 @: J$ l9 |1 v) w/ g: ^ }/ g" N6 a- M W% f+ E: A$ ?
: G& y' o8 v0 M( ?' d% `0 U8 G
// DIVSEL MUST be 0 before PLLCR can be changed from5 m0 S" Z' L& ~0 y3 {
// 0x0000. It is set to 0 by an external reset XRSn& b. z+ k! @1 P+ X1 B
// This puts us in 1/4
6 c% i3 n7 \" L' T if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0)7 z" L: _8 m. O+ k5 e' j: x- p9 B
{4 c6 Y, \. \6 e
EALLOW;& \6 `* C+ b- q1 D7 n7 f
SysCtrlRegs.PLLSTS.bit.DIVSEL = 0;1 f2 U; A$ i. V* {8 l5 E, Y8 r) _
EDIS;/ ^# M/ F: ]' ~* I0 n- A8 Y+ D
}4 ?! W8 [( ^* p! D
/ R) @* ^" ~/ b1 L! R! J // Change the PLLCR
8 S" l3 x1 T' J( ?- m! n& a# a if (SysCtrlRegs.PLLCR.bit.DIV != val)
" C" C0 z$ H9 p1 C {
T/ K8 Y' N1 | ; [! W" T& i) Z% ?. l
EALLOW;
! q* z3 q- l5 }% X. @+ K // Before setting PLLCR turn off missing clock detect logic
' x& b" p$ n6 h9 f9 P' n SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1;. [7 f. U) B6 O, ^$ |
SysCtrlRegs.PLLCR.bit.DIV = val;9 ]' I/ x f; o) v& ~# @5 y7 L/ x; |
EDIS;
/ O: X1 Z5 e) t. L+ o- `
; y3 \+ j3 v0 \5 A. @ DisableDog();
; N1 Y, Z, j$ g5 k2 _2 Q2 `6 ]% j
+ O+ {& b7 e! `. P- L while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1)
/ `5 K$ B6 S* w$ O- h {3 L% T3 @9 x2 J! f
// Uncomment to service the watchdog4 C0 ]/ Q3 h: o' S3 X& c1 G3 \
// ServiceDog();7 R8 n/ B5 H. k( n
}. J$ B! a! r. M% I1 d
9 Y' F/ g3 s) B! ~- S9 o2 j
EALLOW;" B1 [: h. r- e4 i
SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0;0 [% \% i- ^. Y3 ~4 d4 j
EDIS;
6 n% J; S- l' k3 }& C" z }3 c/ V3 V3 d1 G" [, n
" W* k8 u z! A
// If switching to 1/2
' E+ Z3 k6 L: J% I2 l if((divsel == 1)||(divsel == 2))% W! o) f: l4 s6 c/ |
{
6 d) `& N" F+ e9 i% L EALLOW;' k+ g0 l! f( k* {
SysCtrlRegs.PLLSTS.bit.DIVSEL = divsel;
' ]8 l; V& z# c3 j3 g; D EDIS;
+ d! ^% b0 U; V% o }7 X4 g0 j4 W# E
4 q' e# e L9 H% T% r4 g# i // NOTE: ONLY USE THIS SETTING IF PLL IS BYPASSED (I.E. PLLCR = 0) OR OFF: A: X: v, J3 }1 X
// If switching to 1/1
$ ~. A4 l; R4 D1 a // * First go to 1/2 and let the power settle* c2 Q% H, @$ ]/ o j4 z% R
// The time required will depend on the system, this is only an example2 Z0 l( B9 w: U' }2 w" {+ I# ~
// * Then switch to 1/1
2 H1 A% F6 K% |' F8 n9 [! N- x if(divsel == 3)
' q _ }. p0 h- }' C5 M- v6 i {
6 T' J7 g. @) x/ { EALLOW;
9 c0 f" S- \5 ^0 P& T' V6 ?1 E+ V2 J SysCtrlRegs.PLLSTS.bit.DIVSEL = 2;
: e( _ ?9 `! w# D3 K# S0 z DELAY_US(50L);
) T+ z) d; ]2 r0 v. X8 h. z! R, M- l7 s SysCtrlRegs.PLLSTS.bit.DIVSEL = 3;
! z1 d9 j: Z p6 T3 T EDIS;
4 n# {/ y! X ]4 o* t* ? }
+ a/ z' j. q' t |+ v5 U代码解释:, S" r ]) F. C1 d% ?9 G! M
1 D+ I4 i3 R) S4 C% e( F0 f
1、if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0),检测外部时钟是否存在,保证在外部时钟正常的情况下运行系统。
! f$ n8 q9 I, E: `$ m& |) e9 s$ u2 v
) i* l. L) q: _7 e, N K: S' Q2、 if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0),如果8~7位不等于0,则强制置为0。
4 h. k, D, C2 U% R0 b- }" X8 [+ ]$ E0 ?9 a
* b% N* t3 l! d9 j9 m
- o0 [2 @. @) }5 S0 F2 |3、if (SysCtrlRegs.PLLCR.bit.DIV != val),如果锁相环控制寄存器PLLCR的3~0位不等于10实现10倍频,则使得锁相环状态寄存器MCLKOFF标志位为1,并强制置锁相环控制寄存器PLLCR的3~0位等于10。并且锁定锁相环,然后打开时钟丢失检测功能。
4 G6 S: f& a- n6 Y5 Q' H: x3 n- ^* \$ K) a% d6 y
4、if((divsel == 1)||(divsel == 2)) 与 if(divsel == 3) ,配置锁相环的分频。通过查询头文件可以看到这两个值。证明系统默认的倍频数位10倍频,系统默认的分频数为2分频。6 A" p9 Q; u/ Z, c
1 q& Z' Z5 f! l
+ c, H8 i9 q* w7 ]& C& }
9 D$ A2 ?+ c$ L9 A由于目前的生产工艺,晶振频率为30Mhz的晶振性能更优,配置外部晶振为30Mhz成为主流,因此选择的倍频数为10,分频数为2,30*10/2 = 150 Mhz ,这也是DSP28335主频为150M的由来。
: V6 _6 B3 X# l9 D5 K. I }- ~3 n0 u+ F5 Z5 c
3、初始化外设时钟函数InitPeripheralClocks();
3 D6 v* L: g+ b0 w1 [在进行了外部晶振的倍频和分频后,芯片就要将自己的动力分配给各个外设,驱动各个外设进行工作,这个动力的分配就是初始化外设时钟函数的作用,函数代码如下:1 r& L7 }) j/ |
5 g3 f8 N9 {; n* e- Z' g Avoid InitPeripheralClocks(void)* c2 Q0 ]" P$ Q0 ?
{1 W; [4 w7 f- N
EALLOW;7 A) w% r8 b, C! z8 ?2 A$ U& ~
4 Y- C. v# n5 ~% a
// HISPCP/LOSPCP prescale register settings, normally it will be set to default values
0 p6 J( _# C6 _6 E+ K; _+ S SysCtrlRegs.HISPCP.all = 0x0001;
# W6 Y+ [+ |+ C SysCtrlRegs.LOSPCP.all = 0x0002;/ l2 }; m2 ~! k8 C4 ~* ]
- v& \& J/ Q9 D! M! ^// XCLKOUT to SYSCLKOUT ratio. By default XCLKOUT = 1/4 SYSCLKOUT
) H/ m; V3 F+ u& l // XTIMCLK = SYSCLKOUT/2
2 c. F" `* c! {9 a. C/ G XintfRegs.XINTCNF2.bit.XTIMCLK = 1;/ I& h D/ h7 j% B
// XCLKOUT = XTIMCLK/2: V$ \, j) S6 t! o
XintfRegs.XINTCNF2.bit.CLKMODE = 1;7 a) ~8 T! n4 z, A
// Enable XCLKOUT
z8 _6 g$ a2 _ XintfRegs.XINTCNF2.bit.CLKOFF = 0;
) W7 @, ]0 i3 y2 I# i0 J Y# X0 P& m+ [ 8 N, l" T7 i( p0 F% Z, a
// Peripheral clock enables set for the selected peripherals.2 |" d) n& K2 t# e
// If you are not using a peripheral leave the clock off
4 D0 X' k7 r2 A; p$ N1 c// to save on power.
; b. T- s; l! T. R0 ^//
9 ]' |' H; ^ n! [// Note: not all peripherals are available on all 2833x derivates.
; {. u3 i. y/ ]5 f// Refer to the datasheet for your particular device.
' X2 |6 D' B9 I- Z( n//
$ I- P$ |8 T& m( \# L// This function is not written to be an example of efficient code.7 R( A* J. I( F. e0 J/ h/ p d
8 ?$ k8 i2 Z$ H7 H0 z& A+ P. ?
SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1; // ADC& V' e) W3 Y$ r& Y( Q9 e; k
" ^* H! j- @, z& [$ k* X // *IMPORTANT*
8 N$ Z7 q/ ?! r, C+ a% a2 j; A // The ADC_cal function, which copies the ADC calibration values from TI reserved& `/ e$ a2 O' [* ^
// OTP into the ADCREFSEL and ADCOFFTRIM registers, occurs automatically in the) y( Z8 k8 r$ l8 k# ]5 G" S* P% H% o
// Boot ROM. If the boot ROM code is bypassed during the debug process, the
! q0 ?9 K0 |! G, J+ z5 c! I. u. Y // following function MUST be called for the ADC to function according
" N# c0 v# o0 S, y' x3 S- c // to specification. The clocks to the ADC MUST be enabled before calling this/ y! n+ x' W) }0 }$ f
// function.2 R0 {. e7 k3 b* I
// See the device data manual and/or the ADC Reference0 P: e, C! Y. |
// Manual for more information.
N8 @6 D" q1 B' b+ A
: \1 Z2 G f, d: `: p4 W& I ADC_cal();
3 _: `9 n7 w: a% O+ P O r
0 b1 D$ I( M4 l + q2 m9 E n. E v! m- U
SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 1; // I2C+ i3 V, R' w" m/ o' V% R1 m
SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1; // SCI-A: f* k8 l% d# o: g/ s5 J, x2 z4 l
SysCtrlRegs.PCLKCR0.bit.SCIBENCLK = 1; // SCI-B9 U9 _( j- A% s( R) X
SysCtrlRegs.PCLKCR0.bit.SCICENCLK = 1; // SCI-C; x6 m' b" X# ~! e+ C, h
SysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 1; // SPI-A
% n9 M% x `: y! N s3 N SysCtrlRegs.PCLKCR0.bit.MCBSPAENCLK = 1; // McBSP-A
0 E- i( b" ^" ~! C6 s SysCtrlRegs.PCLKCR0.bit.MCBSPBENCLK = 1; // McBSP-B% \% r- j! h! V$ E4 S
SysCtrlRegs.PCLKCR0.bit.ECANAENCLK=1; // eCAN-A
8 ?/ Z: K# k. ]1 m$ }* ^( u SysCtrlRegs.PCLKCR0.bit.ECANBENCLK=1; // eCAN-B, I0 g' J# u) }
7 A1 T }3 W+ u% I1 W! p7 W SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Disable TBCLK within the ePWM
1 o* z0 \# S' g# i( u. Q5 A SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1; // ePWM1: \; c1 M2 ?/ o) h |( S0 G8 _8 E
SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK = 1; // ePWM2
q4 B9 z& Z" }/ G' | SysCtrlRegs.PCLKCR1.bit.EPWM3ENCLK = 1; // ePWM3
: @& R! h4 o! J; q3 i SysCtrlRegs.PCLKCR1.bit.EPWM4ENCLK = 1; // ePWM4$ C2 Z$ T$ l+ L x; J
SysCtrlRegs.PCLKCR1.bit.EPWM5ENCLK = 1; // ePWM5
~ W' @0 B# ^! d SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK = 1; // ePWM6
: b8 C# h4 g9 M" q9 C; M; u // SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Enable TBCLK within the ePWM% _+ ~9 Q F/ z5 t8 D/ ]
* ?( @( W7 j, C2 b% O- q
SysCtrlRegs.PCLKCR1.bit.ECAP3ENCLK = 1; // eCAP3% j0 B" k2 _ D2 ]0 P
SysCtrlRegs.PCLKCR1.bit.ECAP4ENCLK = 1; // eCAP4
1 _8 _/ e2 c, @8 k, D z SysCtrlRegs.PCLKCR1.bit.ECAP5ENCLK = 1; // eCAP5
# @% f/ x- t1 D* i5 \% u B2 } SysCtrlRegs.PCLKCR1.bit.ECAP6ENCLK = 1; // eCAP6
1 i* p9 d j3 O; I% l# K/ X SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 1; // eCAP1' B- Z2 z+ N" o T1 ^1 P1 ]
SysCtrlRegs.PCLKCR1.bit.ECAP2ENCLK = 1; // eCAP2
) z, h. u7 Q6 G6 i0 Q SysCtrlRegs.PCLKCR1.bit.EQEP1ENCLK = 1; // eQEP1; I9 R# H0 G K! Z
SysCtrlRegs.PCLKCR1.bit.EQEP2ENCLK = 1; // eQEP2
) L8 \, m7 C- q( i9 B, }6 o8 q8 {2 P
) q: [) p6 {3 A! A3 s SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 1; // CPU Timer 0
( N! k: E# G( W* N7 D SysCtrlRegs.PCLKCR3.bit.CPUTIMER1ENCLK = 1; // CPU Timer 1
2 i+ C& b& s4 K+ h4 I1 t2 C SysCtrlRegs.PCLKCR3.bit.CPUTIMER2ENCLK = 1; // CPU Timer 27 n+ ]- W9 k6 T! i4 s1 i. S. q s$ H
. y4 Q( |! C, ~. H1 L, s z
SysCtrlRegs.PCLKCR3.bit.DMAENCLK = 1; // DMA Clock# ] ] M$ A. ~" w
SysCtrlRegs.PCLKCR3.bit.XINTFENCLK = 1; // XTIMCLK) r" ]3 R& @3 d, |1 Q
SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1; // GPIO input clock
1 ~; }6 {2 E4 @/ |7 X4 b2 L
: v* B2 F: D- f& [( u% q4 z EDIS;
3 f k$ o& i5 _}
& M' i# d- q, \4 \* C, i7 N 代码解释:/ T: j" u0 J) q E+ }" q& N
# {+ |5 |6 [, x1 `" d5 c1、SysCtrlRegs.HISPCP.all = 0x0001; 设置高速外设时钟分频 = sysclk / 2。
' w( G1 o* t0 @2 d& q6 O; y; N
/ H$ b4 t9 P- [/ q) y k+ \6 `- o: ~0 |9 K2 d# e. L( s
2、SysCtrlRegs.LOSPCP.all = 0x0002;设置低速外设时钟低速外设时钟分频 = sysclk / 2,这里命名稍微有点出入,但是查询头文件后确实是这个功能。只不过换了一种方式表示。本来我以为我很细,但是发现是我很粗,错过前一句的命名风格,实际就是这么命名的。: O" ]; b1 P! ^
6 S5 p$ h# E( u( A% [) {. w u
+ Y% q6 h4 t5 B( T9 \
4 \$ A5 N0 K$ C l3 q
; W5 |' U# R6 w
/ p: B4 {/ z. ^) \9 Q7 d9 b3、XintfRegs.XINTCNF2.bit.XTIMCLK = 1;配置外部存储器的时钟为默认状态。' s$ n) R1 z$ _/ Z% s
l7 F0 L) G5 F0 z$ g J; R# G0 W
7 T. Z' {9 k8 y, u; i$ S2 H
0 ^5 ]2 W: O3 [8 {$ Q7 O
4、XintfRegs.XINTCNF2.bit.CLKMODE = 1;外设时钟频率控制位,并配置为默认。2 s/ c3 ^8 V) t. g( O/ T
. W" @8 W6 p6 i; F: F" g
7 f& ?0 v Q8 Y" |- s! q. N3 k. M1 {' O0 t. \
5、SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1等; 外设时钟使能,这里的外设时钟控制寄存器PCLKCR0控制片上各种外设时钟的工作状态,使能或者禁止,也就是说这里控制着外设的各个时钟的关闭和开通。% R- k' |: s3 B. G8 z! q
- H, R! x' \; O5 p' p小结:3 n4 R3 n. ]" F. {$ r6 {7 L
通过这个系统初始化函数,我们能够得到几个关键的信息:
* K1 W4 H+ R2 q) x: F2 Y3 d& f
8 h; Z i5 @3 r) {0 I% U W1、外部晶振为30Mhz,经过锁相环PLL的倍频和分频操作可以得到DSP28335的主频150Mhz。
6 j: u1 E g0 u. U+ F
# c/ ^8 M H6 t& s; m0 g2 p2、在初始化函数中,能够选择打开或者关闭各个外设时钟,并且可以配置频率大小。
1 _- L8 M4 x& H/ }& H b% E! C0 `- U; Y( a& y
说实话,在梳理这个初始化程序的过程中,其实好多次想撤退,心里想着反正这些都是固定好的,也不会更改其中的参数,我为什么要花这么多时间去看这个呢,但是咬着牙看下来了。看完之后其实我觉得收获还是挺大的,特别是DSP的主频150Mhz是怎么来的这个点。说来惭愧,用了DSP好久,只知道主频是150Mhz,还真不知道是经过PLL分频又倍频来的,有不有用?我感觉其实还是有用的,我们对需要从事的工作有了更一份的了解,这就有用,也希望自己在日后的学习过程中,刨根究底,不偷懒不粗略,细不细?不够细啊!忍不忍得住,那必须忍得住啊。
' C( `. y) @- r—8 |3 ?6 y" Z) @
|
|