基于STM32F103——SIM900A发送短信+串口打印

发布者:温柔阳光最新更新时间:2022-09-22 来源: csdn关键字:STM32F103  SIM900A  发送短信  串口打印 手机看文章 扫描二维码
随时随地手机看文章

最近用STM32F103做一个智能门锁小玩意,密码输入错误次数多进行验证码解锁,这里我采用SIM900A来通过发送短信输入验证码进行解锁。就是简单的了解了一下在这里也单独的写写这个SIM900A的一写笔记。

基本介绍

在这里插入图片描述

。。。。。。还是直接进入主题吧


一:单独测试

SIM900A是可以AT指令操作的,所以一般我拿到这种模块就是先单独的测试一下这个模块是否正常。通过一个USB-TTL 和 SIM900A连接 进行调试。用我们的电脑串口助手测试即可。没必要上来就用单片机,现单独测试了先。没问题再转成代码也不迟。


1.准备工作

USB-TTL一个

在这里插入图片描述

还有杜邦线就不用说啦


2.接线

image.png

3.指令操作

打开你的串口助手

注意:建议使用卖家配套的串口助手

注意:建议使用卖家配套的串口助手

注意:建议使用卖家配套的串口助手


第一步:发送AT检测是否正常 (记得要回车换行再发送) 成功返回OK


AT


第二步:选择短消息格式(0:PDU模式 1:文本模式) (记得要回车换行再发送) 成功返回OK


AT+CMGF=1


第三步:选择TE字库集 (记得要回车换行再发送) 成功返回OK


AT+CSCS="UCS2"


第四步:保存SMS设置 (记得要回车换行再发送) 成功返回OK


AT+CSCA?


第五步:设置短消息文本模式参数 (记得要回车换行再发送) 成功返回OK


AT+CSMP=17,167,0,25


**第六步:设置接收短信方的电话号码(要转UNICON编码) (记得要回车换行再发送) 成功返回>**不知道咋转往下翻有一个代码是生成的。


AT+CMGS="你接收短信方的电话号码的UNICON编码"


第七步:发送要发送的内容(要转UNICON编码)(记得要回车换行再发送)成功返回>


"发送的内容的UNICON编码"


第八步:发送结束标志 16进制:0X1A 切换到16进制模式发送(不需要回车换行) 成功返回OK


1A


提示:

1.不出意外的话你设置接收短信的手机号码就能接收到你发送的短信内容


2.上面提到的为啥最好用卖家提供的串口助手呢 因为我一开始就没用卖家的,我用的其他,换了2个都是发送最后的1A 返回的error 而不是OK。后来用回他们提供的就成功了。


3.关于UNICON编码转换软件 一般卖家都会提供资料的 如下图

你没有也没关系 或者懒得找咱就自己写一个 我这里也有写 请忘下看 不过我这里是ASCII转Unicode 如果是中文你可以自己写一下 或者还是找软件转吧 哈哈哈哈

在这里插入图片描述

4.测试结果

在这里插入图片描述

二:关于Unicode编码

Unicode基本介绍

Unicode一般指统一码,也叫万国码、单一码,是计算机科学领域里的一项业界标准,包括字符集、编码方案等。Unicode是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。


1、编码方式

unicode是一种国际组织制定能容纳所有文字和符号的字符编码方案。Unicode用数字0-0x10FFFF来映射这些字符,最多可以容纳1114112个字符,或者说有1114112个码位。码位就是可以分配给字符的数字。UTF-8、UTF-16、UTF-32都是将数字转换到程序数据的编码方案。


我们看图 我这里只是ASCII转… 凑合看吧

我们把ASCII字符串用当成双字节汉字转unicode码你发现1这个字符变成了0031

这31是不是你想到了什么,1的16进制不就是0X31吗?前面补2个0后面是它的16进制不就完事了么?

在这里插入图片描述

/**********************************************************************

描述: ASCII 转 unicode      比如 '1'  转成 "0031"

***********************************************************************/

void ASCII_TO_Unicode(char *ASCII,char *Unicode)

