logo资料库

ATMEA128 的485通信.doc

第1页 / 共9页
第2页 / 共9页
第3页 / 共9页
第4页 / 共9页
第5页 / 共9页
第6页 / 共9页
第7页 / 共9页
第8页 / 共9页
资料共9页,剩余部分请下载后查看
{ 软件环境:ICC AVR 6.31A 硬件平台:atmega128a 实现 UART0 的半双工 485 通信,中断方式接受,查询方式发送。485 的收发控制引脚 为 PE2。 供大家学习交流使用 } 1,以下是 delay.h 文件 #ifndef _delay_h_ #define _delay_h_ //void delay_nus(unsigned int n); //void delay_nms(unsigned int n); //void delay_1us(void); //void delay_1ms(void); void delay_1us(void) { NOP(); } void delay_nus(unsigned int n) { unsigned int i=0; for (i=0;i
晶振:11.0592M 查询方式发送,中断接收。 *************************************************/ #ifndef _uart_h #define _uart_h #include #include #include "delay.h" #define fosc 11059200 #define baud 9600 #define uchar unsigned char //#define amount 8 //uchar inbox[amount]; //transmited and received data buff. //data amount //uchar buff = 0; //unsigned char inbox[10]; /****uart0 initialize************/ void Uart0_initial(void) { UCSR0B = 0x00;// disable while setting uart UCSR0A = 0x00; UCSR0C = (1<
/***uart0 transfer one char****/ void putchar0(uchar c) { PORTE &=~ BIT(PE2); delay_nms(5); while (!(UCSR0A&(1<
s++; } } /***uart0 RXD interrupt processing****/ /************************************** #pragma interrupt_handler uart0_RX_interrupt:19 void uart0_RX_interrupt(void) { //UCSR0B = 0x00; //disable uart0 while handling interrupt. buff = UDR0; PORTE &=~ BIT(PE2); delay_nms(3); //收转发设置控制引脚后,要延时,换高频晶振需加大此延时。 putchar0(buff); puts0("Test OK!"); delay_nms(3); PORTE |= BIT(PE2); //UCSR0B = (1<
WDR(); } ptr++; WDR(); } return(crc); } *******************************************************/ unsigned char CRC8(unsigned char *ptr, unsigned char len) { if(len == 7) return (0xAA); } #endif /********* 4,以下是主程序 **************/ #include #include #include "delay.h" #include "CRC8.h" #include "uart.h" #define uchar unsigned char #define amount 8 uchar inbox[amount]; uchar sendbox[amount]; uchar buf_used = 0; uchar buf_flag = 0; uchar buf_saved = 0; uchar fun_code = 0; uchar action_code = 0; uchar key = 0; uchar key_code = 0; uchar relay_status = 0; uchar key_buf = 0x1F; uchar used_times = 0; void Device_initial(void) { PORTC |= 0x3F; //收件箱 //发件箱 //接收的数据个数 //接收缓冲区满标志位 //记忆收发缓存中未使用的个数 //存放功能代码 //存放功能数据 //继电器状态 //存储开关量的值 //记录使用状况 //初始化各 IO 端口和设备
DDRA |= 0xFF; DDRB |= 0xF6; DDRC |= 0x3F; DDRD |= 0x00; //PORTE |= 0xFC; DDRE |= 0x06; SEI(); //PORTA 全部用于 1602 //PORTB 比较混乱,具体参考电路图 //PORTC.0 - PORTC.5 为电源组件反馈端信号输入端 //PE = 1111 1100 =0xFC //DDRE = 0000 0110=0x06 PORTD 待定 //PORTE.0 为 RXD0,PORTE.1 为 TXD0,PORTE.2 为 485(0 号)控制端;PORTE3~7 为继电器控制端口 // watchdog_INI(); } #pragma interrupt_handler uart0_RX_interrupt:19 void uart0_RX_interrupt(void) { //中断方式接受函数 inbox[buf_used] = UDR0; if(inbox[0] == 0x0A) buf_used+=1; if(buf_used == 8) { buf_flag = 1; buf_used = 0; } } void TX(uchar a,uchar b) { //查询方式发送函数 sendbox[0] = 0x0A; sendbox[1] = 0xFF; sendbox[2] = 0x0A; sendbox[3] = 0x07; sendbox[4] = a; sendbox[5] = b; sendbox[6] = 0x0D; sendbox[7] = CRC8(sendbox,amount-1); puts0(sendbox); //WDR(); } void Key_scan(void) { key_code = PINE; key = key_code>>3; if(key!= key_buf) {
//消抖 delay_nms(15); if(key != key_buf)//开关量与上次不同,则上发开关量状态到 ARM { key_buf = key; while(1) { while(buf_flag == 0) { TX('N',key); delay_nms(300); //禁止接收 } CLI(); //buf_used = 0; buf_flag =0; inbox[0] = 0; if(inbox[7] == CRC8(inbox,amount-1)) { if(inbox[4] == 'A'&&inbox[5] == 'R') //应答正确。 { //允许接收。 SEI(); break; } } else SEI(); } } } } void Func_action(void) { switch(fun_code) { case 'J': { relay_status = PINC; while(1) { while(buf_flag == 0) { TX('J',relay_status); delay_nms(300); } //功能响应函数
CLI(); //buf_used = 0; buf_flag =0; inbox[0] = 0;//接收到完整帧后,将起始包头清 0,以供下次接收 if(inbox[7] == CRC8(inbox,amount-1)) { if(inbox[4] == 'A'&&inbox[5] == 'R') { } SEI(); break; else SEI(); } else SEI(); } } break; case 'Z': { PORTC = inbox[5];//写继电器 TX('A','R'); } break; case 'I': Key_scan(); break; //发送开关量状态 case 'R': //每次设备用完,重新循环 used_times = 1; break; default: break; } } void main(void) { Device_initial(); Uart0_initial(); while(1) { used_times = 0; key_buf = 0x1F; while(buf_flag == 0) { ;
分享到:
收藏