|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
近日工作中又涉及到了DSP28335的应用,看来TI的芯片还是得到了公司领导的认可,也直接丢了一份DSP28335的FOC程序给我理解。以前读书阶段较为简单的接触过一段时间,对DSP28335的基础功能部分有了一些浅显的了解,现在工作中要实际开始用了,开始发现之前学习的程度还是不够,因此要更加深入的探究一遍。可能非常基础,希望大家也不要见笑,人真是年龄越大忘东西越快。
7 K, u2 \* J6 v! {# y( w! |
5 }6 I L: H; x' ~+ S: W' m9 l9 C系统初始化, l% b8 }# G0 e. e% j
首先从系统的初始化开始,系统初始化主要是系统时钟、看门狗等功能模块的基础配置,TI官方配置的系统初始化函数如下:3 ^0 _ J8 f4 X4 F& ?2 G
4 _' ` J7 h+ J
void InitSysCtrl(void), C3 I; N5 _5 \5 t! X0 G2 O
{+ G ?1 m8 A0 t9 a: K' {
3 \% E% l7 A, I1 X
// Disable the watchdog6 B: }) i; h) Y z: w
DisableDog();
) z* }( A! M2 \ ' H# L. L* j* `' a, g9 D
// Initialize the PLL control: PLLCR and DIVSEL" C+ h( Q5 ~3 a6 s
// DSP28_PLLCR and DSP28_DIVSEL are defined in DSP2833x_Examples.h
' }, o) @9 i5 B, H! v2 n3 U4 W InitPll(DSP28_PLLCR,DSP28_DIVSEL);, d ~# I3 o' \! m5 g1 z; ~: R
% c" `+ L) I7 j1 ^6 P // Initialize the peripheral clocks4 O* c$ U; @$ o Y8 `3 J" w
InitPeripheralClocks();
! I7 J ?( \9 {6 {: I}
+ B0 M3 L4 w/ @8 l, C ?' v上面代码主要由3个子函数构成,分别为 DisableDog();、InitPll(DSP28_PLLCR,DSP28_DIVSEL);、 InitPeripheralClocks();这三个子函数的功能我们也来一一分析。5 c( v- n8 ]2 R$ S# w% L
: Z, l, \ U6 s0 A3 R9 M5 l
看门狗配置函数DisableDog()
' K3 T$ q, A+ y* @3 ~首先是开门狗初始化函数DisableDog(),函数代码如下:
# T/ ~3 a) s( b0 r
5 o3 m+ d+ l+ B$ Wvoid DisableDog(void), T6 ^7 }3 R# ]# y
{
- ]# H5 ?6 u2 G4 x* ~0 ], g- |/ S EALLOW;
8 O- X) }2 S; G5 {7 Q; d SysCtrlRegs.WDCR= 0x0068;. F( c" e4 g t
EDIS;$ _0 b9 t5 m5 Z( U$ J) q+ f
}
( p0 Q2 D g6 H- z. n3 T: P& F5 x+ q代码解释:+ D" Y w* h( ^1 f1 s8 ^
$ C; y( o2 n. X1、EALLOW /EDIS 打开/关闭状态寄存器保护。EALLOW/EDIS 是DSP为了防止杂散代码或指针破坏关键寄存器的状态宏定义指令,关键寄存器包括ePWM、Flash、器件仿真寄存器、FLASH寄存器、CSM寄存器、PIE矢量表、系统控制寄存器、GPIOMux寄存器等,这些寄存器的状态决定DSP是否稳定运行,因此需要修改之前应用EALLOW打开保护,修改完后必须用EDIS关闭。
. j! M! C6 c K9 ]
5 y, s% B2 @2 I2 C9 E+ 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禁止看门狗模块。
6 B! r Z9 d6 s# S0 Q
- K2 w+ ?% L; y" W4 [3 N! R0 A2 m8 @" _$ C" i
, D3 T9 `+ K& r/ G锁相环初始化函数 InitPll(DSP28_PLLCR,DSP28_DIVSEL)
; {+ T- [: s1 P0 }6 W u8 j其次是锁相环初始化函数,在DSP中锁相环函数主要是用在时钟的分频上,将晶振产生的震荡进行分频和倍频操作,是整个芯片心脏——时钟能够起作用的关键之处,因此必须在程序开头对其进行配置。其代码如下:1 @' ~- \# S6 n+ Q$ u
* r+ y! S# U9 q
void InitPll(Uint16 val, Uint16 divsel)
4 w2 e( [- x D8 J4 ^" O' @{
+ t d7 _/ F, W; d4 f( a: R# P7 ?+ q $ y8 I/ ?& F1 A$ x, O
// Make sure the PLL is not running in limp mode 确保PLL没有运行在故障状态
+ L0 r1 \7 y7 {) g6 A4 \ if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0)
/ X, T% c) J6 L& p; ?3 k& b* v {
* ?4 y$ R: a% i. A' @2 ?" w: [ // Missing external clock has been detected! `# R! @9 x$ ~+ }. P
// Replace this line with a call to an appropriate$ H& z0 t9 X/ O7 D( T4 `8 w
// SystemShutdown(); function., k& Y# r4 u2 {2 J# x$ T5 h
// 若检测到系统失去外部时钟,则关闭系统2 k4 W" {2 ^/ [& N- w, k
asm(" ESTOP0");" [$ G* u$ k% b% X
}& u2 |6 u/ H0 v* Z$ P/ r6 ^. U8 o
; p( ?# i/ h F6 ~* p P // DIVSEL MUST be 0 before PLLCR can be changed from 在PLLCR可以从更改前,DIVSEL必须为0
' T7 E% f1 H: {/ X: v // 0x0000. It is set to 0 by an external reset XRSn 通过外部重置XRSn将其设置为0
# J6 Q3 b% W& o n/ a- I" y // This puts us in 1/43 M$ A$ l/ v8 W& P* n7 O/ b
if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0)0 X! ^. X" ^/ e$ |
{) G1 l7 d' Y% v4 K4 V8 [9 e! }! v
EALLOW;
; H) s' e$ x; t9 d$ P SysCtrlRegs.PLLSTS.bit.DIVSEL = 0;
: K- S+ y5 Z' F: k4 ? EDIS;$ a4 v+ a7 ]' j- }- u& z
}& f! i p9 I( ~! R! g5 l3 l B
3 g0 W0 L7 _- e1 L // Change the PLLCR 更改PLLCR# Q1 V, l, o$ J* X) ?
if (SysCtrlRegs.PLLCR.bit.DIV != val)
5 D& Y1 G& j% S& @ {
" p8 M1 M1 q$ v/ T- j& M6 ]9 b - L. Z g9 W( }7 E9 I
EALLOW;2 g$ W0 e* \3 b' C& _: m `
// Before setting PLLCR turn off missing clock detect logic 在设置PLLCR之前,关闭缺失时钟检测逻辑$ g* [+ M) ~ s5 ]
SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1;
% D7 a+ |/ `0 W9 \' B; t3 |, q7 N SysCtrlRegs.PLLCR.bit.DIV = val;
) V: {+ k8 b1 @; A& `; y EDIS;: s" |1 N4 f1 `# \
) C2 {$ C9 ^9 b/ w6 e; m, g! [: e DisableDog();
0 t8 B' S& J1 A, H8 N
, Z U4 R5 _+ H while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1)
8 D# e3 x. ~3 z8 b" ` {
: h9 E, b: F" Y8 R // Uncomment to service the watchdog' t) V0 a8 _9 F! _, s! [4 K
// ServiceDog();
* X3 @# y$ } p7 l' c( X }9 `6 E% Z$ n* O) p K6 R' p
% Q0 `) \& M3 y% l* x6 Q! [ EALLOW;
4 I$ k4 W9 Z' j% C5 [2 v6 @ SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0;# D5 U4 k, Q+ q( a/ M& U& j3 ~- J: N0 m
EDIS;
% C6 f7 }4 p% |+ u" N7 k }: R }
0 F; f. ~( x* C% K- R5 ? / b ?6 ?' ?0 }/ p5 b( z! M* `7 X
// If switching to 1/2 如果切换至1/2
' G7 A0 a/ _( f, Z" n8 o) r) B: x if((divsel == 1)||(divsel == 2))
+ t, }/ I L5 U8 M9 [7 ^ {
) D8 n! W" U. m, ~4 ~$ O EALLOW;9 b" J- a& O. V; ^
SysCtrlRegs.PLLSTS.bit.DIVSEL = divsel;# t- ~" Y$ E+ }+ w
EDIS;" u4 V5 ?: U% L3 D8 t$ F* s
}
b) L* V' E; t: G4 t A ! r. H- |" q j/ ]. c8 O
// NOTE: ONLY USE THIS SETTING IF PLL IS BYPASSED (I.E. PLLCR = 0) OR OFF
$ t* |9 L, D$ s9 u; G8 n6 c0 L // If switching to 1/1 如果切换至 1/1 ) |9 K' D/ Q5 z4 ]
// * First go to 1/2 and let the power settle- k, E. Z' k& h( K; F% r: u8 ~* z/ D
// The time required will depend on the system, this is only an example0 n+ E. V0 C, g
// * Then switch to 1/14 \3 P2 g3 G% F1 Q
if(divsel == 3)
; a' O0 Q9 j/ r+ R7 @) M' z6 k {
6 p" T- Y9 U! ~& S& e! F EALLOW;% B# X7 U/ `. K! U/ b
SysCtrlRegs.PLLSTS.bit.DIVSEL = 2;+ g# S* }8 {" b+ z I
DELAY_US(50L);
6 o5 D3 D. P3 ^: l: j. | SysCtrlRegs.PLLSTS.bit.DIVSEL = 3;
/ W" \! O, K% g7 q+ T S, n$ E EDIS;% N. \/ i- O: h7 C. J! A, h, [( `( E3 f
}' F: H9 w0 R9 d
}
9 w) R+ R, q/ g . t# N A. L3 W3 m) l }' ]
void InitPll(Uint16 val, Uint16 divsel)' z% e( K2 N2 Z. V# n1 k/ o. F6 e
{5 z* M8 S1 k$ P; B+ s' H( e+ N3 w
3 N& d# Q* u1 j
// Make sure the PLL is not running in limp mode1 Q- }$ z# b& q! e
if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0)
$ \3 R6 s: u) R/ P) [ {" l7 _& `, P5 x
// Missing external clock has been detected
% { G$ c- H$ _- Z // Replace this line with a call to an appropriate. Y8 f( D% A. {) Z5 A+ ^
// SystemShutdown(); function.
% U9 c6 q( k, u7 S5 @ asm(" ESTOP0");
6 f. `3 h( [ T i5 h8 y }
& n2 Y, I$ i# m) ?) G: J- ` 6 H/ I/ W+ }2 e3 J' _
// DIVSEL MUST be 0 before PLLCR can be changed from
5 h, t0 X0 S* s- p. E" `" G // 0x0000. It is set to 0 by an external reset XRSn/ y9 Q; q/ F6 _, \" ]
// This puts us in 1/4. E& C8 j" \& ~0 ]' t* M
if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0)
2 N# F, T& }) ] {# S8 G. t7 {- Z/ F. X) i+ H
EALLOW;
- T! O6 k$ E% v$ i: T SysCtrlRegs.PLLSTS.bit.DIVSEL = 0;9 H* H6 a l: {' V
EDIS;
: T2 Q& r2 b% ~6 o6 L; S1 C }9 b& l' W& w" R. o
: R) j. o. T$ n6 b! G // Change the PLLCR4 v" ?- R' }+ r. g4 c5 R' P' [! d5 A$ d
if (SysCtrlRegs.PLLCR.bit.DIV != val)
]0 B5 E8 i! T! c) \5 ~ {
8 r% _; b. _8 V9 u# t8 Z* B ; w9 l0 g) k2 G7 @9 A+ T
EALLOW;
5 |0 d, K$ d `- @# q/ a2 F // Before setting PLLCR turn off missing clock detect logic# g3 s- C& c" _$ h2 a% ^/ R
SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1;
) _7 Q! d; R7 s4 C SysCtrlRegs.PLLCR.bit.DIV = val;' T. d- J) i5 W
EDIS;8 @ `2 @/ G: D( F4 F9 m8 f7 d
! H( d" W# Z; t7 s: k9 w DisableDog();% d; {3 ]3 V9 h& M3 b, W0 `$ E
% P4 x6 J. A5 p+ _ while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1)
) \, u" l5 P4 Q. t* ]% G ]! N {
' T/ m/ j; ^; ~! R+ n7 n0 q$ L // Uncomment to service the watchdog# i4 S+ C4 @- H9 u/ I
// ServiceDog();( e, m4 K/ z! u1 [9 ~. a
}/ Q; D L4 t! ^& ^
; w9 ~3 J y4 J7 s# f EALLOW;& U; ^ U* T- ]+ d# K
SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0;
1 V3 j! o! w$ o* X+ {& ] EDIS;0 Q2 J9 J1 ], }
}4 e/ n t0 U* [. G$ M
5 Q* L+ {5 s9 }8 o6 ~* r; G3 K // If switching to 1/2
" H) O5 L- J5 r if((divsel == 1)||(divsel == 2))$ p& X! D7 G- u0 w! j+ o
{
4 G% `3 |$ e. A1 F EALLOW;! y0 J6 M2 F* q: U% p0 P$ e
SysCtrlRegs.PLLSTS.bit.DIVSEL = divsel;$ d! P! j- h' a! s8 K
EDIS;/ M7 w8 [( |4 c9 l
}6 e; l0 t* Q, C: ~ w: ^( U
! r# {7 Z) u' x1 p; Z# W+ S
// NOTE: ONLY USE THIS SETTING IF PLL IS BYPASSED (I.E. PLLCR = 0) OR OFF
& q! z9 T) D0 d A: `- T+ X/ U // If switching to 1/14 `1 c% w5 R4 I6 J+ l2 {+ \& ^
// * First go to 1/2 and let the power settle
" A4 P/ B/ e& R, G // The time required will depend on the system, this is only an example$ }; R) g) n' w/ t1 k
// * Then switch to 1/1
1 X8 L: o6 d( Z2 P* v4 w1 M9 T if(divsel == 3), x. n. Z3 Y; X6 U4 \
{
5 g5 F0 G& v6 j8 `4 W EALLOW;% V7 n) U4 k* A: P) O6 C
SysCtrlRegs.PLLSTS.bit.DIVSEL = 2;) Z1 x$ d h/ i R
DELAY_US(50L);2 D/ h8 q6 J. N6 P) n( u
SysCtrlRegs.PLLSTS.bit.DIVSEL = 3;0 h0 r% i/ i' _' _( Y
EDIS;8 a5 \( q3 e9 H0 S
}
) ~; m0 P' d. m6 h: [4 b( X. Q0 [6 C代码解释:
& o' e1 H. r( `% h: k6 m
5 r$ _5 I8 s) [+ ~4 [) A. y. F1、if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0),检测外部时钟是否存在,保证在外部时钟正常的情况下运行系统。
& p" C$ C* V% v/ I7 B+ R C
( D+ Z4 F* `& {8 F7 g4 S7 g2、 if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0),如果8~7位不等于0,则强制置为0。9 w! w F; {- C0 T
: d! r# ^4 y+ X3 Z; g8 h
3 \/ ~8 X7 W' F( a
5 e) e) e ^: ~- S4 f3、if (SysCtrlRegs.PLLCR.bit.DIV != val),如果锁相环控制寄存器PLLCR的3~0位不等于10实现10倍频,则使得锁相环状态寄存器MCLKOFF标志位为1,并强制置锁相环控制寄存器PLLCR的3~0位等于10。并且锁定锁相环,然后打开时钟丢失检测功能。0 o/ B& n9 O$ m* Y
7 |- ]9 R; K2 h% w: p0 S$ Y1 C( R 4、if((divsel == 1)||(divsel == 2)) 与 if(divsel == 3) ,配置锁相环的分频。通过查询头文件可以看到这两个值。证明系统默认的倍频数位10倍频,系统默认的分频数为2分频。
: i( p8 B( _5 J% R& I- B. I# O
3 ^2 Y1 F; O: |
; u5 S9 H5 W& ~7 @- F
1 w5 I& N' ]& N, ^+ J- E由于目前的生产工艺,晶振频率为30Mhz的晶振性能更优,配置外部晶振为30Mhz成为主流,因此选择的倍频数为10,分频数为2,30*10/2 = 150 Mhz ,这也是DSP28335主频为150M的由来。
) I6 e# }7 P1 L( B/ m5 ] ^0 @( q0 \' B( M9 ^1 n9 N$ i% M2 V% `
3、初始化外设时钟函数InitPeripheralClocks();
. d0 o3 b8 k i: Q f+ y) x3 s; h& ]在进行了外部晶振的倍频和分频后,芯片就要将自己的动力分配给各个外设,驱动各个外设进行工作,这个动力的分配就是初始化外设时钟函数的作用,函数代码如下:
6 \: G' W2 D1 F3 m6 X
( ^1 q! o9 k, G& @$ n/ ] o/ Ovoid InitPeripheralClocks(void)$ O- [6 ], V. f5 v! t
{1 O5 s' A5 O+ H" G5 Z
EALLOW;
: F x: D9 ?! u; v6 y# U$ n
2 Y, B. S* j1 h- B$ }" N// HISPCP/LOSPCP prescale register settings, normally it will be set to default values- V) r5 P- [0 Y- j$ c4 x
SysCtrlRegs.HISPCP.all = 0x0001;. Y* [# n% ^$ h; G+ X9 _* r
SysCtrlRegs.LOSPCP.all = 0x0002;
" I5 E( K1 H8 Y8 P7 t T , Z: ?! c) O- \1 n# W- ^1 O
// XCLKOUT to SYSCLKOUT ratio. By default XCLKOUT = 1/4 SYSCLKOUT
: M5 c3 ?3 ]; B' d4 {0 @7 [% k // XTIMCLK = SYSCLKOUT/2
5 U2 X9 h. c- J9 Y XintfRegs.XINTCNF2.bit.XTIMCLK = 1;
4 o) Z$ x" h. ?: L* C2 M // XCLKOUT = XTIMCLK/2- s$ @3 I0 u' u* M0 m8 b- ~! p: u( g
XintfRegs.XINTCNF2.bit.CLKMODE = 1;+ b& @" D, o* l/ L7 ]4 {, t
// Enable XCLKOUT
% k9 a) \- }' q- }8 ]3 V XintfRegs.XINTCNF2.bit.CLKOFF = 0;
- l0 V V; ]5 I( X% R 6 ?3 @! n! x* p
// Peripheral clock enables set for the selected peripherals.- I' K l; H! c. }+ C, K/ l
// If you are not using a peripheral leave the clock off# m- W: L9 Y) J$ m( D
// to save on power.
H& T. s$ b5 a0 t8 Q4 E1 Y//
# n: s: o! O- O# b// Note: not all peripherals are available on all 2833x derivates.
- ~0 l3 V6 {5 ]. j// Refer to the datasheet for your particular device.
- P( w* [; M/ b, t//+ e! k) }+ @( q" i/ w1 K
// This function is not written to be an example of efficient code.$ t& z, |; b2 m ^6 Y
$ {( w4 l+ B3 o
SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1; // ADC
+ u6 l. z4 P: h4 l" z8 `7 w* u5 K
7 j1 I) t2 u+ U% w0 F8 u* Z // *IMPORTANT*
) p9 p0 j, H, y5 r, V s // The ADC_cal function, which copies the ADC calibration values from TI reserved
$ T4 R# D7 }7 I$ ~ // OTP into the ADCREFSEL and ADCOFFTRIM registers, occurs automatically in the
8 j9 v' r n, H* M4 K" ^# `" S" W8 R // Boot ROM. If the boot ROM code is bypassed during the debug process, the ], _) v% i) t8 F1 l
// following function MUST be called for the ADC to function according# p- n2 y( ^1 w! X" v0 N$ O( s
// to specification. The clocks to the ADC MUST be enabled before calling this$ W9 p+ E0 O( ]: e$ \
// function.# c: P; Z! I! v* {
// See the device data manual and/or the ADC Reference! f; e. i8 L0 A8 g$ U# V
// Manual for more information.8 K6 Y" V8 X6 w
8 X% t# F7 [, B }* {, l; L" _
ADC_cal();
# y" L4 R4 b: J + W y" K' M8 B( T$ K7 v. U
2 z8 Y5 H& U2 s# e
SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 1; // I2C
2 w# X; q1 ^8 ~/ y& r1 E: _1 P SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1; // SCI-A
: ~. r ^0 r2 g1 a4 q SysCtrlRegs.PCLKCR0.bit.SCIBENCLK = 1; // SCI-B- }; F2 u0 o8 m8 w6 ?) ~
SysCtrlRegs.PCLKCR0.bit.SCICENCLK = 1; // SCI-C
% ~ q- y0 b+ ]" [+ V SysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 1; // SPI-A
' Q- V' S" G7 T5 \2 N SysCtrlRegs.PCLKCR0.bit.MCBSPAENCLK = 1; // McBSP-A3 g- e$ M7 l5 m$ {; ~) [
SysCtrlRegs.PCLKCR0.bit.MCBSPBENCLK = 1; // McBSP-B. l: w; u- j0 x4 X# D% A/ b( k
SysCtrlRegs.PCLKCR0.bit.ECANAENCLK=1; // eCAN-A
& s `0 |2 g# I" F0 `. X H4 ^ SysCtrlRegs.PCLKCR0.bit.ECANBENCLK=1; // eCAN-B1 R' D4 \. q& V
: [ {1 m. i; I/ G( |4 [5 x SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Disable TBCLK within the ePWM
8 L# \6 L% ~/ U$ U* V" M SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1; // ePWM1
6 s' g9 O# t8 i1 l2 V) s4 m SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK = 1; // ePWM2/ Z4 S) S# {( j! J
SysCtrlRegs.PCLKCR1.bit.EPWM3ENCLK = 1; // ePWM3
* Z1 p1 s0 K3 ^. z SysCtrlRegs.PCLKCR1.bit.EPWM4ENCLK = 1; // ePWM4
6 S9 f- N, J" c) l5 C Q9 v SysCtrlRegs.PCLKCR1.bit.EPWM5ENCLK = 1; // ePWM5" w! P; h5 Q, a1 d/ Y
SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK = 1; // ePWM69 J6 T: C$ a7 _6 u. z
// SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Enable TBCLK within the ePWM* ^- z3 X( h6 N' ]1 j M
2 y0 \+ w8 `. V6 \# P
SysCtrlRegs.PCLKCR1.bit.ECAP3ENCLK = 1; // eCAP3' [3 s l9 q% }
SysCtrlRegs.PCLKCR1.bit.ECAP4ENCLK = 1; // eCAP4
' k- o+ O8 ]6 a' Z1 _5 ] SysCtrlRegs.PCLKCR1.bit.ECAP5ENCLK = 1; // eCAP50 h/ O( r& v! V( M/ B, ?
SysCtrlRegs.PCLKCR1.bit.ECAP6ENCLK = 1; // eCAP6& \0 W$ V5 o: s" B/ {
SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 1; // eCAP1- G/ X' T. x. w% ?! J( S, C7 _. V
SysCtrlRegs.PCLKCR1.bit.ECAP2ENCLK = 1; // eCAP2
/ I3 Z- v [& r* q f SysCtrlRegs.PCLKCR1.bit.EQEP1ENCLK = 1; // eQEP1
. F( A. A; J7 ~& h y( l. ]7 p7 b7 B SysCtrlRegs.PCLKCR1.bit.EQEP2ENCLK = 1; // eQEP2
+ {1 v. L( u+ M0 K5 j4 D
4 J/ j" k4 {" Y SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 1; // CPU Timer 0$ Z2 y) ]5 X& O! N% n2 c# Z
SysCtrlRegs.PCLKCR3.bit.CPUTIMER1ENCLK = 1; // CPU Timer 1
/ b4 s* m3 W; z# V, _# m! Z) f SysCtrlRegs.PCLKCR3.bit.CPUTIMER2ENCLK = 1; // CPU Timer 2- c& x( n. @+ r8 h; e e# A7 h
5 w# v5 R# V1 z0 Y) P# W" E$ Y: r
SysCtrlRegs.PCLKCR3.bit.DMAENCLK = 1; // DMA Clock5 J( P6 ~9 Q1 ^& o5 K4 P
SysCtrlRegs.PCLKCR3.bit.XINTFENCLK = 1; // XTIMCLK
; y* h! i2 \7 T! h- n0 p SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1; // GPIO input clock! f$ T! S- }+ n7 h
) i' m' |+ v2 l7 [+ u8 @5 } EDIS;
8 ~$ A6 b( Y6 l" r! ~0 y}
/ U& U0 K2 C9 w3 Z3 @7 j 代码解释:
1 k R3 l( Q4 v
8 ~) Y/ @* |1 H/ F$ j: V& \1、SysCtrlRegs.HISPCP.all = 0x0001; 设置高速外设时钟分频 = sysclk / 2。* q- i; g& p$ O+ ~
& {- H& o& G7 f" p+ h9 ~
@7 f6 ^8 p4 _( u8 M
2、SysCtrlRegs.LOSPCP.all = 0x0002;设置低速外设时钟低速外设时钟分频 = sysclk / 2,这里命名稍微有点出入,但是查询头文件后确实是这个功能。只不过换了一种方式表示。本来我以为我很细,但是发现是我很粗,错过前一句的命名风格,实际就是这么命名的。
" n8 p! }) U) z0 t3 r. ]' H1 S1 [8 M+ b. \9 X
! X/ q3 o$ y1 y0 h( e6 {
) y+ Q* k+ K0 T5 t5 }6 A( U, y9 |7 [$ w1 F8 J$ {. k
8 @# `& c; r' z% ?% n2 E3、XintfRegs.XINTCNF2.bit.XTIMCLK = 1;配置外部存储器的时钟为默认状态。' ^) q; N3 y% _$ _' b; p
2 S9 H2 }" n% n
9 M3 b/ M. `2 A4 Y; w/ m0 _
5 P" W+ @1 l3 A5 `" y
4、XintfRegs.XINTCNF2.bit.CLKMODE = 1;外设时钟频率控制位,并配置为默认。
/ j. ]- a, K% U+ v2 j& e. `, P/ r8 U4 N0 }9 N% Y: ` D
' C- s9 c. n& y% S+ _' E& Y
5 P5 ]8 d. H2 p4 _7 E* W- Z5、SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1等; 外设时钟使能,这里的外设时钟控制寄存器PCLKCR0控制片上各种外设时钟的工作状态,使能或者禁止,也就是说这里控制着外设的各个时钟的关闭和开通。# ^! {$ H: Z9 H, |
" F2 ] `$ ]- p% u; A& K) f( Y# @
小结:
+ S" J, r: ~: y* l3 u通过这个系统初始化函数,我们能够得到几个关键的信息:3 ^: p: x6 |; G( n
+ h( ^8 b- F; [2 X/ }0 c# E4 B
1、外部晶振为30Mhz,经过锁相环PLL的倍频和分频操作可以得到DSP28335的主频150Mhz。( N) J6 [ w/ p* {$ L | v/ z
4 r( z* t6 V2 ~' J4 p: e% ?3 {! R* `
2、在初始化函数中,能够选择打开或者关闭各个外设时钟,并且可以配置频率大小。7 q+ P' ]% k5 ` i( q( ~8 [7 `
$ a: K6 q- u3 _) h! _( B5 Z
说实话,在梳理这个初始化程序的过程中,其实好多次想撤退,心里想着反正这些都是固定好的,也不会更改其中的参数,我为什么要花这么多时间去看这个呢,但是咬着牙看下来了。看完之后其实我觉得收获还是挺大的,特别是DSP的主频150Mhz是怎么来的这个点。说来惭愧,用了DSP好久,只知道主频是150Mhz,还真不知道是经过PLL分频又倍频来的,有不有用?我感觉其实还是有用的,我们对需要从事的工作有了更一份的了解,这就有用,也希望自己在日后的学习过程中,刨根究底,不偷懒不粗略,细不细?不够细啊!忍不忍得住,那必须忍得住啊。
5 B. I5 ^& C5 F6 {) Z0 ` _( x—3 `2 C* o# j7 t% ]4 n
|
|