|
这是一个综合的例子,演示了ADC模块、DMA模块和USART模块的基本使用。 我们在这里设置ADC为连续转换模式,常规转换序列中有两路转换通道,分别是ADC_CH10(PC0)和ADC_CH16(片内温度传感器)。因为 使用了自动多通道转换,数据的取出工作最适合使用DMA方式取出,so,我们在内存里开辟了一个u16 AD_Value[2]数组,并设置了相应的DMA模块,使ADC在每个通道转换结束后启动DMA传输,其缓冲区数据量为2个HalfWord,使两路通 道的转换结果自动的分别落到AD_Value[0]和AD_Value[1]中。 然后,在主函数里,就无需手动启动AD转换,等待转换结束,再取结果了。我们可以在主函数里随时取AD_Value中的数值,那里永远都是最新的AD转换结果。 如果我们定义一个更大的AD_Value数组,并调整DMA的传输数据量(BufferSize)可以实现AD结果的循环队列存储,从而可以进行各种数字滤波算法。 接着,取到转换结果后,根据V=(AD_Value/4096)*Vref+的公式可以算出相应通道的电压值,也可以根据 T(℃) = (1.43 - Vad)/34*10^(-6) + 25的算法,得到片内温度传感器的测量温度值了。 通过重新定义putchar函数,及包含"stdio.h"头文件,我们可以方便的使用标准C的库函数printf(),实现串口通信。 相关的官方例程,可以参考FWLib V2.0的ADC\ADC1_DMA和USART\printf两个目录下的代码。本代码例子是基于万利199的开发板EK-STM32F实现,CPU=STM32F103VBT6
3 a: [) R1 x9 B% s, t! i- 本文件实现ADC模块的基本功能
9 Z* Q% W1 L- E5 I) d - * 设置ADC1的常规转换序列包含CH10和CH16(片内温度传感器)' Y4 u$ D: u2 V* M
- * 设置了连续转换模式,并使用DMA传输
6 o! e; c# |' }' \2 v5 h( {9 j - * AD转换值被放在了AD_Value[2]数组内,[0]保存CH0结果,[1]保存CH16结果* [' t7 T( _$ y9 j2 B9 s
- * GetVolt函数计算[0]的值对应的电压值(放大100倍,保留2位小数): A J! E" u+ M
- * GetTemp函数计算[1]的值对应的温度值,计算公式在相应函数内有说明) ?! Z, f; N' T
- * 作者:jjldc(九九)
K; z7 P( X0 x% `; h6 j ~ - *******************************************************************************/
0 x) s3 ^* w0 C1 I - 5 h2 _4 W3 ]. L7 c2 D& l- v
- /* Includes ------------------------------------------------------------------*/
. B6 K; D6 F$ V( J0 @7 O! z q$ ` - #include "stm32f10x_lib.h"5 B9 q: E. d9 N) h2 J3 R( d0 w
- #include "stdio.h"
! ?) ^6 m {3 v- m9 s( i6 |: N
" j9 R! ?$ N2 {2 I( {$ f- /* Private typedef -----------------------------------------------------------*/; Z6 }+ j. g7 O; n
- /* Private define ------------------------------------------------------------*/* [$ @+ s& a! |4 |" u
- #define ADC1_DR_Address ((u32)0x4001244C)
3 m" ~5 J) m) |; w+ d2 A - /* Private macro -------------------------------------------------------------*/ }' y7 f$ H. F
- /* Private variables ---------------------------------------------------------*/
$ `& D/ `! ^& M/ G6 t1 K - vu16 AD_Value[2];
8 I( E- \" P; @6 q& W: y- D - vu16 i=0;! \% h( i) g$ |2 H! q/ T4 u
- s16 Temp;! A2 V& l$ M: l
- u16 Volt;
. A/ c+ E: P% u" r6 E
: R$ w. ~6 a+ K* l9 w# ~7 I+ N- /* Private function prototypes -----------------------------------------------*/: e$ I. k' W V1 Q# w# u4 r
- void RCC_Configuration(void);5 @5 g0 m4 c/ ]# ^& @) Y" a9 D
- void GPIO_Configuration(void);
* S% i1 z4 Y+ n: }# F: @ - void NVIC_Configuration(void);$ }9 g9 k: Z4 l6 J0 S' ?% z
- void USART1_Configuration(void);
) A: V0 r- Z) W' ]' x - void ADC1_Configuration(void);
/ m0 M5 d# i8 ^ - void DMA_Configuration(void);
% q$ [5 \+ v* n
+ e, Z. F& p! _8 [5 [& ~, Y# P" Q: T- int fputc(int ch, FILE *f);
& F% M% Z* C7 ?& a( l - void Delay(void);
5 B4 x) q" ]: X6 z9 g. h7 M - u16 GetTemp(u16 advalue);
% E. y9 j6 w% Z8 x( g% @' e - u16 GetVolt(u16 advalue);& k9 a; H1 ?, l) K! P
- /* Private functions ---------------------------------------------------------*/
6 ^+ f/ w$ \# f3 y6 J$ U - /*******************************************************************************
1 I r9 H1 v4 p; j' L - * Function Name : main: e1 }: v2 W% {& |
- * Description : Main program.
) f" x5 q1 z; m6 e4 k* ]2 l - * Input : None" ^) K" ^* m' u( Q9 s' i
- * Output : None4 g! F1 q7 e" L4 O7 {
- * Return : None
" D* T: T1 u1 K9 u8 e/ K0 v8 f$ F - *******************************************************************************/3 {1 o% j. f' d# O1 d6 w$ s0 F( u
- int main(void)* |: k- j* ^! [- W% K* f; d
- {
$ Y) R/ G8 K0 o: Z* j& n2 W3 n - RCC_Configuration();
9 F2 n$ P2 D, i, g - GPIO_Configuration();" F; y! r$ C( c+ n9 V. f: m8 d; ^
- NVIC_Configuration();
* |6 U7 L7 f2 y* C7 s7 ~% t" \ - USART1_Configuration();
/ f3 Z, N2 m& k3 b - DMA_Configuration();
2 a- F5 y/ t$ W. V9 B7 d6 a: Q - ADC1_Configuration();) T) M3 `3 c& s, Z; _8 X% ~& B
- $ z. m; u' ?# e' _7 r2 s
- //启动第一次AD转换
7 @. F* z. a" U - ADC_SoftwareStartConvCmd(ADC1, ENABLE);
; F+ \" w" G1 M' x A - //因为已经配置好了DMA,接下来AD自动连续转换,结果自动保存在AD_Value处
# O, q* T- P7 c1 M- j& M* ` - ( o8 t2 S$ V# D6 e+ m% w1 j& }
- while (1)
( _: q/ j# S! E$ q0 o# ?4 m - {
$ d$ P' L4 W5 s# n/ y5 n* q - Delay();
5 {* t$ n1 W. u# q" }0 T# R6 t - Temp = GetTemp(AD_Value[1]);
% e4 ~+ Q2 A+ m - Volt = GetVolt(AD_Value[0]);
7 G8 Z2 f! V( T - USART_SendData(USART1, 0x0c); //清屏# a7 ^ b9 E# J" f/ I7 a
- //注意,USART_SendData函数不检查是否发送完成
4 @# p e: W# P3 J2 L - //等待发送完成
* ~8 D7 X, R- z+ L7 b - while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);1 }1 w9 p& f% e k
- 2 x7 l+ Q$ c8 F: q; Q! l
- printf("电压:%d.%d\t温度:%d.%d℃\r\n", \
5 F4 S( r H0 M& ?6 `+ @ - Volt/100, Volt%100, Temp/100, Temp%100);/ h6 \2 n+ J, K) H/ J- l
- / v% @% z9 } V- r3 o
- }
. O+ j- {. E! x& p7 C7 l - }
. N8 z x' j$ {0 l0 |. T- f
# e" c$ {! u4 D& h* b. q% g' P- /*******************************************************************************
$ B A2 }/ d. M9 v# _ t5 b - * Function Name : 重定义系统putchar函数int fputc(int ch, FILE *f)
% j2 M0 f7 L' F: }0 { - * Description : 串口发一个字节9 W1 I, r# @8 x+ A7 \5 |( y% l2 ~
- * Input : int ch, FILE *f/ c4 E2 X$ N7 q! D- z
- * Output :3 a/ Z) Q2 t8 k; m5 `3 l% |
- * Return : int ch) l8 S7 W; V* p1 t- d' R' D$ a
- *******************************************************************************/8 x% J; T6 w% [ c1 [
- int fputc(int ch, FILE *f)5 y/ f! n$ x2 l' F7 k
- {( e% g$ V8 i, x
- //USART_SendData(USART1, (u8) ch);
7 D/ v& W" l* B% r1 Z - USART1->DR = (u8) ch;
$ B9 _; k: [* J3 T) |$ t K8 S - 6 {! p% E: H" |, ~ b
- /* Loop until the end of transmission */
+ d! ?* F, W# x: Q( ?0 F - while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); V3 h9 N) X, v4 p7 a2 N% t6 f% V
- {
0 h: W1 J8 G6 x; A% R* y; A1 U - }
. f7 M! A, F+ k" z: L, q4 h) w - ' u* e' ~5 y* b
- return ch;7 L& e. f5 D1 n% B1 a3 f+ A
- }& y5 [. d% f4 N+ a
- ; T6 w+ r% t% o! T
- /*******************************************************************************
$ H( [! {/ o$ m3 w |& { - * Function Name : Delay
9 t1 j' n4 |5 p+ v* z - * Description : 延时函数
9 I8 X0 v. A+ |. a5 J; ~ - * Input : None
' Z' q" u3 \- A* u `" D - * Output : None
, f* V0 m& o* s! V8 ]8 g - * Return : None* `) a% S8 b' L/ S s/ T
- *******************************************************************************/0 o) b M. L! W. @/ \
- void Delay(void)
. ?- }5 t3 C& H# g; p. J - {
: p/ w3 E2 a* G* Y5 i/ o - u32 i;
. O" k* v o9 [' r - for(i=0;i<0x4f0000;i++);
" C2 G# [- n$ t2 Y9 U6 a - return;
9 U9 g3 g( o8 G* g: O7 B1 a9 F2 e - }
7 I8 a4 y5 ^+ U& _
. d7 M5 z- L: F' _0 U- /*******************************************************************************! I* V% E5 x# K3 v4 U
- * Function Name : GetTemp
% N' h+ E" n+ y - * Description : 根据ADC结果计算温度
8 N" ^, D, k! h9 W - * Input : u16 advalue$ @, c: D3 s; }* Y; _2 M1 Z! E
- * Output :. p; [% m2 @+ @, d
- * Return : u16 temp! O) \/ g8 C) ] W( X7 g2 V+ I$ y
- *******************************************************************************/
i. i) @* T2 l: B4 F& v - u16 GetTemp(u16 advalue), n+ a# i# u, A3 n5 @; C- }
- {& T6 H4 o/ b! V( n1 ~
- u32 Vtemp_sensor;8 n/ w- ^8 a% i/ j2 ]0 y% [' `
- s32 Current_Temp;( Q9 T8 t) k9 L$ A( `1 W7 h; ~% X
- + [8 _& F0 T% U9 e" C- h
- // ADC转换结束以后,读取ADC_DR寄存器中的结果,转换温度值计算公式如下:4 X5 h: |" n/ ^! ]5 _' w
- // V25 - VSENSE
2 D3 o$ B- n, T7 S# h) W - // T(℃) = ------------ + 25
2 F4 V, n e& |5 s+ u - // Avg_Slope3 ?) f- o" C) ]8 W& u4 x/ {
- // V25: 温度传感器在25℃时 的输出电压,典型值1.43 V。4 O2 N. l* I- z% e) A
- // VSENSE:温度传感器的当前输出电压,与ADC_DR 寄存器中的结果ADC_ConvertedValue之间的转换关系为: k) Q# x8 \+ n$ I$ x
- // ADC_ConvertedValue * Vdd
' R4 y& G; ~# P: V* x9 D - // VSENSE = --------------------------5 C8 }5 l+ i( Q; l- X
- // Vdd_convert_value(0xFFF)
( H9 m8 H) A' G - // Avg_Slope:温度传感器输出电压和温度的关联参数,典型值4.3 mV/℃。5 g$ G7 g( H+ {
- + T' v* ^3 t- y* N, x9 D
- Vtemp_sensor = advalue * 330 / 4096;
7 p' q4 y7 [- ?; y6 X* Z - Current_Temp = (s32)(143 - Vtemp_sensor)*10000/43 + 2500;2 t! a1 _% [: | B: ]/ v
- return (s16)Current_Temp;
+ ^/ ]8 D: h5 C2 q! ]) i - }
- r; i' T3 z' I. K$ E, o
+ \+ o, [$ ^0 H8 ^
3 v, B; J& v# y% Y- /*******************************************************************************
% H6 b5 p, p: w; S7 M - * Function Name : GetVolt9 h$ v0 H. |& H. B* f6 y# C
- * Description : 根据ADC结果计算电压% C7 U! f0 j% R$ M" l* ?
- * Input : u16 advalue l V3 n& U3 g0 R
- * Output :& q2 y7 G3 D5 V0 h( \$ Z
- * Return : u16 temp
3 W$ }- V# Y5 i6 @# X% n - *******************************************************************************/4 | S7 [# I# ]+ C$ n6 Z
- u16 GetVolt(u16 advalue)
4 l( X( U2 }8 {% ?3 b; ` - {3 @! g q1 X w& T- @2 g
- return (u16)(advalue * 330 / 4096);- D7 n. g6 u" s e0 ?
- }! \ Z; P9 p. H/ O6 ?
- ' l5 v# S! ]3 s- L8 i* l( |$ Q
: Q0 P$ w8 I' r( p' z, ]* o- /*******************************************************************************
% Q) s" Q3 o$ z1 |4 s( N# h- h - * Function Name : RCC_Configuration
& I* i/ e- f9 W5 G) s1 q% ] - * Description : 系统时钟设置( F& r# t8 {; P- H6 C2 G
- * Input : None
6 _; K4 \; T0 {& e5 i, _) s e! R - * Output : None1 @( p# h; _1 N0 q8 _
- * Return : None
" h1 e" A9 e+ {' r1 w - *******************************************************************************/, E" x: c5 e Z/ S
- void RCC_Configuration(void)! w. U1 h2 G5 f6 w
- {! K2 y8 P- h( r
- ErrorStatus HSEStartUpStatus;! C) L% O# H3 G. y
! b+ y5 ]) w# t- P2 j0 u) K- //使能外部晶振, f$ G+ q3 X, ^, U7 P: j$ `2 Q) n$ X
- RCC_HSEConfig(RCC_HSE_ON);
" V; Y6 o( X. T& G& H - //等待外部晶振稳定
4 B: }4 |3 I7 Y$ E - HSEStartUpStatus = RCC_WaitForHSEStartUp();: T& N/ W9 @: \# J& E% N: a
- //如果外部晶振启动成功,则进行下一步操作) w" h8 W- v% j; u( M
- if(HSEStartUpStatus==SUCCESS)( O# B* e: q8 `" {# o
- {: ~0 D8 {* W9 u
- //设置HCLK(AHB时钟)=SYSCLK- H- n, {1 b5 \: c: B* D4 H6 e$ `
- RCC_HCLKConfig(RCC_SYSCLK_Div1);; R/ {8 s, h8 g& ~5 T
% s2 p* Y1 q! F! Z- //PCLK1(APB1) = HCLK/20 n6 C. a) s+ k5 W0 D3 B
- RCC_PCLK1Config(RCC_HCLK_Div2);
0 Y9 ^* `/ z' p- i% ~& l3 q
' o4 `3 n1 T( s1 s1 ^* x$ N. R- m- //PCLK2(APB2) = HCLK' K% j$ J/ J- {' ?
- RCC_PCLK2Config(RCC_HCLK_Div1);
, L" y+ _& [- O2 T# G! N3 W! ~ - ; q/ r! [* K8 T1 P" ]) w
- //设置ADC时钟频率, E1 ? Y6 b) q1 T. t6 q( l2 x. J+ ?
- RCC_ADCCLKConfig(RCC_PCLK2_Div2);3 E$ k1 _4 v+ C' B
- 1 u0 \/ N3 L( Z8 I( ^, E8 M
- //FLASH时序控制
$ R7 ~8 T1 O8 Z8 j6 c3 ~+ @ - //推荐值:SYSCLK = 0~24MHz Latency=0
6 W: n1 ?( a: D- B: u0 m1 u! L - // SYSCLK = 24~48MHz Latency=1. P! K9 e8 i1 _' ^- q% M
- // SYSCLK = 48~72MHz Latency=2
- X$ _( i2 c/ j' c6 a - FLASH_SetLatency(FLASH_Latency_2);
3 O$ q( t2 b/ b; f - //开启FLASH预取指功能
! ^! {( ^, e( S( r" D! M) `$ z - FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
0 a- C2 o2 N5 O& ?/ F1 Z) h
5 I9 |0 P: Y1 T# u- //PLL设置 SYSCLK/1 * 9 = 8*1*9 = 72MHz5 O. U# `2 q; @1 g% s1 U
- RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
1 A# K+ |4 e9 ^! T' z1 U% m) @ - //启动PLL
6 z" Z& u5 w }) O2 @ - RCC_PLLCmd(ENABLE);
6 w5 `/ f7 v- r6 G+ Q( |% E' [, b/ n P - //等待PLL稳定
% k" T' t' S2 k - while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
# g6 i+ k- p1 [: G+ F - //系统时钟SYSCLK来自PLL输出/ R7 r6 q# q7 K2 e9 K1 v7 D2 q' Q
- RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
; _3 b( u( W( a. b9 X% b8 d - //切换时钟后等待系统时钟稳定: `* Y4 i3 N& t9 u9 _8 [: q! q% o
- while(RCC_GetSYSCLKSource()!=0x08);% k9 f6 s- a `
- 5 K5 d$ D& g0 U8 ?1 \, U
- 7 l% j% ^- X9 R! Q2 y7 z
- }" f; O- f* l4 [" p2 I& t
9 M. r! }( N8 W- E9 I- p6 [- //下面是给各模块开启时钟: U" L7 g: J6 V9 l. j) u5 z
- //启动GPIO
1 |3 e- \2 M7 h* q# P6 w; R# A - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | \' P* u& F2 q: C: b* d2 D* [
- RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD,\1 Y) [1 F/ q+ k) Y1 `5 {8 F5 g0 p
- ENABLE);! e/ l- Q' ^4 l/ q! f$ C' Q
- //启动AFIO
2 H% F& v" r( J8 Q5 H - RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);7 @9 K9 O8 \8 L* z7 \
- //启动USART12 p; x- B- p- Y( g
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
# z+ u* Z- I5 e/ | - //启动DMA时钟5 {. K) \# }' I
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);' J6 h# }& {$ E3 _$ J! K
- //启动ADC1时钟9 P8 `3 Y3 S8 _9 j
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);4 a5 L y4 ?1 P$ D/ _8 w. y/ X! ` {
3 K' } s* Z5 {- K, h1 J- }
- {0 t Q2 _) _ R O" }* \9 M& ` - / x: M+ u/ {0 D5 E# ~4 f$ V
& j% j1 l9 k- M2 `6 e$ E( s4 h- /*******************************************************************************" R+ I" e- o& t8 b
- * Function Name : GPIO_Configuration6 e9 e" N0 Z& i) x. E$ T2 m
- * Description : GPIO设置8 Y0 M( S2 e9 F; h, U8 d
- * Input : None( V# O9 U( ]( n0 Y. n# a
- * Output : None, _9 ]: ^- O+ U/ k6 o
- * Return : None
& e' V( Q0 s% c4 ^ - *******************************************************************************/1 `$ u6 Q- d' z$ ]- @+ y
- void GPIO_Configuration(void)) C8 l( o8 q, G. K
- {9 f5 V8 ^5 h! x+ t- e
- GPIO_InitTypeDef GPIO_InitStructure;, K+ }: V- \9 r& _0 t. [" I
. H- l/ ?, m/ ^7 i& I1 Q+ p- //PC口4567脚设置GPIO输出,推挽 2M
5 c0 @, ]. \( L' Q) W) j - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;" H! P: |" a- z8 l, E4 E
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;& e' v* c# U" N2 b; X+ U) f
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
7 y, V E5 x$ w S) H6 E - GPIO_Init(GPIOC, &GPIO_InitStructure);- H, ~8 ?1 K' M1 C4 X, P) H* ]! L
- n2 G* B$ n% y: l- //KEY2 KEY3 JOYKEY
# s7 c' ?- [4 M - //位于PD口的3 4 11-15脚,使能设置为输入
# W0 D. v c5 P1 h! I - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_11 | GPIO_Pin_12 |\: V3 A+ q% t8 b* O* O. N4 D" \) q
- GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;1 c. ?& V5 W n( z
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;7 d; j, K% @' o* @
- GPIO_Init(GPIOD, &GPIO_InitStructure);7 X. ]: m- L m; [7 [- K5 h
, x: h8 i* w( h# r! s- //USART1_TX) \' T; N; ^& E( I* o0 _
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
2 k# b" l: N4 F: W4 Z/ F7 N( Z0 k9 p - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;- g( t. {3 F8 n
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;2 c+ j" q: |: _* B
- GPIO_Init(GPIOA, &GPIO_InitStructure);) G' B6 q6 ^2 t3 k5 S
-
# c/ [, l3 B1 W% Q - //USART1_RX5 I& W& l- d: m. [
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
- l9 d9 r u6 s" S" Y2 p - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;/ L# M9 I: S* w1 Y
- GPIO_Init(GPIOA, &GPIO_InitStructure);
, `( A6 M% e1 U% Y" J% k - , d* C, s, U+ e+ E! P6 J1 w* u5 v
- //ADC_CH10--> PC0$ f* M$ P) b" Q/ m+ { A- A% W: T
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
) z9 q' B' u- j/ M2 u* e2 ?! e - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
! t, M) Q6 {( ?( S - GPIO_Init(GPIOC, &GPIO_InitStructure);
& t$ ^/ A2 J/ n0 i$ M
7 b4 T9 g( p) ~- `- }
$ \; x$ f/ Z8 j% {! Y; ` - ; K& c, X% J2 Q3 S& E% j
5 w. T) v/ x- x, g8 V/ P2 X& A
" u) ]5 _0 i: p% l. G- /******************************************************************************** I) M/ B- ?/ X* F
- * Function Name : NVIC_Configuration7 E1 j& i# O4 b
- * Description : NVIC设置/ @. {* L! l0 k# b" F" S
- * Input : None. S- }' B! L. A, a; H! @) V3 o
- * Output : None& |; _' z H/ d1 U- ]7 V- ]# z n
- * Return : None1 m, g5 z) P5 T0 m# m: J0 j
- *******************************************************************************/
w2 H+ R" K- ^( B) H) M4 Q1 v4 a- H - void NVIC_Configuration(void)9 q# W! T- h5 l, O
- {
5 o9 y; p& w# X# J# F1 l - NVIC_InitTypeDef NVIC_InitStructure;
: L" H2 ?3 X& F2 s1 O' J7 P+ R - 2 z0 R" i m& Z5 C* U/ B
- #ifdef VECT_TAB_RAM
. @8 X3 ?0 c4 _ - // Set the Vector Table base location at 0x20000000
, \4 y6 V- B) o6 S0 ? - NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
) O4 D" ^5 Z1 e! v* i" D; e/ m - #else /* VECT_TAB_FLASH */. i- v/ F( r% a
- // Set the Vector Table base location at 0x080000006 k9 k! q4 c# Y
- NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
9 q( g1 u) V0 d- l/ K. J: F - #endif
9 \+ H( w, n. y, P- _& [1 f - : X s X7 ?8 ^, W' m$ v' c
- //设置NVIC优先级分组为Group2:0-3抢占式优先级,0-3的响应式优先级/ q8 z. Q9 A; @* ~
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);3 Q+ J8 n. h# {/ e, Z8 R0 v
- //串口中断打开0 C2 f# C2 K+ b
- NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;4 R6 P# V1 z5 t8 _ f0 Z
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
$ w/ B1 P: q6 s0 @% H7 I - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;4 v9 w1 S2 h/ u8 k1 d! m
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
; s2 Z8 Q p4 j& f+ V$ _ - NVIC_Init(&NVIC_InitStructure);
1 c- l9 y9 e% ^- `. }% t/ Y - }, X2 y: K7 O- t; h, t
3 h1 J) X) }5 p" v
: U0 v3 N! }4 ]% K: B! T3 S& R# u- /*******************************************************************************
. y4 h7 z. O( b8 {: Z - * Function Name : USART1_Configuration
% M# ?# G! H8 O, ` - * Description : NUSART1设置1 k3 M- N6 d' s5 c, c% P9 g1 Q+ ^
- * Input : None
% _7 k8 l: G2 w% ]! q+ ~ - * Output : None [ O) M4 d6 c& d
- * Return : None
8 t5 |8 U; A7 [- v( J - *******************************************************************************/
9 Y1 g0 R0 L3 m5 F - void USART1_Configuration(void)
H1 M( B! F/ x! C+ Q' O' }9 p - {; Q% {7 b: x/ p
- USART_InitTypeDef USART_InitStructure;
) C0 L, R$ @& u4 |0 | - ' Y, }1 k( q0 G& |; i+ u" A: J
- USART_InitStructure.USART_BaudRate = 19200;6 [' `: Q( y5 g
- USART_InitStructure.USART_WordLength = USART_WordLength_8b;
& U+ r' J& r8 M8 l - USART_InitStructure.USART_StopBits = USART_StopBits_1;: \4 J+ p6 ~0 a
- USART_InitStructure.USART_Parity = USART_Parity_No;
' H# V! K8 c' w - USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;: F1 q G, t$ U7 Z% M$ s
- USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
W" l) V2 z2 U' Q! n; a7 B1 q - USART_Init(USART1, &USART_InitStructure);
$ R" q& Z" X# n4 [; l9 R -
! m8 K4 S7 g( N% y8 t% { - USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);8 M. L) X3 j$ e3 z5 Q+ N$ P
-
7 `, s5 |9 ~9 n( e) i - USART_Cmd(USART1, ENABLE);
5 A8 \! i0 U- Q. U$ F - }. {4 E. q* i6 t+ X; ~: }1 k h
- - j( N: B1 F8 r6 P/ w
- /*******************************************************************************- L, m4 x+ ]) m: J3 B) D
- * Function Name : ADC1_Configuration
* q7 E1 R# o3 X C/ q# l) k - * Description : ADC1设置(包括ADC模块配置和自校准)
: A5 |/ l# g; Y$ p) Q Q) p - * Input : None8 R4 D, ~. q) ~; n i
- * Output : None
6 I5 P* Z7 J! c% ] - * Return : None! z, ?: H7 l) R7 f E
- *******************************************************************************/
/ K, Z7 _" ]% A+ S" j& z8 y& f - void ADC1_Configuration(void)
8 S; ^8 W( c# j" o1 B$ W9 b - {
7 m0 s, C) j2 a6 }, v - ADC_InitTypeDef ADC_InitStructure;
5 l& K5 h% m7 _% x - - X d. G& w4 L' ~* a
- ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
- D- h* q! Q" I. d @1 }- d - ADC_InitStructure.ADC_ScanConvMode = ENABLE;
6 @- i7 [* u( A, b' s& |% S - ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //连续转换开启
! v. M% I: U5 v( h. h$ p: U - ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;* T# A0 V4 _( N# k8 R' g/ S
- ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
) o D; m( O0 b1 X& n4 H: a - ADC_InitStructure.ADC_NbrOfChannel = 2; //设置转换序列长度为2
1 n3 \- h" V( f+ J0 c3 p7 X) k - ADC_Init(ADC1, &ADC_InitStructure);/ N! Z6 |1 R5 t
- ( }! A8 \' M2 M6 r9 c5 {% G$ M( r, o, d
- //ADC内置温度传感器使能(要使用片内温度传感器,切忌要开启它)/ X( B" I% h7 f& ?, l
- ADC_TempSensorVrefintCmd(ENABLE);" i" m( T: c" j, U
- % S% g5 C& ^2 ?2 q2 Y" R( }( C" f( T
- //常规转换序列1:通道10
# Q. U" t) K) p" m; O5 F4 [ - ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_13Cycles5);
$ O: X. d9 h3 I ^8 h - //常规转换序列2:通道16(内部温度传感器),采样时间>2.2us,(239cycles)
. o. J1 ]- r, D( L - ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 2, ADC_SampleTime_239Cycles5);
( c+ `- i+ x, v& c3 W) V - # g+ y' R- j7 _+ j2 ~9 T+ \
- // Enable ADC10 g; w+ K2 u' G6 s# O
- ADC_Cmd(ADC1, ENABLE);, V; q6 F6 B) ~" w
- // 开启ADC的DMA支持(要实现DMA功能,还需独立配置DMA通道等参数)( v+ f ^2 {/ U* W. X3 h
- ADC_DMACmd(ADC1, ENABLE);# i8 `. f; h' z# M9 |
-
& N) Y0 y8 L/ f% x& L2 L8 y - // 下面是ADC自动校准,开机后需执行一次,保证精度- \ d, U8 A; j
- // Enable ADC1 reset calibaration register
& x! X& m8 {6 a% f/ |2 v* o - ADC_ResetCalibration(ADC1);8 G! w+ ?" O8 H9 L7 z# O+ c
- // Check the end of ADC1 reset calibration register
6 j. \+ R) I$ K9 V) p. ~. b$ g$ A - while(ADC_GetResetCalibrationStatus(ADC1));( X5 Y$ Z2 J8 i% Z2 l# x3 f
- . ]9 u+ W7 z" o: Z, S8 W
- // Start ADC1 calibaration9 |2 q; i) _- y7 _
- ADC_StartCalibration(ADC1);( \, K4 ~; W) L# m. p
- // Check the end of ADC1 calibration. \- G5 B/ X) H8 K( ]3 U F* A
- while(ADC_GetCalibrationStatus(ADC1));' x+ p( A6 q8 {& e0 L
- // ADC自动校准结束---------------
) Z8 {! a3 t/ e - 1 e% }6 C/ d7 T
- }( r& U- L; |& H( O
5 R; H E: Q. \4 p5 M3 v' I- /*******************************************************************************" N. p9 R4 _) I. H; u! t M
- * Function Name : DMA_Configuration2 {% m" k: O' l2 s8 z/ M7 g* k
- * Description : DMA设置:从ADC模块自动读转换结果至内存5 {: ]7 J5 z6 B( i1 ]
- * Input : None
+ U: T+ a* [" z0 s& Q - * Output : None
# T0 e) e9 G) U! A4 `; U A1 i - * Return : None
& [3 \* _! k" R4 [0 | - *******************************************************************************/& q* ?, G0 Y& ~7 z" S4 _" r: c
- void DMA_Configuration(void)3 O. m+ l1 O+ i+ _9 H4 B
- {
2 }, Z4 D$ ~9 f - DMA_InitTypeDef DMA_InitStructure;$ j) B8 A/ Z! v4 i1 |
-
- t! x6 A% P6 e1 s; D/ u - DMA_DeInit(DMA1_Channel1);
8 s/ V9 i. A3 \( Y' l: w( Y - DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
2 v& N0 @* l% R - DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&AD_Value;
$ Q4 n @$ I8 ~, v, h - DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;4 K# R2 r$ L$ c1 w4 F: z# s2 W9 w
- //BufferSize=2,因为ADC转换序列有2个通道
: W3 p2 ?. b3 w U' y. [; T7 T. _ - //如此设置,使序列1结果放在AD_Value[0],序列2结果放在AD_Value[1]1 }3 s' P- z, Z- n3 _4 ?
- DMA_InitStructure.DMA_BufferSize = 2;
- O: H; l: v& |! t; B$ P - DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;2 K3 W& N* ^. v6 K9 s
- DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
# P) ]: J- h& A, E' n4 R* ^- ~ - DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
/ @6 }* K; l9 f# \# ` - DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
! P6 `* A) C. x! a0 l% Z/ K8 \ - //循环模式开启,Buffer写满后,自动回到初始地址开始传输
, f1 O. ?" }, F# h) ~4 A - DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
! d: E& T5 o8 J2 c9 Q3 J1 r - DMA_InitStructure.DMA_Priority = DMA_Priority_High;
8 O* L+ B }1 y, L - DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
0 ~% f S, z% Z3 T8 [ - DMA_Init(DMA1_Channel1, &DMA_InitStructure);
' I6 {4 H& ]' \- Z+ M8 z - //配置完成后,启动DMA通道% B+ j+ a. U& S# k4 \; r' F9 k
- DMA_Cmd(DMA1_Channel1, ENABLE);# |! B9 n3 U2 q
- }
9 X$ i5 M, B7 M0 x7 V0 ^$ B! D
复制代码 5 U. s2 r8 V6 J
. b I: u; H8 Z$ i
|