发送中英文短信

**

基于STM32F103ZET6开发板控制SIM800C模块实现发送中英文短信

**
在网上买了个stm32开发板和SIM800C模块板,整理一下模块发短信功能的学习笔记。忘大家勿喷,共勉!利用Unicode 字符集编码 ,发送下面的中英文短信。

(1) 接收号码: +8613316931709
(2) 短信内容: 欢迎使用飞思创 SIM800C 模块
(3) 发送的有效数据长度:43 ( 后面将会说明如何计算出该长度)

发送中英文短信所使用到的命令有: AT+CMGF 、 AT+CSMP 、 AT+CSCS 、AT+CMGS
其中的命令格式不再做详细介绍 , 请自行查看 AT 。注意的一点就是,命令后面记得加回车
只有发送结束符命令 0X1A 的后面不需要加回车。
操作步骤如下:
第一步:设置短信模式为文本模式,发送 AT+CMGF=1 ,模块会响应 OK 。
第二步:设置中英文模式,发送 AT+CSMP=17,167,1,8 , 模块会响应 OK 。
第三步:设置为 UCS2 字符集编码。 AT+CSCS=”UCS2”,模块会响应 OK 。
第四步:设置对方的手机号码。这时候要使用 Unicode 。

这里写图片描述

第五步:待模块响应出现“>”之后,才能发送短信内容。在发之前短信内容需要转换成 Unicode编码。短信内容为“欢迎使用飞思创SIM800C模块!”,转换后的Unicode编码 。注意图中编码间的间隔需要手动去除。
“6B228FCE4F7F752898DE601D521B00530049004D00380030003000436A215757FF01 ”
这里写图片描述

综合以上步骤,演示结果如下图所示:
这里写图片描述

输入1A不加回车把左下角十六进制发送打钩,点击手动发送。稍等几S会出现发送成功的返回信息。单片机程序设计中发送字符串”\r\n”。图中的+CMGS:54 ,表示发送第54条短信。
stm32开发板

SIM800C模块

串口接线

串口接线
以上是电脑端模拟测试的效果,接下来利用stm32开发板控制SIM800C模块板实现发送中英文短信。

/************************************************************************
 * 工程名称:           发送中英文短信测试
 * 描    述: STM32开发板控制模块发送中英文短信
 * 实验平台: STM32F103zet6开发板
 * 版    本: 库函数版---STM32F10x_StdPeriph_Lib_V3.5.0
 * 作    者: kaven.liu 
 * -------------------------硬 件 连 接 说 明-----------------------------
     使用单片串口2与GPRS模块通信  注:使用串口2可以避免下载和通信不会冲突
     STM32      GPRS模块(TTL电平)
     PA3 (RXD)->TXD
     PA2 (TXD)->RXD
     GND        ->GND
   连接形式:交叉式
 * --------------------------测 试 要 求----------------------------------
    发送中英文短信,内容为SIM800C中英文短信测试。
***************************************************************************/
#include "stm32f10x.h"

#include "USART.h"
#include "LED.h"
#include "SysTick.h"
#include "Timer.h"
#include "string.h"
#include <stdio.h>
#include "SMS.h"

/*---------------------------宏 定 义-------------------------------------*/
#define BaudRates  115200 //串口波特率设置为115200,在这里就可以设置串口波特率

/*---------------------------函 数 声 明-----------------------------------*/
void Nvic_InitConfig(void);

