基於STM32實現的的短信實時傳送位置----GPS+GSM


 

總的來說就是實現了一個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模塊中以此為標志位,才發送短信)
}





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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM