码迷,mamicode.com
首页 > 其他好文 > 详细

基于STM32实现的的短信实时传送位置----GPS+GSM

时间:2016-05-26 20:27:37      阅读:289      评论:0      收藏:0      [点我收藏+]

标签:

 

总的来说就是实现了一个GPS数据通过串口发送给STM32,

STM32进行解码,

在通过串口把解码提取出的经纬度发送给GSM,

GSM根据给定的手机号发短信过去。

 

main函数里的最后一个while循环是每隔5s发一个位置出去

延时函数写在sim900a.c里,可以自行调节时间间隔。

就是这么任性。

 

技术分享

 

 

 

main.c

/*
  ******************************************************************************
  * @attention
  *
  * 实验平台:野火 ISO-STM32 开发板

  ******************************************************************************
    */
#include "stm32f10x.h"
#include "bsp_usart1.h"
#include "gps_config.h"
#include <string.h>
#include "gsm.h"
#include <stdio.h>

        

extern void nmea_decode_test(void);

/*
 * 测试GPS模块功能
 * 
 */
 
 
double  zaishichua;
double  zaishichub;
int main(void)
{
    char zaiship1[14];
    char zaiship2[14];
    /* 配置USART1 用于向电脑printf调试信息*/
   USART1_Config();                          
    /* 初始化GPS模块使用的接口 */
    GPS_Config();
    printf("\r\nGPS模块测试例程\r\n");

    printf("\r\nGPS模块测试例程\r\n");      /////////////////////////////////
         while(1)
         {/* GPS解码测试 */
    nmea_decode_test();
    printf("\r\n纬度:%f,经度%f\r\n",zaishichua,zaishichub);
     printf("\r\n纬度:%f,经度%f\r\n",zaishichua,zaishichub);
   

      sprintf(zaiship1,"%013.6f",zaishichua);
      sprintf(zaiship2,"%013.6f",zaishichub);
       gsm(zaiship1,zaiship2);
         }

  
  
}

 

 

bsp_usart1.c

/**
  ******************************************************************************
  * @file    bsp_usart1.c
  * @author  fire
  * @version V1.0
  * @date    2013-xx-xx
  * @brief   重现c库printf函数到usart端口
  ******************************************************************************
  * @attention
  *
  * 实验平台:野火 iSO STM32 开发板
  *
  ******************************************************************************
  */

#include "bsp_usart1.h"


/**
 * @brief  USART1 GPIO 配置,工作模式配置。115200 8-N-1
 * @param  无
 * @retval 无
 */
void USART1_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;

    /* config USART1 clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);

    /* USART1 GPIO config */
    /* Configure USART1 Tx (PA.09) as alternate function push-pull */
    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);

    /* Configure USART1 Rx (PA.10) as input floating */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* USART1 mode config */
    USART_InitStructure.USART_BaudRate = 115200;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_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);

    USART_Cmd(USART1, ENABLE);
}

///重定向c库函数printf到USART1
int fputc(int ch, FILE *f)
{
    /* 发送一个字节数据到USART1 */
    USART_SendData(USART1, (uint8_t) ch);

    /* 等待发送完毕 */
    while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);

    return (ch);
}

///重定向c库函数scanf到USART1
int fgetc(FILE *f)
{
    /* 等待串口1输入数据 */
    while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);

    return (int)USART_ReceiveData(USART1);
}



/*********************************************END OF FILE**********************/

 

bsp_usart2.c

 

/******************** (C) COPYRIGHT 2012 WildFire Team **************************
 * 文件名  :usart2.c
 * 描述    :将printf函数重定向到USART2。这样就可以用printf函数将单片机的数据
 *           打印到PC上的超级终端或串口调试助手。         
 * 实验平台:野火STM32开发板
 * 库版本  :ST3.5.0
 *
 * 作者    :wildfire team 
**********************************************************************************/
#include "bsp_usart2.h"
#include <stdarg.h>


