学习了一个月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) |
|
|
|