/*---------------------------主 函 数 入 口--------------------------------*/
/***
* 函数名称:  main 
* 描    述: 主函数
* 输入参数: 无
* 输    出: 无
* 返    回: 无
* 说    明: 无
***/
int main(void)
{
    /*系统滴答时钟初始化*/
    SysTick_InitConfig(); 

    /*外设初始化*/
    LED_InitConfig();       //GPIO初始化设置

    Nvic_InitConfig();      //中断初始化设置
    Usart1_InitConfig(BaudRates);   //串口1初始化:波特率为115200 ,工作模式为 8-n-1
    Usart2_InitConfig(BaudRates); //串口2初始化:波特率为115200 ,工作模式为 8-n-1

    /*发送中英文短信测试*/
    Usart1_SendString("串口初始化成功,可以与SIM800C模块进行通讯连接!\r\n");
    Usart1_SendString("现在发送中文短信测试:\r\n");   
    Usart1_SendString("正在查询模块是否注册,请稍等......\r\n");

    Wait_Register(); //等待模块注册成功 
    Send_SMS();     //发送一条中文短消息

    /*-----------无限循环---------------------------*/
    while(1)
    {   
      ;
    }
}
/*---------------------------函数自定义 --------------------------------*/
/**
* 函数名称: Nvic_InitConfig
* 描    述: 中断向量初始化配置
* 输    入: 无
* 输    出: 无
* 返    回: 无 
* 说    明: 设置中断优先级
***/
void Nvic_InitConfig()
{
  NVIC_InitTypeDef NVIC_InitStructure;   //定义NVIC初始化结构体

    NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);//将向量表基地选址在0x08000000

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //设置中断优先级组为2,先占优先级和从优先级各两位(可设0~3)

//  /*定时器2中断向量配置*/
//  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;                //TIM2中断
//  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;   //先占优先级1级
//  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;          //从优先级1级
//  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;               //使能IRQ通道
//  NVIC_Init(&NVIC_InitStructure); 

    /*串口1中断向量配置*/
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;                 //串口1中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;   //设置抢先优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;            //设置响应优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                 //使能NVIC
    NVIC_Init(&NVIC_InitStructure);

    /*串口2中断向量配置*/
    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;       //串口2中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1; //抢占优先级3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;      //从优先级3
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         //IRQ通道使能
    NVIC_Init(&NVIC_InitStructure); 

}

以下是发送短信的代码

/*************************************************************************
 * 文件名称 :SMS.c
 * 描    述 :发送中英文短信 
 * 实验平台 :STM32F103zet6开发板
 * 硬件连接 :无
 * 库版本   :STM32F10x_StdPeriph_Lib_V3.5.0
 * 说    明 :1)注意这里调用strcat()字符串拼接函数(库函数)
 *            2)手机号码和短信内容使用汉子Uincode转换小工具
*****************************************************************************/
#include "SMS.h"
#include "USART.h"
#include "LED.h"
#include "SysTick.h"
#include "string.h"
#include "stm32f10x_it.h"

/*---------------------------宏 定 义------------------------------------------*/
#define Buf2_Max      200   //串口2缓存长度

/*-------------------------常 量 声 明  -----------------------------------------*/
//短信内容:SIM800C中英文短信测试
static char *content="00530049004D00380030003000434E2D82F1658777ED4FE16D4B8BD5";
static char *Iphone="\"00310033003300310036003900330031003700300039\"";

/*-------------------------变 量 声 明  -----------------------------------------*/
char Usart2_Buf[Buf2_Max];  //串口2接收缓存
u8   Buffer_Address;   //缓存首地址
vu8  Timer0_start;
u8   shijian;
u8   Times;

/***
* 函数名称: Send_ChineseSMS 
* 描    述: 设置短信为PDU文本模式
* 输入参数: 无
* 输    出: 无
* 返    回: 无
* 说    明: 1)注意AT命令格式,否则发送失败!
*           2)发送中英文短信流程正确步骤,预先处理目标手机号码和短信内容为Unicode编码
* 然后按照下面步骤操作:
* 1.设置文本模式-->2.设置中英文输入模式-->3.设置UCS2编码字符集
*     -->4.发送手机号码-->5.短信内容-->6.发送结束符
**/
void Send_SMS(void)
{
    char temp1[50]="AT+CSCS=";  
    char temp2[50]="AT+CMGS=";
    char *p="\"UCS2\"";

    Send_AtCommand("ATE0","OK",3);  //取消回显

    Send_AtCommand("AT+CMGF=1","OK",3);//设置短信文本模式  或者Usart2_SendString("AT+CMGF=1\r\n");
//  Usart2_SendString("AT+CSMP=17,167,1,8\r\n");//设置中英文模式
    Send_AtCommand("AT+CSMP=17,167,1,8","OK",5);

    strcat(temp1,p);//将字符串P拼接到字符串temp1后面,组成新的字符串temp1(即"AT+CSCS="UCS2"")
  Send_AtCommand(temp1,"OK",3);  //发送AT+CSCS="UCS2"命令,设置为UCS2编码字符集

    Usart1_SendString("写入对方手机号码\r\n");
    strcat(temp2,(char *)Iphone);
    Send_AtCommand(temp2,">",3);  //写入对方手机号码AT+CMGS="00310033003300310036003900330031003700300039"
    Usart1_SendString("写入成功!\r\n");

    Usart1_SendString("输入短信内容\r\n");

    Usart2_SendString(content);           //发送短信内容  

    while(USART_GetFlagStatus(USART2, USART_FLAG_TC)==RESET); 

    USART_SendData(USART2 ,0X1A);         //发送结束符

    Usart1_SendString("输入完成!\r\n");

  Usart1_SendString("发送短信成功!\r\n");

}