/// 配置USART2接收中断
static void NVIC_Configuration(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
    /* Configure the NVIC Preemption Priority Bits */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

    /* Enable the USARTy Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

/*
 * 函数名:USART2_Config
 * 描述  :USART2 GPIO 配置,工作模式配置
 * 输入  :无
 * 输出  : 无
 * 调用  :外部调用
 */
void USART2_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;

    /* config USART2 clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

    /* USART2 GPIO config */
   /* Configure USART2 Tx (PA.02) as alternate function push-pull */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
        
  /* Configure USART2 Rx (PA.03) as input floating */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
      
    /* USART2 mode config */
    USART_InitStructure.USART_BaudRate = 115200;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_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(USART2, &USART_InitStructure); 
    
    /*    配置中断优先级 */
    NVIC_Configuration();
    /* 使能串口2接收中断 */
    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);

    
    USART_Cmd(USART2, ENABLE);
}

/*
 * 函数名:fputc
 * 描述  :重定向c库函数printf到USART2
 * 输入  :无
 * 输出  :无
 * 调用  :由printf调用
 */
//int fputc(int ch, FILE *f)
//{
///* 将Printf内容发往串口 */
//  USART_SendData(USART2, (unsigned char) ch);
//  while (!(USART2->SR & USART_FLAG_TXE));
// 
//  return (ch);
//}

/*
 * 函数名:itoa
 * 描述  :将整形数据转换成字符串
 * 输入  :-radix =10 表示10进制,其他结果为0
 *         -value 要转换的整形数
 *         -buf 转换后的字符串
 *         -radix = 10
 * 输出  :无
 * 返回  :无
 * 调用  :被USART2_printf()调用
 */
static char *itoa(int value, char *string, int radix)
{
    int     i, d;
    int     flag = 0;
    char    *ptr = string;

    /* This implementation only works for decimal numbers. */
    if (radix != 10)
    {
        *ptr = 0;
        return string;
    }

    if (!value)
    {
        *ptr++ = 0x30;
        *ptr = 0;
        return string;
    }

    /* if this is a negative value insert the minus sign. */
    if (value < 0)
    {
        *ptr++ = -;

        /* Make the value positive. */
        value *= -1;
    }

    for (i = 10000; i > 0; i /= 10)
    {
        d = value / i;

        if (d || flag)
        {
            *ptr++ = (char)(d + 0x30);
            value -= (d * i);
            flag = 1;
        }
    }

    /* Null terminate the string. */
    *ptr = 0;

    return string;

} /* NCL_Itoa */


#if 1
//中断缓存串口数据
#define UART_BUFF_SIZE      255
volatile    uint8_t uart_p = 0;
uint8_t     uart_buff[UART_BUFF_SIZE];

void bsp_USART2_IRQHandler(void)
{
    if(uart_p<UART_BUFF_SIZE)
    {
        if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
        {
            uart_buff[uart_p] = USART_ReceiveData(USART2);
            uart_p++;
        }
    }
}



//获取接收到的数据和长度
char *get_rebuff(uint8_t *len)
{
    *len = uart_p;
    return (char *)&uart_buff;
}

void clean_rebuff(void)
{
    uint16_t i=UART_BUFF_SIZE+1;
    uart_p = 0;
    while(i)
        uart_buff[--i]=0;
}

#endif

/*
 * 函数名:USART2_printf
 * 描述  :格式化输出,类似于C库中的printf,但这里没有用到C库
 * 输入  :-USARTx 串口通道,这里只用到了串口2,即USART2
 *             -Data   要发送到串口的内容的指针
 *               -...    其他参数
 * 输出  :无
 * 返回  :无 
 * 调用  :外部调用
 *         典型应用USART2_printf( USART2, "\r\n this is a demo \r\n" );
 *                     USART2_printf( USART2, "\r\n %d \r\n", i );
 *                     USART2_printf( USART2, "\r\n %s \r\n", j );
 */
