ADMUX=ADMUX&240|2; //清除已选择的ADC通道,选择新的ADC通道(0-7)
ADCSRA|=64; //启动单次ADC转换 while((ADCSRA&16)==0); //等待ADC转换结束
adc=ADCH; //结果左对齐只需读取高8位数据 ADCSRA|=16; //清除ADC转换结束标记 putchar(adc/100+48); //从串口输出ADC的百位数 putchar(adc/10+48); //从串口输出ADC的十位数 putchar(adc+48); //从串口输出ADC的个位数 delay_ms(500); //延时 putchar(13); //回车 putchar(10); //换行 } }
ATMEGA8/ATMEGA16多机通讯例子
下面是一个M16的多机通讯例子,也适合M8,只需要修改头文件就可以了,本例子在3台机上测试并稳定通过 主机代码
/*
www.avrdiy.com AVR单片机DIY网 潘小艺 CVAVR1.25.9 通讯规则: 01:时钟7.3728 MHz/波特率9600/9个数据位/奇校验/1个停止位/硬件多机通讯功能/
02:通讯连接采用硬件MAX485,双向单工
03:MAX485的RE/DE并联接到单片机的PD2脚(高电平发送/低电平接收) 04:所有MAX485的A脚并联/B脚并联/D脚接TXD/R脚接RXD
05:每个上行/下行的数据包的字节个数都是一样的(通讯数据量) 06:数据包格式: 地址_数据1_数据2_数据3_数据n_CRC8校验码 07:所有单元的数据接收都是采用中断+查询的方式
08:总是由主机向从机下发一个数据包,从机收到数据包并校验正确后向主机回复一个数据包
09:不管是主机还是从机,如果收到的数据包有任何错误,都将丢弃该数据包,等效于没有接收
10:通讯采用主机轮询方式,从机之间不能相互通讯,必须通过主机才能交换数据
11:无效地址是0,主机地址是1,从机地址是11.12.13...广播地址是255 */
#include
#include
#define amount 10 //设定通讯数据量
#define address 1 //请在这里设定本机地址
#define max485_out PORTD.2=1 #define max485_in PORTD.2=0 #define max485_RW_ok DDRD.2=1
unsigned char send[amount]; //发件箱 unsigned char inbox[amount]; //收件箱 unsigned char n=0; //记忆接收中断的次数
unsigned char x=0;
//**************************************************************************************
void usart_out(unsigned char *datas,unsigned char n) {
unsigned char i=0;
max485_out; //使MAX485处于发送状态
while(i if(i==0) UCSRB|=1; else UCSRB&=254; UDR=*(datas+i); //装载数据开始发送 while((UCSRA&64)==0); //等待发送结束 UCSRA|=64; //清除发送结束标志 i++; //发送次数统计 } max485_in; //使MAX485处于接收状态 } //************************************************************************************** interrupt[12] Rxd_isr(void) //接收中断 { if( UCSRA&28 ){ n=UDR; n=0; UCSRA|=0x01; } else //接收出错就重新打开地址帧筛选功能 { if( UCSRB&2 ) n=0; //检测到地址信息时计数清零 inbox[n]=UDR; n++; //把接收到的数据保存到收件箱 if( inbox[0]==address ) UCSRA&=254; else UCSRA|=0x01; //地址筛选 } } //************************************************************************************** void main(void) { usart_init(); max485_in; max485_RW_ok; DDRA=7; //通讯状态指示 #asm(\ while(1) { x=~x; //测试用的变量 PORTA.0=~PORTA.0; //观察单片机是否死机(供电一定要好) //************************************与从机11对话**************************************** if(x) send[3]=0; else send[3]=255; //更新发件箱的数据(测试代码) send[0]=11; //指向从机地址 send[amount-1]=crc8(send,amount-1); //计算发件箱数据的crc8校验码 usart_out(send,amount); //将发件箱的数据send[]发送出去; n=0; //计数复位,准备接收新数据 delay_ms(15); //等待从机回复数据,这个时间要计算好 if(n==amount && inbox[amount-1]==crc8(inbox,amount-1)) //接收正确处理与测试 { PORTA.1=1; delay_ms(10); PORTA.1=0; } else //接收错误处理与测试 { PORTA.2=1; delay_ms(10); PORTA.2=0; } //************************************与从机12对话**************************************** if(x) send[3]=50; else send[3]=200; //更新发件箱的数据(测试代码) send[0]=12; //指向从机地址 send[amount-1]=crc8(send,amount-1); //计算发件箱数据的crc8校验码 usart_out(send,amount); //将发件箱的数据send[]发送出去; n=0; //计数复位,准备接收新数据 delay_ms(15); //等待从机回复数据,这个时间要计算好 if(n==amount && inbox[amount-1]==crc8(inbox,amount-1)) //接收正确处理与测试 { PORTA.1=1; delay_ms(10); PORTA.1=0; } else //接收错误处理与测试 { PORTA.2=1; delay_ms(10); PORTA.2=0; } } } //end 从机(需要增加多个从机时可以修改从机的地址就可以了) //从机11 #include #define amount 10 //设定通讯数据量 #define address 11 //请在这里设定本机地址 #define max485_out PORTD.2=1 #define max485_in PORTD.2=0 #define max485_RW_ok DDRD.2=1 unsigned char send[amount]; //发件箱 unsigned char inbox[amount]; //收件箱 unsigned char n=0; //记忆中断次数 //************************************************************************************** void usart_out(unsigned char *datas,unsigned char n) { unsigned char i=0; max485_out; //使MAX485处于发送状态 while(i if(i==0) UCSRB|=1; else UCSRB&=254; UDR=*(datas+i); //装载数据开始发送 while((UCSRA&64)==0); //等待发送结束 UCSRA|=64; //清除发送结束标志 i++; //发送次数统计 } max485_in; //使MAX485处于接收状态 }