你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32 MSN&Dial

[复制链接]
gzweiyan-44649 发布时间:2009-2-14 14:21
6 i+ K$ q) I5 x
一.实验内容! m0 q" c+ N- A' F( B
基于stm32平台控制手机模块拨打电话,取消拨打电话以及发送短信。$ ]( ?, r1 j4 u
按下WKUP键拨打电话,按下Tamper键则取消拨打,按下SEL键就以短信形式发送一串英文字符到手机。
8 I- ^/ a8 x, p. g二.实验流程
6 [0 R5 V4 w2 ~! f7 X7 d
' q/ P. m& u  j7 K% R5 ^/ Q . A) y# ?9 I! a, x4 H, h
三.实验结果) ~; ?  E3 V* D. j$ N
按下WKUP键,拨通手机;按下Tamper键截断通话;按下SEL键往手机发送短信。
. t! z" T6 S. d. J6 I" [/ w# Y四.实现原理
5 H8 w- `5 J! @. ~# H( P! A' ~+ u4.1拨打电话命令为atd+电话号码+分号+回车,只要通过串口往手机模块发送这一串命令就可以实现拨打电话
# E- Z/ k" h$ ^3 P功能。
9 }5 }+ Z* N3 c3 ^# h+ D4 @7 s: w# Y4.2截止拨号命令为ath+回车,理解方式是at+hold(举起或停下来),同样,拨打的相对应at指令为atd可以理7 d( h9 Y( E# a! H/ B
解为at+dial(拨打)
' J% i, C0 @% T, N  k+ J) c4.3发送短信的命令相比拨打电话和截止拨号有点复杂,具体分为三步。第一步设置短信消息的格式,第二步' @2 }+ c! V4 g
设置接收短信的手机号码,第三步就是编写短信消息的内容。"AT+CMGF=1\r\n",作用是设置短信消息为英文
% Z) T, e; R+ f. |* z格式,手机模块接到这串命令之后会返回" OK \r\n",那么STM32不停循环检测串口返回来的信息,直至出现* \" S' p( z5 G
回车符才进行下一步动作。接着往手机模块发送"AT+CMGS=\"13800138000\"\r\n",作用是设置短信接收的手/ x6 E+ L: I6 w; B( |
机号码,接着手机模块会返回'>'符号,同理STM32不停循环检测串口接收的信息,直至出现'>'才进行下一步
# S" x! Y' D  Y" |. F% ?% k4 a动作。下一步就是往手机模块发送"We are the best team!\x1a",“We are the best team!”为信息的内
! S0 j: s5 R8 Z. Z: x容,字符” \x1a”为键盘“CTRL+Z”的ASCII码值。这里分为三步,每一步都要完成动作之后才能进行下一+ ~0 q! z2 j1 U
步,假如不循环检测串口返回的信息,一连串往手机模块发送三串命令,手机模块会相应不来,导致丢失部
3 O+ p$ ]! g/ s1 U; t9 m- E! \# e分命令的后果。
2 |/ j& C: ]3 E: k. o' X9 v( k) D2 ?0 V% |! H7 Z, M. R6 _
主循环:6 t9 o- S. P6 x' X
while(1)
- @- w+ i) r9 e1 W, C" L { //如果按下WKUP键,则拨打号码为“13800138000”的手机
7 {% J# A: _) w8 Q% t* Q, K2 e if(!GPIO_Keypress(GPIO_WKUP, BUT_WKUP))
( p! h$ [/ m! }8 S  Serial_PutString("atd13800138000;\r\n");( B: B( u( {, `6 l/ z
  while(!GPIO_Keypress(GPIO_WKUP, BUT_WKUP));
) E/ `4 C: t/ y$ k' v* g$ ` //如果按下Tamper键,则截止通话" V( R0 l0 m* Z; `% S) Y
    if(GPIO_Keypress(GPIO_KEY, BUT_Tamper))" \  t- O1 W2 |7 y9 F3 D
  Serial_PutString("ATH\r\n");
+ ~3 j& Y0 T8 a' g- A' S( S% |  while(GPIO_Keypress(GPIO_KEY, BUT_Tamper));7 J% T8 ~: G7 h( @$ a
 //如果按下SEL键,则调用MSN()函数,达到发送短信的目的
5 q+ q6 D: l+ G    if(GPIO_Keypress(GPIO_KEY, BUT_SEL))
" n- A" ~* R5 W/ V0 m& Y5 y8 M  MSN();( R4 b% Q2 y0 x' K- a+ ^2 Z
  while(GPIO_Keypress(GPIO_KEY, BUT_SEL));
7 r# F9 h8 X. A. S //延迟的作用为简单的防按键抖动功能4 G6 w/ b9 M  |8 ~' e/ a+ l
 Delay(100);$ c  D) Z2 s7 V8 U
 }! `! _% b  Y* F# }; z
发送短信的命令:
$ u1 b' x9 G' ~. A/ ]$ P7 Tvoid MSN(void)
) F% L. R, c3 |/ z# ~! D9 }$ {{u8 word;
& y9 c2 d+ l: F  @3 f4 [  Serial_PutString("AT+CMGF=1\r\n");         //设置短信消息为英文格式
8 x; U9 p" g9 d' P$ E0 Q  while(1), o4 N5 |6 _# F2 O0 |) R
   {word=USART_ReceiveData(USART3);
7 r3 {1 e' K9 i- A: I, Q: V    if(word=='\n')
% r( t8 y% {7 l5 ?2 g- m% p    break;
% |* F0 B) j9 I/ F# q; N    }
  z3 Q$ I% O5 R, s8 L& X& Q6 F$ f4 Z7 H Serial_PutString("AT+CMGS=\"13800138000\"\r\n");   //设置短信接收的号码* z7 l4 I: }2 `, g: N+ d0 B
 while(1)* _( r+ H" o  @  q5 J
   {word=USART_ReceiveData(USART3);
6 E. A4 w. f0 X% Q+ S* l, h2 y: M    if(word=='>')
- ]: `& _6 m$ {+ @- m6 f) U    break;0 p+ n! M. O+ {8 e7 j
    } ' W7 t) M4 V8 y  _9 n/ m4 C
 Serial_PutString("We are the best team!\x1a");    //编写短信内容
! L) w$ M. O+ I2 ? while(1)* E* `6 Q6 |" ?1 i& _$ c2 p
   {word=USART_ReceiveData(USART3);6 u# n* v1 O" }, l: L5 N
    if(word=='\n')0 I" w; T% r/ s& ~7 B' x
    break;
( c  s  v' o7 a  h- [) ^4 P- y    }% r+ `3 T1 T* S! k; K6 ]( w
 }7 L% X% B/ z, z5 y+ C7 s
五.程序深入分析
* F/ s, h8 s& R* [) j5.1 ( n0 |. j4 h$ @9 r& L
STM32需要用到的每一只引脚都需要使能引脚时钟,本程序需要用到三个按键以及一个串口(USTAR3),其中两
# B% e* i4 H8 i$ w/ ]个按键在PC口,一个按键在PA口,程序在RCC_Configuration()函数里面实现:+ j, O2 R/ K$ U$ Q, ]% ?3 ~
/*使能GPIOx 时钟 */
/ x& ]- J3 y9 U! C$ } RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOx, ENABLE);
( J0 j6 S$ C. _/* 使能USARTx 时钟 */& y5 s5 i) ~: l# b
RCC_APB1PeriphClockCmd(RCC_APB_Periph_USARTx, ENABLE);1 s$ _6 ]# a0 X. R
/* 使能按键引脚时钟 */
# O( x3 N* ~7 d$ Y- Q1 j  Q  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO| RCC_APB2Periph_GPIO_BUTTON | 4 G. b. M! ]1 q. S9 C1 Z. T9 R
RCC_APB2Periph_GPIO_WKUP , ENABLE);) o  D# S$ U! y! q* W# J5 k
5.2# \3 Q1 _1 Z3 s( Q3 u5 i0 c
STM32每一只引脚都有复用功能,所以用到的每一只引脚都需要配置引脚的功能,程序在  M0 U- N; q: {/ t& V
GPIO_Configuration()函数里面实现:- `% X9 c* ]( r
GPIO_InitTypeDef GPIO_InitStructure;
- A- i6 [4 @' s! j  GPIO_PinRemapConfig(GPIO_PartialRemap_USART3, ENABLE);
3 k& S6 G- p) `# j  /* 设置USARTx_Tx 为复用推挽输出,频率为50MHz */
: y" |; r/ x: ?  X5 R  GPIO_InitStructure.GPIO_Pin = GPIO_TxPin;
# X8 S( d; E+ f  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
/ k/ W2 m+ d  ?: G) s  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;* [& ?4 X4 Y4 x
  GPIO_Init(GPIOx, &GPIO_InitStructure);/ m& [) q, y4 x! G" m! m$ C
  /* 设置USARTx_Rx为浮空输入,频率为50MHz */+ s3 C7 [2 O: O. @- y$ ~; M
  GPIO_InitStructure.GPIO_Pin = GPIO_RxPin;; }9 D8 w. w' e- q: |7 ~& c: O
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
6 Q0 ]7 Y3 p) M" V  \8 b  GPIO_Init(GPIOx, &GPIO_InitStructure);
, n$ ^' B1 y* }$ j( T  /* 设置按键引脚为浮空输入,频率为2MHz */7 a, P$ `0 I' P1 `! G* L
  GPIO_InitStructure.GPIO_Pin = BUT_LEFT | BUT_RIGHT | BUT_UP | BUT_DOWN | BUT_Tamper | % j2 D. F- |3 n  ?) a2 ^
BUT_SEL;0 J, x7 p* X- R8 s" l! `% X; k* `
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;+ w1 j3 X8 M( A0 m! e; N  M: E
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;; X* t) l% V$ v' V- C
  GPIO_Init(GPIO_KEY, &GPIO_InitStructure);2 `+ w6 q* b' a. u& x# z6 P) [
  GPIO_InitStructure.GPIO_Pin = BUT_WKUP;
