Systick的两大作用: 1、可以产生精确延时; 2、可以提供给操作系统一个单独的心跳(时钟)节拍; 通常实现Delay(N)函数的方法为: for(i=0;i<x;i++) ; 对于STM32系统微处理器来说,执行一条指令只有几十ns(纳秒),进入for循环,要实现N毫秒的x值非常大;而由于系统频率的宽广,很难计算出延时N毫秒的精确值;针对STM32微处理器,需要重新设计一个新的方法去实现该功能,以实现在程序中使用Delay(N); cortex的内核中包含一个SysTick时钟,SysTick为一个24位递减计数器;SysTick设定初值并使能后,每经过1个系统时钟周期,计数值就减1;计数到0,SysTick计数器自动装载初值并继续计数,同时内部的COUNTFLAG标志会置位;触发中断(前提是中断使能); 如果外部晶振(即外接的晶振)位8Mhz,经过内部9分频;系统时钟则为72Mhz(cpu的时钟);SysTick的最高频率为9Mhz(cpu时钟的8分频);在这个条件下;如果设置SysTick值为9000;而SysTick是9Mhz;则能产生1ms的时间基;即SysTick产生1ms的中断;
7 ~3 z1 F+ M6 b9 g* Y" Y3 N SysTick相关的寄存器: CTRL: SysTick控制和状态寄存器; LOAD: SysTick重装载值寄存器; VAL: SysTick当前寄存器;(重新写入的时候;会把状态寄存器的FLAG清零) CALIB: SysTick校准值寄存器; SysTick设置步骤:(使用ST的函数库使用Systick的方法) 1、调用SysTick_CounterCmd()失能SysTick计数器; 2、调用SysTick_ITConfig()失能SysTick中断; 3、调用SysTick_CLKSourceConfig()设置SysTick时钟源; 4、调用SysTick_SetReload() 设置SysTick重装载值; 5、调用SysTick_ITConfig() 使能SysTick中断; 6、调用SysTick_CounterCmd() 开启SysTick计数器;
4 d% m' d Z9 v- /*Include---------------------------*/; Z" @' U) G, ]( B' M F
- #include"stm32f10x_lib.h" //包含所有的头文件
5 f" _# S0 B7 q/ ^ - #include<stdio.h>7 g% q$ R8 ^5 t4 z0 l# z
- A4 H% a5 N" G7 Z% }' }3 ]5 ?6 m
- //----------------函数声明--------------------; m/ T) H* z% }0 k! F3 G4 v5 f
- void Delay_MS(u16 dly);
9 A1 D3 ?0 u u4 ^ - void RCC_Configuration(void);
& @9 ?2 C! K9 w: k - void GPIO_Configuration(void);' F% \ c1 A9 ]. j
- void USART3_Configuration(void);' e+ E( z5 P' Q; \" y$ ]- k
- , c6 G* i/ X6 V$ X- Y, g
3 |! i5 U' n6 |6 P B' b; \- u8 tab[] = "hello welcome to class !";9 ^/ C2 K' s1 t% J. c
! N6 |) n( I3 F4 t2 Y- void SYSTICK_Configuration(void)1 }$ g2 D! ~0 S: M% Q7 A
- {
$ U! {/ P3 q$ K% n/ i. s. j - SysTick_CounterCmd(SysTick_Counter_Disable);2 o% f: S) s9 |, d' Q* i0 Q
- SysTick_ITConfig(DISABLE);* F" a3 }3 V( X( {# w
- SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
7 R# [4 v. l, C( ?/ F - SysTick_SetReload(9000*1000);! r! F) x b4 |- L. W6 i8 d0 E. e
- SysTick_CounterCmd(SysTick_Counter_Enable);
8 _: |) D' o/ u& \
y8 P6 ]! V9 z ]% K" V9 [# H- //*************打开systick时钟,但是由于systick时钟是默认开启的;4 X* l) M0 A( A% }- @/ c. }6 Q9 E, Y
-
# c4 \6 T: n: Z( i, j+ U! Z, _+ e - } 7 x, O/ T/ j$ S/ P+ q
- 9 r: Q1 I }! D: k& j2 T4 u
- ! J: ?% S3 j3 r# s
- /*******************************************************************************% J, W9 C9 s8 E0 J8 r3 g- c
- * Function Name : main' ?/ p; B' G% c ]& b% G& i2 j
- * Description : Main program.
$ z+ k s! s, q! K7 k - * Input : None
1 V, P* e# [" P/ V4 D1 N$ T - * Output : None; F$ { d! R+ X b4 j: H
- * Return : None& G! A* V) a/ C7 r# I
- *******************************************************************************/
5 |5 G$ W) |0 W - int main(void)
% M' ~. @( i7 |2 _, I! h6 ~ - {3 a6 q* I0 X4 G/ a, ]# q! Z: z3 [
- u8 min, sec;8 z; V: F( g( w+ a- h
- #ifdef DEBUG
5 G9 e/ K- V# O$ \4 ]8 X9 X2 f - debug();6 ]6 W9 K. O( c7 a. a, g# S3 ~
- #endif
- k4 R8 F! M: r" _+ [& c - //------------初始化------------
/ H5 V: k. ?* [( [4 v: h; k' b - RCC_Configuration();2 C! c9 _ k0 W, _
- GPIO_Configuration();
1 O/ K; F) w9 s2 t$ L - USART3_Configuration();% d/ _7 U% P4 \* N. a( Q7 N* C
- SYSTICK_Configuration(); |0 Y P+ F% _
- " N7 V8 a5 f# H( Q$ L, w! i
- // id_num[0] = *((u8*)(0x1FFFF7E9)); //stm32芯片id的放置地址,96位id;12字节
7 I9 L( R; X+ o - printf("hello world\n");/ O6 n+ s1 T/ I5 G0 ~* v" m
- //------------将数据上传给上位机-----------' ^7 \/ S* J% U* O. V9 G5 X: O, _# v
- min = 1;9 o6 ^: t% O5 T1 C, U
- sec = 30;
0 L/ I; i3 O0 s$ I5 J% Y9 n
* R# U* P$ }: C# ]- k3 v$ \# {- while(1)" {- L1 Q& g+ N' D* Q- |
- {
4 t( N' g( h4 ^: Y& t - FlagStatus Status;* t/ k4 U2 g; h; N3 S3 C1 T, d
- Status = SysTick_GetFlagStatus(SysTick_FLAG_COUNT);
8 N: ?/ V* o( n* U" P1 H5 ]- Q* x0 @ - if(Status == RESET)) |* u2 z% N. z7 K
- {6 j% p% L$ k1 X8 j- t1 n- A
- ;' b: s r" X! i+ m; X
- }
3 o0 F+ W7 R; @& r3 H. Z4 D. b" Q - else9 t% c, ?! Q. c0 O( Z
- {% F* ]1 h3 ]7 f
- sec++;" D2 O" w7 w4 x7 B, M
- if(sec == 60)+ ?4 Z/ d. d( }
- {
9 \* e( \3 p2 n. K% |, q6 I" u - sec=0;
8 ?1 g0 K$ A& c$ P" a6 h7 k - min++;) ^* L& Y* W5 v4 |- e- \
- }! }0 J. w) }/ K( f T
- printf("\t\t%d:%d", min, sec);' O l3 C1 b: Y
- }' U) Z% _* n7 ]
- }# ]+ V* G$ R# I: w
-
" m; @2 r. i' [6 K* g$ c7 w; f6 `* n# c - }5 Y8 M \& W- L' ^# z
- 8 f) `/ i3 y' ?3 Q0 K- S( _
- /*******************************************************************************5 X' i7 g9 Z2 u
- * Function Name : Delay_Ms7 H+ d: r$ s$ P
- * Description : delay 1 ms.
- R4 z* {" C+ Y$ e4 E6 ?, a - * Input : dly (ms)2 B" _. A# Q* b7 X6 _
- * Output : None
; I+ G ~0 l$ k" b3 h; a - * Return : None9 `; q' e; x+ b! d9 e0 p2 o# p
- *******************************************************************************// Y- r/ K- e1 Q* z, a, t) z
- void Delay_MS(u16 dly)
* Z8 e+ k, {5 o9 x8 R6 ~ - {" A* A4 f) V+ }$ V& c$ I
- u16 i,j;
, B7 [4 h& r/ j5 x5 U" h' V - for(i=0;i<dly;i++) ]3 Y6 S, ^* M' A K9 z C
- for(j=1000;j>0;j--);0 X, }: M6 a1 S2 T, y3 ~# b* z
- }
$ V9 Q5 ^/ N+ _ - % L M# k5 U% |5 `0 f7 q+ T
- /*******************************************************************************
2 y" e G8 l. q - * Function Name : RCC_Configuration& S* d/ b2 k U5 O
- * Description : Configures the different system clocks.! k9 ~+ m& H" w1 F
- * Input : None
( x4 Z: @# _; \* H) ~% @9 T6 D0 \ - * Output : None
( @* L* g4 c) @ Z" [9 Q% u1 U - * Return : None
5 J% F) m* _ m( N# p - *******************************************************************************/
) o" j. f7 w: l4 C! ]$ n - void RCC_Configuration(void)' x1 F: D, P; {+ x4 k# q2 l, N
- {
( l6 _; P D' G* e2 s - //----------使用外部RC晶振-----------
0 O: B* ]8 m+ E, `# m( g3 C0 d - RCC_DeInit(); //初始化为缺省值- p* y5 a/ d' G; ]# H+ _$ f6 N
- RCC_HSEConfig(RCC_HSE_ON); //使能外部的高速时钟 5 A! H. {1 F/ O) n
- while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET); //等待外部高速时钟使能就绪
2 t1 g( q- l' H1 | -
1 S4 ~9 ?+ ^8 q; v' g - FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //Enable Prefetch Buffer
- C6 e4 Q: U) o - FLASH_SetLatency(FLASH_Latency_2); //Flash 2 wait state
: E1 A( g2 u2 Y% a- f, e - ; G4 M4 q) W. C' p4 d: p
- RCC_HCLKConfig(RCC_SYSCLK_Div1); //HCLK = SYSCLK# b. X0 _' {: O
- RCC_PCLK2Config(RCC_HCLK_Div1); //PCLK2 = HCLK2 m5 y; _, ?2 Q0 s/ M) b
- RCC_PCLK1Config(RCC_HCLK_Div2); //PCLK1 = HCLK/2
9 |, M9 I' V) |% A0 q) m - RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9); //PLLCLK = 8MHZ * 9 =72MHZ+ q |3 J! J2 @
- RCC_PLLCmd(ENABLE); //Enable PLLCLK
5 t1 Q9 u4 G7 Y8 b& }5 t' C5 S - , T, u3 j% C* S% H0 T$ J
- while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //Wait till PLLCLK is ready
* [! j" k! D- ~. I5 B - RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //Select PLL as system clock
6 S$ ?" i: ~" H; i; h$ r9 B - while(RCC_GetSYSCLKSource()!=0x08); //Wait till PLL is used as system clock source& t- e9 A8 ]' b+ b0 a( p0 Q7 v
-
/ k4 K$ X+ P8 E1 H6 J - //---------打开相应外设时钟--------------------
1 C; l6 C9 V6 K. D4 B* X3 [! ~2 ~; I - RCC_APB2PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE); //使能APB2外设的GPIOC的时钟; b9 E p: f3 c7 y6 D
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE); //复用功能时钟开启
) ~- l, E0 Y. ?8 e% Z; {2 ?* x - }) N7 ?( c& H3 [
- 6 {* U: u/ T% Z% ?: F/ f8 j4 x
- /*******************************************************************************
) [* I; J3 L; O$ o1 j - * Function Name : GPIO_Configuration
- T a8 F4 a, ]& w) P7 i; m2 R% @$ R - * Description : 初始化GPIO外设
. q6 s6 ~! `7 M# h a5 o! W2 u - * Input : None
2 n3 I0 c" ]2 N3 \ - * Output : None
8 {1 n, O* R; f - * Return : None
1 z, \) Z$ Z1 h0 M) B% C/ A - *******************************************************************************/
: ^. T7 A9 q# n, ]- B - //由电路图可知;配置PC10,PC11引脚
! b* t# T7 z) O3 I - void GPIO_Configuration(void)! D+ g8 a' d- n5 g% a
- {; ^1 R. c; J! e& k4 l$ @
- //CLK:PB5 CLR:PE11 DATA:PE109 ?% @, _7 M0 \& C' f8 `! b# c+ S
- GPIO_InitTypeDef GPIO_InitStructure; //声明一个结构体变量
# o0 F* Y) l1 c! ]& R: I- i - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //选择PB.1-
6 C) `1 I" r$ T% U - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //管脚频率为50MHZ
/ }8 p" D% E6 V) _/ s - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //输出模式为 "复用推挽输出"
+ y( N+ H/ g5 Q( _) G - GPIO_Init(GPIOC,&GPIO_InitStructure); //初始化GPIOB寄存器, b9 v( I6 ^5 M
- $ ]6 G* `& d* S2 P7 B
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 |GPIO_Pin_11 ; //选择PE.10 PE.11
% t" Z' }) I. T8 d/ f. \ - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //管脚频率为50MHZ2 {) i' m7 [; c8 O& v4 t3 E
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //输出模式为 "浮空输入"
6 c5 ` c7 p2 d+ ?4 g - GPIO_Init(GPIOC,&GPIO_InitStructure); //初始化GPIOE寄存器
5 S; m& S) ? b/ G- s - / j/ `0 m0 I0 M9 c' e. G
- //开启时钟 必须在RCC_Configuration中设置 , S+ ?9 g0 W' t: q! o
- 9 ]( o$ q/ M- h" J4 [
-
6 [+ v4 o) @: j% T8 t' v4 C - //端口重映射:PC10/PC110 {4 ?! f+ X- w& P. r& m& W* `
- GPIO_PinRemapConfig(GPIO_PartialRemap_USART3, ENABLE); 7 \2 v7 K+ C9 s+ z: C! h
- } 9 ], M) T: a& U3 E6 Y2 }
- 1 M' Q0 T( c! j7 m3 C
- void USART3_Configuration(void)
1 E9 }# W- k2 f" f# b; S - {2 ]6 K3 L' q8 i. z( h
- USART_InitTypeDef USART_InitStructure;1 w: L* X! n' n& M8 P
- USART_InitStructure.USART_BaudRate = 9600;
1 S1 I5 v- e% F3 i \! O. x3 F - USART_InitStructure.USART_WordLength = USART_WordLength_8b;5 x1 P# O' [8 I- S1 I. e. d
- USART_InitStructure.USART_StopBits = USART_StopBits_1;/ M; x+ E6 }- z
- USART_InitStructure.USART_Parity = USART_Parity_No;; ]# r3 D$ t4 g* Q# {- }4 O
- USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
* e* m0 U1 n+ w" E - USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
) \+ O/ I( P+ W3 k - 3 A9 y& M* c% P
- USART_Init(USART3, &USART_InitStructure);0 K8 c& x" h9 p2 j$ N+ _+ ^
- 4 L' I0 H2 d' x8 R
- USART_Cmd(USART3, ENABLE); //开启使能
; ]$ g0 K7 F+ x' e - }; V. Q6 @9 S# A. j& \* ~3 K+ F
; i$ f0 o& \! D8 s$ { m- /***********************************************************
7 V( c$ b# v; e1 B0 ?2 ?9 [' P5 w0 _ - name: fputc *
. C5 J0 x' r; r0 v- X& C - Description:重定向这个c库printf函数,文件流--->串口USART *
* ?$ v9 {# U5 f. i - */ Y4 e4 j& y9 E' A# ?% A3 l3 m" C
- ************************************************************/
4 F1 L) V+ n: e - int fputc(int ch,FILE *f)9 j; t9 E7 a. o
- {! W+ _+ f) x: O
- //ch发送给USART1
9 T. X, c8 t# C. O5 y - USART_SendData(USART3, ch);
, h5 ?# ?/ k" I/ J" I - //等待发送完毕
( L% ?6 P7 d1 V% M1 k% w - while(USART_GetFlagStatus(USART3, USART_FLAG_TC)==RESET)
8 k1 B, v6 Z5 M& a. T% i - ;
8 i' [2 c1 o5 D) ] - return ch;
/ l, \! w3 F! g' k - }
复制代码 3 `1 v) l+ I# X" D( s, m4 [9 c4 g" i
|