RS485多机通信程序终结版AVR.docx
- 文档编号:7795583
- 上传时间:2023-01-26
- 格式:DOCX
- 页数:8
- 大小:17.12KB
RS485多机通信程序终结版AVR.docx
《RS485多机通信程序终结版AVR.docx》由会员分享,可在线阅读,更多相关《RS485多机通信程序终结版AVR.docx(8页珍藏版)》请在冰豆网上搜索。
RS485多机通信程序终结版AVR
RS485多机通信程序(终结版AVR)
单片机:
AVRATMEGA8
通信:
RS485
芯片:
MAX485/MAX487
要求:
一个主机从机三个以上。
(本例使用3个从机)
工作原理:
三个从机:
采集电压(1-5V),并把数据发给主机
模数采样引脚PC0/ADC0
MAX487的RE和DE连在一起,并接到PD3
主机:
MAX487的RE和DE连在一起,并接到PD3
PC0-PC3接1602液晶的D4-D7(只用4条数据线)
PD7接LCDE
PC4接LCDRW
PC5接LCDRS
工作过程:
从机等间隔进行进行AD采样
1.主机发送地址(adr):
01寻找01从机,01号从机收到后,把AD采回来的数据发给主机,主机把数
据显示在LCD上。
2.从机改变发送02找2号从机,重复步骤1。
完了再发03。
这样轮换的通信。
程序在实际硬件上已经调试成功,验证了正确性,下面把程序贴出来供大家参考。
采用9位数据帧
下面是程序,使用ICCAVR软件编写
主机程序:
#include
#include
#pragmainterrupt_handleruartrupt:
12
unsignedchartemp;//接收临时变量
unsignedcharadr;//从机地址及标志位
constunsignedcharLCD[]="IP01IP02IP03";
constunsignedcharLCDASC[]={0X30,0X31,0X32,0X33,0X34,0X35,0x36,0x37,0x38,0x39};
unsignedcharLCDA=0;
unsignedcharLCDB=0;
unsignedcharLCDC=0;
//QQQQQQQQQQQQQQQQQQQ
//名称:
Delay()
//功能:
延时程序
//QQQQQQQQQQQQQQQQQQQ
voidDelay(intt)
{
while(t--);
}
voidLDelay(intt)//延时程序(时间较长)
{
for(;t>0;t--)
{
Delay(4000);
}
}
//*************************************
//名称:
LCDCOM()与LCDTATA()LCDinit()
//功能:
1602液晶显示
//*************************************
voidLCDCOM(unsignedcharcom)
{
unsignedchartempcom;
tempcom=com;
DDRC|=0X3F;//PORTC0-5OUTPUT
DDRD|=0X80;//pd7output
PORTC&=~0x20;//RS=0
com=com>>4;
com=com&0x0f;
PORTC&=0XF0;//低4位清零
Delay(100);
PORTC|=com;//写指令
Delay(100);
PORTD|=0x80;//EN
Delay(100);
PORTD&=~0x80;
//LLLLLLLLLLL
com=tempcom&0x0f;
PORTC&=0XF0;//清零
Delay(100);
PORTC|=com;//写指令
Delay(200);
PORTD|=0x80;//EN
Delay(100);
PORTD&=~0x80;
}
voidLCDTATA(unsignedchartata)
{
unsignedchartemptata;
temptata=tata;
DDRC|=0X3F;
DDRD|=0X80;//pd7output
PORTC|=0x20;//RS=1
tata=tata>>4;
tata&=0x0f;
PORTC&=0XF0;//清零
Delay(100);
PORTC|=tata;//写指令
Delay(100);
PORTD|=0x80;//EN
Delay(100);
PORTD&=~0x80;
//LLLLLLLLLLL
tata=temptata&0x0f;
PORTC&=0XF0;//清零
Delay(100);
PORTC|=tata;//写指令
Delay(100);
PORTD|=0x80;//EN
Delay(100);
PORTD&=~0x80;
}
voidLCDinit()
{
LCDCOM(0X28);
Delay(3000);
LCDCOM(0X28);
Delay(3000);
LCDCOM(0X28);
Delay(3000);
LCDCOM(0X28);
Delay(3000);//while(t--)Delay(3000)以上
LCDCOM(0X08);
Delay(3000);
LCDCOM(0X01);
Delay(3000);
LCDCOM(0X06);
Delay(3000);
LCDCOM(0X0c);
Delay(3000);
LCDCOM(0x01);//清屏
}
//======================
//名称:
USARTinit()
//功能:
串行通信初始化,设置引脚功能,波特率,通信方式
//波特率=fosc/16(ubrr+1)
//======================
voidUSARTinit()
{
UBRRL=25;//波特率2400//UCSRA正常波特率
//UBRRH=0x00;
UCSRA=0X0;
UCSRB=0X0;
//UCSRA=RXC|TXC|UDRE|FE|DOR|PE|U2X|MPCM(10100001)
UCSRA=0X0;//接收数据
//UCSRC=URSEL|UMSEL|UPM1|UPM0|USBS|UCSZ1|UCSZ0|UCPOL
UCSRC|=0x86;//设置数据位
//UCSRB=RXCIE|TXCIE\UDRIE|RXEN|TXEN|UCSZ2|RXB8|TXB8(10011000)
UCSRB=0X9c;//引脚功能设为TXD与RXD,发送地址//UCSZ2=1即9位数据
MCUCR|=0x00;//开中断(MCU控制寄存器)
GICR=0x00;////通用中断控制器
TIMSK=0x00;//定时计数据中断屏蔽寄存器
//总中断必须是最后使能
SREG|=0x80;//开中断
}
//========================
//名称:
发送地址函数
//功能:
寻找从机
//========================
voidSEND(unsignedcharmydata)
{
DDRD|=0X08;//MAX485允许输出
PORTD|=0X08;
UCSRB|=0x01;//TXB8=0发地址
Delay(1000);
while(!
UDRE);
UDR=mydata;
Delay(1000);//必有
PORTD&=~0X08;//发送后立即转为接收等从机发来数据
}
//==分解数
voidTOLCD(unsignedcharLCDP)//发送变量数据给LCD
{
LCDA=LCDP/100;
LCDA=(int)LCDA;
LCDB=(LCDP%100)/10;
LCDB=(int)LCDB;
LCDC=(LCDP%100)%10;
LCDC=(int)LCDC;
LCDTATA(LCDASC[LCDA]);
LCDTATA(LCDASC[LCDB]);
LCDTATA(LCDASC[LCDC]);
}
//======================
//名称:
接收中断
//功能:
接收数据
//======================
voiduartrupt()
{
temp=UDR;//读数据
//第一行显示:
IP01IP02IP03
//各从机数据在LCD的第二行,不同位置显示
//IP01IP02IP03
//1.2V2.3V3.6V
//显示如上,控制显示位置是下面这几句:
if(adr==1){LCDCOM(0xc0);TOLCD(temp);}
if(adr==2){LCDCOM(0xc0+5);TOLCD(temp);}
if(adr==3){LCDCOM(0xc0+10);TOLCD(temp);}
}
//======================
//名称:
主函数
//======================
voidmain()
{unsignedcharstr;
DDRD|=0X08;//MAX485允许输出
PORTD|=0X08;
USARTinit();
LCDinit();
DDRB|=0X03;//PORTBOUT
Delay(4000);
Delay(4000);
//液晶第一行:
IP1IP2IP3
LCDCOM(0x80);//第一行
while(LCD[str]!
='\0')//字符串是否完成
{
LCDTATA(LCD[str]);
str++;//
}
str=0;//跳出来之后清空str=0切记!
切记!
//液晶第一行
while
(1)
{
LDelay
(2);
//RRRRRRRRRRRRRRRRRRRRRRRR读数据
for(adr=1;adr<4;adr++)
{
SEND(adr);//发送地址寻找从机,地址ADR从01-03
LDelay(20);//延时
}
//RRRRRRRRRRRRRRRRRRRRRRRR读数据
}
}
从机程序:
#include
#include
#pragmainterrupt_handleruartrupt:
12
unsignedchartemp;//接收临时变量
unsignedcharsendtata=123;
//QQQQQQQQQQQQQQQQQQQ
//名称:
Delay()
//功能:
延时程序
//QQQQQQQQQQQQQQQQQQQ
voidDelay(intt)
{
while(t--);
}
voidLDelay(intt)//延时程序(时间较长)
{
for(;t>0;t--)
{
Delay(4000);
}
}
//AD转换
#defineADC_REF_AVCC0x40
#defineMUX_ADC00x00
unsignedcharADC_Value;
voidAD_Init(void)
{
//CLI();
ACSR|=(1 ADMUX|=0X40|MUX_ADC0|(1 SFIOR=0X00; ADCSRA|=(1 unsignedcharRead_ADC(void) { unsignedcharADC_dat; ADCSRA|=(1 return(ADC_dat); } //====================== //名称: USARTinit() //功能: 串行通信初始化,设置引脚功能,波特率,通信方式 //波特率=fosc/16(ubrr+1) //====================== voidUSARTinit() { UBRRL=25;//波特率2400 //UBRRH=0x00; UCSRA=0X0; UCSRB=0X0; //UCSRA=RXC|TXC|UDRE|FE|DOR|PE|U2X|MPCM(10100001) UCSRA|=0X01;//只接收地址,从机CPCM=1 //UCSRC=URSEL|UMSEL|UPM1|UPM0|USBS|UCSZ1|UCSZ0|UCPOL(10000110) UCSRC|=0x86;//设置数据位 //UCSRB=RXCIE|TXCIE\UDRIE|RXEN|TXEN|UCSZ2|RXB8|TXB8(10011000) UCSRB|=0x9c;//引脚功能设为TXD与RXD MCUCR|=0x00;//开中断 GICR=0x00; TIMSK=0x00; //最后才开总中断 Delay(1000); SREG=0x80;//开中断 DDRD|=0X08;// PORTD&=~0X08;//未收到主机命令禁止MAX485输出 } //======================== //名称: 发送数据函数 //功能: 给主机发数据 //======================== voidSEND(unsignedcharmydata) { DDRD|=0X08;//MAX485允许输出 PORTD|=0X08; Delay(1000); UDR=mydata; //while(! UDRE); Delay(1000);//Delay(100)可发s PORTD&=~0X08;//发送后立即转为接收 } //====================== //名称: 接收中断 //功能: 接收地址 //====================== voiduartrupt() { temp=UDR;//接收地址 if(temp==0x02) { //sendtata=Read_ADC(); DDRB|=0x01; PORTB|=0X01;//LED SEND(sendtata);//发送数据 } } //====================== //名称: 主函数 //====================== voidmain() { unsignedcharadr; Delay(4000); DDRB|=0X03;//PORTBOUT USARTinit(); AD_Init(); while (1) { LDelay(100); PORTB|=0X01;//LED sendtata=Read_ADC(); } }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- RS485 通信 程序 终结 AVR