/***
* 函数名称: Send_AtCommand 
* 描    述: 发送AT指令函数
* 输入参数: b--- 发送数据的指针(命令)
*            a----  希望接收到的应答数据指针(应答)
*                       wait_time ----发送等待时间(单位:S)  (等待时间)
* 输    出: 无
* 返    回: 无
* 说    明: 无
**/
void Send_AtCommand(char *b,char *a,u8 wait_time)         
{
    u8 i;
    char *c;
    c = b;                              //保存字符串地址到c
    Clear_Buf2();         //清除串口2缓存数据

    i = 0;
    while(i == 0)                    
    {
        if(!Find_String(a)) 
        {
            if(Timer0_start == 0)
            {
                b = c;                          //将字符串地址给b
                for (; *b!='\0';b++)  
                {
                    while(USART_GetFlagStatus(USART2, USART_FLAG_TC)==RESET);
                    USART_SendData(USART2,*b);     
                }
                Usart2_SendLR;       //回车换行
                Times = 0;
                shijian = wait_time;
                Timer0_start = 1;
          }
    }
      else
        {
            i = 1;
            Timer0_start = 0;
        }
    }
    Clear_Buf2(); 
}

/***
* 函数名称:  Find_String
* 描    述: 判断缓存中是否含有指定的字符串
* 输入参数: 字符串 p
* 输    出: 无
* 返    回: unsigned char:1 找到指定字符,0 未找到指定字符
* 说    明: 调用extern char *strstr(char *str1, char *str2)该函数,
*           功能:从字符串str1中查找是否有字符串str2, 如果有,从str1中的str2位置起,
*                             返回str1的指针,如果没有,返回null。
*           返回值:返回该位置的指针,如找不到,返回空指针。
**/
u8 Find_String(char* p)
{ 
  if(strstr(Usart2_Buf,p)!=NULL)
        return 1;
    else
            return 0;
}

/***
* 函数名称:  Wait_Register 
* 描    述: 等待模块注册成功
* 输入参数: 无
* 输    出: 无
* 返    回: 无
* 说    明: 无
**/
void Wait_Register(void)
{
    u8 i;
    u8 k;
    i = 0;
    Clear_Buf2();
  while(i == 0)                 
    {
        Clear_Buf2();             //  清除串口2的缓存        
        Usart2_SendString("AT+CREG?\n\r"); //  查询模块是否注册成功
        Delay_Nms(5000);                           // 延时5秒,等待模块回应
        Usart1_SendString("模块注册中......\n\r");
      for(k=0;k<Buf2_Max;k++)               
    {
            if(Usart2_Buf[k] == ':')
            {
                if((Usart2_Buf[k+4] == '1')||(Usart2_Buf[k+4] == '5')) //说明模块注册成功
                {
                    i = 1;
                    Usart1_SendString("模块注册成功\n\r");
                  break;
                }
            }
        }
    }
}

/***
* 函数名称: Clear_Buf2
* 描    述: 清除串口2缓存数据
* 输    入: 无
* 输    出: 无
* 返    回: 无 
* 说    明: 无
***/
void Clear_Buf2(void)
{
    u16 k;
    for(k=0;k<Buf2_Max;k++)    //将缓存内容清零
    {
        Usart2_Buf[k] = 0x00;
    }
    Buffer_Address = 0;      //接收字符串的起始存储位置
}

以下是中断服务函数