void USART2_printf(USART_TypeDef* USARTx, char *Data,...)
{
    const char *s;
  int d;   
  char buf[16];

  va_list ap;
  va_start(ap, Data);

    while ( *Data != 0)     // 判断是否到达字符串结束符
    {                                          
        if ( *Data == 0x5c )  //‘\‘
        {                                      
            switch ( *++Data )
            {
                case r:                                      //回车符
                    USART_SendData(USARTx, 0x0d);
                    Data ++;
                    break;

                case n:                                      //换行符
                    USART_SendData(USARTx, 0x0a);    
                    Data ++;
                    break;
                
                default:
                    Data ++;
                    break;
            }             
        }
        else if ( *Data == %)
        {                                      //
            switch ( *++Data )
            {                
                case s:                                          //字符串
                    s = va_arg(ap, const char *);
          for ( ; *s; s++) 
                    {
                        USART_SendData(USARTx,*s);
                        while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET );
          }
                    Data++;
          break;

        case d:                                        //十进制
          d = va_arg(ap, int);
          itoa(d, buf, 10);
          for (s = buf; *s; s++) 
                    {
                        USART_SendData(USARTx,*s);
                        while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET );
          }
                    Data++;
          break;
                 default:
                        Data++;
                    break;
            }         
        } /* end of else if */
        else USART_SendData(USARTx, *Data++);
        while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET );
    }
}
/******************* (C) COPYRIGHT 2012 WildFire Team *****END OF FILE************/

 

bsp_usart3.c

 

 

 

/******************** (C) COPYRIGHT 2012 WildFire Team **************************
 * 文件名  :usart3.c
 * 描述    :将printf函数重定向到USART2。这样就可以用printf函数将单片机的数据
 *           打印到PC上的超级终端或串口调试助手。         
 * 实验平台:野火STM32开发
 * 库版本  :ST3.5.0
 *
 * 作者    :wildfire team 
**********************************************************************************/
#include "bsp_usart3.h"//头文件要在外面改头文件名,现只将其中内容改为usart3
#include <stdarg.h>




/*
 * 函数名:USART2_Config
 * 描述  :USART2 GPIO 配置,工作模式配置
 * 输入  :无
 * 输出  : 无
 * 调用  :外部调用
 */
void USART3_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;

    /* config USART2 clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//此处也要修改,修改为GPIOB
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);

    /* USART2 GPIO config */
  /* Configure USART2 Tx (PB.10) as alternate function push-pull *///此处改为b10
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
        
  /* Configure USART2 Rx (PB.11) as input floating */ //此处改为b11
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
      
    /* USART2 mode config */
    USART_InitStructure.USART_BaudRate = 9600;                //GPS模块默认使用波特率:9600
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_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(USART3, &USART_InitStructure); 

    USART_Cmd(USART3, ENABLE);
}

 

gps_config.c

 

/**
  ******************************************************************************
  * @file    gps_config.c
  * @author  fire
  * @version V1.0
  * @date    2014-08-xx
  * @brief   gps模块接口配置驱动
  ******************************************************************************
  * @attention
  *
  * 实验平台:野火 ISO-STM32 开发板
  *
  ******************************************************************************
    */

#include "gps_config.h"
#include "bsp_usart3.h"
#include "nmea/nmea.h"


/* DMA接收缓冲  */
uint8_t gps_rbuff[GPS_RBUFF_SIZE];

/* DMA传输结束标志 */
__IO uint8_t GPS_TransferEnd = 0, GPS_HalfTransferEnd = 0;



/**
  * @brief  GPS_Interrupt_Config 配置GPS使用的DMA中断 
  * @param  None.
  * @retval None.
  */
static void GPS_Interrupt_Config(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

    // DMA2 Channel Interrupt ENABLE
    NVIC_InitStructure.NVIC_IRQChannel = GPS_DMA_IRQn;//中断用的是RX不是TX啊啊啊啊fuxx!!
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

}


/**
  * @brief  GPS_ProcessDMAIRQ GPS DMA中断服务函数
  * @param  None.
  * @retval None.
  */
void GPS_ProcessDMAIRQ(void)
{
  
  if(DMA_GetITStatus(GPS_DMA_IT_HT) )         /* DMA 半传输完成 */
  {
    GPS_HalfTransferEnd = 1;                //设置半传输完成标志位
    DMA_ClearFlag(GPS_DMA_FLAG_HT);
        
  }
  else if(DMA_GetITStatus(GPS_DMA_IT_TC))     /* DMA 传输完成 */
  {
    GPS_TransferEnd = 1;                    //设置传输完成标志位
    DMA_ClearFlag(GPS_DMA_FLAG_TC);

   }
}