{

    int length;

    int i = 0;

    int j = 0;

memset(Unicode,'',sizeof(Unicode));

    length = strlen(ASCII);


    for(i=0;i    {

        Unicode[j++] = '0';

        Unicode[j++] = '0';


        Unicode[j++] = (ASCII[i] / 16) + 0x30;

        Unicode[j++] = (ASCII[i] % 16) + 0x30;

    }


}


比如我想把接收短信方的电话号码转一下

在这里插入图片描述

三:代码编写

有了刚才的测试,我们就可以转成代码来 用STM32F103来控制SIM900A发送短信了。


我这里不加入显示屏来了。直接用串口打印信息查看了。


用到资源:两个串口

串口1用于打印信息(充当显示屏)

串口2用于和SIM900A通信。


sim900a.c

#include "sim900a.h"

#include

#include

#include

#include

#include "usart.h"

#include "delay.h"


uint8_t verification_code[7]; //存放验证码 


uint8_t sim900a_receive_data[128] = {0};

uint16_t sim900a_receive_count;


/**********************************************************************

描述:   SIM900A模块发送指令 函数

参数: *str:指令内容 ack:正常返回结果的数据 time:允许时间(1次代表 10ms)

返回: 0:指令得到正确回应 1: 指令没得到回应

***********************************************************************/

uint8_t sim900a_send_cmd(uint8_t *str,uint8_t *ack,uint16_t time)

{

memset(sim900a_receive_data,'',sizeof(sim900a_receive_data));

sim900a_receive_count = 0;

usart_sendString(USART2,(char *)str); //发送指令

if(ack == NULL) return 0;

//开启中断接收

OPEN_USART2_RECEIVE;

while(time--)

{

delay_ms(10);

//寻找要找的关键词 找到关中断接收 并且返回0

if(strstr((char *)sim900a_receive_data,(char *)ack) != NULL)

{

CLOSE_USART2_RECEIVE; //关闭中断接收

return 0;

}

}

CLOSE_USART2_RECEIVE; //关闭中断接收

return 1; //超时还没收到想要得到的关键词 关串口中断 并且返回1

}



/**********************************************************************

描述:   SIM900A模块发送指令 函数

参数: *str:指令内容 ack:正常返回结果的数据 time:允许时间(1次代表 10ms)

返回: 0:指令得到正确回应 1: 指令没得到回应

***********************************************************************/

uint8_t sim900a_send_end(uint8_t data,uint8_t *ack,uint16_t time)

{

sim900a_receive_count = 0;

memset(sim900a_receive_data,'',sizeof(sim900a_receive_data));


usart_sendByte(USART2,data); //发送结束指令

if(ack == NULL) return 0;

//开启中断接收

OPEN_USART2_RECEIVE;

while(time--)

{

delay_ms(10);

//寻找要找的关键词 找到关中断接收 并且返回0

if(strstr((char *)sim900a_receive_data,(char *)ack) != NULL)

{

CLOSE_USART2_RECEIVE; //关闭中断接收

return 0;

}

}

CLOSE_USART2_RECEIVE; //关闭中断接收

return 1; //超时还没收到想要得到的关键词 关串口中断 并且返回1

}




/**********************************************************************

描述:   随机生成验证码('0'~'9')

        产生字符 '0' ~ '9'  十进制也就是 48 ~ 57

***********************************************************************/

void generate_verification_code(char *data,uint8_t number)

{

    uint8_t i;

//    srand(time(NULL));


    for(i=0;i    {

        data[i] = 48 + (rand() % 10);

    }

}


/**********************************************************************

描述: ASCII 转 unicode      比如 '1'  转成 "0031"

***********************************************************************/

void ASCII_TO_Unicode(char *ASCII,char *Unicode)

{

    int length;

    int i = 0;

    int j = 0;

memset(Unicode,'',sizeof(Unicode));

    length = strlen(ASCII);


    for(i=0;i    {

        Unicode[j++] = '0';

        Unicode[j++] = '0';


        Unicode[j++] = (ASCII[i] / 16) + 0x30;

        Unicode[j++] = (ASCII[i] % 16) + 0x30;

    }


}


/**********************************************************************

描述: SIM900A 发送验证码 函数

返回: 0:成功 1:失败

***********************************************************************/

uint8_t sim900a_send_verification_code(void)

{

uint8_t ack; //存放状态

uint8_t err = 3; //设置可错误次数 

uint8_t send_count = 3; //发送次数 发送次数达到还是没成功则放弃发送

uint8_t sim900a_send_buffer[96] = {0};


SEND_AT:

strcpy((char *)sim900a_send_buffer,"AT+CMGS="");

//发送指令AT 检测是否返回OK 给300ms时间检测

ack = sim900a_send_cmd(SIM900A_SEND_AT,"OK",30);

if(ack)

{

if(err-- == 0)

{

printf("AT FAILrn");

return 1;

}

goto SEND_AT;

}

printf("AT OKrn");

err = 3;

//发送 短消息格式 指令 检测是否返回OK 给300ms时间检测

SELECT_SMS_FORMAT:

ack = sim900a_send_cmd(SIM900A_SELECT_SMS_FORMAT,"OK",30);

if(ack)

{

if(err-- == 0)

{

printf("SMS FORMAT FAILrn");

return 1;

}

goto SELECT_SMS_FORMAT;

}

printf("SMS FORMAT SUCCESSrn");

err = 3;




//发送 选择TE字库集 指令 检测是否返回OK 给300ms时间检测

SELECT_TE_FONT:

ack = sim900a_send_cmd(SIM900A_SELECT_TE_FONT,"OK",30);

if(ack)

{

if(err-- == 0)

{

printf("SELECT_TE_FONT FAILrn");

return 1;

}

goto SELECT_TE_FONT;

}

printf("SELECT_TE_FONT SUCCESSrn");

err = 3;




//发送 选择TE字库集 指令 不检测返回值

SAVE_SMS_SET:

ack = sim900a_send_cmd(SIM900A_SAVE_SMS_SET,NULL,0);

if(ack)

{

if(err-- == 0)

{

printf("SAVE_SMS_SET FAILrn");

return 1;

}

goto SAVE_SMS_SET;

}

printf("SAVE_SMS_SET SUCCESSrn");

err = 3;



//发送 设置短消息文本模式参数 指令 检测是否返回OK 给300ms时间检测

SET_SMS_TEST_MODE:

ack = sim900a_send_cmd(SIM900A_SET_SMS_TEST_MODE,"OK",30);

if(ack)

{

if(err-- == 0)

{

printf("SMS TEST MODE FAILrn");

return 1;

}

goto SET_SMS_TEST_MODE;

}

printf("SMS TEST MODE SUCCESSrn");

err = 3;



//让我们的设置接收短信方电话号码生成unicode编码

ASCII_TO_Unicode(PHONE_NUMBER,&sim900a_send_buffer[strlen(sim900a_send_buffer)]);

strcat((char *)sim900a_send_buffer,""rn");

printf("%srn",sim900a_send_buffer);

//发送 接收短信方电话号码 指令 检测是否返回OK 给1000ms时间检测

SELECT_PHONE_NUMBER:

ack = sim900a_send_cmd(sim900a_send_buffer,">",100);

if(ack)

{

if(err-- == 0)

{

printf("SET PHONE NUMBER FAILrn");

return 1;

}

goto SELECT_PHONE_NUMBER;

}

printf("SET PHONE NUMBER SUCCESSrn");

err = 3;

//清空缓冲区 准备为发送验证码做准备

memset(sim900a_send_buffer,'',sizeof(sim900a_send_buffer));


//在这里开始就是开始发送内容了

//1-生成验证码

strcpy((char *)sim900a_send_buffer,"9A8C8BC17801003A"); //添加unicode码 "验证码:"

generate_verification_code((char *)verification_code,6);//生成验证码

printf("验证码生成结果:%srn",verification_code);

//2-将随机产生的6位验证码转Unicode编码 并且拼接一起

ASCII_TO_Unicode((char *)verification_code,&sim900a_send_buffer[strlen(sim900a_send_buffer)]);

strcat((char *)sim900a_send_buffer,"rn"); //加上回车换行 

printf("%srn",sim900a_send_buffer);

//3-发送数据

SEND_DATA:

ack = sim900a_send_cmd(sim900a_send_buffer,">",300);

if(ack)

{

if(err-- == 0)

{

printf("SEND DATA FAILrn");

return 1;

}

goto SEND_DATA;

}

printf("SEND DATA SUCCESSrn");

//4-发送 0X1A 标志

ack = sim900a_send_end(0x1a,"OK",800);

if(ack)

{

if(send_count-- == 0) return 1;

memset(sim900a_send_buffer,'',sizeof(sim900a_send_buffer));

err = 3;

goto SEND_AT; //重发短信

}

printf("SEND MESSAGE SUCCESSrn");

return 0;

}


/**********************************************************************

描述: SIM900A 初始化 函数

返回: 0:成功 1:失败

***********************************************************************/

uint8_t sim900a_init(void)

{

uint8_t ack; //存放状态

uint8_t err; //设置可错误次数 


err = 3;

//发送指令AT 检测是否返回OK 给300ms时间检测

SEND_AT:

ack = sim900a_send_cmd(SIM900A_SEND_AT,"OK",30);

if(ack)

{

if(err-- == 0)

{

printf("AT FAILrn"); //ESP8266模块不存在

return 1;

}


goto SEND_AT;

}

printf("AT SUCCESSrn");

return 0;

}


sim900a.h

#ifndef __SIM900A_H

#define __SIM900A_H

#include "stm32f10x.h"


/*用户必改 xxxxxxxxxxx 改成接收短信的电话号码*/

#define PHONE_NUMBER "xxxxxxxxxxx"



#define SIM900A_SEND_AT "ATrn"

//1.选择短消息格式 (0:PDU模式 1:文本模式)

#define SIM900A_SELECT_SMS_FORMAT "AT+CMGF=1rn"

//2.选择TE字库集

#define SIM900A_SELECT_TE_FONT "AT+CSCS="UCS2"rn"

//3.保存SMS设置

#define SIM900A_SAVE_SMS_SET "AT+CSCA?rn"

//4.设置短消息文本模式参数

#define SIM900A_SET_SMS_TEST_MODE "AT+CSMP=17,167,0,25rn"


extern uint8_t  sim900a_receive_data[128];

extern uint16_t  sim900a_receive_count;

[1] [2]
关键字:STM32F103  SIM900A  发送短信  串口打印 引用地址:基于STM32F103——SIM900A发送短信+串口打印

上一篇:基于STM32F103+AS608指纹模块+4X4矩阵按键+SIM900A发短信——智能门禁卡系统
下一篇:基于STM32F103——AS608指纹模块+串口打印

推荐阅读最新更新时间:2024-11-16 22:27

STM32f103的电阻触摸屏的五点校正算法
由于电阻式触摸屏就是一种传感器,它利用压力感应进行控制,将矩形区域中触摸点(X,Y)的物理位置转换为代表X坐标和Y坐标的电压。这里先引入两个概念,物理坐标和逻辑坐标。物理坐标指触摸屏上点的实际位置,通常以液晶上点的个数来度量。逻辑坐标指这点被触摸时A/D转换后的坐标值。如图1,我们假定液晶最左下角为坐标轴原点A,在液晶上任取一点B(十字线交叉中心),B在X方向距离A10个点,在Y方向距离A20个点,则这点的物理坐标为(10,20)。如果我们触摸这一点时得到的X向A/D转换值为100,Y向A/D转换值为200,则这点的逻辑坐标为(100,200)。 常用的电阻式触摸屏矫正方法有两点校准法和三点校准法。本文这里介绍的是结合了不同的
[单片机]
<font color='red'>STM32f103</font>的电阻触摸屏的五点校正算法
STM32F103串口1和串口2不同波特率之间交换数据问题
前几天写一个东西,要用到STM32F103的串口1和串口2以不同的波特率交换数据,也就是说串口1波特率为9600,串口2波特率为115200,串口1可以把接收到的数据通过串口2发送出去,串口2也可以把接收到的数据通过串口1发送出去。低波特率向高波特率发送数据没问题,高波特率向低波特率发送数据会丢数据,原因是低波特率的串口还没发送完数据高波特率的串口就又发数据过来了,处理不过来。在同事的在帮助下,写出一个先进先出环形队列(FIFO)程序。接收数据用中断,发送数据用在主函数中查询发送完成标志位。希望对大家有点帮助,可能程序不完美,但程序可以用。定义一个fifo.h部件和一个fifo.c文件。其他的都在主函数中调用。 #ifndef
[单片机]
基于stm32f103zet6之NRF905无线模块的学习
stm32f103zet6简介 STM32F系列属于中低端的32位ARM微控制器,该系列芯片是意法半导体(ST)公司出品,其内核是Cortex-M3。 该系列芯片按片内Flash的大小可分为三大类:小容量(16K和32K)、中容量(64K和128K)、大容量(256K、384K和512K)。 芯片集成定时器,CAN,ADC,SPI,I2C,USB,UART,等多种功能。 NRF905简介 nRF905是挪威Nordic公司推出的一款单片射频发射器芯片,采用32引脚5mm 5mm QFN封装,工作于433、868、915MHz 3个ISM(工业、科学和医学)频道,其中国内433频段可以免费使用。nRF905由频率合成器、接
[单片机]
基于<font color='red'>stm32f103</font>zet6之NRF905无线模块的学习
STM32F103C8T6定时器TIM4通道1、2输出PWM
这美妙的波形,真好,我他喵的终于把你弄出来了。 STM32F103C8T6使用定时器TIM4进行双通道的PWM输出: 下面的图是从STM32中文参考手册中截取的,定时器TIM4的通用和复用功能I/O 我选用的是TIM4_CH1和TIM4_CH2也就是PB6和PB7输出。 注意事项: 输出PWM是属于IO口的复用功能,所以在设置GPIO_Mode的时候一定要设置为GPIO_Mode_AF_PP也就是推挽复用。 我就是被这个卡了好长时间……,感觉自己蠢到家了。 我是用的正点原子的精英板学的32,所以一些写代码的习惯都是学的正点原子的。 下面是代码 timer.c #include timer.h //TIM
[单片机]
<font color='red'>STM32F103</font>C8T6定时器TIM4通道1、2输出PWM
使用STM32F101xx和STM32F103xx DMA控制器
这篇应用笔记描述了怎么使用STM32F101xx和STM32F103xx的直接内存访问(DMA)控制器。STM32F101xx和STM32F103xx DMA控制器、Cortex-M3内核、先进的微控制器总线架构和存储系统,是为了提供一个高的数据带宽,并开发响应时间非常快的软件。这篇文档也描述了怎样充分利用这些特性,以及对于不同的外设和子系统怎样保证正确的响应时间。 在下文中STM32F101xx 和STM32F103xx都记作STM32F10xxx,DMA控制器都记作DMA。 1、DMA控制器 DMA是一个AMBA先进的高性能总线(AHB),它的特点是它具有两个AHB端口:一个从端口,用于DMA编程;一个是主端口,主端口
[单片机]
使用STM32F101xx和<font color='red'>STM32F103</font>xx DMA控制器
STM32 DHT11串口打印源程序
1.硬件准备: USB转TTL工具一个 核心板STM32F103C8T6 DHT11传感器 2.软件准备: 串口调试助手 2.硬件连线 USB转TTL的RX----32板子上的PA9 USB转TTL的TX----32板子上的PA10 DHT11的DAT连接PB14 3.程序源码 #include dht11.h ////////////////////////////////////////////////////////////////////////////////// #include delay.h //////////////////////////////////////////////////////
[单片机]
STM32 DHT11<font color='red'>串口</font><font color='red'>打印</font>源程序
STM32F103之系统时钟初始化及延迟函数
一、简介 本文以STM32F103编程为例,介绍STM32F103系统时钟初始化及延迟函数编写 二、实验平台 电脑平台:Windows7 64位旗舰 编译软件:Keil5 硬件平台:STM32F103RC 三、版权声明 四、实验前提 1、在进行本文步骤前,请先安装keil5版本;准备好STM32F103RC硬件平台。 五、基础知识 暂无 六、源码地址 暂无 七、关联文章 暂无 八、实验内容 1.初始化系统时钟 /*外部时钟最高72MHz 内部时钟最高64MHz*/ typedef enum{ HAL_CLOCK_HSE_SYS = (unsigned char
[单片机]
Nokia_5110显示屏STM32F103x开发
一、显示屏模块选型 1.1 Nokia 5110 LCD(蓝屏) 液晶屏模块 1.2 简介: 1.3 显示屏 显示分成 5 行 二、程序开发 这里有两个,关于 显示 数据的 数组,我把放在两个不同的 头文件 中,一个为了方便显示英文,一个为了方便显示中文。英文操作简单一点。 2.1 main函数 程序链接: https://download.csdn.net/download/qq_37788383/11887775 #include stm32f10x.h #include delay.h #include sys.h #include usart.h #include nokia_5110.h
[单片机]
Nokia_5110显示屏<font color='red'>STM32F103</font>x开发
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved