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的中断; h M6 }& X+ \5 u9 V* L
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计数器; . p8 C3 u. b2 k) N0 f: j
- /*Include---------------------------*/
- M) |& W1 p% O- F, W - #include"stm32f10x_lib.h" //包含所有的头文件
5 E* z( ?* h* s: O7 _; w& B; i - #include<stdio.h>
; J( _( Y$ S) @5 q$ [ - % W+ h9 ]0 p0 g2 H
- //----------------函数声明--------------------
8 n' b9 W! U( D" H( e - void Delay_MS(u16 dly);( A9 C) y# r" i3 w2 _5 p" G
- void RCC_Configuration(void);# t+ h; K' A( \2 L( g
- void GPIO_Configuration(void);$ w/ l; T: y' s9 V9 ^1 l
- void USART3_Configuration(void);/ J9 e- C# k! t" C
- " [. E1 w9 o* n H# J, G
7 Z& z) R4 a4 j3 ?' y9 y$ O" a- u8 tab[] = "hello welcome to class !";
$ j# N" Y8 U: v# _ - - t3 H- K; g+ X
- void SYSTICK_Configuration(void)
- |2 @6 H2 p% w% v5 |% I - {
! G# f4 u& \. v" P$ p - SysTick_CounterCmd(SysTick_Counter_Disable);
$ k/ w3 h' o5 J: n - SysTick_ITConfig(DISABLE);: O0 @8 k9 q# X3 Z" x+ r3 [5 Z" o
- SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
* n7 {* ~ V9 `( ^ - SysTick_SetReload(9000*1000);
5 [: \; p% ~" T7 X6 F t5 K8 w% a - SysTick_CounterCmd(SysTick_Counter_Enable);
4 S2 T- T* }+ Z# b
9 R/ d1 d f) P7 O- //*************打开systick时钟,但是由于systick时钟是默认开启的;' B* b& F; h+ z
- 1 m3 U' l4 B: P# U2 ^0 C
- } 7 U# o; S0 P6 I0 f* i0 j
! e# ?8 @& H. Z- * ~! a. z$ z/ \4 A( c' s
- /*******************************************************************************' p3 T- l* O3 ~% O2 y* [
- * Function Name : main' ~: D1 C" D0 v0 M: X' j& J
- * Description : Main program.% l+ D% J- ]1 R% L( R; S$ m
- * Input : None
) r: p `& Q) K9 @ d1 `. ~( D1 p - * Output : None
( i3 D0 W1 Q" c8 J! B, x n - * Return : None
( a4 t4 D4 H* p5 }1 ^: C9 \ - *******************************************************************************/
8 g1 Z5 V7 u# J% ~ - int main(void)- P; @1 C9 c& ?4 [: ]3 M# t# d
- {8 c; t& a/ h* [6 Y: N
- u8 min, sec;
. y9 y: S& }2 Y! q% O9 J8 H! U6 ]5 b - #ifdef DEBUG
' p: N% u/ S+ P - debug();: j2 F* `9 B" H ^/ `- b) D8 b
- #endif$ B, K6 |7 `3 ?( o# c+ T& {
- //------------初始化------------
- {7 `8 I& _' E. q; j; C - RCC_Configuration();9 m: |5 J& w) I) _, a% }. U
- GPIO_Configuration(); X2 Q0 E. o8 s
- USART3_Configuration();% @" A7 ?( T" {5 ?3 D$ O
- SYSTICK_Configuration(); 0 r$ M2 H5 V( l, f+ V: }6 r
# l/ i" K b! X- |$ E, C- // id_num[0] = *((u8*)(0x1FFFF7E9)); //stm32芯片id的放置地址,96位id;12字节
. R" I; j& a P) u9 C% F - printf("hello world\n");! T) E6 c6 k. ~" \) w! ~
- //------------将数据上传给上位机-----------; m# Z n' ^! F2 h! Z; t
- min = 1;6 B3 l- g% E- A* ?5 `9 ]
- sec = 30;
4 ~1 `1 z: n+ q8 l8 C a - 4 [) j2 S& Q! a. c, Z, D
- while(1)
& }5 q( f; _2 G% a - {; x$ i+ ~+ s) p% } @% R
- FlagStatus Status;; L! u) J" C! Z( C& [% [9 q
- Status = SysTick_GetFlagStatus(SysTick_FLAG_COUNT);( ^0 ?& y7 `; K, K2 A& ^' Y5 q4 ^
- if(Status == RESET)' Q8 w! C# P3 U$ P* ?
- {/ |* ?9 t" {; [3 P. [0 W9 T) B! x
- ;/ b; c, C6 U1 A4 K; M0 g" V
- }+ D7 g5 I. J* R: x; V* D x
- else
; U. Y$ _" _' C/ }& J - {4 M- l' a2 i3 ~: A; r) Y# _) ^
- sec++;
+ j8 }: s# @2 `' B - if(sec == 60)
8 m& e, c1 g7 [& l' z+ q3 E4 w6 K - {
2 b8 O" M; u3 U ?' p7 X5 G) ? D - sec=0;1 S! r) m6 G7 v
- min++;
1 ]( O. \$ Y1 U2 z9 s I* I& ?4 V - }
4 j5 e; E5 O5 c$ I - printf("\t\t%d:%d", min, sec);/ M& r. n/ U2 r; e
- }
- U! [4 k; [2 B. }. O+ e0 Q0 s/ \ - }6 H6 e' z! q0 Z( `6 t
-
~$ i+ e4 c( a - }3 D5 V% @/ L! y5 }
- 9 T9 u! U0 m r8 z
- /*******************************************************************************+ Q. B/ S( r _# {3 D" M/ C
- * Function Name : Delay_Ms
8 o J) Z5 _: O, I - * Description : delay 1 ms.& S& x. i# r/ R' \ E, u5 o) _! `
- * Input : dly (ms)/ H2 Z" A* l+ |" M. M, B
- * Output : None# Y. b- M! a- b j2 u7 R: ?
- * Return : None3 D& W7 r m1 b0 w! b5 ~; Y# Y
- *******************************************************************************/
, s' U# g; _/ `& z- u4 E - void Delay_MS(u16 dly)
5 _4 K% S4 O2 s- t: }3 r% o - {1 K; z2 | s3 H; y* F1 E# }; B2 R
- u16 i,j;" {8 R" g& }# t: X- G
- for(i=0;i<dly;i++)$ ^) [8 G# x# ?1 K9 X6 t7 ?
- for(j=1000;j>0;j--);0 F, Y+ i- A, A- }" T( R
- }1 V1 }6 C! m! x" I+ X; F( h" E
- y) G' s: X& D- M0 I3 \- /*******************************************************************************. {/ Q' `6 K7 Q
- * Function Name : RCC_Configuration
8 `7 C! x# \; i6 b' ^! t - * Description : Configures the different system clocks.
! L% o4 x: Q- G - * Input : None. B" G5 P, `' r) [2 e
- * Output : None% M- g+ `; t6 O ]. ?7 |, |5 K+ K# B
- * Return : None
. m+ g6 W3 h; Y' t5 K - *******************************************************************************/9 Q, R9 Y/ v/ D. c5 Z
- void RCC_Configuration(void) f6 u1 o" u8 W
- {
1 Z" p! [$ N7 }' V# _6 Y C. R - //----------使用外部RC晶振-----------" O1 ~0 u ] _ v5 c) g
- RCC_DeInit(); //初始化为缺省值
- \# W# Q- e0 o w% x5 I - RCC_HSEConfig(RCC_HSE_ON); //使能外部的高速时钟 5 _2 I# L% m8 ^! a s
- while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET); //等待外部高速时钟使能就绪' h* Q; _& N8 X. z5 u3 w" a
-
; o: l z' r# q% v$ u - FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //Enable Prefetch Buffer
- V0 K" D/ i+ J2 S, d/ @! v - FLASH_SetLatency(FLASH_Latency_2); //Flash 2 wait state. i- U- J7 w% C( L/ S* ^
-
; M( M/ i2 K% L3 H - RCC_HCLKConfig(RCC_SYSCLK_Div1); //HCLK = SYSCLK
) Q0 R: j s( t! i5 r- H& w - RCC_PCLK2Config(RCC_HCLK_Div1); //PCLK2 = HCLK) p) @4 z6 B2 j8 L
- RCC_PCLK1Config(RCC_HCLK_Div2); //PCLK1 = HCLK/2+ u6 ~5 F/ |1 l' x) u+ j
- RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9); //PLLCLK = 8MHZ * 9 =72MHZ5 N7 ]: }7 U7 v- n" \
- RCC_PLLCmd(ENABLE); //Enable PLLCLK
- l! b- D, S+ I1 i - " o, W# X7 k0 J2 P c8 W* T& |- `
- while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //Wait till PLLCLK is ready
$ [0 \+ S0 B3 _8 i - RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //Select PLL as system clock: z; [0 @& W6 n. a6 b- v% e
- while(RCC_GetSYSCLKSource()!=0x08); //Wait till PLL is used as system clock source
! q8 H/ |, v4 q6 d$ o) H" t -
1 F& a7 v( V( p5 B9 e R5 f - //---------打开相应外设时钟--------------------
* N1 u! y' {9 q1 h& ~ - RCC_APB2PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE); //使能APB2外设的GPIOC的时钟
+ Z1 C. Q+ g3 ? - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE); //复用功能时钟开启 , A1 G5 @2 f1 ], l1 M. H0 C1 i: X+ w* b4 d
- }: C# {# o0 [8 C4 W
; D0 X. Q: f" e' u2 @- /*******************************************************************************
' C3 b6 I1 O" i' G8 I8 N @ - * Function Name : GPIO_Configuration* j6 j. A2 [0 A8 M) Y; o- I) ^
- * Description : 初始化GPIO外设
, C7 d3 u) K' g; u$ k# { - * Input : None
6 W1 r+ c" B; _ E" y - * Output : None
- A0 Y& u* q5 A2 }) H - * Return : None
$ T% {. ]+ ~0 C: O7 @9 M) A - *******************************************************************************/
( P6 Z. E" Q. f+ Q$ E - //由电路图可知;配置PC10,PC11引脚# b0 X( ~! O+ d, k1 W% X
- void GPIO_Configuration(void)9 l) y5 Q0 j, _$ v6 ^7 K; @
- {
9 d) a% A. h. n. F - //CLK:PB5 CLR:PE11 DATA:PE100 [2 |2 T% L2 o1 J- n- B' f5 E
- GPIO_InitTypeDef GPIO_InitStructure; //声明一个结构体变量3 y9 S$ V, Z3 y& q) @3 X
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //选择PB.1-
* O( W3 U7 x- a1 [1 M% b e - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //管脚频率为50MHZ3 F( Y N1 ^+ R8 r) }
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //输出模式为 "复用推挽输出"
8 |! h2 h1 G* z: [ - GPIO_Init(GPIOC,&GPIO_InitStructure); //初始化GPIOB寄存器( S5 f( b8 U% `: V6 T- q
-
4 p: A; v5 M$ x: Y1 t7 c: Q# a" S - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 |GPIO_Pin_11 ; //选择PE.10 PE.11/ W( z# X/ n3 |" u
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //管脚频率为50MHZ3 S2 ~+ j3 e9 m$ ]. z
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //输出模式为 "浮空输入"
* b0 h0 b+ t: s) t - GPIO_Init(GPIOC,&GPIO_InitStructure); //初始化GPIOE寄存器
) D8 l4 }+ f! g$ _ -
& J' D# r! X# l }4 T" X - //开启时钟 必须在RCC_Configuration中设置 , g4 r; I4 Q. o! I, z; h
-
1 g6 ?" f* _1 {# j$ x; A4 {- ^ - - M9 c. x; c. d
- //端口重映射:PC10/PC11
6 r- Q& S" r. S2 K+ T - GPIO_PinRemapConfig(GPIO_PartialRemap_USART3, ENABLE); / a8 u: A! I; z
- } + \& h p/ e u4 {. j: |8 d
- . b8 R% m z8 X# j
- void USART3_Configuration(void)
5 n! h8 O z f0 e/ c6 e8 {( { - {( q' u6 h2 Q/ G6 L& [$ Q. t# D* Q; M
- USART_InitTypeDef USART_InitStructure;. H* F1 S! g# E; x1 ?6 ]$ R
- USART_InitStructure.USART_BaudRate = 9600;1 c$ ?6 B6 J8 z$ I, f
- USART_InitStructure.USART_WordLength = USART_WordLength_8b;2 o" ~. K0 ?5 ]. t) {8 }. b8 P2 t9 W
- USART_InitStructure.USART_StopBits = USART_StopBits_1;: V! G* y+ i B
- USART_InitStructure.USART_Parity = USART_Parity_No;6 E) ?/ n$ p6 H: S5 Q
- USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
5 s* a/ V+ F5 r( N3 S# W - USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;3 @& W! ?1 A; i5 ]0 d- S
& C, k. R- P4 v( _- USART_Init(USART3, &USART_InitStructure);
- n0 X* W( X7 N/ K- C; u
' O7 x7 s4 \4 a0 ?- USART_Cmd(USART3, ENABLE); //开启使能: v: h8 Z! Y) B9 v* k
- }1 C" C9 E% E' y* z; s
5 U1 q0 r& r9 \. A- /***********************************************************9 Z" _- j7 h1 f4 F d; e* Z: M
- name: fputc *4 s9 `( \$ U9 |
- Description:重定向这个c库printf函数,文件流--->串口USART *
1 t ^( ^/ _7 S+ D - *( O* d/ Z3 n: V* s) _# r5 g4 ~
- ************************************************************/4 Q! ?+ c9 ?% j6 O
- int fputc(int ch,FILE *f); L# j+ h* n3 X! @' V i8 _2 M
- {' ?4 { K7 e" g' P m& ?2 K
- //ch发送给USART1, p6 r* x! w/ {3 W3 r' t& g! i. P: U* p
- USART_SendData(USART3, ch);
/ O7 g! c2 E) P - //等待发送完毕$ @* B2 u1 w8 a/ l
- while(USART_GetFlagStatus(USART3, USART_FLAG_TC)==RESET)$ S: {! A+ N( o( i4 z) v' L
- ;
2 ^7 a' R. ^3 R5 K+ o# m3 z - return ch;
8 _9 X$ S. d! ~" x) W. z - }
复制代码 " p, c4 B* C! X: B; b% r
|