/**
  * @brief  GPS_DMA_Config gps dma接收配置
  * @param  无
  * @retval 无
  */
static void GPS_DMA_Config(void) //其为一个函数
{
        DMA_InitTypeDef DMA_InitStructure; //定义一个DMA_InitTypeDef类型的结构体,名为DMA_InitStructure
    
        /*开启DMA时钟*/
        RCC_AHBPeriphClockCmd(GPS_DMA_CLK, ENABLE);

        /*设置DMA源:串口数据寄存器地址*/
        DMA_InitStructure.DMA_PeripheralBaseAddr = GPS_DATA_ADDR;       //带点号为结构体内的成员,可直接赋值,相当于变量
//从该处进入gps.config.h可见,gps的串口通信定义为USart2,我们可从这里修改
        /*内存地址(要传输的变量的指针)*/
        DMA_InitStructure.DMA_MemoryBaseAddr = (u32)gps_rbuff;

        /*方向:从外设到内存 */        
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;    

        /*传输大小DMA_BufferSize=SENDBUFF_SIZE*/    
        DMA_InitStructure.DMA_BufferSize = GPS_RBUFF_SIZE;

        /*外设地址不增*/        
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //想修改可直接找到相对应的名字修改

        /*内存地址自增*/
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;    

        /*外设数据单位*/    
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

        /*内存数据单位 8bit*/
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;     

        /*DMA模式:不断循环*/
        DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;     

        /*优先级:中*/    
        DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;  

        /*禁止内存到内存的传输    */
        DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

        /*配置DMA的通道*/           
        DMA_Init(GPS_DMA_CHANNEL, &DMA_InitStructure);        
    
    GPS_Interrupt_Config();
        
    DMA_ITConfig(GPS_DMA_CHANNEL,DMA_IT_HT|DMA_IT_TC,ENABLE);  //配置DMA发送完成后产生中断

        /*使能DMA*/
        DMA_Cmd (GPS_DMA_CHANNEL,ENABLE);        
    
    /* 配置串口 向 DMA发出TX请求 */
        USART_DMACmd(GPS_USART, USART_DMAReq_Rx, ENABLE);


}

/**
  * @brief  GPS_Config gps 初始化
  * @param  无
  * @retval 无
  */
void GPS_Config(void)
{
  GPS_USART_INIT();   //初始化串口
  GPS_DMA_Config();  //初始化串口配套的DMA模式
  
}

 

/**
  * @brief  trace 在解码时输出捕获的GPS语句
  * @param  str: 要输出的字符串,str_size:数据长度
  * @retval 无
  */
void trace(const char *str, int str_size)
{
  #ifdef __GPS_DEBUG    //在gps_config.h文件配置这个宏,是否输出调试信息
    uint16_t i;
    printf("\r\nTrace: ");
    for(i=0;i<str_size;i++)
      printf("%c",*(str+i));
  
    printf("\n");
  #endif
}

/**
  * @brief  error 在解码出错时输出提示消息
  * @param  str: 要输出的字符串,str_size:数据长度
  * @retval 无
  */
void error(const char *str, int str_size)
{
    #ifdef __GPS_DEBUG   //在gps_config.h文件配置这个宏,是否输出调试信息

    uint16_t i;
    printf("\r\nError: ");
    for(i=0;i<str_size;i++)
      printf("%c",*(str+i));
    printf("\n");
    #endif
}



/******************************************************************************************************** 
**     函数名称:            bit        IsLeapYear(uint8_t    iYear) 
**    功能描述:            判断闰年(仅针对于2000以后的年份) 
**    入口参数:            iYear    两位年数 
**    出口参数:            uint8_t        1:为闰年    0:为平年 
********************************************************************************************************/ 
static uint8_t IsLeapYear(uint8_t iYear) 
{ 
    uint16_t    Year; 
    Year    =    2000+iYear; 
    if((Year&3)==0) 
    { 
        return ((Year%400==0) || (Year%100!=0)); 
    } 
     return 0; 
} 

