liu9174 发表于 2009-3-31 01:33:50

基于AVR的短信收发(WinAVR)

学习了一个月C语言和AVR,做了一个短信工程的示例,很菜,但能用.
那一个月的日子用一句话形容----"苦过种田",这个工程让我免于露宿街头,
很感谢这里的朋友,很无私,这里的例子给我很大的帮助......现在我把这个东西发上来,希望有心的朋友给我指点,因为不知道.H文件的用法所以只有.C文件,
因为还没有学会AtmanAvr软件就过期了,所以用了GCC,
====================================cc1.c
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#define uchar unsigned char
#define uint unsigned int
#define SIZEX 100//缓冲区大小
====================================/

====================================liu.c
int getat(char *czn,char *ato,int tim)//设置,初始化
{   
   switch(tim)
             {
                     case 500:
                         *czn=1;
                         outtx("AT\r",3);
                       break;
                       case 2000:
                         *czn=2;
                         outtx("AT+CSMS=1\r",10);
                       break;
                       case 3000:
                             *czn=3;
                               outtx("AT+CNMI=2,2,0,0,1\r",18);       
                       break;
                       case 3800:
                               *czn=4;
                               outtx("AT+CMGF=1\r",10);
                       break;
               }
}

int outss(char *czn,int *tim,int *ynduanx,char *arrout,char *enters,int *lenss) //短信发送函数
//(当前操作标计,计时,目标电话号码尾位置,内容,数据)
{   
   if((*czn==5)&&(*tim==100))
       {
             outtx("AT+CNMA\r",8);
               *czn=6;
       }
   if ((*czn==6)&&(*tim==300))
       {
             char str;
               char str1[]={"AT+CMGS=\""};
               int lenw=0;
             int i=0;
               //if
               //{
               ///////////取号码//取内容(位置)////////////
                     for(i=0;i<40;i++)
                     {
                         if(i<9)
                             {
                             str=str1;
                             }
                               else
                               {
                                     str=*(arrout+i-2);
                           if((*(arrout+i-3)==0x22)&&(*(arrout+i-2)==0x2c))
                     {   
                                   lenw=i+1;
                                   break;
                                 }
                               }
                     }
                       str=0x0d;
                     outtx(str,lenw);
                       
                       *czn=7;
                     PORTB=0X00;
             //}
       }
        if ((*czn==7)&&(*tim==700))
       {
             //if
             //{
                     //for(i=0;i<(*ynduanx+1);i++)
                       //{
                       //    str[]=(arrout+(*lenss-*ynduanx-1+i)
                       //}
                       *(arrout+(*lenss-*ynduanx+1)+(*ynduanx-1))=0x1a;
                       outtx((arrout+(*lenss-*ynduanx+1)),(*ynduanx));
                       //outtx("abcdef",6);
                     *czn=0;
                       *tim=0;
                       *enters=0;
                       //初始化收缓冲
                     enters=0;
             *ynduanx=0;
                       *lenss=0;
                     PORTB=0Xff;
             //}
       }
       

}

       //char str1[]={"AT+CMGS=\"+8613060932737\"\r"};

       //char str1[]={"123456liu\0"};

int dodata(uchar *arrout,int lenss,char *czn,int *tim,int *ynduanx,char *enters)    //处理短信
{
   
       int i=0;
       int telw=0;
       if((*ynduanx>0)&&(*enters==6))
       {
             
                       *czn=5;   //发短信
                       *tim=0;
                       //outtx("AT+CNMA\r",8);
               //////////////////////////////////////////
               //*ynduanx=0;   //处理完短信
               //*enters=0;
               //*czn=0;
               
       }
       
}
int atstar(uchar *arrout,int lenss,char *czn,char *aok,int *tim)    //处理数据,初始化
{
       //uchar strr;   
   int yns=0;
       switch(*czn)
       {
             case 0:
                     
                     break;
               case 1:
                       yns=ynstr("OK",arrout,lenss);
                     break;
               case 2:
                       yns=ynstr("OK",arrout,lenss);
                     break;
               case 3:
                       yns=ynstr("OK",arrout,lenss);
                     break;
               case 4:
                       yns=ynstr("OK",arrout,lenss);
                     break;
       }
       if(yns==1)
       {
             
             *(aok+*czn)=1; //设置成功
               PORTB=0Xf0;
               //outtx(aok,5);
               if((*czn==4)&&(*(aok+1)==1))
               {
                     
                     *aok=1;
                       //*czn=5;   //发短信(测试)
                       //*tim=0;
               }
               else
               {
                     *czn=0;
               }
       }
       
       
       
}