#include "stm32f10x_it.h"
#include "LED.h"
/* Private variables ---------------------------------------------------------*/
extern vu8  Timer0_start;  
extern u8   shijian;
extern u8   Times;
extern u8   Buffer_Address; 
extern char Usart2_Buf[]; 
/* Private functions ---------------------------------------------------------*/
/***
* 函数名称:  USART2_IRQHandler 
* 描    述:  串口2中断服务函数
* 输入参数:  无
* 输    出:  无
* 返    回:  无
* 说    明:  无
***/
void USART2_IRQHandler(void)                    
{
    u8 Res=0;
    Res =USART_ReceiveData(USART2);
    Usart2_Buf[Buffer_Address] = Res; //将接收到的字符串存到缓存中

    Buffer_Address++;           //缓存指针向后移动
    if(Buffer_Address > 200)            //如果缓存满,将缓存指针指向缓存的首地址
    {
        Buffer_Address = 0;
    }    
} 
/*************************************************************************
 * 文件名称 :USART.c
 * 描    述 :串口通信驱动函数         
 * 实验平台 :STM32F103zet6开发板
 * 硬件连接 :串口1用于与电脑通讯及程序下载,串口2用于与评估板通讯
 *    (开发板串口2)Usart2 ---------GPRS模块
 *            PA2  (TXD)----------->  RXD   
 *                   PA3  (RXD) ---------->  TXD   
 *                   GND  ---------------> GND
 *    (开发板串口1)Usart1 : -------  电 脑
 *            PA9 (TXD) ------->   TXD  
 *            PA10 (RXD)------->   RXD  
 *            GND   -------------->  GND
 * 库版本  :STM32F10x_StdPeriph_Lib_V3.5.0
*****************************************************************************/
#include "USART.h"

/***
* 函数名称: Usart1_InitConfig
* 描    述: 串口1初始化配置
* 输    入: BaudRate1:波特率
* 输    出: 无
* 返    回: 无 
* 说    明: 无
***/
void Usart1_InitConfig(u32 BaudRate1)
{
    Usart1_GpioConfig();             //1.端口1工作模式设置

  Usart1_ParameterConfig(BaudRate1);//2.串口1工作参数设置   

    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//3.使能串口1接收中断

    USART_Cmd(USART1, ENABLE);           //4.使能串口1 

    USART_ClearFlag(USART1, USART_FLAG_TC);     //5.清除串口1的发送完成标志
}

/***
* 函数名称: Usart2_InitConfig
* 描    述: 串口2初始化设置
* 输    入: BaudRate2:波特率
* 输    出: 无
* 返    回: 无 
* 说    明: 无
***/
void Usart2_InitConfig(u32 BaudRate2)
{   
    Usart2_GpioConfig();                    //1.端口2工作模式设置   

    Usart2_ParameterConfig(BaudRate2);      //2.串口2工作参数设置

    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//3.使能串口2接收中断

    USART_Cmd(USART2, ENABLE);               //4.使能串口 

    USART_ClearFlag(USART2, USART_FLAG_TC);     //5.清除发送完成标志
}

/***
* 函数名称: Usart1_SendString
* 描    述: 串口1发送字符串
* 输    入: *s --字符串指针
* 输    出: 无
* 返    回: 无 
* 说    明: 无
***/
void Usart1_SendString(char* s)
{
    while(*s)//检测字符串结束符
    {
        while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET); 
        USART_SendData(USART1 ,*s++);//发送当前字符
    }
}

/***
* 函数名称: Usart2_SendString
* 描    述: 串口2发送字符串
* 输    入: *s --字符串指针
* 输    出: 无
* 返    回: 无 
* 说    明: 无
***/
void Usart2_SendString(char* s)
{
    while(*s)//检测字符串结束符
    {
        while(USART_GetFlagStatus(USART2, USART_FLAG_TC)==RESET); 
        USART_SendData(USART2 ,*s++);//发送当前字符
    }
}

