STM32开发 -- 4G模块开发详解(2)

二、软件部分

1、初始化

模块的波特率为115200,8位数据位,1位停止位,没有校验位和流控。

之前有讲到串口部分,参看:STM32开发 – 串口详解

void    Bsp_Usart_Init(u8   USART_ID,   u32 baud_rate)
{
    GPIO_InitTypeDef        gpio_init;
    USART_InitTypeDef       usart_init;
    USART_ClockInitTypeDef  usart_clk_init;

    /* ----------------- INIT USART STRUCT ---------------- */
    usart_init.USART_BaudRate            = baud_rate;
    usart_init.USART_WordLength          = USART_WordLength_8b;
    usart_init.USART_StopBits            = USART_StopBits_1;
    usart_init.USART_Parity              = USART_Parity_No ;
    usart_init.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    usart_init.USART_Mode                = USART_Mode_Rx | USART_Mode_Tx;

    usart_clk_init.USART_Clock           = USART_Clock_Disable;
    usart_clk_init.USART_CPOL            = USART_CPOL_Low;
    usart_clk_init.USART_CPHA            = USART_CPHA_2Edge;
    usart_clk_init.USART_LastBit         = USART_LastBit_Disable;

    /*-------------------USART1   用作GSM通信 -----------*/
    if (USART_ID == DEF_USART_1)
    {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
        GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);  //通讯角映射到PB6,PB7 

        /* Configure GPIOA.9 as push-pull              USART1-TX         */
        gpio_init.GPIO_Pin   = BSP_GPIOB_USART1_TX_PINS;
        gpio_init.GPIO_Speed = GPIO_Speed_10MHz;
        gpio_init.GPIO_Mode  = GPIO_Mode_AF_PP;
        GPIO_Init(GPIOB, &gpio_init);

        /* Configure GPIOA.10 as input floating        USART1-RX         */
        gpio_init.GPIO_Pin   = BSP_GPIOB_USART1_RX_PINS;
        gpio_init.GPIO_Mode  = GPIO_Mode_IN_FLOATING;
        //gpio_init.GPIO_Mode  = GPIO_Mode_IPU;
        GPIO_Init(GPIOB, &gpio_init);       

        /* ------------------ SETUP USART1 -------------------- */
        USART_Init(USART1, &usart_init);
        USART_ClockInit(USART1, &usart_clk_init);

        // Clean interrupt flag, and disable txd & rxd interrupt
        USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
        USART_ITConfig(USART1, USART_IT_TXE, DISABLE);

        USART_ClearITPendingBit(USART1, USART_IT_RXNE);
        USART_ClearITPendingBit(USART1, USART_IT_TXE);

        USART_GetFlagStatus(USART1, USART_FLAG_TC);/* 记得加上,不先读一下第一字节会发不出去,*/                        
        USART_Cmd(USART1, ENABLE);  
    }
    else if (USART_ID == DEF_USART_2)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);  
        /* ----------------- SETUP USART2 GPIO ---------------- */
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);           
        /* Configure GPIOA.2 as push-pull                       */
        gpio_init.GPIO_Pin   = GPIO_Pin_2;
        gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
        gpio_init.GPIO_Mode  = GPIO_Mode_AF_PP;
        GPIO_Init(GPIOA, &gpio_init);       
        /* Configure GPIOA.3 as input floating                  */
        gpio_init.GPIO_Pin   = GPIO_Pin_3;
        gpio_init.GPIO_Mode  = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOA, &gpio_init);
        /* ------------------ SETUP USART2 -------------------- */
        USART_Init(USART2, &usart_init);
        //USART_ClockInit(USART2, &usart_clk_init);

        // Clean interrupt flag, and disable txd & rxd interrupt
        USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);
        USART_ITConfig(USART2, USART_IT_TXE, DISABLE);

        USART_ClearITPendingBit(USART2, USART_IT_RXNE);
        USART_ClearITPendingBit(USART2, USART_IT_TXE);

        USART_GetFlagStatus(USART2, USART_FLAG_TC);/* 记得加上,不先读一下第一字节会发不出去,*/
        USART_Cmd(USART2, ENABLE);
    }
    else if (USART_ID == DEF_USART_3)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
                                                                                /* Configure GPIOB.10 as push-pull                      */
        gpio_init.GPIO_Pin   = GPIO_Pin_10;
        gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
        gpio_init.GPIO_Mode  = GPIO_Mode_AF_PP;
        GPIO_Init(GPIOB, &gpio_init);

        gpio_init.GPIO_Pin   = GPIO_Pin_11;
        gpio_init.GPIO_Mode  = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOB, &gpio_init);
        /* ------------------ SETUP USART3 -------------------- */
        USART_Init(USART3, &usart_init);
        USART_ClockInit(USART3, &usart_clk_init);
        // Clean interrupt flag, and disable txd & rxd interrupt
        USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);
        USART_ITConfig(USART3, USART_IT_TXE, DISABLE);

        USART_ClearITPendingBit(USART3, USART_IT_RXNE);
        USART_ClearITPendingBit(USART3, USART_IT_TXE);
        USART_GetFlagStatus(USART3, USART_FLAG_TC);/* 记得加上,不先读一下第一字节会发不出去,*/
        USART_Cmd(USART3, ENABLE);
    }
    //--------------------UART4   打印     调试窗口
    else if (USART_ID == DEF_UART_4)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);

        /* ----------------- SETUP USART4 GPIO ---------------- */
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
        /* Configure GPIOC.10 as push-pull                       */
        gpio_init.GPIO_Pin   = GPIO_Pin_10;
        gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
        gpio_init.GPIO_Mode  = GPIO_Mode_AF_PP;
        GPIO_Init(GPIOC, &gpio_init);
        /* Configure GPIOC.11 as input floating                 */
        gpio_init.GPIO_Pin   = GPIO_Pin_11;
        gpio_init.GPIO_Mode  = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOC, &gpio_init);   

        /* ------------------ SETUP UART4 -------------------- */
        USART_Init(UART4, &usart_init);
        USART_ClockInit(UART4, &usart_clk_init);

        // Clean interrupt flag, and disable txd & rxd interrupt
        USART_ITConfig(UART4, USART_IT_RXNE, DISABLE);
        USART_ITConfig(UART4, USART_IT_TXE, DISABLE);

        USART_ClearITPendingBit(UART4, USART_IT_RXNE);
        USART_ClearITPendingBit(UART4, USART_IT_TXE);

        USART_GetFlagStatus(UART4, USART_FLAG_TC);/* 记得加上,不先读一下第一字节会发不出去,*/
        USART_Cmd(UART4, ENABLE);       
    }
}
}

