[STM32F1]

STM32+GSM 检测GSM模块工作状态

[复制链接]
3148|32
手机看帖
扫描二维码
随时随地手机跟帖
gaoke231|  楼主 | 2018-4-27 22:52 | 显示全部楼层 |阅读模式
本帖最后由 gaoke231 于 2018-4-27 22:53 编辑

主函数部分
#include "sim900a.h"
#include "usart2.h"
#include "delay.h"
#include "sys.h"
#include "string.h"

int main(void)
{
        u8 res;
        delay_init();                     //延时函数初始化          
        NVIC_Configuration();          //设置NVIC中断分组2:2位抢占优先级,2位响应优先级         LED_Init();                             //LED端口初始化
        USART2_Init(115200);        //初始化串口2
        USART3_Init(9600);        //LOG信息
        UART3SendString("系统初始化完毕\r\n",strlen("系统初始化完毕\r\n"));       
       
        while(1)
        {
                res=GSM_Dect();
                delay_ms(2000);
                if(!res)       
                {
                        while(1);
                }
        }
}

gaoke231|  楼主 | 2018-4-27 22:54 | 显示全部楼层
串口初始化
void USART1_Config(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;

        /* 使能 USART1 时钟*/
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);

        /* USART1 使用IO端口配置 */   
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);   
  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;        //浮空输入
  GPIO_Init(GPIOA, &GPIO_InitStructure);   //初始化GPIOA
          
        /* USART1 工作模式配置 */
        USART_InitStructure.USART_BaudRate = 9600;        //波特率设置:115200
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;        //数据位数设置:8位
        USART_InitStructure.USART_StopBits = USART_StopBits_1;         //停止位设置:1位
        USART_InitStructure.USART_Parity = USART_Parity_No ;  //是否奇偶校验:无
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;        //硬件流控制模式设置:没有使能
        USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//接收与发送都使能
        USART_Init(USART1, &USART_InitStructure);  //初始化USART1
        USART_Cmd(USART1, ENABLE);// USART1使能
}

使用特权

评论回复
gaoke231|  楼主 | 2018-4-27 22:54 | 显示全部楼层
发送一个字节数据
void UART1SendByte(unsigned char SendData)
{          
        USART_SendData(USART1,SendData);
        while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);            
}  

使用特权

评论回复
gaoke231|  楼主 | 2018-4-27 22:55 | 显示全部楼层
接收一个字节数据*/
unsigned char UART1GetByte(unsigned char* GetData)
{             
        if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET)
        {  return 0;//没有收到数据
                }
        *GetData = USART_ReceiveData(USART1);
        return 1;//收到数据
}

使用特权

评论回复
gaoke231|  楼主 | 2018-4-27 22:55 | 显示全部楼层
接收一个数据,马上返回接收到的这个数据*/
void UART1Test(void)
{
       unsigned char i = 0;

       while(1)
       {   
                                while(UART1GetByte(&i))
        {
         USART_SendData(USART1,i);
        }      
       }     
}

使用特权

评论回复
gaoke231|  楼主 | 2018-4-27 22:57 | 显示全部楼层
//usmart支持部分
//将收到的AT指令应答数据返回给电脑串口
//mode:0,不清零USART2_RX_STA;
//     1,清零USART2_RX_STA;
void sim_at_response(u8 mode)
{
        if(USART2_RX_STA&0X8000)                //接收到一次数据了
        {
                USART2_RX_BUF[USART2_RX_STA&0X7FFF]=0;//添加结束符
                printf("%s",USART2_RX_BUF);        //发送到串口
                if(mode)USART2_RX_STA=0;               
        }
}

使用特权

评论回复
gaoke231|  楼主 | 2018-4-27 22:57 | 显示全部楼层
//ATK-SIM900A 各项测试(拨号测试、短信测试、GPRS测试)共用代码
//sim900a发送命令后,检测接收到的应答
//str:期待的应答结果
//返回值:0,没有得到期待的应答结果
//    其他,期待应答结果的位置(str的位置)
u8* sim900a_check_cmd(u8 *str)
{
        char *strx=0;
        if(USART2_RX_STA&0X8000)                //接收到一次数据了
        {
                USART2_RX_BUF[USART2_RX_STA&0X7FFF]=0;//添加结束符
                strx=strstr((const char*)USART2_RX_BUF,(const char*)str);
        }
        return (u8*)strx;
}

使用特权

