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的手冊。