/***
* 函数名称: USART1_GPIOConfig
* 描    述: 串口1的GPIO端口配置
* 输    入: 无
* 输    出: 无
* 返    回: 无 
* 说    明: 串口1时钟是挂载在APB2上
***/
void Usart1_GpioConfig()
{
  GPIO_InitTypeDef  GPIO_InitStructure;

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

    /*复位串口1*/
     USART_DeInit(USART1);

  /*USART1_GPIO初始化设置*/ 
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;            //USART1_TXD(PA.9)     
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;      //复用推挽输出
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  //设置引脚输出最大速率为50MHz
   GPIO_Init(GPIOA, &GPIO_InitStructure);  //调用库函数中的GPIO初始化函数,初始化USART1_TXD(PA.9) 

   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;               //USART1_RXD(PA.10)
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;    //浮空输入
   GPIO_Init(GPIOA, &GPIO_InitStructure);  //调用库函数中的GPIO初始化函数,初始化USART1_RXD(PA.10)

}

/***
* 函数名称: Usart2_GpioConfig
* 描    述: 串口2的GPIO端口配置
* 输    入: 无
* 输    出: 无
* 返    回: 无 
* 说    明: 串口2时钟是挂载在APB1
***/
void Usart2_GpioConfig()
{
   GPIO_InitTypeDef  GPIO_InitStructure;

    /*使能USART2和GPIOA外设时钟*/ 
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);   
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);    

    /*复位串口2*/
     USART_DeInit(USART2);

  /*USART1_GPIO初始化设置*/ 
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;            //USART2_TXD(PA.2)     
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;      //复用推挽输出
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    //设置引脚输出最大速率为50MHz
   GPIO_Init(GPIOA, &GPIO_InitStructure);//调用库函数中的GPIO初始化函数,初始化  USART1_TXD(PA.2) 

   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;            //USART2_RXD(PA.3)
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
   GPIO_Init(GPIOA, &GPIO_InitStructure);   //调用库函数中的GPIO初始化函数,初始化USART1_RXD(PA.3)
}

/***
* 函数名称: Usart1_ParameterConfig
* 描    述: 串口1参数配置
* 输    入: Bound1:波特率(常用:2400、4800、9600、19200、38400、115200等)
* 输    出: 无
* 返    回: 无 
* 说    明: 工作模式:8-n-1
***/
void Usart1_ParameterConfig(u32 Bound1)
{
    USART_InitTypeDef   USART_InitStructure;

    /*USART1 参数设置*/
    USART_InitStructure.USART_BaudRate = Bound1;    //设置波特率
    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);         //初始化串口1

}

/***
* 函数名称: Usart2_ParameterConfig
* 描    述: 串口2参数配置
* 输    入: Bound2:波特率(常用:2400、4800、9600、19200、38400、115200等)
* 输    出: 无
* 返    回: 无 
* 说    明: 工作模式:8-n-1
***/ 
void Usart2_ParameterConfig(u32 Bound2)
{
    USART_InitTypeDef   USART_InitStructure;

    /*USART1 初始化设置*/
    USART_InitStructure.USART_BaudRate = Bound2;    //设置波特率
    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(USART2, &USART_InitStructure);         //初始化串口1

}

以下是USART函数头文件

#ifndef __USART_H
#define __USART_H

#include "stm32f10x.h"
#include <stdio.h>
/*--------------------函数声明-----------------------*/
void Usart1_InitConfig(u32 BaudRate1);

void Usart2_InitConfig(u32 BaudRate2);

void Usart1_GpioConfig(void);

void Usart2_GpioConfig(void);

void Usart1_ParameterConfig(u32 Bound1);

void Usart2_ParameterConfig(u32 Bound2);

void Usart1_SendString(char* s);

void Usart2_SendString(char* s);

void Usart1_NvicConfig(void);

void Usart2_NvicConfig(void);

#endif

以下是LED控制函数

* 函数名称: LED_GpioConfig 
* 描    述: 配置LED引脚端口 
* 输入参数: 无
* 输    出: 无
* 返    回: 无
* 说    明: 1)LED1的IO口是:PB0 
*           2)被函数LED_InitConfig()调用
***/
void LED_GpioConfig(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;     
  RCC_APB2PeriphClockCmd(LED_RCC, ENABLE);          //使能GPIOB的外设时钟  

  GPIO_InitStructure.GPIO_Pin =LED1 ;               //选择要初始化的GPIOA引脚PB0
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //设置引脚工作模式为通用推挽输出       
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置引脚输出最大速率为50MHz
  GPIO_Init(LED_PORT, &GPIO_InitStructure);     

}