评论回复
gaoke231|  楼主 | 2018-4-27 22:57 | 显示全部楼层
//向sim900a发送命令
//cmd:发送的命令字符串(不需要添加回车了),当cmd<0XFF的时候,发送数字(比如发送0X1A),大于的时候发送字符串.
//ack:期待的应答结果,如果为空,则表示不需要等待应答
//waittime:等待时间(单位:10ms)
//返回值:0,发送成功(得到了期待的应答结果)
//       1,发送失败
u8 sim900a_send_cmd(u8 *cmd,u8 *ack,u16 waittime)
{
        u8 res=0;
        USART2_RX_STA=0;
        if((u32)cmd<=0XFF)
        {
                while(DMA1_Channel7->CNDTR!=0);        //等待通道7传输完成   
                USART2->DR=(u32)cmd;
        }else u2_printf("%s\r\n",cmd);//发送命令
        if(ack&&waittime)                //需要等待应答
        {
                while(--waittime)        //等待倒计时
                {
                        delay_ms(10);
                        if(USART2_RX_STA&0X8000)//接收到期待的应答结果
                        {
                                if(sim900a_check_cmd(ack))break;//得到有效数据
                                USART2_RX_STA=0;
                        }
                }
                if(waittime==0)res=1;
        }
        return res;
}

使用特权

评论回复
gaoke231|  楼主 | 2018-4-27 22:57 | 显示全部楼层
u8 sim900a_work_test(void)
{
        if(sim900a_send_cmd((u8 *)"AT",(u8 *)"OK",100))
        {
                if(sim900a_send_cmd((u8 *)"AT",(u8 *)"OK",100))return SIM_COMMUNTION_ERR;        //通信不上
        }               
        if(sim900a_send_cmd((u8 *)"AT+CPIN?",(u8 *)"READY",400))return SIM_CPIN_ERR;        //没有SIM卡
        if(sim900a_send_cmd((u8 *)"AT+CREG?",(u8 *)"0,1",400))
        {
                if(strstr((const char*)USART2_RX_BUF,"0,5")==NULL)
                {
                         if(!sim900a_send_cmd((u8 *)"AT+CSQ",(u8 *)"OK",200))       
                         {
                                        memcpy(SIM900_CSQ,USART2_RX_BUF+15,2);
                         }
                         return SIM_CREG_FAIL;        //等待附着到网络
                }
        }
        return SIM_OK;
}

使用特权

评论回复
gaoke231|  楼主 | 2018-4-27 22:58 | 显示全部楼层
u8 GSM_Dect(void)
{
        u8 res;
        res=sim900a_work_test();       
        switch(res)
        {
                case SIM_OK:
                        UART3SendString("GSM模块自检成功\r\n",strlen("GSM模块自检成功\r\n"));
                        break;
                case SIM_COMMUNTION_ERR:
                        UART3SendString("与GSM模块未通讯成功,请等待\r\n",strlen("与GSM模块未通讯成功,请等待\r\n"));
                        break;
                case SIM_CPIN_ERR:
                        UART3SendString("没检测到SIM卡\r\n",strlen("没检测到SIM卡\r\n"));       
                        break;
                case SIM_CREG_FAIL:
                        UART3SendString("注册网络中。。。\r\n",strlen("注册网络中。。。\r\n"));       
                        UART3SendString("当前信号值:",strlen("当前信号值:"));        UART3SendString(SIM900_CSQ,2);UART3SendString("\r\n",2);
                        break;               
                default:
                        break;
        }
        return res;
}

使用特权

评论回复
gaoke231|  楼主 | 2018-4-27 22:59 | 显示全部楼层
OLED部分
//更新显存到LCD                 
void OLED_Refresh_Gram(void)
{
        u8 i,n;                    
        for(i=0;i<8;i++)  
        {  
                OLED_WR_Byte (0xb0+i,OLED_CMD);    //设置页地址(0~7)
                OLED_WR_Byte (0x00,OLED_CMD);      //设置显示位置—列低地址
                OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置—列高地址   
                for(n=0;n<128;n++)OLED_WR_Byte(OLED_GRAM[n][i],OLED_DATA);
        }   
}

使用特权

评论回复
gaoke231|  楼主 | 2018-4-27 22:59 | 显示全部楼层
#if OLED_MODE==1        //8080并口
//向SSD1306写入一个字节。
//dat:要写入的数据/命令
//cmd:数据/命令标志 0,表示命令;1,表示数据;
void OLED_WR_Byte(u8 dat,u8 cmd)
{
        DATAOUT(dat);            
        OLED_RS=cmd;
        OLED_CS=0;          
        OLED_WR=0;         
        OLED_WR=1;
        OLED_CS=1;          
        OLED_RS=1;         
}                         
#else
//向SSD1306写入一个字节。
//dat:要写入的数据/命令
//cmd:数据/命令标志 0,表示命令;1,表示数据;
void OLED_WR_Byte(u8 dat,u8 cmd)
{       
        u8 i;                          
        OLED_RS=cmd; //写命令
        OLED_CS=0;                  
        for(i=0;i<8;i++)
        {                          
                OLED_SCLK=0;
                if(dat&0x80)OLED_SDIN=1;
                else OLED_SDIN=0;
                OLED_SCLK=1;
                dat<<=1;   
        }                                 
        OLED_CS=1;                  
        OLED_RS=1;             
}
#endif

使用特权

评论回复
gaoke231|  楼主 | 2018-4-27 23:00 | 显示全部楼层
//开启OLED显示   
void OLED_Display_On(void)
{
        OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
        OLED_WR_Byte(0X14,OLED_CMD);  //DCDC ON
        OLED_WR_Byte(0XAF,OLED_CMD);  //DISPLAY ON
}

使用特权

评论回复
gaoke231|  楼主 | 2018-4-27 23:01 | 显示全部楼层
//关闭OLED显示     
void OLED_Display_Off(void)
{
        OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
        OLED_WR_Byte(0X10,OLED_CMD);  //DCDC OFF
        OLED_WR_Byte(0XAE,OLED_CMD);  //DISPLAY OFF
}                 

使用特权

评论回复
gaoke231|  楼主 | 2018-4-27 23:02 | 显示全部楼层
//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!          
void OLED_Clear(void)  
{  
        u8 i,n;  
        for(i=0;i<8;i++)for(n=0;n<128;n++)OLED_GRAM[n][i]=0X00;  
        OLED_Refresh_Gram();//更新显示
}

使用特权

评论回复
静听风易| | 2018-4-28 15:30 | 显示全部楼层
好像现在2G基站都要撤销了,GSM应该很快就不能用了吧

使用特权

评论回复
gaoke231|  楼主 | 2018-4-28 16:41 | 显示全部楼层
静听风易 发表于 2018-4-28 15:30
好像现在2G基站都要撤销了,GSM应该很快就不能用了吧

支持3G吧

使用特权

评论回复
gaoke231|  楼主 | 2018-4-28 16:45 | 显示全部楼层
//画点
//x:0~127
//y:0~63
//t:1 填充 0,清空                                  
void OLED_DrawPoint(u8 x,u8 y,u8 t)
{
        u8 pos,bx,temp=0;
        if(x>127||y>63)return;//超出范围了.
        pos=7-y/8;
        bx=y%8;
        temp=1<<(7-bx);
        if(t)OLED_GRAM[x][pos]|=temp;
        else OLED_GRAM[x][pos]&=~temp;            
}

使用特权

评论回复
gaoke231|  楼主 | 2018-4-28 16:46 | 显示全部楼层
//x1,y1,x2,y2 填充区域的对角坐标
//确保x1<=x2;y1<=y2 0<=x1<=127 0<=y1<=63                  
//dot:0,清空;1,填充          
void OLED_Fill(u8 x1,u8 y1,u8 x2,u8 y2,u8 dot)  
{  
        u8 x,y;  
        for(x=x1;x<=x2;x++)
        {
                for(y=y1;y<=y2;y++)OLED_DrawPoint(x,y,dot);
        }                                                                                                            
        OLED_Refresh_Gram();//更新显示
}

使用特权

评论回复
gaoke231|  楼主 | 2018-4-28 16:46 | 显示全部楼层
//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//mode:0,反白显示;1,正常显示                                 
//size:选择字体 12/16/24
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size,u8 mode)
{                                  
        u8 temp,t,t1;
        u8 y0=y;
        u8 csize=(size/8+((size%8)?1:0))*(size/2);                //得到字体一个字符对应点阵集所占的字节数
        chr=chr-' ';//得到偏移后的值                 
    for(t=0;t<csize;t++)
    {   
                if(size==12)temp=asc2_1206[chr][t];                  //调用1206字体
                else if(size==16)temp=asc2_1608[chr][t];        //调用1608字体
                else if(size==24)temp=asc2_2412[chr][t];        //调用2412字体
                else return;                                                                //没有的字库
        for(t1=0;t1<8;t1++)
                {
                        if(temp&0x80)OLED_DrawPoint(x,y,mode);
                        else OLED_DrawPoint(x,y,!mode);
                        temp<<=1;
                        y++;
                        if((y-y0)==size)
                        {
                                y=y0;
                                x++;
                                break;
                        }
                }           
    }         
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

54

主题

1310

帖子

5

粉丝