static  void    BSP_NVIC_Configuration(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;

    /*!!注意!!*/
    /*应用程序参数地址定义在CPU FLASH中间位置(具体定义见hal_h.h宏定义)*/
    /*如果去掉程序偏移,当写系统参数时将导致直接改写应用程序代码,从而导致死机*/

    //设置向量地址偏移
    /* Set the Vector Table base location at 0x0800A000 */
    //NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0xA000);
    //NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0);
    NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x2000);

    /* Configure one bit for preemption priority */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);


    /* USART1_IRQn中断 [GSM] */   
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    /* CAN1接收中断 */
    NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure); 

    /* USART2_IRQn中断 [GPS] */
    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 4;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure); 

    /* USART3_IRQn中断 [IBeacon] */
    NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 5;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);                 
}

这里需要注意的几点:
1、串口时钟使能
APB1(低速)、APB2(高速)
APB2负责 AD,I/O,高级TIM,串口1
APB1负责 DA,USB,SPI,I2C,CAN,串口2345,普通TIM,PWR

USART1是挂载在 APB2 下面的外设,所以使能函数为:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1)

2、GPIO端口模式设置
TX的GPIO工作模式为:GPIO_Mode_AF_PP;//复用推挽输出
RX的GPIO工作模式为:GPIO_Mode_IN_FLOATING;//浮空输入或者上拉输入
这里写图片描述

2、AT指令操作

AT 即 Attention,AT 指令集是从终端设备(Terminal Equipment,TE)或数据终端设备(DataTerminal Equipment, DTE)向终端适配器(Terminal Adapter, TA)或数据电流终端设备(DataCircuit Terminal Equipment, DCE)发送的。通过 TA, TE 发送 AT 指令来控制移动台(MobileStation, MS)的功能,与 GSM 网络业务进行交互。用户可以通过 AT 指令进行呼叫、短信、电话本、数据业务、传真等方面的控制。
AT 指令必须以“AT”或“at”开头,以回车()结尾。模块的响应通常紧随其后,格式为: <回车><换行><响应内容><回车><换行>。