/******************************************************************************************************** 
**     函数名称:            void    GMTconvert(uint8_t *DT,uint8_t GMT,uint8_t AREA) 
**    功能描述:            格林尼治时间换算世界各时区时间 
**    入口参数:            *DT:    表示日期时间的数组 格式 YY,MM,DD,HH,MM,SS 
**                        GMT:    时区数 
**                        AREA:    1(+)东区 W0(-)西区 
********************************************************************************************************/ 
void    GMTconvert(nmeaTIME *SourceTime, nmeaTIME *ConvertTime, uint8_t GMT,uint8_t AREA) 
{ 
    uint32_t    YY,MM,DD,hh,mm,ss;        //年月日时分秒暂存变量 
     
    if(GMT==0)    return;                //如果处于0时区直接返回 
    if(GMT>12)    return;                //时区最大为12 超过则返回         

    YY    =    SourceTime->year;                //获取年 
    MM    =    SourceTime->mon;                 //获取月 
    DD    =    SourceTime->day;                 //获取日 
    hh    =    SourceTime->hour;                //获取时 
    mm    =    SourceTime->min;                 //获取分 
    ss    =    SourceTime->sec;                 //获取秒 

    if(AREA)                        //东(+)时区处理 
    { 
        if(hh+GMT<24)    hh    +=    GMT;//如果与格林尼治时间处于同一天则仅加小时即可 
        else                        //如果已经晚于格林尼治时间1天则进行日期处理 
        { 
            hh    =    hh+GMT-24;        //先得出时间 
            if(MM==1 || MM==3 || MM==5 || MM==7 || MM==8 || MM==10)    //大月份(12月单独处理) 
            { 
                if(DD<31)    DD++; 
                else 
                { 
                    DD    =    1; 
                    MM    ++; 
                } 
            } 
            else if(MM==4 || MM==6 || MM==9 || MM==11)                //小月份2月单独处理) 
            { 
                if(DD<30)    DD++; 
                else 
                { 
                    DD    =    1; 
                    MM    ++; 
                } 
            } 
            else if(MM==2)    //处理2月份 
            { 
                if((DD==29) || (DD==28 && IsLeapYear(YY)==0))        //本来是闰年且是2月29日 或者不是闰年且是2月28日 
                { 
                    DD    =    1; 
                    MM    ++; 
                } 
                else    DD++; 
            } 
            else if(MM==12)    //处理12月份 
            { 
                if(DD<31)    DD++; 
                else        //跨年最后一天 
                {               
                    DD    =    1; 
                    MM    =    1; 
                    YY    ++; 
                } 
            } 
        } 
    } 
    else 
    {     
        if(hh>=GMT)    hh    -=    GMT;    //如果与格林尼治时间处于同一天则仅减小时即可 
        else                        //如果已经早于格林尼治时间1天则进行日期处理 
        { 
            hh    =    hh+24-GMT;        //先得出时间 
            if(MM==2 || MM==4 || MM==6 || MM==8 || MM==9 || MM==11)    //上月是大月份(1月单独处理) 
            { 
                if(DD>1)    DD--; 
                else 
                { 
                    DD    =    31; 
                    MM    --; 
                } 
            } 
            else if(MM==5 || MM==7 || MM==10 || MM==12)                //上月是小月份2月单独处理) 
            { 
                if(DD>1)    DD--; 
                else 
                { 
                    DD    =    30; 
                    MM    --; 
                } 
            } 
            else if(MM==3)    //处理上个月是2月份 
            { 
                if((DD==1) && IsLeapYear(YY)==0)                    //不是闰年 
                { 
                    DD    =    28; 
                    MM    --; 
                } 
                else    DD--; 
            } 
            else if(MM==1)    //处理1月份 
            { 
                if(DD>1)    DD--; 
                else        //新年第一天 
                {               
                    DD    =    31; 
                    MM    =    12; 
                    YY    --; 
                } 
            } 
        } 
    }         

    ConvertTime->year   =    YY;                //更新年 
    ConvertTime->mon    =    MM;                //更新月 
    ConvertTime->day    =    DD;                //更新日 
    ConvertTime->hour   =    hh;                //更新时 
    ConvertTime->min    =    mm;                //更新分 
    ConvertTime->sec    =    ss;                //更新秒 
}  






