基于STM32F103——SIM900A发送短信+串口打印
STM32F103-SIM900A发短信+串口打印
- 基本介绍
- 一:单独测试
- 1.准备工作
- 2.接线
- 3.指令操作
- 4.测试结果
- 二:关于Unicode编码
- Unicode基本介绍
- 三:代码编写
- sim900a.c
- sim900a.h
- main.c
- 项目演示
- 总结
最近用STM32F103做一个智能门锁小玩意,密码输入错误次数多进行验证码解锁,这里我采用SIM900A来通过发送短信输入验证码进行解锁。就是简单的了解了一下在这里也单独的写写这个SIM900A的一写笔记。
基本介绍
。。。。。。还是直接进入主题吧
一:单独测试
SIM900A是可以AT指令操作的,所以一般我拿到这种模块就是先单独的测试一下这个模块是否正常。通过一个USB-TTL 和 SIM900A连接 进行调试。用我们的电脑串口助手测试即可。没必要上来就用单片机,现单独测试了先。没问题再转成代码也不迟。
1.准备工作
USB-TTL一个
还有杜邦线就不用说啦
2.接线
USB-TTL | SIM900A |
---|---|
5V | VCC5 |
GND | GND |
TX | 5VR |
RX | 5VT |
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,'\0',sizeof(Unicode));length = strlen(ASCII);for(i=0;i<length;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 <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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,'\0',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);//寻找要找的关键词 找到关中断接收 并且返回0if(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,'\0',sizeof(sim900a_receive_data));usart_sendByte(USART2,data); //发送结束指令if(ack == NULL) return 0;//开启中断接收OPEN_USART2_RECEIVE;while(time--){delay_ms(10);//寻找要找的关键词 找到关中断接收 并且返回0if(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<number;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,'\0',sizeof(Unicode));length = strlen(ASCII);for(i=0;i<length;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 FAIL\r\n");return 1; }goto SEND_AT;}printf("AT OK\r\n");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 FAIL\r\n"); return 1; }goto SELECT_SMS_FORMAT;}printf("SMS FORMAT SUCCESS\r\n");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 FAIL\r\n");return 1; }goto SELECT_TE_FONT;}printf("SELECT_TE_FONT SUCCESS\r\n");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 FAIL\r\n");return 1; }goto SAVE_SMS_SET;}printf("SAVE_SMS_SET SUCCESS\r\n");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 FAIL\r\n");return 1; }goto SET_SMS_TEST_MODE;}printf("SMS TEST MODE SUCCESS\r\n");err = 3;//让我们的设置接收短信方电话号码生成unicode编码 ASCII_TO_Unicode(PHONE_NUMBER,&sim900a_send_buffer[strlen(sim900a_send_buffer)]);strcat((char *)sim900a_send_buffer,"\"\r\n"); printf("%s\r\n",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 FAIL\r\n");return 1; }goto SELECT_PHONE_NUMBER;}printf("SET PHONE NUMBER SUCCESS\r\n");err = 3; //清空缓冲区 准备为发送验证码做准备memset(sim900a_send_buffer,'\0',sizeof(sim900a_send_buffer));//在这里开始就是开始发送内容了//1-生成验证码strcpy((char *)sim900a_send_buffer,"9A8C8BC17801003A"); //添加unicode码 "验证码:"generate_verification_code((char *)verification_code,6);//生成验证码printf("验证码生成结果:%s\r\n",verification_code); //2-将随机产生的6位验证码转Unicode编码 并且拼接一起ASCII_TO_Unicode((char *)verification_code,&sim900a_send_buffer[strlen(sim900a_send_buffer)]);strcat((char *)sim900a_send_buffer,"\r\n"); //加上回车换行 printf("%s\r\n",sim900a_send_buffer);//3-发送数据
SEND_DATA:ack = sim900a_send_cmd(sim900a_send_buffer,">",300); if(ack){if(err-- == 0){printf("SEND DATA FAIL\r\n");return 1; }goto SEND_DATA;}printf("SEND DATA SUCCESS\r\n");//4-发送 0X1A 标志ack = sim900a_send_end(0x1a,"OK",800);if(ack){if(send_count-- == 0) return 1;memset(sim900a_send_buffer,'\0',sizeof(sim900a_send_buffer));err = 3;goto SEND_AT; //重发短信}printf("SEND MESSAGE SUCCESS\r\n");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 FAIL\r\n"); //ESP8266模块不存在return 1; }goto SEND_AT;}printf("AT SUCCESS\r\n");return 0;
}
sim900a.h
#ifndef __SIM900A_H
#define __SIM900A_H
#include "stm32f10x.h"/*用户必改 xxxxxxxxxxx 改成接收短信的电话号码*/
#define PHONE_NUMBER "xxxxxxxxxxx"#define SIM900A_SEND_AT "AT\r\n"
//1.选择短消息格式 (0:PDU模式 1:文本模式)
#define SIM900A_SELECT_SMS_FORMAT "AT+CMGF=1\r\n"
//2.选择TE字库集
#define SIM900A_SELECT_TE_FONT "AT+CSCS=\"UCS2\"\r\n"
//3.保存SMS设置
#define SIM900A_SAVE_SMS_SET "AT+CSCA?\r\n"
//4.设置短消息文本模式参数
#define SIM900A_SET_SMS_TEST_MODE "AT+CSMP=17,167,0,25\r\n"extern uint8_t sim900a_receive_data[128];
extern uint16_t sim900a_receive_count;extern uint8_t verification_code[7]; //存放验证码uint8_t sim900a_send_cmd(uint8_t *str,uint8_t *ack,uint16_t time); //SIM900A模块发送字符串指令 函数
uint8_t sim900a_send_end(uint8_t data,uint8_t *ack,uint16_t time); //SIM900A模块发送单字节指令 函数
void generate_verification_code(char *data,uint8_t number); // 随机生成验证码('0'~'9')
void ASCII_TO_Unicode(char *ASCII,char *Unicode); // ASCII 转 unicode
uint8_t sim900a_init(void);
uint8_t sim900a_send_verification_code(void);
#endif
main.c
#include "stm32f10x.h"
#include "delay.h"
#include "usart.h"
#include "sim900a.h"/*
注意:先到 sim900a.h 填写接收短信的电话号码。 接线:
STM32F103 SIM900A
PA2 5VR
PA3 5VT
5V 5V
GND GND
*/int main()
{usart1_init(115200); //串口1初始化 用于打印信息usart2_init(115200); //串口2初始化 用于和SIM900A模块do{printf("SIM900A Init...\r\n");}while(sim900a_init());printf("SIM900A Init Success\r\n");if(sim900a_send_verification_code()){printf("发送短信失败\r\n");}else{printf("发送短信成功\r\n");}while(1);
}
项目演示
总结
问题1:一开始我采用电脑串口助手单独测试的时候,用了两个串口助手都到最后一步 发送 0x1A 时候返回error,以为是这个模块有问题,然后用回商家给的那个就成功了。。。。。所以还是建议用商家给的那个串口助手吧。。。。
问题2:如果发送失败,也有可能是你手机欠费了 哈哈哈哈哈哈哈。啊,我就是。擦。整我半天。
如果我哪里写的有问题,或者不好,请大家多多指教
#整个工程代码。
printf("+meQ:844797079\n")
如果觉得这篇文章对你有用。欢迎大家点赞、评论哈哈
继续加油!!!
基于STM32F103——SIM900A发送短信+串口打印相关推荐
- MATLAB收取邮件,Matlab 程序结束后发送短信或者邮件
近期,在服务器上运行matlab程序,由于数据比较多,程序比较复杂,运行时间不固定,而且需要经常改变参数,重复运行几次,所以不清楚程序何时结束,以便于修改参数,继续运行.开始有时间就看看程序是否运行结 ...
- SIM900A英文短信的读取与发送
一.英文短信的发送: 一般分为五步进行短信的发送: 1.我们用到AT+CSCS指令来设置TE字符集,默认的为GSM7位缺省字符集,在发送英文短信时,需要发送:AT+CSCS="GSM&quo ...
- C# 通过串口发送短信
手机短信群发作为企业日常通知,公告,天气预报等信息的一个发布平台,在于成本低,操作方便等诸多特点,成为企业通讯之首选.本文介绍短信的编码方式,AT指令以及用C#实现串口通讯的方法. 前言目前,发送短信 ...
- 基于SMS短信平台给手机发送短信
JAVA发送手机短信,我知道的有三种方式,恰逢项目需求,自己整理了基于SMS的短信发送,其他两种这里就说说一下 使用webservice接口发送手机短信,这个可以使用sina提供的webservice ...
- 基于MFC与阿里云制作简易发送短信
***~~ 做到最后可能会只是不能识别汉字,但是能识别英文和数字,有待改进的地方` ` ~~ *** # 详细步骤见如下 一. 新建一个MFC项目:打开VS2013,文件->新建->项目 ...
- 基于HTTP协议用JAVA实现读取天气预报和twilio发送短信(无需审核)
文章目录 一.读取指定城市的天气预报 二.twilio平台java编程实现发送短信 三.总结 四.参考 一.读取指定城市的天气预报 代码如下: package network;import java. ...
- Flask - 基于阿里云的短信发送
目录 一.前期准备 二.官方 SDK_demo 的学习使用 2-1 sms_send 2-2 sms_query 指定手机号的短信发送的 三.基于SDK发送短信 + Celery 实现异步任务 一.前 ...
- SIM800C通过串口AT指令拨打电话与发送短信
目录 一.更新时间 二.相关器件 三.硬件连接 四.现象与事件 五.具体操作: 5.1 准备工作(查询器件是否正常) 5.2 拨打电话 5.3 发送短信 5.3.1 短信消息模式为文本模式 5.3.2 ...
- python控制手机发短信_python-在python3中使用容联云通讯发送短信验证码
2020-08-15更新 今天进容联云官网发现其已经更新了最新版的Python SDK,可以直接 pip install ronglian_sms_sdk 即可安装使用,具体新的使用方法可以查看官网案 ...
- Linux-C实现GPRS模块发送短信
"GSM模块,是将GSM射频芯片.基带处理芯片.存储器.功放器件等集成在一块线路板上,具有独立的操作系统.GSM射频处理.基带处理并提供标准接口的功能模块.GSM模块根据其提供的数据传输速率 ...
最新文章
- 综合程序设计 7-4 完美的代价 (40分)
- redhat配置centos的yum源
- (转)C#网络编程(基本概念和操作) - Part.1
- mysql数据库表复制备份_mysql数据库的备份以及表格数据之间的复制
- 20180105随笔
- data.name.toLowerCase() is not a function问题
- android Handler更新UI
- 将SSM架构中原来关于springSecurity3.x版本的写法配迁移到SpringBoot2.0框架中出现的问题解决记...
- 计算机基础应用教材分析,关于《计算机应用基础》的说课稿一、教材分析(说教材):.pdf...
- 思源黑体下载 - Google 联合 Adobe 发布免费开源优雅的设计字体 (简繁中文/日韩文)
- 魔方游戏程序设计制作(C语言)
- IOS版aplayer使用教程_管家婆服装版使用教程,重庆任我行管家婆服装软件的使用方法...
- 专升本英语——应试题型突破——翻译——固定搭配【学习笔记】
- 如何进行网站流量分析(二)
- 数据库附加失败解决方法
- python小玩意——性格测试
- 嵌入式设备系统有无操作系统的区别
- 如何恢复移动硬盘数据?
- 【数据结构 C描述】一个文本串可用事先给定的字母映射表进行加密。
- 数据加密方式(3类)