GPRS 通信

相信都能在网上找到相关的AT指令手册,所以不一一介绍了。
这里着重看一下GPRS 通信相关的AT指令。
1,ATI
显示模块信息

ATI

Manufacturer: LYNQ
Model: LYNQ_L506
Revision: L506v03.02bxxxx
SN: P4HC1204020xxx
IMEI: 86569903007xxxx
+GCAP: +CGSM,+MS,+DS

OK

2,ATE0
关闭回显

ATE0

OK

在通过电脑串口调试助手调试的时候,我们发送: ATE1,开启回显,可以方便调试,但是我们通过单片机程序控制的时候,用不到回显功能,所以发送: ATE0,将其关闭。

3,AT+CPIN?
查询SIM卡的状态

AT+CPIN?

+CPIN: READY

OK

4,AT+CREG=2
网络注册信息设置命令,自动上报网络注册未知结果码,同时带有位置信息,+CREG: [,,]

AT+CREG=2

OK

5,AT+CICCID
读取SIM卡的CICCID

AT+CICCID

+CICCID: 898607B32217710307xx

OK

6,AT+CSQ
查询信号,最大的有效值是 31

AT+CSQ

+CSQ: 21,99

OK

7,AT+CREG?

网络注册信息查询命令,当stat的值为1(本地网络)或5(漫游)的时,网络注册成功。

AT+CREG?

+CREG: 2,1,"FFFE","160D601",7

OK

8,AT+CGATT?
查询是否附着网络,0是分离,1是附着

AT+CGATT?

+CGATT: 1

OK

9,AT+CGATT=1
设置附着网络

AT+CGATT=1

OK

10,AT+CIPMODE=0
设置传输模式
参数:
–> 0: 非透明传输模式, 1: 透明传输模式(透明传输模式下新建的连接将被强制到 0 号连接上)

AT+CIPMODE=0

OK

透明传输是指不管所传数据是什么样的比特组合,都应当能够在链路上传送。当所传数据中的比特组合恰巧与某一个控制信息完全一样时,就必须采取适当的措施,使收方不会将这样的数据误认为是某种控制信息。这样才能保证数据链路层的传输是透明的。

11,AT+NETOPEN
打开封包网络

AT+NETOPEN

OK

12,AT+CIPOPEN=0,”TCP”,”211.152.x.xxx”,10102,0
建立与TCP服务器的连接

AT+CIPOPEN=0,"TCP","211.152.x.xxx",10102,0

OK

+CIPOPEN:SUCCESS,0

13,AT+CIPSEND=0,4
在 0 号 link 上发送 4 个字符

AT+CIPSEND=0,4

>2233

+CIPSEND:SUCCESS,0,4,4 
// 0:连接索引 4:请求发送数据个数 4:实际发送数据个数

14,CIPRXGET
AT+CIPRXGET=0,0
设置接收模式,默认应该是自动获取网络数据的方式,0号link。所以可以不配置?

AT+CIPRXGET=0,0

OK

然后,自动接收模式下在 0 号 link 上收到数据(无需用户使用指令读取)

+CIPRXGET: SUCCESS,0,0,15, 
//成功收到数据 0:自动接收模式 1:连接索引 15:接收数据个

ddddddddddddddf //当前读取的数据

15,AT+CIPCLOSE=0
关闭 0 号 link

AT+CIPCLOSE=0

OK

+CIPCLOSE: SUCCESS,0

在网络或者服务器主动断开的情况下系统会自动给出如下提示:
+SERVER DISCONNECTED:0 //0:被动断开的连接索引 (服务器断开提示)
+NETWORK DISCONNECTED:0//0:被动断开的连接索引(网络断开提示)
16,AT+NETCLOSE
关闭网络

AT+NETCLOSE

OK

+NETCLOSE: SUCCESS

3、GPIO配置