/*********************************************************end of file**************************************************/

 

nmea_decode_test.c
/**
  ******************************************************************************
  * @file    nmea_decode_test.c
  * @author  fire
  * @version V1.0
  * @date    2013-xx-xx
  * @brief   测试NEMA解码库
  ******************************************************************************
  * @attention
  *
  * 实验平台:野火 iSO STM32 开发板 
  * 论坛    :http://www.chuxue123.com
  * 淘宝    :http://firestm32.taobao.com
  *
  ******************************************************************************
  */ 
  
#include "stm32f10x.h"
#include "bsp_sdio_sdcard.h"
#include "bsp_usart1.h"    
#include "bsp_usart3.h"
#include "nmea/nmea.h"
#include "gps_config.h"

  



/**
  * @brief  nmea_decode_test 解码GPS模块信息
  * @param  无
  * @retval 无
  */
int nmea_decode_test(void)//文件中使用的应该是这个函数
{
    
    
    nmeaINFO info;          //GPS解码后得到的信息,为结构体
    nmeaPARSER parser;      //解码时使用的数据结构  
    uint8_t new_parse=0;    //是否有新的解码数据标志
  
    nmeaTIME beiJingTime;    //北京时间 
        
    /* 设置用于输出调试信息的函数 */
    nmea_property()->trace_func = &trace;
    nmea_property()->error_func = &error;

    /* 初始化GPS数据结构 */
    nmea_zero_INFO(&info);
    nmea_parser_init(&parser);
    
while(!GPS_HalfTransferEnd);      
while(GPS_HalfTransferEnd)
  {
      if(GPS_HalfTransferEnd)     /* 接收到GPS_RBUFF_SIZE一半的数据 */
      {
        /* 进行nmea格式解码 */
        nmea_parse(&parser, (const char*)&gps_rbuff[0], HALF_GPS_RBUFF_SIZE, &info);
        
        GPS_HalfTransferEnd = 0;   //清空标志位
        new_parse = 1;             //设置解码消息标志      ////////////////////////////////////////////
      }
      else if(GPS_TransferEnd)    /* 接收到另一半数据 */////////注意每一半的缓存区都足够储存一次完整的GPS的数据,此处不是把一次GPS数据分成两部分;
      {

        nmea_parse(&parser, (const char*)&gps_rbuff[HALF_GPS_RBUFF_SIZE], HALF_GPS_RBUFF_SIZE, &info);
       
        GPS_TransferEnd = 0;
        new_parse =1;
      }
      
      if(new_parse )                //有新的解码消息   
      {   

                zaishichua=info.lat;///////////////////////////////////////////////////////////
                zaishichub=info.lon;/////////////////////////////////////////////////////////////
        /* 对解码后的时间进行转换,转换成北京时间 */
        GMTconvert(&info.utc,&beiJingTime,8,1);
        
        /* 输出解码得到的信息 */
        printf("\r\n时间%d,%d,%d,%d,%d,%d\r\n", beiJingTime.year+1900, beiJingTime.mon+1,beiJingTime.day,beiJingTime.hour,beiJingTime.min,beiJingTime.sec);
        printf("\r\n纬度:%f,经度%f\r\n",info.lat,info.lon);
        printf("\r\n纬度:%f,经度%f\r\n",zaishichua,zaishichub);///////////////////////////////////////////
                printf("\r\n正在使用的卫星:%d,可见卫星:%d",info.satinfo.inuse,info.satinfo.inview);
        printf("\r\n海拔高度:%f 米 ", info.elv);
        printf("\r\n速度:%f km/h ", info.speed);
        printf("\r\n航向:%f 度", info.direction);
        
        new_parse = 0;
      }
    
    }

    /* 释放GPS数据结构 */
    // nmea_parser_destroy(&parser);

    
      return 0;
}