以下是LED函数头文件

#ifndef __LED_H__
#define __LED_H__

#include "stm32f10x.h"
/*--------------------宏 定 义-------------------------*/

#define LED_RCC     RCC_APB2Periph_GPIOB  //LED时钟 
#define LED_PORT    GPIOB                 //LED的GPIO端口

#define LED1        GPIO_Pin_0    

#define LED1_ON     GPIO_SetBits(LED_PORT,LED1)   //例如 LED1_ON:点亮LED1 
#define LED1_OFF    GPIO_ResetBits(LED_PORT,LED1) //例如  LED1_OFF:熄灭LED1 

/*--------------------函 数 声 明-----------------------*/
void LED_GpioConfig(void);
void LED_InitConfig(void);
#endif
/*************************************************************************
 * 文件名称 :SysTick.c
 * 描    述 :通过系统滴答时钟SysTick中断实现nMs(n毫秒)、nS(n秒)的延时         
 * 实验平台 :STM32F103zet6开发板
 * 硬件连接 :无                  
 * 库版本   :STM32F10x_StdPeriph_Lib_V3.5.0 
**************************************************************************/
#include "SysTick.H"

static u32 SysTickDelayTime;

/***
* 函数名称: SysTick_InitConfig
* 描    述: 初始化系统滴答时钟SysTick
* 输入参数: 无
* 输    出: 无
* 返    回: 无
* 说    明: 1)、SystemFrequency / 1000     1ms中断一次
*                 2)、SystemFrequency / 100000   10us中断一次
*                 3)、SystemFrequency / 1000000  1us中断一次
*           计算方法:(SystemFrequency / Value)个系统时钟节拍中断一次
***/
void SysTick_InitConfig(void)
{
    while(SysTick_Config(SystemCoreClock / 1000));  //初始化并使能系统滴答时钟,返回1表示计数设置太大           

    SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;          //失能滴答定时器 

}

/***
* 函数名称: Delay_Nus
* 描    述: n倍微秒延时
* 输入参数: nus
* 输    出: 无
* 返    回: 无
* 说    明: 无
***/
void Delay_Nus(u32 nus)
{ 
    SysTickDelayTime = nus*1000000;      
    SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;   //使能滴答定时器 
    while(SysTickDelayTime != 0);                   //等待延时时间到
}

/***
* 函数名称: Delay_Nms
* 描    述: n倍毫秒延时
* 输入参数: 无
* 输    出: 无
* 返    回: 无
* 说    明: 无
***/
void Delay_Nms(u32 nms)
{ 
    SysTickDelayTime = nms;      
    SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;   //使能滴答定时器 
    while(SysTickDelayTime != 0);                   //等待延时时间到
}

/***
* 函数名称: Delay_Ns
* 描    述: n倍秒延时
* 输入参数: ns
* 输    出: 无
* 返    回: 无
* 说    明: 无
***/
void Delay_Ns(u32 ns)
{ 
    SysTickDelayTime = ns*1000;      
    SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;   //使能滴答定时器 
    while(SysTickDelayTime != 0);                   //等待延时时间到
}

/***
* 函数名称: SysTickDelayTime_Counter
* 描    述: 获取节拍程序
* 输入参数: 无
* 输    出: 无
* 返    回: 无
* 说    明: 在SysTick中断程序SysTick_Handler()调用(stm32f10x_it.c)
***/
void SysTickDelayTime_Counter(void)
{
    if (SysTickDelayTime > 0)
    { 
        SysTickDelayTime--;
    }
}

以下是延时头文件

#ifndef __SYSTICK_H
#define __SYSTICK_H

#include "stm32f10x.h"

/*--------------------函 数 声 明-----------------------*/
void SysTick_InitConfig(void);
void SysTickDelayTime_Counter(void);
void Delay_Nus(u32 nus);
void Delay_Nms(u32 nms);
void Delay_Ns(u32 ns);
#endif 

实验效果如图所示:
发送中英文短信实验

评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值