搜索
bottom↓
回复: 26

基于AVR的短信收发(WinAVR)

[复制链接]

出0入0汤圆

发表于 2009-3-31 01:33:50 | 显示全部楼层 |阅读模式
学习了一个月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)

出0入0汤圆

 楼主| 发表于 2009-3-31 01:52:09 | 显示全部楼层
"&times" 发上去后变成了"x" ,不知为什么

出0入0汤圆

 楼主| 发表于 2009-3-31 01:53:33 | 显示全部楼层
"×"是& t i m e s去空格

出0入0汤圆

发表于 2009-3-31 08:48:56 | 显示全部楼层
如果有原理图更直观。

出0入4汤圆

发表于 2009-3-31 08:52:37 | 显示全部楼层
无图不强大~

出0入0汤圆

发表于 2009-3-31 09:02:42 | 显示全部楼层
楼主没有说明gsm模块型号,不同型号发送短信过程不完全一样

出0入0汤圆

发表于 2009-3-31 09:30:26 | 显示全部楼层
看别人的程序真难,我坐过发送短信的,调试成功了,看楼主的程序也不好懂啊

出0入0汤圆

 楼主| 发表于 2009-4-25 01:16:35 | 显示全部楼层
不好懂才是合理的,因为做这个东西时只有一个月的C语言功底,好在做过ASP网站,网页的JavaScript各这个有点像.

出0入0汤圆

发表于 2009-4-26 09:59:36 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-4-26 12:42:48 | 显示全部楼层
将GSM模块换成CDMA、PHS的只要改AT指令集就成

出0入0汤圆

发表于 2009-4-27 09:16:40 | 显示全部楼层
MARK
头像被屏蔽

出0入0汤圆

发表于 2009-4-27 09:38:15 | 显示全部楼层
Cool !

出0入0汤圆

发表于 2009-4-27 11:27:51 | 显示全部楼层
阿莫,为何论坛不增加一个自己可以修改或删除帖子的功能啊?

出0入0汤圆

发表于 2009-4-27 12:24:17 | 显示全部楼层
学习了

出0入0汤圆

发表于 2011-4-14 17:00:49 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-4-14 23:30:19 | 显示全部楼层
关注中

出0入0汤圆

发表于 2011-4-15 08:36:05 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-4-16 18:56:16 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-4-19 00:00:26 | 显示全部楼层
GOOD

出0入0汤圆

发表于 2011-4-19 00:00:30 | 显示全部楼层
GOOD

出0入0汤圆

发表于 2011-4-26 13:00:05 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-4-26 13:56:15 | 显示全部楼层
学习

出0入0汤圆

发表于 2013-12-17 21:16:55 | 显示全部楼层
学习一下

出0入0汤圆

发表于 2013-12-17 23:23:42 | 显示全部楼层

如果有原理图更直观。

出0入0汤圆

发表于 2013-12-20 18:39:32 | 显示全部楼层
what a xx guy!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-29 05:41

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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