A. sim900a可以和STC89C51单片机的txd和rxd直接相连吗
SIM900A模块是可以直接与单片机的TXD和RXD连接。
需要设置一下波特率,然后就可以直接通信了。
B. 51单片机怎样和SIM900a模块连接起来
一、单模块故障排除
分别测试“USB转TTL”“SIM900a”“51单片机”的UART通讯能否正常使用,主要测试51单片机芯片RX-TX引脚短接后能否自首自发。
二、模块协作故障排除
PC-USB-TTL-SIM900a
PC-USB-TTL-51单片机
51单片机-SIM900a
三、问题原因猜测
1、TX-RX连接线序错误
2、TTL-RS232电平错误
3、单片机串口多硬件接入相互冲突,比如TX-RX引出的同时连接了USB转UART芯片
4、单片机代码问题
C. 用51单片机读取sim900里的短信程序怎么写
买模块商家送资料, 串口配置程序略,主程序如下:
/**********************************************************************************
* 工程名 :短信控制LED
* 描述 :通过短信控制开发板的LED
* 实验平台:C51
* 库版本 :
* 作者 :泥人通信模块开发平台团队
* 博客 :http://nirenelec.blog.163.com
* 淘宝 :http://shop105683814.taobao.com
* 硬件连接说明
使用单片串口与GPRS模块通信
C51 GPRS模块
P30 (RXD)->RXD
P31 (TXD)->TXD
GND ->GND
* 软件功能说明
板子上电后运行指示灯RUNING_LED会以一秒的频率闪烁
手机发送“onled”点亮LED;
手机发送“offled”熄灭LED;
**********************************************************************************/
#include "config.h"
#include "string.h"
#include "delay.h"
#include "uart.h"
#define Automatic_Startup 1 //定义自启动 V1.2版本起有自启动功能
#define Buf1_Max 200 //串口1缓存长度
/************* 本地常量声明 **************/
sbit RUNING_LED = P1^2; //运行指示灯
sbit LED = P1^3; //控制指示灯
/************* 本地变量声明 **************/
xdata u8 Uart1_Buf[Buf1_Max];
u8 Times=0,First_Int = 0,shijian=0;
bdata u8 Flag;//定时器标志位
sbit Timer0_start =Flag^0; //定时器0延时启动计数器
/************* 本地函数声明 **************/
void GPIO_config(void); //引脚初始化
void Timer0Init(void); //定时器0初始化
void CLR_Buf1(void); //清串口接收缓存
u8 Find(u8 *a); //查找字符串
void Second_AT_Command(u8 *b,u8 *a,u8 wait_time);//发送指令
void Wait_CREG(void); //查询等待模块注册成功
void Set_Text_Mode(void); //设置短信为TEXT模式
void Check_New_Message(void); //查询新短信
/************* 外部函数和变量声明*****************/
/*******************************************************************************
* 函数名 : main
* 描述 : 主函数
* 输入 :
* 输出 :
* 返回 :
* 注意 : 串口波特率是9600,GPRS模块默认波特率是115200,需要自己通过串口助手修改
为9600方可使用。
程序会删除手机卡上的短信,请注意
*******************************************************************************/
void main(void)
{
Timer0Init(); //初始化定时器0
GPIO_config();
EA=1; //开总中断
Uart1Init(); //初始化串口9600
Wait_CREG(); //查询等待模块注册成功
Set_Text_Mode();//设置短信为TEXT模式
//Second_AT_Command("AT+CMGD=1,4","OK",3);//删除卡上所有短信
while(1)
{
Check_New_Message();
}
}
/*******************************************************************************
* 函数名 : Uart1
* 描述 : 串口1中断服务入口函数
* 输入 :
* 输出 :
* 返回 :
* 注意 :
*******************************************************************************/
void Uart1() interrupt 4
{
if (RI)
{
RI = 0; //清除RI位
Uart1_Buf[First_Int] = SBUF; //将接收到的字符串存到缓存中
First_Int++; //缓存指针向后移动
if(First_Int > Buf1_Max) //如果缓存满,将缓存指针指向缓存的首地址
{
First_Int = 0;
}
}
if (TI)
{
TI = 0; //清除TI位
}
}
/*******************************************************************************
* 函数名 : Timer0_ISR
* 描述 : 定时器0中断服务入口函数,20ms中断一次
* 输入 :
* 输出 :
* 返回 :
* 注意 :
*******************************************************************************/
void Timer0_ISR() interrupt 1
{
static u8 Time_count=0;
TR0=0;//关定时器
TL0 = 0x00; //重设定时器初值
TH0 = 0xB8; //重设定时器初值
Time_count++;
if(Time_count>=50)
{
Time_count = 0;
RUNING_LED =~RUNING_LED;
}
if(count_20ms) //20ms延时计数器
count_20ms--;
if(Timer0_start)
Times++;
if(Times > (50*shijian))
{
Timer0_start = 0;
Times = 0;
}
TR0=1;//开定时器
}
/*******************************************************************************
* 函数名 : GPIO_config
* 描述 : IO口配置函数
* 输入 :
* 输出 :
* 返回 :
* 注意 :
*******************************************************************************/
void GPIO_config(void)
{
LED=1;
RUNING_LED=1;
}
/*******************************************************************************
* 函数名 : Timer0Init
* 描述 : 定时器0初始化,20ms定时
* 输入 :
* 输出 :
* 返回 :
* 注意 :
*******************************************************************************/
void Timer0Init(void) //20毫秒@11.0592MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //
TMOD |= 0x01; //设置定时器模式,16位定时器
TL0 = 0x00; //设置定时器初值
TH0 = 0xB8; //设置定时器初值
TF0 = 0; //清TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
}
/*******************************************************************************
* 函数名 : CLR_Buf1
* 描述 : 清除串口2缓存数据
* 输入 :
* 输出 :
* 返回 :
* 注意 :
*******************************************************************************/
void CLR_Buf1(void)
{
u16 k;
for(k=0;k<Buf1_Max;k++) //将缓存内容清零
{
Uart1_Buf[k] = 0x00;
}
First_Int = 0; //接收字符串的起始存储位置
}
/*******************************************************************************
* 函数名 : Find
* 描述 : 判断缓存中是否含有指定的字符串
* 输入 :
* 输出 :
* 返回 : unsigned char:1 找到指定字符,0 未找到指定字符
* 注意 :
*******************************************************************************/
u8 Find(u8 *a)
{
if(strstr(Uart1_Buf,a)!=NULL)
return 1;
else
return 0;
}
/*******************************************************************************
* 函数名 : Second_AT_Command
* 描述 : 发送AT指令函数
* 输入 : 发送数据的指针、希望收到的应答、发送等待时间(单位:S)
* 输出 :
* 返回 :
* 注意 :
*******************************************************************************/
void Second_AT_Command(u8 *b,u8 *a,u8 wait_time)
{
u8 i;
u8 *c;
c = b; //保存字符串地址到c
CLR_Buf1();
i = 0;
while(i == 0)
{
if(!Find(a)) //查找需要应答的字符
{
if(Timer0_start == 0)
{
b = c; //将字符串地址给b
for (b; *b!='\0';b++)
{
UART1_SendData(*b);
}
UART1_SendLR();
Times = 0;
shijian = wait_time;
Timer0_start = 1;
}
}
else
{
i = 1;
Timer0_start = 0;
}
}
CLR_Buf1();
}
/*******************************************************************************
* 函数名 : Set_Text_Mode
* 描述 : 设置短信为TEXT文本模式
* 输入 :
* 输出 :
* 返回 :
* 注意 :
*******************************************************************************/
void Set_Text_Mode(void)
{
Second_AT_Command("ATE0","OK",3); //取消回显
Second_AT_Command("AT+CNMI=3,2,0,0,0","OK",3); //新短信直接输出
Second_AT_Command("AT+CMGF=1","OK",3); //TEXT模式
Second_AT_Command("AT+CPMS=\"SM\",\"SM\",\"SM\"","OK",3);//所有操作都在SIM卡中进行
}
/*******************************************************************************
* 函数名 : Check_Message_rec
* 描述 : 检查是否有新信息,并执行信息内容指令
* 输入 :
* 输出 :
* 返回 :
* 注意 :
*******************************************************************************/
void Check_New_Message(void)
{
u8 temp=0;
if(strstr(Uart1_Buf,"+CMT")!=NULL) //若缓存字符串中含有"+CMT"就表示有新的短信
{
delay_ms(3);//等待数据全部接收完成
if(strstr(Uart1_Buf,"onled")!=NULL)
{
LED = 0;
}
if(strstr(Uart1_Buf,"offled")!=NULL)
{
LED = 1;
}
CLR_Buf1();
//Second_AT_Command("AT+CMGD=1,4","OK",3);//删除短信
}
}
/*******************************************************************************
* 函数名 : Wait_CREG
* 描述 : 等待模块注册成功
* 输入 :
* 输出 :
* 返回 :
* 注意 :
*******************************************************************************/
void Wait_CREG(void)
{
u8 i;
u8 k;
i = 0;
CLR_Buf1();
while(i == 0)
{
CLR_Buf1();
UART1_SendString("AT+CREG?");//查询模块网络注册状态
UART1_SendLR();
delay_ms(250);
for(k=0;k<Buf1_Max;k++)
{
if(Uart1_Buf[k] == ':')
{
if((Uart1_Buf[k+4] == '1')||(Uart1_Buf[k+4] == '5')) //表明网络注册成功
{
i = 1;
break;
}
}
}
}
}
D. 姹备竴涓89C51鍗旷墖链 鎺у埗SIM900(鐩镐技镄勪篃鍙浠)锛屾敹鍙戠煭淇$殑绋嫔簭锛
浠g爜濡备笅 娴佺▼鏄涓镊寸殑 鍙鏄绔鍙e畾涔変笉钖
#include "sim900a.h"
#include "usart.h"
#include "delay.h"
#include "led.h"
#include "key.h"
#include "lcd.h"
#include "dma.h"
#include "flash.h"
#include "touch.h"
#include "malloc.h"
#include "string.h"
#include "text.h"
#include "usart2.h"
#include "ff.h"
//灏嗘敹鍒扮殑AT鎸囦护搴旂瓟鏁版嵁杩斿洖缁欑数鑴戜覆鍙
//mode:0,涓嶆竻闆禅SART2_RX_STA;
// 1,娓呴浂USART2_RX_STA;
void sim_at_response(u8 mode)
{
if(USART2_RX_STA&0X8000) //鎺ユ敹鍒颁竴娆℃暟鎹浜
{
USART2_RX_BUF[USART2_RX_STA&0X7FFF]=0;//娣诲姞缁撴潫绗
printf("%s",USART2_RX_BUF); //鍙戦佸埌涓插彛
if(mode)USART2_RX_STA=0;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
//ATK-SIM900A 钖勯”娴嬭瘯(𨰾ㄥ彿娴嬭瘯銆佺煭淇℃祴璇曘丢PRS娴嬭瘯)鍏辩敤浠g爜
//sim900a鍙戦佸懡浠ゅ悗,妫娴嬫帴鏀跺埌镄勫簲绛
//str:链熷緟镄勫簲绛旂粨鏋
//杩斿洖鍊:0,娌℃湁寰楀埌链熷緟镄勫簲绛旂粨鏋
// 鍏朵粬,链熷緟搴旂瓟缁撴灉镄勪綅缃(str镄勪綅缃)
u8* sim900a_check_cmd(u8 *str)
{
char *strx=0;
if(USART2_RX_STA&0X8000) //鎺ユ敹鍒颁竴娆℃暟鎹浜
{
USART2_RX_BUF[USART2_RX_STA&0X7FFF]=0;//娣诲姞缁撴潫绗
strx=strstr((const char*)USART2_RX_BUF,(const char*)str);
}
return (u8*)strx;
}
//钖憇im900a鍙戦佸懡浠
//cmd:鍙戦佺殑锻戒护瀛楃︿覆(涓嶉渶瑕佹坊锷犲洖杞︿简),褰揷md<0XFF镄勬椂鍊,鍙戦佹暟瀛(姣斿傚彂阃0X1A),澶т簬镄勬椂鍊椤彂阃佸瓧绗︿覆.
//ack:链熷緟镄勫簲绛旂粨鏋,濡傛灉涓虹┖,鍒栾〃绀轰笉闇瑕佺瓑寰呭簲绛
//waittime:绛夊緟镞堕棿(鍗曚綅:10ms)
//杩斿洖鍊:0,鍙戦佹垚锷(寰楀埌浜嗘湡寰呯殑搴旂瓟缁撴灉)
// 1,鍙戦佸け璐
u8 sim900a_send_cmd(u8 *cmd,u8 *ack,u16 waittime)
{
u8 res=0;
USART2_RX_STA=0;
if((u32)cmd<=0XFF)
{
while(DMA1_Channel7->CNDTR!=0); //绛夊緟阃氶亾7浼犺緭瀹屾垚
USART2->DR=(u32)cmd;
}else u2_printf("%s\r\n",cmd);//鍙戦佸懡浠
if(ack&&waittime) //闇瑕佺瓑寰呭簲绛
{
while(--waittime) //绛夊緟鍊掕℃椂
{
delay_ms(10);
if(USART2_RX_STA&0X8000)//鎺ユ敹鍒版湡寰呯殑搴旂瓟缁撴灉
{
if(sim900a_check_cmd(ack))break;//寰楀埌链夋晥鏁版嵁
USART2_RX_STA=0;
}
}
if(waittime==0)res=1;
}
return res;
}
//灏1涓瀛楃﹁浆鎹涓16杩涘埗鏁板瓧
//chr:瀛楃,0~9/A~F/a~F
//杩斿洖鍊:chr瀵瑰簲镄16杩涘埗鏁板
u8 sim900a_chr2hex(u8 chr)
{
if(chr>='0'&&chr<='9')return chr-'0';
if(chr>='A'&&chr<='F')return (chr-'A'+10);
if(chr>='a'&&chr<='f')return (chr-'a'+10);
return 0;
}
//灏1涓16杩涘埗鏁板瓧杞鎹涓哄瓧绗
//hex:16杩涘埗鏁板瓧,0~15;
//杩斿洖鍊:瀛楃
u8 sim900a_hex2chr(u8 hex)
{
if(hex<=9)return hex+'0';
if(hex>=10&&hex<=15)return (hex-10+'A');
return '0';
}
//unicode gbk 杞鎹㈠嚱鏁
//src:杈揿叆瀛楃︿覆
//dst:杈揿嚭(uni2gbk镞朵负gbk鍐呯爜,gbk2uni镞,涓簎nicode瀛楃︿覆)
//mode:0,unicode鍒癵bk杞鎹;
// 1,gbk鍒皍nicode杞鎹;
void sim900a_unigbk_exchange(u8 *src,u8 *dst,u8 mode)
{
u16 temp;
u8 buf[2];
if(mode)//gbk 2 unicode
{
while(*src!=0)
{
if(*src<0X81) //闱炴眽瀛
{
temp=(u16)ff_convert((WCHAR)*src,1);
src++;
}else //姹夊瓧,鍗2涓瀛楄妭
{
buf[1]=*src++;
buf[0]=*src++;
temp=(u16)ff_convert((WCHAR)*(u16*)buf,1);
}
*dst++=sim900a_hex2chr((temp>>12)&0X0F);
*dst++=sim900a_hex2chr((temp>>8)&0X0F);
*dst++=sim900a_hex2chr((temp>>4)&0X0F);
*dst++=sim900a_hex2chr(temp&0X0F);
}
}else //unicode 2 gbk
{
while(*src!=0)
{
buf[1]=sim900a_chr2hex(*src++)*16;
buf[1]+=sim900a_chr2hex(*src++);
buf[0]=sim900a_chr2hex(*src++)*16;
buf[0]+=sim900a_chr2hex(*src++);
temp=(u16)ff_convert((WCHAR)*(u16*)buf,0);
if(temp<0X80){*dst=temp;dst++;}
else {*(u16*)dst=swap16(temp);dst+=2;}
}
}
*dst=0;//娣诲姞缁撴潫绗
}
//阌鐩樼爜琛
const u8* kbd_tbl1[13]={"1","2","3","4","5","6","7","8","9","*","0","#","DEL"};
const u8* kbd_tbl2[13]={"1","2","3","4","5","6","7","8","9",".","0","#","DEL"};
u8** kbd_tbl;
u8* kbd_fn_tbl[2];
//锷犺浇阌鐩樼晫闱锛埚昂瀵镐负240*140锛
//x,y:鐣岄溃璧峰嫔潗镙囷纸320*240鍒呜鲸鐜囩殑镞跺欙纴x蹇呴’涓0锛
void sim900a_load_keyboard(u16 x,u16 y,u8 **kbtbl)
{
u16 i;
POINT_COLOR=RED;
kbd_tbl=kbtbl;
LCD_Fill(x,y,x+240,y+140,WHITE);
LCD_DrawRectangle(x,y,x+240,y+140);
LCD_DrawRectangle(x+80,y,x+160,y+140);
LCD_DrawRectangle(x,y+28,x+240,y+56);
LCD_DrawRectangle(x,y+84,x+240,y+112);
POINT_COLOR=BLUE;
for(i=0;i<15;i++)
{
if(i<13)Show_Str_Mid(x+(i%3)*80,y+6+28*(i/3),(u8*)kbd_tbl[i],16,80);
else Show_Str_Mid(x+(i%3)*80,y+6+28*(i/3),kbd_fn_tbl[i-13],16,80);
}
}
E. 求51单片机与sim900a相连接的最简单的程序。
/************************************************************
程序说明:
本程序运行后如果gprs模块找到服务商信号,就拨打指定电话。
1.将自己的51单片机的串口1连接到GSM的tx rx gnd
2.找到程序中前面的#define处,根据说明修改好自己的单片机配置,编译程序
2.下载程序
3.按下模块复位键,启动模块,等待信号灯闪烁变慢,复位单片机
4.等待发送成功
*************************************************************/
#include <REGX52.H>
#define uchar unsigned char
#define uint unsigned int
//以下是板子上LED的配置,把Px_x改成自己对应的脚。
#define LED1_ON P1_0 = 0
#define LED1_OFF P1_0 = 1
#define LED2_ON P1_1 = 0
#define LED2_OFF P1_1 = 1
#define LED3_ON P1_2 = 0
#define LED3_OFF P1_2 = 1
#define LED4_ON P1_3 = 0
#define LED4_OFF P1_3 = 1
//以下是你的51单片机的晶振大小
#define FOSC_110592M
//#define FOSC_12M
//以下是开机后发送到手机的内容,发送的号码在程序中修改。
uchar sms_text[] = "123";
//注意,无论接收到信号还是发送完信号,都会进中断服务程序的
/*初始化程序(必须使用,否则无法收发),次程序将会使用定时器1*/
void SerialInti()//初始化程序(必须使用,否则无法收发)
{
TMOD=0x20;//定时器1操作模式2:8位自动重载定时器
#ifdef FOSC_12M //在这里根据晶振大小设置不同的数值初始化串口
TH1=0xf3;//装入初值,波特率2400
TL1=0xf3;
#else
TH1=0xfd;//装入初值,波特率9600
TL1=0xfd;
#endif //end of SOC_12M
TR1=1;//打开定时器
SM0=0;//设置串行通讯工作模式,(10为一部发送,波特率可变,由定时器1的溢出率控制)
SM1=1;//(同上)在此模式下,定时器溢出一次就发送一个位的数据
REN=1;//串行接收允许位(要先设置sm0sm1再开串行允许)
EA=1;//开总中断
ES=1;//开串行口中断
}
/*串行通讯中断,收发完成将进入该中断*/
void Serial_interrupt() interrupt 4
{
// a=SBUF;
P2=SBUF;
RI=0;//接收中断信号清零,表示将继续接收
// flag=1;//进入中断的标志符号
}
void Uart1Send(uchar c)
{
SBUF=c;
while(!TI);//等待发送完成信号(TI=1)出现
TI=0;
}
//串行口连续发送char型数组,遇到终止号/0将停止
void Uart1Sends(uchar *str)
{
while(*str!='\0')
{
SBUF=*str;
while(!TI);//等待发送完成信号(TI=1)出现
TI=0;
str++;
}
}
//延时函数大概是1s钟,不过延时大的话不准...
void DelaySec(int sec)
{
uint i , j= 0;
for(i=0; i<sec; i++)
{
for(j=0; j<65535; j++)
{
}
}
}
void main()
{
uchar i = 0;
LED1_OFF;
LED2_OFF;
LED3_OFF;
LED4_OFF;
SerialInti();
while(1)
{
LED1_ON;
LED2_OFF;
Uart1Sends("AT+CMGF=1\r");
DelaySec(3);//延时3秒
Uart1Sends("AT+CSCS=\"GSM\"\r");
DelaySec(3);//延时3秒
Uart1Sends("AT+CSMP=17,167,0,250\r");//设备短信模式(手机自动保存模式)
// Uart1Sends("AT+CSMP=17,167,0,240\r");//设备短信模式(手机非自动保存模式)
DelaySec(3);//延时3秒
Uart1Sends("AT+CMGS=\"18332563682\"\r");
DelaySec(5);//延时3秒
Uart1Sends(sms_text);
Uart1Send(0x1a);
LED2_ON;
LED1_OFF;
DelaySec(15);//延时20秒
}
}
//你接p3.0和p3.1吧
F. 怎么用51单片机读取sim900a接收的短信
需要串口中断接收才行,哪里不懂你可以在问。。。
void Uart2InterruptReceive(void) interrupt 8
{
unsigned char tmp2;
//char i;
//num2=0;
IE2 &= (~ES2);//关闭串口2中断//ES2 = 0;
if(S2CON & S2RI) //if(S2RI == 1)
{
S2CON &= (~S2RI);//S2RI = 0;
tmp2 = S2BUF;
//Uart1Send(tmp2);
rev_buf2[num2++]=tmp2;
if(num2>=80)
{
num2=0;
//Uart1Sends("GSM B "); 以上全试过可以发送7/23,20:03
}
}
else
{
S2CON &= (~S2TI);//S2TI = 0;
}
IE2 |= ES2;//ES2 = 1
}
G. 51单片机控制sim900a收发短信,到了删短信那里卡住了(灯不亮),求大神指出哪里错了
可以查看是不是while(!Hand("OK"));这句语句没有通过,你可以把LED4=0; 放while(!Hand("OK"));前面,看看灯会不会亮,如果两,则说明while(!Hand("OK"));没有满足跳转条件,你得进一步查找
sim900a的手册。