查看: 556|回复: 0
打印 上一主题 下一主题

基于AVR的短信收发(WinAVR)

[复制链接]
跳转到指定楼层
沙发
发表于 2016-4-25 21:40:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
学习了一个月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[100];
                 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[lenw-1]=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[SIZEX+2]; //发送数据绶冲区
uchar RecvBuf[SIZEX+2]; //接收数据缓冲区

int oldlen=0;

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

char czno=0;  //当前操作
int ynduanx=0;  //操作状态
char atok[6]={0,0,0,0,0};   //**状态

int times=0;   //时间

//timer0中断

SIGNAL(SIG_OVERFLOW0)
{

        TCNT0=0x9e;
        if (times>=5000)
         {
             times=0;
                 
         }
     else
         {
         times++;
         }
          /////////////////
         if(atok[0]==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]!=0))
                                 {
                            enters=0;
                                        RxdLen=0;
                                        RxdPos=0;
                                 }
                         }
                     break;
                 default:
                 if(enters==2) //接收数据
                     {
                     
                 if(RxdLen<SIZEX)  //如果缓冲没满
                 {
                    RecvBuf[RxdPos++]=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[RxdPos++]=c;  //数据写入缓冲,位置后移一字节
                 RxdLen++;          //长度加1
                                  ynduanx++;          //短信长度加1
                                  }
                         }
         }
}

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

int readrxd(void)
{
     cli();
     int i;
         char a=4;
         if(atok[0]!=0)
         {
         a=6;
         }
     if((enters==a)&&(RxdLen>0))  //如果收到完整数据帧
         {
            
                 //读数据
             //uchar uarr[RxdLen];
             //for(i=0;i<RxdLen;i++)
             //{
         //    uarr=RecvBuf;   //将接收到的数据复制出来
             //}           
                 if(atok[0]==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>

(原文件名:0838105.jpg)







回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入因仑

本版积分规则

快速回复 返回顶部 返回列表