ATMEGA16单片机与MCGS通信MODBUSRTU协议.docx
- 文档编号:11199601
- 上传时间:2023-02-25
- 格式:DOCX
- 页数:18
- 大小:17.69KB
ATMEGA16单片机与MCGS通信MODBUSRTU协议.docx
《ATMEGA16单片机与MCGS通信MODBUSRTU协议.docx》由会员分享,可在线阅读,更多相关《ATMEGA16单片机与MCGS通信MODBUSRTU协议.docx(18页珍藏版)》请在冰豆网上搜索。
ATMEGA16单片机与MCGS通信MODBUSRTU协议
#include
#include
#include
#include"ds18b20.h"
#defineucharunsignedchar
#defineuintunsignedint
volatileucharreve_data,renum=0,mend=0,nend=0,a1=1,a2=1,a3=1,a4=1,a5=1,a6=1,a7=1,a8=1,a9=1;
voidINT_Init();
#defineBAUD38400//波特率38.4kbp/s
volatileucharrx[7]={0x01,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00};
uchartx[30];
volatileucharcrcl=0x00,crch=0x00;
ucharled=0xff;
voidinti_uart(void)//uart初始化
{
UBRRH=(F_CPU/BAUD/16-1)/256;
UBRRL=(F_CPU/BAUD/16-1)%256;
UCSRC=0x86;//8bitdata,1bitstop
UCSRB=(1< } //发送字符 voidsend_char(uchardata) { /*等待发送缓冲器为空*/ while(! (UCSRA&(1< /*将数据放入缓冲器,发送数据*/ UDR=data; } //发送字符串 voidsend_string(uchar*p,ucharmend) { uchark=0; for(k=0;k { send_char(*p++); } } voidinti_port() { DDRB=0xff; PORTB=0xff; DDRC=0xff; PORTC=0x00; } //CRC效验,将结果存储到CRCok变量中。 checkcrc(uchar*q,ucharnend) { uintwcrc=0xffff; intj=0,i=0; for(i=0;i { wcrc^=*q++; for(j=0;j<8;j++) { if(wcrc&1) { wcrc>>=1; wcrc^=0xa001; } else { wcrc>>=1; } } } crcl=wcrc; crch=wcrc>>8; } intmain(void) { inti_uart(); inti_port(); INT_Init(); sei(); while (1) { gettemp(); _delay_ms(1050); } } SIGNAL(SIG_UART_RECV) { rx[renum++]=UDR; if(renum==8) { renum=0; switch(rx[1]) { case0x01: if(! rx[3]) { tx[0]=rx[0];//leD灯 tx[1]=rx[1]; tx[2]=0x01; DDRB=0X00; tx[3]=PORTB; DDRB=0XFF; checkcrc(tx,4); tx[4]=crcl; tx[5]=crch; send_string(tx,6); break; } else { tx[0]=rx[0];//继电器和蜂鸣器 tx[1]=rx[1]; tx[2]=0x01; DDRC=0X00; tx[3]=PORTC; tx[3]>>=7; DDRC=0XFF; checkcrc(tx,4); tx[4]=crcl; tx[5]=crch; send_string(tx,6); break; } case0x04: tx[0]=rx[0]; tx[1]=rx[1]; tx[2]=rx[5]<<1; tx[3]=0x00; tx[4]=teml; tx[5]=0x00; tx[6]=temh; checkcrc(tx,nend=tx[2]+3); tx[tx[2]+3]=crcl; tx[tx[2]+4]=crch; send_string(tx,mend=tx[2]+5); break; case0x05: DDRB=0XFF; switch(rx[3]) { case0x00: if(! rx[4]) PORTB&=~(1< else PORTB|=(1< break; case0x01: if(! rx[4]) PORTB&=~(1< else PORTB|=(1< break; case0x02: if(! rx[4]) PORTB&=~(1< else PORTB|=(1< break; case0x03: if(! rx[4]) PORTB&=~(1< else PORTB|=(1< break; case0x04: if(! rx[4]) PORTB&=~(1< else PORTB|=(1< break; case0x05: if(! rx[4]) PORTB&=~(1< else PORTB|=(1< break; case0x06: if(! rx[4]) PORTB&=~(1< else PORTB|=(1< break; case0x07: if(! rx[4]) PORTB&=~(1< else PORTB|=(1< break; case0x08: if(rx[4]) PORTC|=(1< else PORTC&=~(1< break; } send_string(rx,8); break; default: break; } } } //*****************************红外线接收**********************************************// //外部中断初始化 voidINT_Init(void) { MCUCR|=_BV(ISC01);//选择外部中断0,下降沿触发中断 MCUCR&=~_BV(ISC00);//10: INT0的下降沿产生异步中断请求 GICR|=(1< DDRD&=~_BV(PD2);//设置为输入, PORTD|=_BV(PD2);//使能上拉电阻 } SIGNAL(SIG_INTERRUPT0) { cli(); uchari,j,k=0,addr[4]={0}; renum=0; GICR&=~(1< for(i=0;i<14;i++) { _delay_us(400); if(PIND&(1< { GICR|=(1< return; } } while(! (PIND&(1< for(i=0;i<4;i++)// { for(j=0;j<8;j++)// { while(PIND&(1< while(! (PIND&(1< while(PIND&(1< { _delay_us(100); k++; if(k>=30)//高电平时间过长,则退出处理程序 { GICR|=(1< return;// } } addr[i]=addr[i]>>1;//接受一位数据 if(k>=8) { addr[i]=addr[i]|0x80;//高电平时间大于0.56,则为数据1 } k=0;//计时清零 } } switch(addr[3]) { DDRB=0XFF; case0x07: if(a1) { PORTB&=~(1< a1=0; } else { PORTB|=(1< a1=1; } break;//1 case0x0b: if(a2) { PORTB&=~(1< a2=0; } else { PORTB|=(1< a2=1; } break;//2 case0x0f: if(a3) { PORTB&=~(1< a3=0; } else { PORTB|=(1< a3=1; } break;//3 case0x13: if(a4) { PORTB&=~(1< a4=0; } else { PORTB|=(1< a4=1; } break;//4 case0x17: if(a5) { PORTB&=~(1< a5=0; } else { PORTB|=(1< a5=1; } break;//5 case0x1b: if(a6) { PORTB&=~(1< a6=0; } else { PORTB|=(1< a6=1; } break;//6 case0x1f: if(a7) { PORTB&=~(1< a7=0; } else { PORTB|=(1< a7=1; } break;//7 case0x23: if(a8) { PORTB&=~(1< a8=0; } else { PORTB|=(1< a8=1; } break;//8 case0x03: if(a9)//蜂鸣器和继电器 { PORTC|=(1< a9=0; } else { PORTC&=~(1< a9=1; } break;//8 case0x27: PORTB=0X00;break;//9 case0x2b: PORTB=0XFF;break;//空格*/ default: break; } GICR|=(1< sei(); } #ifndef__ds18b20__H #define__ds18b20__H #include #include #include #defineucharunsignedchar #defineuintunsignedint #defineCLR_DIR_1WIREDDRC&=~(1< #defineSET_DIR_1WIREDDRC|=(1< #defineSET_OP_1WIREPORTC|=(1< #defineCLR_OP_1WIREPORTC&=~(1< #defineCHECK_IP_1WIRE(PINC&0x40) voidinit_1820(void); voidwrite_1820(unsignedcharx); unsignedcharread_1820(void); voidgettemp(void); volatileuintTemperature; volatileunsignedchartemh,teml; volatileucharNum[4]; voidinit_1820(void) { SET_DIR_1WIRE;//设置PA0为输出 SET_OP_1WIRE;//输出1 CLR_OP_1WIRE;//输出0 _delay_us(480);//480us以上 SET_OP_1WIRE;//输出1 CLR_DIR_1WIRE;//设置PA0为输入 _delay_us(20);//15~60us while(CHECK_IP_1WIRE); SET_DIR_1WIRE; SET_OP_1WIRE; _delay_us(140);//60~240us sei(); } voidwrite_1820(unsignedcharx) { unsignedcharm; for(m=0;m<8;m++) { CLR_OP_1WIRE; if(x&(1< SET_OP_1WIRE; else {CLR_OP_1WIRE;} _delay_us(40);//15~60us SET_OP_1WIRE; } SET_OP_1WIRE; } unsignedcharread_1820(void) { unsignedchartemp,k,n; temp=0; for(n=0;n<8;n++) { CLR_OP_1WIRE; SET_OP_1WIRE; CLR_DIR_1WIRE; k=(CHECK_IP_1WIRE);//读数据,从低位开始 if(k) temp|=(1< else temp&=~(1< _delay_us(50);//60~120us SET_DIR_1WIRE; } return(temp); } voidgettemp(void)//读取温度值 { cli(); init_1820();//复位18b20 write_1820(0xcc);//发出转换命令 write_1820(0x44); //_delay_ms(10);//不延时也好使,不知道怎么回事! init_1820(); write_1820(0xcc);//发出读命令 write_1820(0xbe); teml=read_1820();//读数据 temh=read_1820(); sei(); } #endif
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ATMEGA16 单片机 MCGS 通信 MODBUSRTU 协议