
![]() 一.实验内容 基于stm32平台控制手机模块拨打电话,取消拨打电话以及发送短信。 按下WKUP键拨打电话,按下Tamper键则取消拨打,按下SEL键就以短信形式发送一串英文字符到手机。4 o% f8 f! e6 x$ g) B- u) Z5 X 二.实验流程 ![]() - E. y! r" t7 A7 K1 |7 x 三.实验结果 按下WKUP键,拨通手机;按下Tamper键截断通话;按下SEL键往手机发送短信。7 m/ {) m, ?: V) I: h8 f: Z 四.实现原理 4.1拨打电话命令为atd+电话号码+分号+回车,只要通过串口往手机模块发送这一串命令就可以实现拨打电话: n1 p( [8 C5 S( m0 `& t 功能。 4.2截止拨号命令为ath+回车,理解方式是at+hold(举起或停下来),同样,拨打的相对应at指令为atd可以理 解为at+dial(拨打)) H m* B0 X5 l) T, F' e1 a; j1 k1 O 4.3发送短信的命令相比拨打电话和截止拨号有点复杂,具体分为三步。第一步设置短信消息的格式,第二步% W* d+ ]9 L! r: R) Y1 d 设置接收短信的手机号码,第三步就是编写短信消息的内容。"AT+CMGF=1\r\n",作用是设置短信消息为英文' X1 f& ?$ M+ g1 G' m 格式,手机模块接到这串命令之后会返回" OK \r\n",那么STM32不停循环检测串口返回来的信息,直至出现 回车符才进行下一步动作。接着往手机模块发送"AT+CMGS=\"13800138000\"\r\n",作用是设置短信接收的手. @3 F; l# u8 j9 Z( f$ e2 y9 ? 机号码,接着手机模块会返回'>'符号,同理STM32不停循环检测串口接收的信息,直至出现'>'才进行下一步& s7 T# y+ M& e( O* _ 动作。下一步就是往手机模块发送"We are the best team!\x1a",“We are the best team!”为信息的内 容,字符” \x1a”为键盘“CTRL+Z”的ASCII码值。这里分为三步,每一步都要完成动作之后才能进行下一 步,假如不循环检测串口返回的信息,一连串往手机模块发送三串命令,手机模块会相应不来,导致丢失部 分命令的后果。" @/ m8 r+ q& j0 F: m5 u ' z+ c6 L3 h/ u: u 主循环: while(1) { //如果按下WKUP键,则拨打号码为“13800138000”的手机* Z0 Y; _! k } if(!GPIO_Keypress(GPIO_WKUP, BUT_WKUP)); p) a, J( t6 E$ k( \ Serial_PutString("atd13800138000;\r\n");0 b$ u5 t- `. g' ?( U8 j while(!GPIO_Keypress(GPIO_WKUP, BUT_WKUP));. X3 c8 N F% u# v9 P, a //如果按下Tamper键,则截止通话 if(GPIO_Keypress(GPIO_KEY, BUT_Tamper)) Serial_PutString("ATH\r\n"); while(GPIO_Keypress(GPIO_KEY, BUT_Tamper));8 q6 m5 k& M5 r% L6 @6 D) R //如果按下SEL键,则调用MSN()函数,达到发送短信的目的$ U+ u7 ~, H; |" O1 C if(GPIO_Keypress(GPIO_KEY, BUT_SEL))4 K$ ~, ]9 w1 c) \: \; ] MSN();# k- F9 m+ l4 H0 A9 L, r while(GPIO_Keypress(GPIO_KEY, BUT_SEL));! h4 h; ?" Q b! J$ ` //延迟的作用为简单的防按键抖动功能 Delay(100); } 发送短信的命令:, n* B6 c4 k p N# }5 I void MSN(void) {u8 word; Serial_PutString("AT+CMGF=1\r\n"); //设置短信消息为英文格式 while(1) {word=USART_ReceiveData(USART3);( p3 w2 e6 B4 A6 Z if(word=='\n')% Z& C8 D/ R1 J+ E9 e break; } Serial_PutString("AT+CMGS=\"13800138000\"\r\n"); //设置短信接收的号码& \! y$ y0 w0 x, T, L7 V while(1)3 m# r9 D4 Y; `& T$ ~# K {word=USART_ReceiveData(USART3);3 P2 B. c' d) L7 X5 _6 N( { if(word=='>')6 e! g6 [6 c3 ~+ d1 i break; } Serial_PutString("We are the best team!\x1a"); //编写短信内容 while(1) {word=USART_ReceiveData(USART3); if(word=='\n') break; } }$ k7 x6 z% @+ }& B8 X ~& S+ K: F 五.程序深入分析 5.1 8 U4 ]/ d9 ~' F STM32需要用到的每一只引脚都需要使能引脚时钟,本程序需要用到三个按键以及一个串口(USTAR3),其中两! B+ d& _, d) p! C4 R3 N- y: J 个按键在PC口,一个按键在PA口,程序在RCC_Configuration()函数里面实现:6 v4 f" F9 [& ~7 F ~/ b$ E! j: S /*使能GPIOx 时钟 */1 b% L3 H# ?$ @2 D RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOx, ENABLE); /* 使能USARTx 时钟 */4 T$ t4 ^6 f5 P RCC_APB1PeriphClockCmd(RCC_APB_Periph_USARTx, ENABLE); /* 使能按键引脚时钟 */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO| RCC_APB2Periph_GPIO_BUTTON | & |5 B) U8 J# k1 O; V RCC_APB2Periph_GPIO_WKUP , ENABLE); 5.2 STM32每一只引脚都有复用功能,所以用到的每一只引脚都需要配置引脚的功能,程序在 GPIO_Configuration()函数里面实现:4 j5 _: d3 _% a5 H: Z$ a GPIO_InitTypeDef GPIO_InitStructure;6 G9 a8 U* n4 n3 E; y8 D/ S) \: d3 f GPIO_PinRemapConfig(GPIO_PartialRemap_USART3, ENABLE); /* 设置USARTx_Tx 为复用推挽输出,频率为50MHz */ GPIO_InitStructure.GPIO_Pin = GPIO_TxPin; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;" F4 ?4 z" D8 U/ e GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOx, &GPIO_InitStructure); /* 设置USARTx_Rx为浮空输入,频率为50MHz */; c% X) E3 D4 X( I/ |1 C GPIO_InitStructure.GPIO_Pin = GPIO_RxPin;7 n# S0 {( d! P9 W GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOx, &GPIO_InitStructure); /* 设置按键引脚为浮空输入,频率为2MHz */ GPIO_InitStructure.GPIO_Pin = BUT_LEFT | BUT_RIGHT | BUT_UP | BUT_DOWN | BUT_Tamper | BUT_SEL;; P6 a0 ]: B9 G* y0 [7 F GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;' } q) C! V' j5 M4 o GPIO_Init(GPIO_KEY, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = BUT_WKUP; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;( |. s9 z' F% Z4 z' r# ^, K GPIO_Init(GPIO_WKUP, &GPIO_InitStructure); 引脚的配置有三项,Pin、Speed与Mode,在设置USARTx_Tx时把三项都设置了,而在设置USART_Rx时却只设置 了两项,其中Speed没有设置,则保持上一次设置的状态,也就是在设置USART_Tx时的50MHz。同理在设置上$ e# w* {% @' @* _' o% L9 v9 B 下左右与Tamper、SEL键对应引脚时都设置了三项,而设置WKUP键对应引脚时只是配置了两项。8 W/ U! b# f/ T7 [( i; c 5.3 在主函数的死循环里面最后一步是调用delay()函数来延迟100ms,作用是防止按键的抖动。而delay 函数的实现是通过调用SysTick时钟源溢出中断来实现的,SysTick时钟源在main函数的开头设置了为1ms中断 一次。7 I' L# o3 H4 V- m& B/ t 5.4 主程序是通过串口3和手机模块通信的,而波特率设置为115200,程序如下:! V: @/ S( B& [5 h. ~4 q- A USART_InitStructure.USART_BaudRate = 115200;. ^( D' J# R8 k* R! N+ G USART_InitStructure.USART_WordLength = USART_WordLength_8b;+ j4 o4 x5 G" T; e# I2 y USART_InitStructure.USART_StopBits = USART_StopBits_1;( B* k+ ~& P8 w n: t7 m4 k USART_InitStructure.USART_Parity = USART_Parity_No ; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;6 Y/ S- o3 {* k% q* d$ ?6 h USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;" H2 Y5 X9 l: K( g2 G' ? 其实手机模块也有其通讯频率的,假如两者的频率不同,那么就不能达到通讯的目的,现在就让我们来看看! i6 ?: H5 \4 V" }, l7 \( l 如何查看和修改手机模块的通讯频率。硬件的连接很简单,只需要把手机模块的电源接上,插上手机模块和% C: E- e X0 { 手机卡,用USB转串口线把电脑和手机模块连接起来,打开SecureCRT软件,并设置好通讯频率。假如软件设 置的通信频率和手机模块的实际频率不同,那么在软件的窗口就会出现乱码。现在有一个疑问啦,假如手机/ Y% Y% {, K: M0 s' n6 f 模块刚买回来,不知道通信频率怎么办,不用担心,手机模块如果没经设置,它的通讯频率是默认第一次接8 U8 k8 d# k' o; d% _5 m 收数据的数据频率。下面举例子把手机模块的通讯频率由115200改为57600,具体操作如下: ![]() " \; ^+ x- P) R! ^5 j/ B 指令at+ipr?的作用为查看当前手机模块的通讯频率,at+ipr=115200为设置手机模块的当前通讯频率。回车 之后,再次输入数据就会出现乱码,因为手机模块的通讯频率已经修改了,现在只需停止串口软件通信,然 后把软件的通讯频率改为115200就可以了。# R3 a, A% Z7 v4 L9 ] / {- {9 E; M! {( _: o& P 伟研科技,http://www.gzweiyan.com/html/products/20081201/56.html |