之前有讲到GPIO部分,参看:STM32开发 – GPIO详解
这里写图片描述
然后再看原理图,主要是串口收发、EN_GSM、PWRKEY、STATUS这几个引脚配置
GPIO配置方法的话都是大同小异的。
这里需要注意的几点:
1、GPIO 8种工作模式应用场合
(1) GPIO_Mode_AIN 模拟输入
(2) GPIO_Mode_IN_FLOATING 浮空输入
(3) GPIO_Mode_IPD 下拉输入
(4) GPIO_Mode_IPU 上拉输入
(5) GPIO_Mode_Out_OD 开漏输出
(6) GPIO_Mode_Out_PP 推挽输出
(7) GPIO_Mode_AF_OD 复用开漏输出
(8) GPIO_Mode_AF_PP 复用推挽输出

这8种工作模式相比很清楚。但是它们的应用场合需要搞清楚。
①上拉输入、下拉输入可以用来检测外部信号;例如,按键等;
②浮空输入模式,由于输入阻抗较大,一般把这种模式用于标准通信协议的I2C、USART的接收端;
③普通推挽输出模式一般应用在输出电平为0和3.3V的场合。而普通开漏输出模式一般应用在电平不匹配的场合,如需要输出5V的高电平,就需要在外部一个上拉电阻,电源为5V,把GPIO设置为开漏模式,当输出高阻态时,由上拉电阻和电源向外输出5V电平。
④对于相应的复用模式(复用输出来源片上外设),则是根据GPIO的复用功能来选择,如GPIO的引脚用作串口的输出(USART/SPI/CAN),则使用复用推挽输出模式。如果用在I2C、SMBUS这些需要线与功能的复用场合,就使用复用开漏模式。
⑤在使用任何一种开漏模式时,都需要接上拉电阻。

TX的GPIO工作模式为:GPIO_Mode_AF_PP;//复用推挽输出
RX的GPIO工作模式为:GPIO_Mode_IN_FLOATING;//浮空输入或者上拉输入
EN_GSM的GPIO工作模式为:GPIO_Mode_Out_PP;//推挽输出
PWRKEY的GPIO工作模式为:GPIO_Mode_Out_PP;//推挽输出
STATUS的GPIO工作模式为:GPIO_Mode_IPU;上拉输入

PS,STATUS使用了三极管,信号取反。正常GPIO工作模式应为:
GPIO_Mode_IPD;下拉输入

2、引脚输出高/低电平

GPIO_SetBits 置高电平
GPIO_ResetBits 置低电平

根据上一篇文章所讲

  • 4G模组开机:
    PWRKEY先低电平,延时500ms,然后再高电平。
    PS,又因为使用了三极管,信号取反。
    GSM_PORKEY_LOW(); 
    DelayMS(500);
    GSM_PORKEY_HIGH(); 

    #define GSM_PORKEY_LOW()            (GPIO_SetBits       (BSP_GPIOC_PORTS, BSP_GPIOC_GSM_PORKEY_PINS))
    #define GSM_PORKEY_HIGH()           (GPIO_ResetBits     (BSP_GPIOC_PORTS, BSP_GPIOC_GSM_PORKEY_PINS))
  • 模块主电源使能引脚(EN_GSM)
    控制 EN_GSM 引脚,高电平GSM工作,低电平GSM不工作。
#define GSM_POWER_ON()              (GPIO_SetBits       (BSP_GPIOA_PORTS, BSP_GPIOA_GSM_POWEN_PINS))    
#define GSM_POWER_OFF()             (GPIO_ResetBits     (BSP_GPIOA_PORTS, BSP_GPIOA_GSM_POWEN_PINS))

3、 读取指定端口管脚的输入

GPIO_ReadInputDataBit 读取指定端口管脚的输入
返回值为:0(低电平)、1(高电平)

  • STATUS引脚作为模块状态标志,高电平表示开机,低电平表示关机。
    GPIO_ReadInputDataBit 返回值 0(低电平、关机)、1(高电平、开机)
    PS,又因为使用了三极管,信号取反。
DETECT_GSM_STATUS()  返回值 0 (开机),1 (关机)

#define DETECT_GSM_STATUS()         (GPIO_ReadInputDataBit (BSP_GPIOC_PORTS, BSP_GPIOC_GSM_STATUS_PINS))

猜你喜欢

转载自blog.csdn.net/qq_29350001/article/details/81773782
今日推荐