int ynstr(char *str1,char *str2,int lenss) //字符串比较
{
       char yns=1;
       int i=0;
   for(i=0;i<lenss;i++)
       {
             if(*(str1+i)!=*(str2+i))
               {
               yns=0;
               break;
               }
       }
       return yns;
}
=====================================================================================/

====================================================================main.c
#include "cc1.c"
#include "liu.c"
uchar TxdPos=0; //发送定位
uchar TxdLen=0; //本次发送字节数

uchar RxdPos=0; //接收定位
uchar RxdLen=0; //本次接收字节数

uchar SendBuf; //发送数据绶冲区
uchar RecvBuf; //接收数据缓冲区

int oldlen=0;

char enters;   //接收帧识别(0D~1,0D 0A~2,..........)

char czno=0;//当前操作
int ynduanx=0;//操作状态
char atok={0,0,0,0,0};   //短信猫状态

int times=0;   //时间

//timer0中断

SIGNAL(SIG_OVERFLOW0)
{

        TCNT0=0x9e;
        if (times>=5000)
       {
             times=0;
               
       }
   else
       {
         times++;
       }
          /////////////////
       if(atok==0)//如果没初始化
       {
               getat(&czno,atok,times);
               PORTB=0X0f;
       }
       else
       {
         outss(&czno,×,&ynduanx,RecvBuf,&enters,&oldlen);
               //outss(char *czn,int *tim,int *ynduanx,char *arrout,int lenss);
               if(times>1000)times=0;
   }

}
SIGNAL(SIG_USART_RECV)
{   
   uchar c=UDR;
   switch(c)
       {
             case 13:
               
                     if((enters%2)==0)
                       {
                             
                               enters++;
                               if(czno>5)enters=0;
                       }
                       else
                       {   
                             if(ynduanx<=1)
                               {
                             enters=1;
                               }
                               else
                               {
                               
                               }
                       }
                     break;
               case 10:
                     if((enters%2)==1)
                       {
                             enters++;
                               if(enters==2)//初始化缓冲,准备接收数据
                               {
                         RxdLen=0;
                         RxdPos=0;
                               }
                               if((enters==4)&&(ynduanx<1)&&(atok!=0))
                               {
                            enters=0;
                                        RxdLen=0;
                                        RxdPos=0;
                               }
                       }
                     break;
               default:
                 if(enters==2) //接收数据
                     {
                     
               if(RxdLen<SIZEX)//如果缓冲没满
               {
                  RecvBuf=c;//数据写入缓冲,位置后移一字节
                  RxdLen++;          //长度加1
                                        if(RxdLen==5)//检测是否为短信
                                        {
                                          ynduanx=ynstr("+CMT",RecvBuf,4);
                                        }
               }
                         else   
                         {
                                  //初始化收缓冲
                            enters=0;
                                        RxdLen=0;
                                        RxdPos=0;
                         }
                     }
                     else
                     {
                             if(ynduanx==0)//如果没有短信,初始化收缓冲
                             {
                         enters=0;
                             RxdLen=0;
                             RxdPos=0;
                             }
                     }
                       if((enters==4)&&(ynduanx>0))//收短信的内容
                       {
                             if(RxdLen<SIZEX)//如果缓冲没满
                              {
               RecvBuf=c;//数据写入缓冲,位置后移一字节
               RxdLen++;          //长度加1
                              ynduanx++;          //短信长度加1
                              }
                       }
       }
}

//发送中断
SIGNAL (SIG_UART_TRANS)
{
    if(TxdPos<TxdLen)   //如果有待发数据
        {
         UDR=SendBuf;//发一个数据,位置后移一字节
        }
        else
        {
             //UCSRB&=~_BV(UDRIE);//关闭发送数据空中断
               TxdLen=0;
               TxdPos=0;
        }
}

