1、完了再发03。这样轮换的通信。程序在实际硬件上已经调试成功,验证了正确性,下面把程序贴出来供大家参考。采用9位数据帧下面是程序,使用ICCAVR软件编写主机程序:#include#pragma interrupt_handler uartrupt:12unsigned char temp; /接收临时变量unsigned char adr; /从机地址及标志位const unsigned char LCD=IP01 IP02 IP03;const unsigned char LCDASC=0X30,0X31,0X32,0X33,0X34,0X35,0x36,0x37,0x38,0x39;uns
2、igned char LCDA=0;unsigned char LCDB=0;unsigned char LCDC=0;/QQQQQQQQQQQQQQQQQQQ/名称:Delay()/功能:延时程序void Delay(int t)while(t-);void LDelay(int t)/延时程序(时间较长) for(;t0;t-)Delay(4000);/*/名称:LCDCOM()与LCDTATA()LCDinit()1602液晶显示void LCDCOM(unsigned char com)unsigned char tempcom;tempcom = com;DDRC |=0X3F; /
3、PORTC0-5 OUTPUTDDRD |=0X80;/pd7 outputPORTC &=0x20; /RS = 0com = com4;com =com&0x0f;=0XF0; /低4位清零Delay(100);PORTC |=com;/写指令PORTD|=0x80; /ENPORTD&=0x80; /LLLLLLLLLLLcom = tempcom& /清零Delay(200);void LCDTATA(unsigned char tata)unsigned char temptata;temptata = tata;PORTC|=0x20; /RS = 1tata= tatatata
4、&= 0x0f;PORTC |=tata;tata = temptata&void LCDinit()LCDCOM(0X28);Delay(3000); /while(t-) Delay(3000)以上LCDCOM(0X08);LCDCOM(0X01);LCDCOM(0X06);LCDCOM(0X0c);LCDCOM(0x01);/清屏/=USARTinit()串行通信初始化,设置引脚功能,波特率,通信方式/波特率=fosc/16(ubrr+1)void USARTinit()UBRRL=25; /波特率2400 /UCSRA 正常波特率 /UBRRH=0x00;UCSRA=0X0;UCSRB
5、=0X0;/UCSRA=RXC|TXC|UDRE|FE|DOR|PE|U2X|MPCM(10100001)/接收数据 /UCSRC=URSEL|UMSEL|UPM1|UPM0|USBS|UCSZ1|UCSZ0|UCPOLUCSRC|=0x86 ; /设置数据位/UCSRB=RXCIE|TXCIEUDRIE|RXEN|TXEN|UCSZ2|RXB8|TXB8(10011000)UCSRB=0X9c; /引脚功能设为TXD与RXD,发送地址/UCSZ2=1即9位数据MCUCR|=0x00; / 开中断(MCU控制寄存器)GICR=0x00; /通用中断控制器TIMSK=0x00; /定时计数据中断
6、屏蔽寄存器/总中断必须是最后使能SREG|=0x80; /开中断/=发送地址函数/功能:寻找从机void SEND(unsigned char mydata)DDRD|=0X08; /MAX485允许输出PORTD|=0X08;UCSRB|=0x01; /TXB8=0发地址Delay(1000);while(!UDRE);UDR=mydata; /必有=0X08; /发送后立即转为接收等从机发来数据/=分解数void TOLCD(unsigned char LCDP) /发送变量数据给LCDLCDA=LCDP/100;LCDA=(int)LCDA;LCDB=(LCDP%100)/10;LCDB
7、=(int)LCDB;LCDC=(LCDP%100)%10;LCDC=(int)LCDC;LCDTATA(LCDASCLCDA);LCDTATA(LCDASCLCDB);LCDTATA(LCDASCLCDC);接收中断接收数据void uartrupt()temp=UDR; /读数据/第一行显示:IP01 IP02 IP03/各从机数据在LCD的第二行,不同位置显示/IP01 IP02 IP03/1.2V 2.3V 3.6V /显示如上,控制显示位置是下面这几句:if(adr=1)LCDCOM(0xc0);TOLCD(temp); if(adr=2)LCDCOM(0xc0+5);if(adr=
8、3)LCDCOM(0xc0+10);主函数void main()unsigned char str;USARTinit();LCDinit();DDRB |= 0X03; /PORTB OUT/液晶第一行:IP1 IP2 IP3LCDCOM(0x80); /第一行while(LCDstr!=0) /字符串是否完成LCDTATA(LCDstr);str+;/str=0; /跳出来之后清空str=0切记!切记!/液晶第一行while(1)LDelay(2);/RRRRRRRRRRRRRRRRRRRRRRRR读数据for(adr=1;adradr+)SEND(adr); /发送地址寻找从机,地址AD
9、R从01-03LDelay(20); /延时 从机程序:unsigned char sendtata=123;void LDelay(int t) /延时程序(时间较长)/AD转换#define ADC_REF_AVCC 0x40#define MUX_ADC0 0x00unsigned char ADC_Value;void AD_Init(void)/CLI();ACSR |= (1 ADCSRA &=(1 ADMUX &= 0x20;/清参考电压, ADCn输入端ADMUX |=0X40|MUX_ADC0|(1 ADCSRA |= (1 ADCSRA |=0x01;/2分频SFIOR =
10、 0X00;ADCSRA |= (1 unsigned char Read_ADC(void)unsigned char ADC_dat; while(ADCSR&(1 ADC_dat = ADCH;return (ADC_dat); /波特率2400 UCSRA|=0X01; /只接收地址,从机CPCM=1/UCSRC=URSEL|UMSEL|UPM1|UPM0|USBS|UCSZ1|UCSZ0|UCPOL(10000110)UCSRC|=0x86;UCSRB|=0x9c; /引脚功能设为TXD与RXD/最后才开总中断SREG=0x80;/开中断 / /未收到主机命令禁止MAX485输出发送数据函数给主机发数据/while(! /Delay(100)可发s /发送后立即转为接收接收地址 /接收地址if(temp=0x02)/sendtata=Read_ADC();DDRB|=0x01;PORTB |= 0X01;/LED SEND(sendtata); /发送数据/PORTB OUTAD_Init();LDelay(100);sendtata=Read_ADC();