![]() 一.实验内容3 y0 q. A6 l4 G3 _) z9 [ 基于stm32平台控制手机模块拨打电话,取消拨打电话以及发送短信。 按下WKUP键拨打电话,按下Tamper键则取消拨打,按下SEL键就以短信形式发送一串英文字符到手机。 二.实验流程1 i/ M! f2 ^" G: b7 @1 R" _* m5 f8 d $ m* d" h8 I% _) I三.实验结果 按下WKUP键,拨通手机;按下Tamper键截断通话;按下SEL键往手机发送短信。 四.实现原理 4.1拨打电话命令为atd+电话号码+分号+回车,只要通过串口往手机模块发送这一串命令就可以实现拨打电话 功能。 4.2截止拨号命令为ath+回车,理解方式是at+hold(举起或停下来),同样,拨打的相对应at指令为atd可以理 解为at+dial(拨打)* P# w' V' @; h/ \ 4.3发送短信的命令相比拨打电话和截止拨号有点复杂,具体分为三步。第一步设置短信消息的格式,第二步 设置接收短信的手机号码,第三步就是编写短信消息的内容。"AT+CMGF=1\r\n",作用是设置短信消息为英文 格式,手机模块接到这串命令之后会返回" OK \r\n",那么STM32不停循环检测串口返回来的信息,直至出现( s- n3 s" C ? 回车符才进行下一步动作。接着往手机模块发送"AT+CMGS=\"13800138000\"\r\n",作用是设置短信接收的手 机号码,接着手机模块会返回'>'符号,同理STM32不停循环检测串口接收的信息,直至出现'>'才进行下一步 动作。下一步就是往手机模块发送"We are the best team!\x1a",“We are the best team!”为信息的内% z& N; m6 W/ U( l, h t8 j 容,字符” \x1a”为键盘“CTRL+Z”的ASCII码值。这里分为三步,每一步都要完成动作之后才能进行下一 步,假如不循环检测串口返回的信息,一连串往手机模块发送三串命令,手机模块会相应不来,导致丢失部8 B) f# H3 k; Y( c' h: @4 p 分命令的后果。- C) I. e" `" m. k3 X 主循环:) ]' }: n7 y7 u( f) [, x while(1)/ i+ S, o, }/ ~' o- J { //如果按下WKUP键,则拨打号码为“13800138000”的手机 if(!GPIO_Keypress(GPIO_WKUP, BUT_WKUP))+ A; B: X( H6 }+ J2 J Serial_PutString("atd13800138000;\r\n"); while(!GPIO_Keypress(GPIO_WKUP, BUT_WKUP));. y6 D7 {4 _- R //如果按下Tamper键,则截止通话+ \! q/ b. S3 ?( ] if(GPIO_Keypress(GPIO_KEY, BUT_Tamper)) Serial_PutString("ATH\r\n");8 m, |1 l: L- P* Q while(GPIO_Keypress(GPIO_KEY, BUT_Tamper));: [- X- {- A, L1 m& { //如果按下SEL键,则调用MSN()函数,达到发送短信的目的 if(GPIO_Keypress(GPIO_KEY, BUT_SEL)): G$ W( S5 |7 i' r MSN();) t2 b' P1 l4 g! d while(GPIO_Keypress(GPIO_KEY, BUT_SEL)); //延迟的作用为简单的防按键抖动功能 Delay(100); } 发送短信的命令:3 O1 ^' L6 y" f& K) K+ e void MSN(void) {u8 word;6 ]2 f0 y z7 `3 P& p Serial_PutString("AT+CMGF=1\r\n"); //设置短信消息为英文格式7 D, u8 d# p2 N7 y) w0 D5 p while(1)! ?: t0 H3 q f; D4 w& T) [ {word=USART_ReceiveData(USART3);' t- \5 W; |/ G' v' U2 e F if(word=='\n')$ t8 B" U7 X( M" B% {" L! i" s/ j5 y# d break; } Serial_PutString("AT+CMGS=\"13800138000\"\r\n"); //设置短信接收的号码% Q6 t- N0 x* z1 ?8 { while(1)' K5 l4 x4 @/ L {word=USART_ReceiveData(USART3); if(word=='>') break;. J/ L! Z- K4 Z$ M } Serial_PutString("We are the best team!\x1a"); //编写短信内容2 N# M* s7 T4 F8 P' b while(1)2 d: e' K0 p: {# S9 Y {word=USART_ReceiveData(USART3);+ _% j9 ~1 l$ y8 ]; }# ~( O if(word=='\n') break;5 e! U. r9 d5 ?8 ^9 M; x0 @ } } 五.程序深入分析" {, ~6 O1 y: O* d4 z' M, K 5.1 5 H" B7 p* M9 q" A0 K STM32需要用到的每一只引脚都需要使能引脚时钟,本程序需要用到三个按键以及一个串口(USTAR3),其中两/ r7 H; v; e1 Z: {9 C9 y b; m 个按键在PC口,一个按键在PA口,程序在RCC_Configuration()函数里面实现:' W( v# T/ ~1 k L' i; }8 c /*使能GPIOx 时钟 */+ ]! Q3 v' u( C3 A RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOx, ENABLE);5 D3 \6 X5 J: a! Z" G) q /* 使能USARTx 时钟 */ RCC_APB1PeriphClockCmd(RCC_APB_Periph_USARTx, ENABLE);( \( y0 j5 i4 o /* 使能按键引脚时钟 */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO| RCC_APB2Periph_GPIO_BUTTON | RCC_APB2Periph_GPIO_WKUP , ENABLE);% Z$ w# m5 [; \& e) ?9 q 5.2 STM32每一只引脚都有复用功能,所以用到的每一只引脚都需要配置引脚的功能,程序在7 D9 w0 ` ]* h( P# b2 C, P" J GPIO_Configuration()函数里面实现:, F0 t& p' A& N. D# X- | GPIO_InitTypeDef GPIO_InitStructure;( s0 S: X, s' l2 x$ _ GPIO_PinRemapConfig(GPIO_PartialRemap_USART3, ENABLE);3 \! B* @0 m- a1 ~6 s, U4 q /* 设置USARTx_Tx 为复用推挽输出,频率为50MHz */3 w& D9 w7 r/ n; V9 R1 g! k GPIO_InitStructure.GPIO_Pin = GPIO_TxPin;( N: l3 D1 ?2 f GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOx, &GPIO_InitStructure); /* 设置USARTx_Rx为浮空输入,频率为50MHz */- s% o- E$ I- W. u# N2 E8 e# P4 H GPIO_InitStructure.GPIO_Pin = GPIO_RxPin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;. }, S% b; a! C* t" z GPIO_Init(GPIOx, &GPIO_InitStructure); /* 设置按键引脚为浮空输入,频率为2MHz */' D' I# G) u3 N' [+ O0 p; t GPIO_InitStructure.GPIO_Pin = BUT_LEFT | BUT_RIGHT | BUT_UP | BUT_DOWN | BUT_Tamper | BUT_SEL;: ^) t, b% O1 A6 m2 n GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;* j2 D6 w4 h: c6 ] GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIO_KEY, &GPIO_InitStructure);7 A/ |) z; I1 G GPIO_InitStructure.GPIO_Pin = BUT_WKUP;. u9 N) x4 S% t1 H3 c2 A6 P6 X( H GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;8 b" v5 _9 d, g' V: X# v" t4 ]: N& N GPIO_Init(GPIO_WKUP, &GPIO_InitStructure); 引脚的配置有三项,Pin、Speed与Mode,在设置USARTx_Tx时把三项都设置了,而在设置USART_Rx时却只设置3 v& v# Q( o6 N% P, C 了两项,其中Speed没有设置,则保持上一次设置的状态,也就是在设置USART_Tx时的50MHz。同理在设置上 下左右与Tamper、SEL键对应引脚时都设置了三项,而设置WKUP键对应引脚时只是配置了两项。) ~+ p: U# B& U/ Q/ S! T# |% O; W 5.3 在主函数的死循环里面最后一步是调用delay()函数来延迟100ms,作用是防止按键的抖动。而delay) L" J2 J* h9 z* B% ` 函数的实现是通过调用SysTick时钟源溢出中断来实现的,SysTick时钟源在main函数的开头设置了为1ms中断 一次。1 i' e' J* v" R. T/ P 5.4 主程序是通过串口3和手机模块通信的,而波特率设置为115200,程序如下: USART_InitStructure.USART_BaudRate = 115200;) |8 {0 j7 M: v) i USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; d9 U( w! k: {! y1 K! y USART_InitStructure.USART_Parity = USART_Parity_No ;: G e/ \' Q) B3 O5 l USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;2 Z4 V1 J3 m% I0 E* X8 v$ j USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; 其实手机模块也有其通讯频率的,假如两者的频率不同,那么就不能达到通讯的目的,现在就让我们来看看" w, V* E& V8 @# Z: [7 \5 g8 V 如何查看和修改手机模块的通讯频率。硬件的连接很简单,只需要把手机模块的电源接上,插上手机模块和: N' w# ~0 `# w- v 手机卡,用USB转串口线把电脑和手机模块连接起来,打开SecureCRT软件,并设置好通讯频率。假如软件设 置的通信频率和手机模块的实际频率不同,那么在软件的窗口就会出现乱码。现在有一个疑问啦,假如手机 模块刚买回来,不知道通信频率怎么办,不用担心,手机模块如果没经设置,它的通讯频率是默认第一次接6 e$ I7 o, U! H/ E 收数据的数据频率。下面举例子把手机模块的通讯频率由115200改为57600,具体操作如下: , e: _: k L8 C) ]( ~$ \6 Y) @ Q& p) ]4 [ 指令at+ipr?的作用为查看当前手机模块的通讯频率,at+ipr=115200为设置手机模块的当前通讯频率。回车% }, V4 O' v& @7 e* k$ E 之后,再次输入数据就会出现乱码,因为手机模块的通讯频率已经修改了,现在只需停止串口软件通信,然! {; b: n* D& S5 N' W* G& D# v+ @ 后把软件的通讯频率改为115200就可以了。4 h( W5 U/ z0 n8 t" u 伟研科技,http://www.gzweiyan.com/html/products/20081201/56.html |
微信公众号
手机版