int readrxd(void)
{
   cli();
   int i;
       char a=4;
       if(atok!=0)
       {
       a=6;
       }
   if((enters==a)&&(RxdLen>0))//如果收到完整数据帧
       {
             
               //读数据
             //uchar uarr;
             //for(i=0;i<RxdLen;i++)
             //{
         //    uarr=RecvBuf;   //将接收到的数据复制出来
             //}         
                 if(atok==0)
                       {
               atstar(RecvBuf,RxdLen,&czno,atok,times);//处理数据
                       }
                       else
                       {   
                             oldlen=RxdLen;
                             dodata(RecvBuf,RxdLen,&czno,times,&ynduanx,&enters);//处理数据
                       }
                       //初始化收缓冲
                     enters=0;
                     RxdLen=0;
                     RxdPos=0;
               
       }
       
       sei();
}
int outtx(uchar *arrout,int lenss)   //发数据
{   
       cli();
       if(TxdLen==TxdPos)
       {
             int i;
             uchar *sends=SendBuf;//数组名就是其指针的值
               for(i=0;i<lenss;i++)
               {
             *(sends+i)=*(arrout+i);   //将接要发的数据复制到发送缓冲区
                       TxdLen++;
               }
               UDR=*sends;   //发第一个字,触发发送中断
               TxdPos=1;
       }
       sei();       
       return (TxdLen==TxdPos);
}


//////////////////////////////////////////////////////////////
int main( void )
{
   //uchar i;
   //uart 初始化
   //接收使能、发送使能、接收中断允许、发送中断允许
   UCSRB=(1<<RXCIE)|(1<<TXCIE)|(1<<RXEN)|(1<<TXEN);
   UBRRL=23; // baud=9600 UBRR=CK/(baud*16) -1
   /////
   TCNT0=0x9e;
   TCCR0=4;
   TIMSK=(1<<TOIE0);
       /////
       PORTB=0X00;
       DDRB=0XFF;
       TCNT0=0X9E;
       TCCR0=4;
       TIMSK=(1<<TOIE0);
   sei();//总中断允许
   while(1)
   {
         readrxd();
               
   }
}
====================================================================/

不用电路图的,用的是成品串口TC35短信猫,其实就是串口通信,7.3728MHz晶振的最小系统,MAX232电平转换</font>
http://cache.amobbs.com/bbs_upload782111/files_14/ourdev_439550.jpg
(原文件名:0838105.jpg)

liu9174 发表于 2009-3-31 01:52:09

"&times" 发上去后变成了"x" ,不知为什么

liu9174 发表于 2009-3-31 01:53:33

"×"是& t i m e s去空格

mfkqqw 发表于 2009-3-31 08:48:56

如果有原理图更直观。

bbandpp 发表于 2009-3-31 08:52:37

无图不强大~

zc3909 发表于 2009-3-31 09:02:42

楼主没有说明gsm模块型号,不同型号发送短信过程不完全一样

hushuqin 发表于 2009-3-31 09:30:26

看别人的程序真难,我坐过发送短信的,调试成功了,看楼主的程序也不好懂啊

liu9174 发表于 2009-4-25 01:16:35

不好懂才是合理的,因为做这个东西时只有一个月的C语言功底,好在做过ASP网站,网页的JavaScript各这个有点像.

huanxin1456 发表于 2009-4-26 09:59:36

mark

penguin 发表于 2009-4-26 12:42:48

将GSM模块换成CDMA、PHS的只要改AT指令集就成

whuctx 发表于 2009-4-27 09:16:40

MARK

armok 发表于 2009-4-27 09:38:15

Cool !

cdhua1983 发表于 2009-4-27 11:27:51

阿莫,为何论坛不增加一个自己可以修改或删除帖子的功能啊?

jchqxl 发表于 2009-4-27 12:24:17

学习了

hao876474206 发表于 2011-4-14 17:00:49

mark

diziaihaozhe 发表于 2011-4-14 23:30:19

关注中

gloryzkl 发表于 2011-4-15 08:36:05

MARK

raohao101 发表于 2011-4-16 18:56:16

mark

zxs115523805 发表于 2011-4-19 00:00:26

GOOD

zxs115523805 发表于 2011-4-19 00:00:30

GOOD

gloryzkl 发表于 2011-4-26 13:00:05

mark

zxs2000 发表于 2011-4-26 13:56:15

学习

ssssnancy 发表于 2013-12-17 21:16:55

学习一下 {:mad:}

追风少年 发表于 2013-12-17 23:23:42


如果有原理图更直观。

luvemcu 发表于 2013-12-20 18:39:32

what a xx guy!
页: [1]
查看完整版本: 基于AVR的短信收发(WinAVR)