一下是15系列的代碼;哪位大神可以幫轉話成89C51RC的源代碼:
51 單片機例程 適用于 STC15F 系列
實驗內容 : 發送PDU短信息
UART1 映射到 P36 P37口 KEY1 : 觸發發送目標短信
PS: A6模塊上電注冊是要一定的時間的!
在這里也解釋下 AT+CMGS=39 39是怎么來的? AT+CMGS=xx xx是正文的長度 在PDU模式下,8位真實TP數據單位的長度(即RP層的SMSC地址中的8位字符將不計算在該長度內!)
所以我們轉換過來的PDU碼長度是40,要減掉SMSC地址中的8位字符,所以是40-1=39。
串口1全雙工中斷方式收發通訊程序。本例程使用11.0592MHZ時鐘,如要改變,請修改下面的"定義主時鐘"的值并重新編譯。
串口設置為:115200,8,n,1.
通過PC向MCU發送數據, MCU收到后通過串口把收到的數據原樣返回.
******************************************/
/************* 本地常量聲明 **************/
#define MAIN_Fosc 11059200L //定義主時鐘
#define BaudRate1 115200UL //選擇波特率
#define Timer1_Reload (65536UL -(MAIN_Fosc / 4 / BaudRate1)) //Timer 1 重裝值, 對應300KHZ
#define Timer2_Reload (65536UL -(MAIN_Fosc / 4 / BaudRate1)) //Timer 2 重裝值, 對應300KHZ
#include "STC15Fxxxx.H"
#include "delay.h"
#include "string.h"
#include "Exti.h"
/************* 本地變量聲明 **************/
#define Automatic_Startup 1 //定義自啟動 V1.2版本起有自啟動功能
#define Buf1_Max 60 //串口1緩存長度
#define Buf2_Max 60 //串口2緩存長度
//串口1發送回車換行
#define UART1_SendLR() UART1_SendData(0X0D);\
UART1_SendData(0X0A)
/************* 本地常量聲明 **************/
//sbit RUNING_LED = P1^2; //運行指示燈
sbit LEDA = P1^3; //測試用LED
sbit LEDB = P1^0;
sbit LEDC = P1^5;
sbit KEY1 = P3^3; //發送短信
/************* 本地變量聲明 **************/
xdata u8 Uart1_Buf[Buf1_Max];
u8 Register_Flag=0; //A6 注冊標志位 1 :注冊成功 3:注冊失敗 5:注冊成功,但處于漫游狀態下,無法撥打電話發短信
u8 Times=0,First_Int = 0,shijian=0;
bdata u8 Flag;//定時器標志位
sbit Timer0_start =Flag^0; //定時器0延時啟動計數器
//長度是40 的PDU碼值 內容 :果云科技-GPRS-A6
static unsigned char *message="0011000D91683145821957F90008AA18679C4E9179D16280002D0047005000520053002D00410036";//發送PDU短信
/************* 本地函數聲明 **************/
void USART1_Init(void); //串口1初始化
void Timer0Init(void); //20毫秒@11.0592MHz
void CLR_Buf1(void); //清串口接收緩存
u8 Find(u8 *a); //查找字符串
void Second_AT_Command(u8 *b,u8 *a,u8 wait_time) ;//a6 at命令發送
void Set_PDU_Mode(void);
void Check_New_Message(void);
void UART1_SendData(u8 dat);//串口1發送 1字節
void UART1_SendString(char *s);//串口1發送 字符串
void Wait_CREG(void);
void Send_Message(void);
/**********************************************/
void main(void)
{
USART1_Init();//串口初始化
Timer0Init();//TIM0初始化
Wait_CREG();//等待GSM注冊成功
Set_PDU_Mode();//設置為PDU模式
while (1)
{
if(KEY1==0)
{
Send_Message();
while(!KEY1);
}
}
}
/********************* UART1中斷函數************************/
void UART1_int (void) interrupt UART1_VECTOR
{
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位
}
}
void USART1_Init(void)
{
S1_8bit(); //8位數據
//S1_USE_P30P31(); //UART1 使用P30 P31口 默認
S1_USE_P36P37(); //UART1 使用P36 P37口
//S1_USE_P16P17(); //UART1 使用P16 P17口
AUXR &= ~(1<<4); //Timer stop 波特率使用Timer2產生
AUXR |= 0x01; //S1 BRT Use Timer2;
AUXR |= (1<<2); //Timer2 set as 1T mode
TH2 = (u8)(Timer2_Reload >> 8);
TL2 = (u8)Timer2_Reload;
AUXR |= (1<<4); //Timer run enable
REN = 1; //允許接收
ES = 1; //允許中斷
EA = 1; //允許全局中斷
}
/*******************************************************************************
* 函數名 : Timer0Init
* 描述 : 定時器0初始化,20ms定時
* 輸入 :
* 輸出 :
* 返回 :
* 注意 :
*******************************************************************************/
void Timer0Init(void) //20毫秒@11.0592MHz
{
AUXR &= 0x7F; //定時器時鐘12T模式
TMOD &= 0xF0; //
TMOD |= 0x01; //設置定時器模式,16位定時器
TL0 = 0x70; //設置定時器初值
TH0 = 0xFC; //設置定時器初值
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_PDU_Mode
* 描述 : 設置短信為PDU模式
* 輸入 :
* 輸出 :
* 返回 :
* 注意 :
*******************************************************************************/
void Set_PDU_Mode(void)
{
u8 buf[30]="AT+CSCS=";
Second_AT_Command("ATE0","OK",3); //取消回顯
Second_AT_Command("AT+CMGF=0","OK",3); //配置短信為PDU模式
Second_AT_Command("AT+CPMS=\"SM\",\"SM\",\"SM\"","OK",3);//所有操作都在SIM卡中進行
}
/*******************************************************************************
* 函數名 : Send_Message
* 描述 : 發送PDU信息
* 輸入 :
* 輸出 :
* 返回 :
* 注意 :
*******************************************************************************/
void Send_Message(void)
{
Second_AT_Command("AT+CMGS=39",">",3);//發送指令后直到出現 ">" 后發送內容
UART1_SendString(message);//發送內容
UART1_SendData(0x1A);//結束符
}
/*******************************************************************************
* 函數名 : Check_Message_rec
* 描述 : 檢查是否有新信息,并執行信息內容指令
* 輸入 :
* 輸出 :
* 返回 :
* 注意 :
******************************************************************************/
void Check_New_Message(void)
{
u8 temp=0;
if(strstr(Uart1_Buf,"+CMT")!=NULL) //若緩存字符串中含有"+CMT"就表示有新的短信
{
delay_ms(5);//等待數據全部接收完成
if(strstr(Uart1_Buf,"R00")!=NULL)
{
}
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(100);
for(k=0;k<Buf1_Max;k++)
{
if((Uart1_Buf[k] == 'C')&&(Uart1_Buf[k+1] == 'R')&&(Uart1_Buf[k+2] == 'E')&&(Uart1_Buf[k+3] == 'G')&&(Uart1_Buf[k+4] == ':'))
{
if((Uart1_Buf[k+8] == '1')&&(Uart1_Buf[k+9] != '3'))
{
i = 1;
Register_Flag=1;
LEDB =0;
break;
}
if((Uart1_Buf[k+8] == '1')&&(Uart1_Buf[k+9] == '3'))
{
i = 1;
Register_Flag=3;
LEDA =0;
break;
}
if(Uart1_Buf[k+8] == '5')
{
i = 1;
Register_Flag=5;
LEDC =0;
break;
}
}
}
}
}
/*----------------------------
UART1 發送串口數據
-----------------------------*/
void UART1_SendData(u8 dat)
{
ES=0; //關串口中斷
SBUF=dat;
while(TI!=1); //等待發送成功
TI=0; //清除發送中斷標志
ES=1; //開串口中斷
}
/*----------------------------
UART1 發送字符串
-----------------------------*/
void UART1_SendString(char *s)
{
while(*s)//檢測字符串結束符
{
UART1_SendData(*s++);//發送當前字符
}
}
/*******************************************************************************
* 函數名 : Timer0_ISR
* 描述 : 定時器0中斷服務入口函數,1ms中斷一次
* 輸入 :
* 輸出 :
* 返回 :
* 注意 :
*******************************************************************************/
void Timer0_ISR() interrupt 1
{
static u8 Time_count=0;
TR0=0;//關定時器
TL0 = 0x70; //重設定時器初值
TH0 = 0xFC; //重設定時器初值
Time_count++;
if(Time_count>=50)
{
Time_count = 0;
if(count_20ms) //20ms延時計數器
count_20ms--;
}
if(Timer0_start)
Times++;
if(Times > (50*shijian))
{
Timer0_start = 0;
Times = 0;
}
TR0=1;//開定時器
}
|