/**************************************************end of file****************************************/

 

gsm.c

#include"gsm.h"
const char num[]="18112728175";//大帅比的手机号
int gsm(char *p1,char *p2)
{
    USART2_Config();
    SysTick_Init();
    sim900a_sms((char *)num,strcat(strcat(p1,","),p2));
        SIM900A_DELAY(5000);               //////////////////////////延时是必须的,因为模块接收信息再传输需要时间
        //sim900a_sms((char *)num,p2);
  
    return 0;
}

 

bsp_SysTick.c
/**
  ******************************************************************************
  * @file    bsp_SysTick.c
  * @author  fire
  * @version V1.0
  * @date    2013-xx-xx
  * @brief   SysTick 系统滴答时钟10us中断函数库,中断时间可自由配置,
  *          常用的有 1us 10us 1ms 中断。     
  ******************************************************************************
  * @attention
  *
  * 实验平台:野火 iSO STM32 开发板 
  *
  ******************************************************************************
  */
  
#include "bsp_SysTick.h"

static __IO u32 TimingDelay;
 
/**
  * @brief  启动系统滴答定时器 SysTick
  * @param  无
  * @retval 无
  */
void SysTick_Init(void)
{
    /* SystemFrequency / 1000    1ms中断一次
     * SystemFrequency / 100000     10us中断一次
     * SystemFrequency / 1000000 1us中断一次
     */
//    if (SysTick_Config(SystemFrequency / 100000))    // ST3.0.0库版本
    if (SysTick_Config(SystemCoreClock / 1000000))    // ST3.5.0库版本
    { 
        /* Capture error */ 
        while (1);
    }
        // 关闭滴答定时器  
    SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;
}

/**
  * @brief   us延时程序,10us为一个单位
  * @param  
  *        @arg nTime: Delay_us( 1 ) 则实现的延时为 1 * 10us = 10us
  * @retval  无
  */
void Delay_us(__IO u32 nTime)
{ 
    TimingDelay = nTime;    

    // 使能滴答定时器  
    SysTick->CTRL |=  SysTick_CTRL_ENABLE_Msk;

    while(TimingDelay != 0);
}

/**
  * @brief   us延时程序,10us为一个单位
  * @param  
  *        @arg nTime: Delay_us( 1 ) 则实现的延时为 1 * 10us = 10us
  * @retval  无
  */
void Delay_ms(__IO u32 nTime)
{ 
    while(nTime--)
    {
        Delay_us(1000);
    }
}

/**
  * @brief  获取节拍程序
  * @param  无
  * @retval 无
  * @attention  在 SysTick 中断函数 SysTick_Handler()调用
  */
void TimingDelay_Decrement(void)
{
    if (TimingDelay != 0x00)
    { 
        TimingDelay--;
    }
}
/*********************************************END OF FILE**********************/

 

sim900a.c

#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
//#include "bsp_usart1.h"
#include "bsp_usart2.h"
#include "sim900a.h"
  


void sim900a_sms(char *num,char *smstext)
{
  //  char ucsbuff[160];
    SIM900A_CLEAN_RX();                 //清空了接收缓冲区数据
        //英文
        sim900a_tx_printf("AT+CSCS=\"GSM\"\r");     //"GSM"字符集
        SIM900A_DELAY(100);
        
        sim900a_tx_printf("AT+CMGF=1\r");           //文本模式
        SIM900A_DELAY(100);
        
        sim900a_tx_printf("AT+CMGS=\"%s\"\r",num);  //电话号码
        SIM900A_DELAY(100);

        sim900a_tx_printf("%s",smstext);            //短信内容
        //SIM900A_DELAY(100);          
    
     
    SIM900A_DELAY(1); 
    USART2->DR=(u32)0x1A;        //发送十六进制数:0X1A,信息结束符号//////////////////(gsm模块中以此为标志位,才发送短信)
}





/*---------------------------------------------------------------------*/

 

基于STM32实现的的短信实时传送位置----GPS+GSM

标签:

原文地址:http://www.cnblogs.com/MnsterLu/p/5532399.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!