( j6 R+ E; S# y$ ^) j9 W) `  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;( n0 L! v( s1 v2 v
  GPIO_Init(GPIO_WKUP, &GPIO_InitStructure);* P5 Y6 }! M, j9 n- S& a( o
引脚的配置有三项,Pin、Speed与Mode,在设置USARTx_Tx时把三项都设置了,而在设置USART_Rx时却只设置
' f% M$ C) b6 z- r了两项,其中Speed没有设置,则保持上一次设置的状态,也就是在设置USART_Tx时的50MHz。同理在设置上
* C1 y6 b9 p5 C1 H% d5 c3 [+ p% N下左右与Tamper、SEL键对应引脚时都设置了三项,而设置WKUP键对应引脚时只是配置了两项。, t- N& c( V( W  a) K3 c
5.3 在主函数的死循环里面最后一步是调用delay()函数来延迟100ms,作用是防止按键的抖动。而delay6 U3 b+ |3 r. a4 _% C- Z
函数的实现是通过调用SysTick时钟源溢出中断来实现的,SysTick时钟源在main函数的开头设置了为1ms中断# [0 C# q* V9 \/ ~( m
一次。
( r- ^$ _2 i  w5 [' P- ~9 u5.4 主程序是通过串口3和手机模块通信的,而波特率设置为115200,程序如下:
' n9 m8 l0 \/ kUSART_InitStructure.USART_BaudRate = 115200;% I* c# u2 [0 R! ~' O/ W
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
: ]4 X/ [, c! q' S- }/ C* x  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  e1 \# ]: X# M5 P0 v  USART_InitStructure.USART_Parity = USART_Parity_No ;
3 Q9 _  n7 |7 Z, L0 s9 v! r: H' N  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
3 g* n3 @) V# \$ j, @! {  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
/ [# }( N( b4 b( K) B/ p8 D  G- i5 b其实手机模块也有其通讯频率的,假如两者的频率不同,那么就不能达到通讯的目的,现在就让我们来看看
& Q; }9 u. x+ W4 K; o5 @如何查看和修改手机模块的通讯频率。硬件的连接很简单,只需要把手机模块的电源接上,插上手机模块和
7 F' a0 j& Q6 N+ l8 N) T! V手机卡,用USB转串口线把电脑和手机模块连接起来,打开SecureCRT软件,并设置好通讯频率。假如软件设
5 ?9 J% @2 G# b6 G! g: q# G置的通信频率和手机模块的实际频率不同,那么在软件的窗口就会出现乱码。现在有一个疑问啦,假如手机: t3 p' L. F7 f0 |) X+ `8 B
模块刚买回来,不知道通信频率怎么办,不用担心,手机模块如果没经设置,它的通讯频率是默认第一次接
5 ?2 ~0 F4 r! i* z  a- b1 C0 {4 L4 q收数据的数据频率。下面举例子把手机模块的通讯频率由115200改为57600,具体操作如下:
5 P- R- g# h2 E  c8 }2 _" {$ A- [4 q
 9 o$ N" [, n% R
指令at+ipr?的作用为查看当前手机模块的通讯频率,at+ipr=115200为设置手机模块的当前通讯频率。回车
5 T) a: z. r6 k, t: N6 U3 L& n之后,再次输入数据就会出现乱码,因为手机模块的通讯频率已经修改了,现在只需停止串口软件通信,然# C0 l1 f4 c1 m- x
后把软件的通讯频率改为115200就可以了。9 y- X+ |  E; Y& N& B
6 u! Z, a: s+ O8 J& J! l
伟研科技,http://www.gzweiyan.com/html/products/20081201/56.html
赞 收藏 评论0 发布时间:2009-2-14 14:21

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版