|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
近日工作中又涉及到了DSP28335的应用,看来TI的芯片还是得到了公司领导的认可,也直接丢了一份DSP28335的FOC程序给我理解。以前读书阶段较为简单的接触过一段时间,对DSP28335的基础功能部分有了一些浅显的了解,现在工作中要实际开始用了,开始发现之前学习的程度还是不够,因此要更加深入的探究一遍。可能非常基础,希望大家也不要见笑,人真是年龄越大忘东西越快。9 H7 s- o; C2 |1 _8 t' ]' {) `
, E0 B! a. e) N3 X2 H系统初始化
- \7 |3 Z2 j( ~首先从系统的初始化开始,系统初始化主要是系统时钟、看门狗等功能模块的基础配置,TI官方配置的系统初始化函数如下:
2 _0 m( y; T( p( q9 j' b: g5 ^7 G k: k/ i2 C% P6 u
void InitSysCtrl(void)8 A. P9 F: R0 E3 A6 Y
{; t* B! y) P+ m3 O v$ t& t. u
: [* A8 @- {2 i0 W // Disable the watchdog- K6 g: c3 K2 P; `* _4 E# }
DisableDog();
; Z: M; g) n4 |) D& d9 P% c0 ` 1 ]1 }2 d( K0 r% l3 x
// Initialize the PLL control: PLLCR and DIVSEL
1 P% h. \4 ~ P$ `" o6 L: F: k% m // DSP28_PLLCR and DSP28_DIVSEL are defined in DSP2833x_Examples.h( h0 e! G! h+ I/ v8 f' E' X
InitPll(DSP28_PLLCR,DSP28_DIVSEL);3 F( ^$ j; F- ]) F( j" }
( L; w9 A" u. O% o // Initialize the peripheral clocks! J" B- \! s J
InitPeripheralClocks();
0 W$ v* }+ }6 q! Q0 m7 Y6 i7 E}
( ]& Q+ k3 v4 Y( E4 x4 v" y上面代码主要由3个子函数构成,分别为 DisableDog();、InitPll(DSP28_PLLCR,DSP28_DIVSEL);、 InitPeripheralClocks();这三个子函数的功能我们也来一一分析。( m7 W0 Z7 t! P% h& F9 E/ N
+ v7 ~6 X+ H) Q# F3 J5 i i) y看门狗配置函数DisableDog()
. y6 Y# H4 ]6 t首先是开门狗初始化函数DisableDog(),函数代码如下:& U X: S$ P5 i7 K0 n; a
, n/ i* p# d: u; J( v" \$ A- evoid DisableDog(void)
) u5 o0 f' I: t% V{
0 V" G: M# z2 o% J EALLOW;
) K8 k$ |$ E8 ^+ R* O4 l SysCtrlRegs.WDCR= 0x0068;- ?8 a4 t: @2 q1 h* f7 Q
EDIS;$ T( |2 ] t+ f: E
}$ n: f2 A, c5 i9 Z' Q
代码解释:
3 |) h* ?) `5 w. h6 ]( d
% f( r/ A+ I& q1 q% C" P1、EALLOW /EDIS 打开/关闭状态寄存器保护。EALLOW/EDIS 是DSP为了防止杂散代码或指针破坏关键寄存器的状态宏定义指令,关键寄存器包括ePWM、Flash、器件仿真寄存器、FLASH寄存器、CSM寄存器、PIE矢量表、系统控制寄存器、GPIOMux寄存器等,这些寄存器的状态决定DSP是否稳定运行,因此需要修改之前应用EALLOW打开保护,修改完后必须用EDIS关闭。
$ J6 u# d$ F2 J0 v# {7 V0 L4 d; u7 _$ n) z& h* u
2、配置SysCtrlRegs.WDCR寄存器为0x0068。关闭看门狗,也可以戏称为把狗杀了,好残忍,看门狗的实际作用就是防止CPU跑飞或者其他故障导致系统出现不可挽回的故障,如果一段时间收不到CPU稳定运行的信号就会复位CPU,从而保证CPU的稳定性。打开WDCR寄存器表可知,寄存器后8位起到实际作用,0x0068 = 0110 1000 ,第7位置0看门狗不满足复位条件,第6位置1禁止看门狗模块,第5~3位写101强制写,第2~0位写000配置看门狗时钟。关键为第6位置1禁止看门狗模块。& F! s) O d2 B7 w: d$ ^9 X
$ I6 _) u- H4 \' G6 ~; x) [) l" y
, b8 n- \, U) r L w8 s
9 |: S/ T2 h2 k2 o' s锁相环初始化函数 InitPll(DSP28_PLLCR,DSP28_DIVSEL)
) [$ ?) z; n# i8 T* j6 A其次是锁相环初始化函数,在DSP中锁相环函数主要是用在时钟的分频上,将晶振产生的震荡进行分频和倍频操作,是整个芯片心脏——时钟能够起作用的关键之处,因此必须在程序开头对其进行配置。其代码如下:$ j% H! V, ` H* [+ J: x; B
/ R5 ?( @8 {5 X/ e4 ?void InitPll(Uint16 val, Uint16 divsel)7 n6 J% `3 R2 {+ S5 U {
{8 M: J- b7 E l; ~2 }
6 B9 s* j: g5 ]! \" T0 x // Make sure the PLL is not running in limp mode 确保PLL没有运行在故障状态
: |, @: [( @3 ]6 K% W8 R if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0)
7 d w. i1 c& m. r* { {$ {( J7 j l9 d) c
// Missing external clock has been detected
, S3 @8 W4 C5 I% X; Q0 ~) G // Replace this line with a call to an appropriate
[5 ?2 O! B0 @! H& T // SystemShutdown(); function.
3 G4 d9 `! u* E6 `* _0 T8 W% k" G // 若检测到系统失去外部时钟,则关闭系统
1 m' [5 L" C$ l3 y4 o, b+ ?* D asm(" ESTOP0");
" X& {1 G1 f# A0 |7 q+ H# q }
+ B2 f5 J1 F6 v7 b f
8 I- T" j$ a& u7 h; Z0 J, \ // DIVSEL MUST be 0 before PLLCR can be changed from 在PLLCR可以从更改前,DIVSEL必须为0
8 C$ I% v2 ]( M+ @2 C( r. ^ // 0x0000. It is set to 0 by an external reset XRSn 通过外部重置XRSn将其设置为0
( b8 _2 `; y' M6 ^0 F // This puts us in 1/4
" L* R( w; I! ^" S l if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0)
* E0 {2 w5 |3 d0 d9 R {! z# i* D5 K& D" v) e
EALLOW;7 Z, r8 e0 `! {- O, K2 T
SysCtrlRegs.PLLSTS.bit.DIVSEL = 0;6 M4 w4 E4 e( d1 g
EDIS;
( u. K5 Z! j8 `+ F; R3 } }
& u! t- S* X, c$ i8 {
$ @( q. {4 z$ \- R) d8 C // Change the PLLCR 更改PLLCR
& q; V+ Y9 ^- r# U9 B' u0 ` if (SysCtrlRegs.PLLCR.bit.DIV != val)
+ K+ ^; q W. Y; H$ H: ? {
* o8 }( W; m# s' {( o" a 6 D# W' X4 H- V$ M: x& L7 m/ w3 O. y
EALLOW;' V" J% i( W% h/ L1 D3 m( u
// Before setting PLLCR turn off missing clock detect logic 在设置PLLCR之前,关闭缺失时钟检测逻辑* V, _+ s+ J0 X" j" j
SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1;6 f8 P, G4 [. z) M" d8 C6 l1 L
SysCtrlRegs.PLLCR.bit.DIV = val;
1 a" f8 r( W% d EDIS;$ N3 a2 I4 P4 V& j- |5 w
1 x, Q* m1 ?- w- S7 }% A DisableDog();9 s( P: W( o% S# ^, C
/ e5 z; |9 I- O' V0 W
while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1)$ x; o H: d/ m0 F
{6 m( |, S" f( ]& H& d. t# h
// Uncomment to service the watchdog* n( t6 N* P7 R
// ServiceDog();
1 X. p/ d4 k" R3 D }
# z* y' Z* }& h, I
2 U% @# x4 q% ^7 @2 X EALLOW;
8 `$ i0 h* v) A2 `8 S, s- b SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0;
, b! c, l* h) u: Q8 X- o EDIS;0 [, K5 W. y; M7 r. X* L
}4 | ?4 x' c$ {8 L9 }# L( ^5 l
1 y; `0 O6 w A3 j) r* l // If switching to 1/2 如果切换至1/2! B: I& ~& w& W" H, [8 _, v3 h, l
if((divsel == 1)||(divsel == 2))
4 L; Z, E( M: [ {
! n x) c- c$ x3 J) k- B$ t EALLOW;8 O+ ~2 [0 F1 v
SysCtrlRegs.PLLSTS.bit.DIVSEL = divsel;
/ _2 a8 o1 m. E. L$ A EDIS;! o4 R# u" E' n2 q* {
}1 a5 `7 |$ a1 I% s6 f
; }5 n& V* _2 B* c. q2 Q
// NOTE: ONLY USE THIS SETTING IF PLL IS BYPASSED (I.E. PLLCR = 0) OR OFF
; p/ L% p# Y6 z- S/ F0 O2 i: ~ // If switching to 1/1 如果切换至 1/1 3 s8 P; J4 f+ ?* v; g+ K$ w4 t+ Z
// * First go to 1/2 and let the power settle
1 n% e; |9 J1 \% n! N // The time required will depend on the system, this is only an example% i6 P# m+ E. r7 p. D1 F4 }. D
// * Then switch to 1/1, o3 a, U* d5 C$ H: I% D1 G
if(divsel == 3)
& E9 i" j( C6 T/ q2 v {- N% C" m% o7 Q( Y; E% g
EALLOW;
3 [6 w& ~. A, ]! M) d2 Q j8 b+ O; t SysCtrlRegs.PLLSTS.bit.DIVSEL = 2;
' d$ b3 ~3 H4 k8 T DELAY_US(50L);
( T' P3 d7 Y: ~ SysCtrlRegs.PLLSTS.bit.DIVSEL = 3;
5 F+ Y" r( Z w$ ?, @ EDIS;4 f! Y- j# c8 T# D9 D
}7 P. T& b! G# t9 m, w
}
9 D9 s& I1 [5 s % T0 ?+ n1 G$ w& a
void InitPll(Uint16 val, Uint16 divsel)
5 }& K! T1 I q( h{
% w, |) o; ?3 M. M
8 J# K W7 {" V) V. K1 z* W // Make sure the PLL is not running in limp mode9 J& @6 ]1 l/ L# C
if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0)# l3 m; b x ]/ Z9 E: W
{' x9 y. k: u. M6 H4 k4 h) e
// Missing external clock has been detected& g4 t4 G. A: c4 Y3 l1 ^
// Replace this line with a call to an appropriate) H2 x. B: v5 n0 x) S9 c- e+ P
// SystemShutdown(); function.
3 z& W( E& j# [( ~3 {8 p asm(" ESTOP0");
7 i7 b' l/ w* \$ D9 Q }
' i% ~# L+ x; A" D* Z- I; @ 9 |) o9 }9 B: z! _6 A7 t
// DIVSEL MUST be 0 before PLLCR can be changed from
- U4 u; v. A/ d- }) b# H // 0x0000. It is set to 0 by an external reset XRSn
0 W" `2 C4 W2 v- O4 c // This puts us in 1/4
7 Y1 r! a8 V" i: W+ J) m% M# R/ l if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0)
! H5 A3 _, v2 _ {9 B# W+ t, `2 B# r& u$ m% ^3 h
EALLOW;' h4 |4 o* S2 @
SysCtrlRegs.PLLSTS.bit.DIVSEL = 0;4 _ A/ X! v# g/ g& Z
EDIS;
: Z9 I7 D. H1 q$ D* E, P }, t9 W1 ?. B) g2 s
7 U* a7 t# ^1 W& k! s m% j
// Change the PLLCR2 u' ^' j- { P, x9 }, ]2 `
if (SysCtrlRegs.PLLCR.bit.DIV != val)- P! ^- k& b, P! G$ c
{! l2 ?5 Y9 k) E% s
8 m: m9 Z u0 x$ {& z2 g EALLOW;
; H$ Y4 N0 ~1 ]; Z: l# K' y& S // Before setting PLLCR turn off missing clock detect logic4 V8 x, H* I$ f. e- b: j/ C! q
SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1;
- k; L& l9 o k: u! a; I SysCtrlRegs.PLLCR.bit.DIV = val;
?* [) e& A# K% e- Q EDIS;4 |! F% d. O0 O# N }
P- G7 |+ a4 `" A6 v# ~" F
DisableDog();; H& \+ z0 }: x2 {; Q/ ~0 Q
- s, X. ~& ?1 x7 |. G- }# e
while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1)
( _- [6 x _& |9 N {! s! j4 z5 d2 n [0 o2 b
// Uncomment to service the watchdog. D- y) ]0 ]5 b
// ServiceDog();
; ?% d) j0 W; ` Y$ y }
/ K% C, i Q/ A3 f 1 D1 |/ s h" b6 @) l
EALLOW;
" t, u$ C* w- V% z- q; \ SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0;
9 l' ^ ^5 G: m% T8 _' B4 }' ~& a+ m EDIS;
/ T1 g0 q: P& z& V }
4 }* a5 o# e6 b L n) U7 [ 6 Z- d0 `! X+ ^8 R4 j9 G3 [
// If switching to 1/20 V# P ^8 d6 x2 G' M
if((divsel == 1)||(divsel == 2)); Z9 d0 H8 n" R: \
{0 J) v3 B1 l3 K5 o- B
EALLOW;
, e$ G- Y" c+ `* J9 I- O# p0 } SysCtrlRegs.PLLSTS.bit.DIVSEL = divsel;* V2 o' s" S3 y+ d6 Q
EDIS;
3 N) H* O) r* u: J- @4 E. n7 h, d; @ }0 D* R$ }* s; M. S" M/ x7 B
; B5 R# B: @. q3 d3 _/ Z // NOTE: ONLY USE THIS SETTING IF PLL IS BYPASSED (I.E. PLLCR = 0) OR OFF
6 Y/ i0 Z6 b& D2 u // If switching to 1/1. q4 b+ d: |/ K4 q+ \9 {% ?
// * First go to 1/2 and let the power settle: v' r7 q- e8 }* ]* N8 @# |$ H" ^
// The time required will depend on the system, this is only an example/ J3 |) V2 o# H; u+ g& s
// * Then switch to 1/1
5 i7 y" d6 ^. o" W1 X' J if(divsel == 3)/ @3 N; W. h* K5 e9 K' S+ W
{7 G4 ^$ t% W6 u: m, H4 l) Z: A
EALLOW;5 I/ x# e! J6 c* |3 K: H8 J. a* n
SysCtrlRegs.PLLSTS.bit.DIVSEL = 2;. G' z; X$ p& v; z
DELAY_US(50L);1 O. }3 w1 m8 U. a
SysCtrlRegs.PLLSTS.bit.DIVSEL = 3;
2 F% l# J% U$ ?" I! w! g' u& j* O2 o EDIS; B2 k, c1 Q' L& H' h: R3 }3 L
}
- x% Z- F- W. f& J代码解释:2 Q; V3 E- f1 t8 V% F0 Z
8 B! U0 S) K" K! b
1、if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0),检测外部时钟是否存在,保证在外部时钟正常的情况下运行系统。
7 ?* g3 i1 Z2 }. M8 n
' l5 ~+ X# [; b9 Q: Y( U3 \2、 if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0),如果8~7位不等于0,则强制置为0。
# ^+ F/ J3 D: x `. G
6 B# X# f+ C# C4 o6 n+ t( h4 j- ?0 N/ P! C7 X m, X
+ V+ A" D! J% t0 V- i( M
3、if (SysCtrlRegs.PLLCR.bit.DIV != val),如果锁相环控制寄存器PLLCR的3~0位不等于10实现10倍频,则使得锁相环状态寄存器MCLKOFF标志位为1,并强制置锁相环控制寄存器PLLCR的3~0位等于10。并且锁定锁相环,然后打开时钟丢失检测功能。* J$ T/ K/ A8 H5 t% D+ _* H8 k4 N
) |, ?# }& M5 H* V
4、if((divsel == 1)||(divsel == 2)) 与 if(divsel == 3) ,配置锁相环的分频。通过查询头文件可以看到这两个值。证明系统默认的倍频数位10倍频,系统默认的分频数为2分频。7 o" L h3 I5 c) t Y$ } R+ w
" E! m# n, [) I1 N# ]; P, V
1 m8 P8 S) D% J& ^2 h! U" a# B
$ ~7 ?$ i2 [# ~- X) z6 G由于目前的生产工艺,晶振频率为30Mhz的晶振性能更优,配置外部晶振为30Mhz成为主流,因此选择的倍频数为10,分频数为2,30*10/2 = 150 Mhz ,这也是DSP28335主频为150M的由来。
6 v7 T: G( w6 V- Y6 C2 c4 \4 F1 d
8 A! p2 T% T( ?' ]# N3、初始化外设时钟函数InitPeripheralClocks();
# ?1 k# p( Z3 \$ r) g在进行了外部晶振的倍频和分频后,芯片就要将自己的动力分配给各个外设,驱动各个外设进行工作,这个动力的分配就是初始化外设时钟函数的作用,函数代码如下: C' S8 K: Y1 K6 b1 n- n! c
/ u* v" y; s% S3 k Y9 m4 |9 fvoid InitPeripheralClocks(void)% a% c7 U& n/ V8 c7 n4 w
{
- Q' _5 q8 u n# f EALLOW;4 X+ c% Y- ^1 v
! _! K6 G9 Y7 h0 N( R6 o; m5 H
// HISPCP/LOSPCP prescale register settings, normally it will be set to default values
7 a6 z/ O6 R0 L0 e' B! {5 y- O( X+ F4 ^ SysCtrlRegs.HISPCP.all = 0x0001;& U. _( i- l: p$ r+ T! h; \% `
SysCtrlRegs.LOSPCP.all = 0x0002;- a2 F2 a- _, Y4 [$ m9 L0 f
4 Y* r0 K3 l$ j3 v( m; g
// XCLKOUT to SYSCLKOUT ratio. By default XCLKOUT = 1/4 SYSCLKOUT0 H; F; e1 \7 l
// XTIMCLK = SYSCLKOUT/2# ]! T1 U, X0 d7 ~" {
XintfRegs.XINTCNF2.bit.XTIMCLK = 1;- n7 G w$ c) M( w1 P* U( {! D
// XCLKOUT = XTIMCLK/2
" `2 G* f' I" _. c& b XintfRegs.XINTCNF2.bit.CLKMODE = 1;
) M* }1 ]8 w6 s! Z8 x0 N3 n c // Enable XCLKOUT
+ E$ H' Y1 J( |: m$ X. Y7 i& H XintfRegs.XINTCNF2.bit.CLKOFF = 0;
0 M7 R: w9 @3 R, Q1 B
$ y( O9 h4 W2 W" X$ u8 W6 \! A// Peripheral clock enables set for the selected peripherals.: n6 j& ~/ ^. E$ n' Q2 d, W
// If you are not using a peripheral leave the clock off
8 K: C# n* [' R( i// to save on power.* z/ [! h: Z$ ]# }
//
% W# n; H5 ^4 `- N, Z- t// Note: not all peripherals are available on all 2833x derivates. z/ g2 B" Q( n' Z3 Y
// Refer to the datasheet for your particular device." n2 k7 X6 K9 Z0 m
//; |0 P$ r% [" Y- t5 J* L
// This function is not written to be an example of efficient code.
* |3 U3 I3 @( h$ P8 n4 {' t
" |, @4 [% r# `( a0 o$ ]* D SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1; // ADC
2 g3 {$ Z# A- X& e' V : X' O( @6 ]6 }" K7 N# C
// *IMPORTANT*
- E1 T+ ?9 t3 n3 X" O% A/ Q+ @ // The ADC_cal function, which copies the ADC calibration values from TI reserved: T; U5 G& E; A' \& l4 F
// OTP into the ADCREFSEL and ADCOFFTRIM registers, occurs automatically in the
3 ~5 M" Z; v0 N% |' o% w // Boot ROM. If the boot ROM code is bypassed during the debug process, the
/ ]6 V$ q" N+ f+ R6 @# @2 e) G7 t // following function MUST be called for the ADC to function according
3 _ g/ q* N; ]9 E! p0 Z // to specification. The clocks to the ADC MUST be enabled before calling this# B7 l# [ s5 @2 O3 @- ^) i
// function.
. d$ U- x: q9 `( N5 W7 s // See the device data manual and/or the ADC Reference
8 H9 P/ f4 l, n7 B6 I0 R // Manual for more information.2 S$ x0 I1 r0 N
1 I; ^4 x0 M7 j: j; R# E, }2 A2 Q
ADC_cal();
9 a" `! E1 r8 l6 ?% U & w5 _2 b8 L6 U
. r0 K9 ]* E4 ]. ^. w
SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 1; // I2C
% K) k* _1 W: Z; e8 O SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1; // SCI-A" t& G) Y' ]4 W ?
SysCtrlRegs.PCLKCR0.bit.SCIBENCLK = 1; // SCI-B
8 M# \; a; }- |. V& \) z SysCtrlRegs.PCLKCR0.bit.SCICENCLK = 1; // SCI-C
: [' S0 S% v3 W. B SysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 1; // SPI-A0 t* u+ N- m+ H" D4 u- H
SysCtrlRegs.PCLKCR0.bit.MCBSPAENCLK = 1; // McBSP-A
1 Y; C$ S8 s" R- \" k( B7 m' Z: m% l SysCtrlRegs.PCLKCR0.bit.MCBSPBENCLK = 1; // McBSP-B1 \% Z* K! M7 H
SysCtrlRegs.PCLKCR0.bit.ECANAENCLK=1; // eCAN-A
( ?; N! J; b, ^. b SysCtrlRegs.PCLKCR0.bit.ECANBENCLK=1; // eCAN-B
1 K/ e; |1 D9 ~- n
2 n6 a% [ h% A' W SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Disable TBCLK within the ePWM
+ j& z; A0 X6 h! B8 Y2 ^ SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1; // ePWM1- i1 \' K4 t" k) n# t
SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK = 1; // ePWM2
' q. O6 a' t0 I SysCtrlRegs.PCLKCR1.bit.EPWM3ENCLK = 1; // ePWM3
( O7 d) L% K, L& H( O SysCtrlRegs.PCLKCR1.bit.EPWM4ENCLK = 1; // ePWM4
" X8 F! e1 z8 T( [- ^( |" n SysCtrlRegs.PCLKCR1.bit.EPWM5ENCLK = 1; // ePWM50 c0 C* `0 {% x0 p
SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK = 1; // ePWM6
1 I8 h6 q9 V% \. w // SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Enable TBCLK within the ePWM3 ~( W; E9 v2 {$ B/ q% h( a
6 l. I$ E. w2 L3 C: x9 I9 S8 O SysCtrlRegs.PCLKCR1.bit.ECAP3ENCLK = 1; // eCAP3- J L3 d! a; U" h/ P
SysCtrlRegs.PCLKCR1.bit.ECAP4ENCLK = 1; // eCAP43 |4 R! m4 B9 ^' Y& Q
SysCtrlRegs.PCLKCR1.bit.ECAP5ENCLK = 1; // eCAP5. c& P* u8 }6 `8 e0 W ` D
SysCtrlRegs.PCLKCR1.bit.ECAP6ENCLK = 1; // eCAP6
) L) u$ {# U, V4 s SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 1; // eCAP1
9 x5 D9 S! W9 @( u9 x SysCtrlRegs.PCLKCR1.bit.ECAP2ENCLK = 1; // eCAP26 P, g2 n( d# o: o& F
SysCtrlRegs.PCLKCR1.bit.EQEP1ENCLK = 1; // eQEP15 b; d! c; m; m" t, i
SysCtrlRegs.PCLKCR1.bit.EQEP2ENCLK = 1; // eQEP2
1 f! ?. q: M; m$ y
, i/ _% r! A) j$ N% L SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 1; // CPU Timer 0
) \8 D7 e0 O; U9 Q! c) W$ b" C SysCtrlRegs.PCLKCR3.bit.CPUTIMER1ENCLK = 1; // CPU Timer 19 _' P6 k0 m* I/ c0 C6 O8 w7 ?
SysCtrlRegs.PCLKCR3.bit.CPUTIMER2ENCLK = 1; // CPU Timer 2
1 J2 D$ _0 x [1 v: \, n/ y
) b3 s9 \8 w! P s' V+ L SysCtrlRegs.PCLKCR3.bit.DMAENCLK = 1; // DMA Clock
. k5 b6 ?7 s& F6 h$ M7 C SysCtrlRegs.PCLKCR3.bit.XINTFENCLK = 1; // XTIMCLK
6 R" k1 V2 `' A: I' s SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1; // GPIO input clock1 I" f1 |. K6 W
2 k: v4 V7 O- [" l) k
EDIS;7 t/ h' Q. ]0 h/ }+ x4 r8 J
}# j. a; ^* h( ?# d
代码解释:
( E' x8 j: `* V
) }3 n* t+ M7 M' i8 w# n; T1、SysCtrlRegs.HISPCP.all = 0x0001; 设置高速外设时钟分频 = sysclk / 2。
, J- e; g5 `$ r; P% w5 i) q! p) [* X F& L5 m) v5 W
1 w# C( `+ G0 t T6 F1 ^
2、SysCtrlRegs.LOSPCP.all = 0x0002;设置低速外设时钟低速外设时钟分频 = sysclk / 2,这里命名稍微有点出入,但是查询头文件后确实是这个功能。只不过换了一种方式表示。本来我以为我很细,但是发现是我很粗,错过前一句的命名风格,实际就是这么命名的。& ~) D2 i, K: U8 q6 x" q. X% D) ]' _
5 h" |8 J2 T ^( |! u; e
* ^) H$ K+ ?, x' Y1 w3 d5 _- W' l
" M' l2 C" Y6 q) j7 a& m
# f% \& R# D5 k I2 w9 P+ _4 }: A. |: I# H7 q Q
3、XintfRegs.XINTCNF2.bit.XTIMCLK = 1;配置外部存储器的时钟为默认状态。8 ?% L% m6 @2 e
) K$ |& g& u$ B& p' V1 W
7 n2 O) E: b5 b: w2 G8 D5 `# X2 p J: d* y2 M+ |
4、XintfRegs.XINTCNF2.bit.CLKMODE = 1;外设时钟频率控制位,并配置为默认。
/ |+ w" s, y* C% z6 Y$ Z
5 X. m2 s( I& R
8 N1 z3 z' h, ^& l4 W5 V& t% U3 Q5 l9 C# Q
5、SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1等; 外设时钟使能,这里的外设时钟控制寄存器PCLKCR0控制片上各种外设时钟的工作状态,使能或者禁止,也就是说这里控制着外设的各个时钟的关闭和开通。/ O; {4 }; m& V$ _, C2 J
* b7 P2 f3 ^1 i小结:2 B1 G k# a4 Q2 o- A* R# X2 E
通过这个系统初始化函数,我们能够得到几个关键的信息:
- V* S3 G/ r% I' u h1 x6 t4 ]: [/ l6 M* A* W4 R
1、外部晶振为30Mhz,经过锁相环PLL的倍频和分频操作可以得到DSP28335的主频150Mhz。
5 c8 o6 m9 n; U. j8 O u$ N& B
1 _* Z* H* \+ ~' s2、在初始化函数中,能够选择打开或者关闭各个外设时钟,并且可以配置频率大小。8 l1 b" p$ y z: p8 v
$ W/ o% Q, @' v$ P说实话,在梳理这个初始化程序的过程中,其实好多次想撤退,心里想着反正这些都是固定好的,也不会更改其中的参数,我为什么要花这么多时间去看这个呢,但是咬着牙看下来了。看完之后其实我觉得收获还是挺大的,特别是DSP的主频150Mhz是怎么来的这个点。说来惭愧,用了DSP好久,只知道主频是150Mhz,还真不知道是经过PLL分频又倍频来的,有不有用?我感觉其实还是有用的,我们对需要从事的工作有了更一份的了解,这就有用,也希望自己在日后的学习过程中,刨根究底,不偷懒不粗略,细不细?不够细啊!忍不忍得住,那必须忍得住啊。
; o; H" n3 i# F, }—
% H7 f9 k2 G8 |% g+ j8 L& ?0 ~7 c' d |
|