|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
近日工作中又涉及到了DSP28335的应用,看来TI的芯片还是得到了公司领导的认可,也直接丢了一份DSP28335的FOC程序给我理解。以前读书阶段较为简单的接触过一段时间,对DSP28335的基础功能部分有了一些浅显的了解,现在工作中要实际开始用了,开始发现之前学习的程度还是不够,因此要更加深入的探究一遍。可能非常基础,希望大家也不要见笑,人真是年龄越大忘东西越快。' j1 q* k' z$ @. b
9 T, `6 F* h8 x$ a* w3 b4 T系统初始化7 m- ] t; J! ?( N
首先从系统的初始化开始,系统初始化主要是系统时钟、看门狗等功能模块的基础配置,TI官方配置的系统初始化函数如下:
9 P9 a5 I; ~# o4 {; R
% j6 W. ?- m" p. L; G: u* Lvoid InitSysCtrl(void)
6 b7 L! F* ?$ t- k1 r+ x) ~- r{! f) I! _- Y9 D; ~% Y0 M k6 Q" N5 T
. m' W6 a+ b- P( X/ ` // Disable the watchdog
]/ Y- J S9 p, ]' ^8 o DisableDog();: u5 N- p: q$ T* W
9 E8 A/ n' I, G) x5 G5 L
// Initialize the PLL control: PLLCR and DIVSEL( x* c, N/ a, ` `3 L( Y
// DSP28_PLLCR and DSP28_DIVSEL are defined in DSP2833x_Examples.h
& H' R2 @; [; I% i) O InitPll(DSP28_PLLCR,DSP28_DIVSEL);0 w# F6 y7 J4 K9 `& e3 a' H
+ H: j+ C& l$ U. `
// Initialize the peripheral clocks# ]$ d; t# ~" B2 t8 y9 r
InitPeripheralClocks();
" X' ^( U8 g) @: e5 u}
2 D: d, |' B2 P5 G上面代码主要由3个子函数构成,分别为 DisableDog();、InitPll(DSP28_PLLCR,DSP28_DIVSEL);、 InitPeripheralClocks();这三个子函数的功能我们也来一一分析。6 A2 v& {1 ~7 l8 X/ W' ]% m; j2 r
4 o2 ]7 b! Y: l, `) S看门狗配置函数DisableDog() }, H$ ~4 C( g5 E: E+ \
首先是开门狗初始化函数DisableDog(),函数代码如下:: F6 u! V' \* b' j: b) q
U5 m9 r1 ?- j$ X. B# H
void DisableDog(void)
; Q( R& O5 @8 ^ |0 t2 C- K' Z- L{0 a" u8 [0 W+ t, L& P
EALLOW;
5 t% @/ n3 `0 n0 \7 I8 V0 E SysCtrlRegs.WDCR= 0x0068;
) Q3 V: X7 ?4 Y. ?1 M) c5 I EDIS;! m2 H- f) Q- p
}0 ?7 B g6 o+ f9 R7 {: j
代码解释:
6 ?* h) Y0 V! ?' y3 W/ _
( F0 q: {. K" Q. ?3 O1、EALLOW /EDIS 打开/关闭状态寄存器保护。EALLOW/EDIS 是DSP为了防止杂散代码或指针破坏关键寄存器的状态宏定义指令,关键寄存器包括ePWM、Flash、器件仿真寄存器、FLASH寄存器、CSM寄存器、PIE矢量表、系统控制寄存器、GPIOMux寄存器等,这些寄存器的状态决定DSP是否稳定运行,因此需要修改之前应用EALLOW打开保护,修改完后必须用EDIS关闭。; a* n3 t4 b* J* f9 B# {/ `
% f. `5 k5 C9 g) C2、配置SysCtrlRegs.WDCR寄存器为0x0068。关闭看门狗,也可以戏称为把狗杀了,好残忍,看门狗的实际作用就是防止CPU跑飞或者其他故障导致系统出现不可挽回的故障,如果一段时间收不到CPU稳定运行的信号就会复位CPU,从而保证CPU的稳定性。打开WDCR寄存器表可知,寄存器后8位起到实际作用,0x0068 = 0110 1000 ,第7位置0看门狗不满足复位条件,第6位置1禁止看门狗模块,第5~3位写101强制写,第2~0位写000配置看门狗时钟。关键为第6位置1禁止看门狗模块。 W( {; a" B# Y* F+ i% ]
1 q, v J# J, B/ P6 v
4 z( V. T( p( A8 P, p( w6 ?$ ^
! H+ x/ N ~ Q% l8 Q6 u5 }
锁相环初始化函数 InitPll(DSP28_PLLCR,DSP28_DIVSEL)
+ t# K% | |5 c) G' [其次是锁相环初始化函数,在DSP中锁相环函数主要是用在时钟的分频上,将晶振产生的震荡进行分频和倍频操作,是整个芯片心脏——时钟能够起作用的关键之处,因此必须在程序开头对其进行配置。其代码如下:6 C4 p7 t$ c% Y* w
* V# }* k) w% Z0 Y& v7 L8 I" D- {void InitPll(Uint16 val, Uint16 divsel)
9 j4 V( b* @! R) v/ t{7 G+ D- ~ B+ H- {
& F- u% ?5 n0 B/ e# a! _7 h
// Make sure the PLL is not running in limp mode 确保PLL没有运行在故障状态+ l5 Q( u( \1 }9 l9 j+ p5 r
if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0)3 |) k9 {: }, {- g7 x; [
{
! f ]0 z% k$ d! z$ R3 c // Missing external clock has been detected
( P; z5 y8 k" T3 e- m- t% N/ y // Replace this line with a call to an appropriate2 Q* {0 J8 y$ Z( u' `/ F
// SystemShutdown(); function.
9 V* y/ {9 C8 H0 H# H // 若检测到系统失去外部时钟,则关闭系统8 k& t; z7 s/ o- j8 f* w/ b
asm(" ESTOP0");& v; O4 d: J% k1 c( H- g u! g( y
}# W9 e9 {, t+ p8 z4 ]. s
6 N2 ] d$ I' m o, [
// DIVSEL MUST be 0 before PLLCR can be changed from 在PLLCR可以从更改前,DIVSEL必须为0' t" Q. f* @, q1 b: z8 z
// 0x0000. It is set to 0 by an external reset XRSn 通过外部重置XRSn将其设置为0
: f3 x, H# {2 B4 W7 _ // This puts us in 1/4* T# m$ j9 w/ @$ ?: ?
if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0)" f, ^: O* k) _& k+ H+ X
{
/ v# W2 L; S$ }' z; r+ m( ]& O* ~ EALLOW;: U+ B3 z! G2 Y+ }# z
SysCtrlRegs.PLLSTS.bit.DIVSEL = 0;* b, \; q4 r% F& c$ v9 N
EDIS;
; i: y V; n, p3 y }
7 j7 r: [3 V4 i* v
7 _/ `* K* e# P0 _4 b8 n // Change the PLLCR 更改PLLCR
$ G1 i! b2 r( C if (SysCtrlRegs.PLLCR.bit.DIV != val)6 ^& @: n7 M: A" Q* w
{
5 j" w$ q" a6 X$ i/ c9 c
4 N, G; W0 E. S* J! M EALLOW;9 W M i1 G% f9 S0 ]; i
// Before setting PLLCR turn off missing clock detect logic 在设置PLLCR之前,关闭缺失时钟检测逻辑
R& t# Y8 V5 S SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1;
7 `4 \# D& \4 l) V: D0 u1 M SysCtrlRegs.PLLCR.bit.DIV = val;: a5 [$ ?/ Y! l4 s+ N/ S
EDIS;
. G, k: z% N& r5 {6 {4 [' ^ |+ E
/ s/ w) U" s: x0 M- d8 R DisableDog();
2 a8 x# R* n- Z5 u' N( Q1 l
( Y* ^) e9 C# y# p while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1)% a9 e; B; U9 r& a E9 @
{% ?4 [2 q% v4 g. I
// Uncomment to service the watchdog( o( z5 a3 a7 ~; I2 d
// ServiceDog();
& m) _. D0 `; I' E8 \ }
! T9 L+ G6 t/ E
2 q2 Y! C. a, `2 s" Z3 u EALLOW;
2 E$ w( G1 a3 U SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0;
( H% ~2 |; q, S2 d9 [" Q EDIS;
1 q! _) X. ?$ ^& o3 S; a2 M }
) x. u8 w8 Z' |( D 9 u# x5 t7 S* h' N
// If switching to 1/2 如果切换至1/2
) R2 w) ]7 V& U T& }8 ?9 ~ if((divsel == 1)||(divsel == 2))
9 @9 N u% C0 m$ G2 q: y {
0 t) V* B# U/ t% k0 u EALLOW;4 ]. ?: @0 F+ W# k
SysCtrlRegs.PLLSTS.bit.DIVSEL = divsel;& B. I3 G7 d# J( F1 w# T
EDIS;
' F: y0 Z0 d, R Z( p }2 j* Y+ J, E% t; P# O1 I
3 z3 H8 ?5 c$ W
// NOTE: ONLY USE THIS SETTING IF PLL IS BYPASSED (I.E. PLLCR = 0) OR OFF
- |) H, `7 ]* O O // If switching to 1/1 如果切换至 1/1 5 u- C; v( m# r0 Z
// * First go to 1/2 and let the power settle3 l/ e2 `. D& S/ D5 U1 l8 F
// The time required will depend on the system, this is only an example
1 g8 \' c% Q* ~! b5 N0 x# { // * Then switch to 1/1
% L3 S$ g8 {4 Q" x9 u. _ if(divsel == 3)
# c8 j; l. s, ^( C {& a( B( ^+ A ~
EALLOW;
2 b) s, y: R- ~ Q ] SysCtrlRegs.PLLSTS.bit.DIVSEL = 2;' Q$ g; K( g5 Y" T/ h
DELAY_US(50L);6 [6 R1 l' Y3 U) I7 R
SysCtrlRegs.PLLSTS.bit.DIVSEL = 3;) g4 h$ |7 e5 Q ]
EDIS;# p8 O5 U" i# P) y* N1 X% F
}
5 L1 t1 i. h5 {/ ]/ r# @ }) B8 t" r}9 c3 E8 u9 w; \& U8 M1 k
; i9 n8 T5 o+ F- C) i: avoid InitPll(Uint16 val, Uint16 divsel)
6 i V3 e5 H( ?3 U{
7 ]0 ^. P* D, m4 h
5 t0 h6 E6 P4 t& K v5 l // Make sure the PLL is not running in limp mode
' T) |1 v% ~4 m1 Z) l/ J- _ if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0)
* ]0 H# m1 g6 h6 c, j0 L {
1 @+ r. e" e+ s // Missing external clock has been detected
; d! U( s5 b: V2 C1 g2 S% E // Replace this line with a call to an appropriate9 W4 T( e" A$ A! M% m6 z' w% x( j* g
// SystemShutdown(); function.
) a* W O2 [. Y3 G' W asm(" ESTOP0");& C% l) @9 t7 U5 m2 E
}4 R* l1 i( Q! D' w
& z I% p" O& Y5 v; r
// DIVSEL MUST be 0 before PLLCR can be changed from
& U. t# ]0 N3 R7 \6 C" z6 V. `+ k // 0x0000. It is set to 0 by an external reset XRSn! e3 T# m! Q, b% [
// This puts us in 1/4
0 L% U' S+ a, O* U6 K if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0)
H, O' X; T6 O h {
! N% a1 k+ \, U, i EALLOW;9 v. A) s6 Q% x* O
SysCtrlRegs.PLLSTS.bit.DIVSEL = 0;
9 e; g$ K! y2 H EDIS;
- P. |1 h" a! s; Q }
3 C, A! O" d) g* i8 E" ?$ L
) E' P! B' p. n# Y$ I/ S // Change the PLLCR) I0 E" w& O4 H) {/ ?# z. a
if (SysCtrlRegs.PLLCR.bit.DIV != val), y2 ^! D1 G( G1 }- c; M6 E& |5 Q
{# n! i3 J1 h3 L# |3 a, r8 _ R
% ~4 Q! {# R }6 c R
EALLOW;
: c$ D. Q! @% D7 R6 F; u // Before setting PLLCR turn off missing clock detect logic
K( A4 X! E; y5 I$ z a- B SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1;3 B3 T7 n6 j8 l% l
SysCtrlRegs.PLLCR.bit.DIV = val;, C: D M) w' W2 Q! q
EDIS;
: U6 s1 P- s# e1 b/ s1 B
, O# C4 N; _0 {* I3 d DisableDog();
8 `' ~0 H' ~0 a+ E; \" Z* l * U; m7 e, Y( |3 B& A. d0 g
while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1)
4 A2 V7 q9 L7 l0 m8 |8 A {# E- \' a5 k& P% |( t
// Uncomment to service the watchdog+ r5 u) t7 B2 h ~2 |# u; i
// ServiceDog();. ~* U# f* t! J* e5 s- e
}$ R( d: \: D) r9 j! I: H; B+ |
2 y! O" w4 Q( R7 J# x# Y5 u: N EALLOW;: O! y! T" U6 W4 O2 F- ~" N
SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0;
0 \7 z* r- _0 y! h& U3 o( E: A! q EDIS;% @6 L" j+ ^ ^% c4 {
}
. r) ]( H) T+ J, O7 Z( L, \
0 s+ \. S1 `/ q7 E$ S- C/ O // If switching to 1/2# a- o" w6 r; j2 E
if((divsel == 1)||(divsel == 2))$ Y8 I8 Z+ z% X$ d
{
! U, _% t( a2 h+ ^' D0 b- ^ EALLOW;; Z$ P+ Q& }" I. l8 L$ m, d4 R& z
SysCtrlRegs.PLLSTS.bit.DIVSEL = divsel;
' m+ P- ^ E# z9 G# O3 c% J& K EDIS;
1 f f9 g0 m# F: F9 O) X% {1 x }
! I* v9 K+ x' J* T* Q6 p : O! c7 f2 ]+ A
// NOTE: ONLY USE THIS SETTING IF PLL IS BYPASSED (I.E. PLLCR = 0) OR OFF3 b' F! ^! ^* } K6 o/ x$ Y8 N
// If switching to 1/18 n! q3 P2 y r9 L( O0 V: L& Y7 `' i
// * First go to 1/2 and let the power settle
: V4 c) H( N- _6 | // The time required will depend on the system, this is only an example
: R' Z" h3 m5 a0 m- f/ P // * Then switch to 1/1
! G" w& O; P% m3 s. K& _ b if(divsel == 3)% Q5 G5 u: X) n
{
/ `' e( h. V" w5 f+ i) I! i EALLOW;
- e- X j' C/ a3 X; ^ SysCtrlRegs.PLLSTS.bit.DIVSEL = 2;
* o. Z' D% w" y( c" v Q9 a DELAY_US(50L);
9 ~4 f+ q' V3 D" } d; f SysCtrlRegs.PLLSTS.bit.DIVSEL = 3;- n) C! V; T4 D1 v* R
EDIS;, x. F( V" ?$ F! m0 f- S5 ?7 R% m
}
! Q0 l# {- W2 s. V; n0 I代码解释:! v/ D, P( K' X" c
* C% z5 @, X2 q' M" f* s8 m# ~1、if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0),检测外部时钟是否存在,保证在外部时钟正常的情况下运行系统。
! S+ }6 {7 T; O. Y) Y8 L+ g j( g
2 V, K& W* N1 e* c/ u9 D2、 if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0),如果8~7位不等于0,则强制置为0。
: @- w: N8 _8 `2 h+ Y
: P8 l5 T% v/ e, k8 c0 h- f4 E! ~3 S7 P; T7 M+ s# T
7 ^! e( }: j5 ~- i& d3、if (SysCtrlRegs.PLLCR.bit.DIV != val),如果锁相环控制寄存器PLLCR的3~0位不等于10实现10倍频,则使得锁相环状态寄存器MCLKOFF标志位为1,并强制置锁相环控制寄存器PLLCR的3~0位等于10。并且锁定锁相环,然后打开时钟丢失检测功能。
i, G! j5 i# L l( D0 c( g9 t0 c& o
4、if((divsel == 1)||(divsel == 2)) 与 if(divsel == 3) ,配置锁相环的分频。通过查询头文件可以看到这两个值。证明系统默认的倍频数位10倍频,系统默认的分频数为2分频。
7 \3 k. \5 ]+ C, Z* @' n
0 n3 |' g8 l- N4 D; J" g0 s% E( z, G
) @( I- O& W: B/ Y2 d/ J8 M
由于目前的生产工艺,晶振频率为30Mhz的晶振性能更优,配置外部晶振为30Mhz成为主流,因此选择的倍频数为10,分频数为2,30*10/2 = 150 Mhz ,这也是DSP28335主频为150M的由来。2 f8 N4 ]. K5 C; z/ E8 }
9 b4 P4 P9 H0 E3 K3 p: Z W
3、初始化外设时钟函数InitPeripheralClocks();( v, k, _' o0 g: T d
在进行了外部晶振的倍频和分频后,芯片就要将自己的动力分配给各个外设,驱动各个外设进行工作,这个动力的分配就是初始化外设时钟函数的作用,函数代码如下:
- i1 x1 b: P F+ X, o0 @" j$ B6 m T8 p
void InitPeripheralClocks(void)
0 j% ?- i) t9 m. q! O' t; b{ I R1 h4 b* L( l! f# @/ Y
EALLOW;
% w; X ?. O' H
; ^0 h! L4 w* B$ P- a6 x// HISPCP/LOSPCP prescale register settings, normally it will be set to default values. o& e1 \; ^$ q ~! k" _9 X5 s
SysCtrlRegs.HISPCP.all = 0x0001;
/ R8 U' s" C1 }; R% W4 X SysCtrlRegs.LOSPCP.all = 0x0002;
* H1 P+ r5 E" I 8 X& b) @3 I: |
// XCLKOUT to SYSCLKOUT ratio. By default XCLKOUT = 1/4 SYSCLKOUT( U6 I6 \. k% i- A+ v! R7 ?
// XTIMCLK = SYSCLKOUT/2' b/ I; f0 B+ W
XintfRegs.XINTCNF2.bit.XTIMCLK = 1;
5 H7 e3 {% m* l // XCLKOUT = XTIMCLK/2
" t9 ^! `' L( B8 S9 O3 `0 S3 i' |+ p XintfRegs.XINTCNF2.bit.CLKMODE = 1;0 o$ |' ?# A3 p0 n( ?
// Enable XCLKOUT
3 U# f( W1 f( m% ?. P XintfRegs.XINTCNF2.bit.CLKOFF = 0;
; z0 f( ^. f' o5 [# D9 r
, S$ u, s5 @0 B4 d. \' t1 U5 i0 ]// Peripheral clock enables set for the selected peripherals.
# u" G; @2 K0 I* h& b// If you are not using a peripheral leave the clock off
, }; h4 A& g& o2 ^// to save on power.
/ N7 l7 j7 u6 ~1 ]( x6 W2 R//; P7 J; d7 J( s1 B" e
// Note: not all peripherals are available on all 2833x derivates.
- ?: T6 C4 r8 q+ m5 n1 g* ~// Refer to the datasheet for your particular device.1 ]: g6 F, s) Z; H
//* a! r5 q G' z! p* E. m
// This function is not written to be an example of efficient code. j X9 w+ R C4 s8 ?
7 n5 P% w) U1 U+ Q( b
SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1; // ADC
, O5 q; I4 c U
: G9 \6 t1 v1 u7 F // *IMPORTANT*+ m3 c1 @: a# r# N+ Z; h3 w
// The ADC_cal function, which copies the ADC calibration values from TI reserved6 F) B0 q3 t: o# y9 W
// OTP into the ADCREFSEL and ADCOFFTRIM registers, occurs automatically in the
' @; H! J9 ~6 ]& `9 z# i: s$ D // Boot ROM. If the boot ROM code is bypassed during the debug process, the
3 z" N i. A- @; y; v // following function MUST be called for the ADC to function according
* N9 t- | m$ J2 d: M( k8 x // to specification. The clocks to the ADC MUST be enabled before calling this
5 G' y9 H) {7 j0 E // function.
. e) Z% ~! u# p! L // See the device data manual and/or the ADC Reference% r! `# ]9 p8 n6 }
// Manual for more information.2 g; p0 |( o4 m( Z- V% a4 l9 r
% F% h( H. N( O( l4 {( I& Q; Y' a
ADC_cal();
c2 l5 {! p& Y3 q* s; m1 K
6 \! i: g1 j, G/ _4 x, U6 D
. t4 I$ K$ H$ b* N6 X SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 1; // I2C- F% ?1 z1 z$ C6 ~3 }
SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1; // SCI-A& r6 u9 c" |! ]$ E. |
SysCtrlRegs.PCLKCR0.bit.SCIBENCLK = 1; // SCI-B
/ H- ~! M# H3 @, u: z6 g) G SysCtrlRegs.PCLKCR0.bit.SCICENCLK = 1; // SCI-C# E+ N! i+ N( V/ v
SysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 1; // SPI-A
4 K+ S2 N0 k* z" o5 e5 o, W u* ^ SysCtrlRegs.PCLKCR0.bit.MCBSPAENCLK = 1; // McBSP-A/ |6 Y: }; B( e3 L
SysCtrlRegs.PCLKCR0.bit.MCBSPBENCLK = 1; // McBSP-B
: D, }4 x# Z( G% X' i SysCtrlRegs.PCLKCR0.bit.ECANAENCLK=1; // eCAN-A
3 f o1 e, P3 B& j/ U SysCtrlRegs.PCLKCR0.bit.ECANBENCLK=1; // eCAN-B
7 k9 g. M, K# r' p
3 ^8 w* }' m q& t' Y2 u: I SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Disable TBCLK within the ePWM5 i" A" [1 P m. D# _
SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1; // ePWM19 x! Q# [- {- u8 G, V- i! i4 `
SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK = 1; // ePWM2
B5 L/ E0 H$ K SysCtrlRegs.PCLKCR1.bit.EPWM3ENCLK = 1; // ePWM32 O8 w& l, J3 A
SysCtrlRegs.PCLKCR1.bit.EPWM4ENCLK = 1; // ePWM4$ y, r2 R# M% L( A9 ]
SysCtrlRegs.PCLKCR1.bit.EPWM5ENCLK = 1; // ePWM5$ K+ ^0 l; J- t% S- O# a* j n. D
SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK = 1; // ePWM6
" ^4 S4 p+ T3 M2 E; { // SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Enable TBCLK within the ePWM& g4 F. n$ z1 U5 \2 s5 p
; Z0 a f* K- L1 n) i7 W% e) s
SysCtrlRegs.PCLKCR1.bit.ECAP3ENCLK = 1; // eCAP35 f( a( o( E9 V; ~6 Y0 V
SysCtrlRegs.PCLKCR1.bit.ECAP4ENCLK = 1; // eCAP4* C5 R/ u/ ~2 \$ p
SysCtrlRegs.PCLKCR1.bit.ECAP5ENCLK = 1; // eCAP5
_) Q( Q) e3 b% w; Y: e SysCtrlRegs.PCLKCR1.bit.ECAP6ENCLK = 1; // eCAP6
' _% y* C( Z# h. ~6 z# d4 I: X SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 1; // eCAP1
6 B6 u% s9 N0 m' [ SysCtrlRegs.PCLKCR1.bit.ECAP2ENCLK = 1; // eCAP2
% ]3 g7 h# h, q' [ SysCtrlRegs.PCLKCR1.bit.EQEP1ENCLK = 1; // eQEP11 G5 q- V. q# x% F
SysCtrlRegs.PCLKCR1.bit.EQEP2ENCLK = 1; // eQEP2! u! z. d } E
' |8 F( [5 S, Q* J9 V SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 1; // CPU Timer 0
8 U! _) z _9 X: o4 S& P: E SysCtrlRegs.PCLKCR3.bit.CPUTIMER1ENCLK = 1; // CPU Timer 1
- T! `8 h* o' D% D9 h+ x SysCtrlRegs.PCLKCR3.bit.CPUTIMER2ENCLK = 1; // CPU Timer 2 D j% \7 I! t8 b6 u/ J; a) g
: m9 N% P" T) m* ]3 u& y$ v7 b0 I1 h6 ]
SysCtrlRegs.PCLKCR3.bit.DMAENCLK = 1; // DMA Clock
: {: x8 }2 d S% s8 c9 I SysCtrlRegs.PCLKCR3.bit.XINTFENCLK = 1; // XTIMCLK
, X8 U$ a ~4 G SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1; // GPIO input clock# K$ o4 N6 [2 B! X! \: y' w" {4 @
; Q. _. V* l1 [, o6 r5 l, ]
EDIS;+ I8 h1 {1 ?% B# H1 X9 ^
}* a& x9 o( f+ K: d0 b7 K) E5 t
代码解释:
* t, d6 `/ n% k! c( }4 s) }
+ R1 h( ^. Z: h/ S. ], h, j- U- s1、SysCtrlRegs.HISPCP.all = 0x0001; 设置高速外设时钟分频 = sysclk / 2。
, Y5 V) F4 C* P+ A6 X. w4 N" b t0 i+ ^4 D
+ ?! H' Y( l/ m7 i9 T8 z 2、SysCtrlRegs.LOSPCP.all = 0x0002;设置低速外设时钟低速外设时钟分频 = sysclk / 2,这里命名稍微有点出入,但是查询头文件后确实是这个功能。只不过换了一种方式表示。本来我以为我很细,但是发现是我很粗,错过前一句的命名风格,实际就是这么命名的。
3 f3 N2 j ]! g2 b* u; c* b
: s G4 H e1 ~. \. o! y9 ?" ]7 C; _
, O6 {" ?; F+ C C4 {" _, `5 J0 b N! O2 r; M6 l4 C0 E7 n5 a
6 U+ C$ l$ X/ }( y! _3、XintfRegs.XINTCNF2.bit.XTIMCLK = 1;配置外部存储器的时钟为默认状态。3 Y0 s& _+ ?% _
6 a" ^0 ~3 T; N
9 l; K) i0 }" v3 B3 W5 |
4 e f( Q* x% S& H
4、XintfRegs.XINTCNF2.bit.CLKMODE = 1;外设时钟频率控制位,并配置为默认。
1 w5 H$ ?; y* C* b* b
* ^. e- Z8 F. b# d6 p/ @2 F- J( K) g# S0 U4 m
$ V, b; J1 O! F$ S/ p
5、SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1等; 外设时钟使能,这里的外设时钟控制寄存器PCLKCR0控制片上各种外设时钟的工作状态,使能或者禁止,也就是说这里控制着外设的各个时钟的关闭和开通。
1 i' w0 W3 [/ Q' [
! e7 A0 M+ h/ N# f* D9 D小结:: b2 Z5 J+ @- ^, k) f4 Q
通过这个系统初始化函数,我们能够得到几个关键的信息:1 j7 U9 ~" L5 Z- s6 o
K7 Y4 c/ A; |6 g: U4 V
1、外部晶振为30Mhz,经过锁相环PLL的倍频和分频操作可以得到DSP28335的主频150Mhz。: Q5 F% l( {4 X ?8 k7 h( y
8 i2 b& ?( J& Y, f, k2、在初始化函数中,能够选择打开或者关闭各个外设时钟,并且可以配置频率大小。! G; R3 B3 ]2 t* \( P
; C( ?3 i+ ?/ ~' x6 y2 R" G0 r! C说实话,在梳理这个初始化程序的过程中,其实好多次想撤退,心里想着反正这些都是固定好的,也不会更改其中的参数,我为什么要花这么多时间去看这个呢,但是咬着牙看下来了。看完之后其实我觉得收获还是挺大的,特别是DSP的主频150Mhz是怎么来的这个点。说来惭愧,用了DSP好久,只知道主频是150Mhz,还真不知道是经过PLL分频又倍频来的,有不有用?我感觉其实还是有用的,我们对需要从事的工作有了更一份的了解,这就有用,也希望自己在日后的学习过程中,刨根究底,不偷懒不粗略,细不细?不够细啊!忍不忍得住,那必须忍得住啊。
8 ^6 r; P) t: z* |( m—. z& A, j5 r* }1 ~( G
|
|