关于使用两片ATMEGA128实现UART单线半双工通信
准备使用128做双机通信,使用半双工模式,电路原理图如图所示单片机1的TXD 和RXD与单片机2的TXD和RXD分别用继电器切换,传输使用一条信道,我编的程序总是有问题,求大神指点···
这是单片机一的程序:
#include<iom128v.h>
#include<macros.h>
#define uchar unsigned char
#define uint unsigned int
#define data_1602_DDR DDRA
#define data_1602_PORT PORTA
#define control_1602_DDR DDRB
#define control_1602_PORT PORTB
#define CON_DDR DDRF
#define CON_PORT PORTF
#pragma interrupt_handler ADD:2
#pragma interrupt_handler UART_receive:19
#pragma interrupt_handler UART_transmit0:21
uchar flag=0,rdata,tdata=0;
//***************************************
void init_1602()
{
data_1602_DDR=0XFF;
control_1602_DDR=0XFF;
control_1602_PORT&=~BIT(2);
write_com(0x38);
delay(5);
write_com(0x01);
delay(5);
write_com(0x0c);
delay(5);
write_com(0x06);
delay(5);
}
//****************************************
void write_dat(uchar dat)
{
control_1602_PORT|=BIT(0);
control_1602_PORT&=~BIT(1);
data_1602_PORT=dat;
control_1602_PORT|=BIT(2);
delay(1);
control_1602_PORT&=~BIT(2);
}
//*************************************
void write_com(uchar com)
{
control_1602_PORT&=~BIT(0);
control_1602_PORT&=~BIT(1);
data_1602_PORT=com;
control_1602_PORT|=BIT(2);
delay(1);
control_1602_PORT&=~BIT(2);
}
//*************************************
void show_1602(uint x)
{
uchar table1[]="receive:";
uchar ASCII[]={48,49,50,51,52,53,54,55,56,57,114,115,47,46,32,118,100,66};//0 1 2 3 4 5 6 7 8 9 r s . /
uchar m1,n1,m2,n2,k;
write_com(0x80+0x01);
delay(5);
for(n1=0;n1<8;n1++)
{
write_dat(table1);
delay(1);
}
write_com(0x80+0x09);
delay(5);
write_dat(ASCII);
delay(1);
}
//***************************************
void delay(uint ms)
{
uint i,j;
for(i=0;i<ms;i++)
{
for(j=0;j<1141;j++);
}
}
//****************************************
void UART_init()
{
UCSR0B=0X00;
UCSR0A=0X00;//控制和状态寄存器清零
UCSR0B=(1<<RXCIE0)|(1<<RXEN0)|(1<<TXEN0)|(1<<TXCIE0);//接收结束中断使能,接收、发送使能
UCSR0C=(1<<UCSZ01)|(1<<UCSZ00);//八个数据位,一个停止位
UBRR0H=0;
UBRR0L=51;//设置波特率为9600
DDRE|=BIT(1);//PE1口输出 即TXD0为输出
DDRE&=~BIT(0);//PE0口输入 即RXD0为输入
SEI();//开全局中断
}
//***********************************
void UART_transmit(uchar data)//发送数据
{
while(!(UCSR0A&(1<<UDRE0)));//等待发送缓冲器为空
UDR0=data;//将数据放入缓冲期,发送数据
while(!(UCSR0A&(1<<TXC0)));//等待数据发送结束
UCSR0A|=BIT(TXC0);//对TXC0位写1,清除标志
}
//***********************************
void UART_receive()//接收结束中断
{
UCSR0B&=~BIT(RXCIE0);
flag=1;
CON_PORT|=BIT(0);
rdata=UDR0;
UCSR0B|=BIT(RXCIE0);
}
void UART_transmit0()//发送结束中断
{
UCSR0B&=~BIT(TXCIE0);
UDR0=0;
CON_PORT&=~BIT(0);
UCSR0B|=BIT(TXCIE0);
}
//***********************************
void ADD()
{
tdata=tdata+1;
if(tdata==10)
{
tdata=0;
}
}
//***********************************
int main(void)
{
CON_DDR|=BIT(0);
CON_PORT&=~BIT(0);
DDRD&=~BIT(0);
EIMSK|=BIT(0);
EICRA=0X00;
SEI();
init_1602();
UART_init();
while(1)
{
UART_transmit(tdata);
if(flag==1)
{
flag=0;
}show_1602(rdata);
}
}
单片机2的程序:
#include<iom128v.h>
#include<macros.h>
#define uchar unsigned char
#define uint unsigned int
#define data_1602_DDR DDRA
#define data_1602_PORT PORTA
#define control_1602_DDR DDRB
#define control_1602_PORT PORTB
#define CON_DDR DDRF
#define CON_PORT PORTF
#pragma interrupt_handler ADD:2
#pragma interrupt_handler UART_receive:19
#pragma interrupt_handler UART_transmit0:21
uchar flag=0,rdata,tdata=0,flag1=0;
//***************************************
void init_1602()
{
data_1602_DDR=0XFF;
control_1602_DDR=0XFF;
control_1602_PORT&=~BIT(2);
write_com(0x38);
delay(5);
write_com(0x01);
delay(5);
write_com(0x0c);
delay(5);
write_com(0x06);
delay(5);
}
//****************************************
void write_dat(uchar dat)
{
control_1602_PORT|=BIT(0);
control_1602_PORT&=~BIT(1);
data_1602_PORT=dat;
control_1602_PORT|=BIT(2);
delay(1);
control_1602_PORT&=~BIT(2);
}
//*************************************
void write_com(uchar com)
{
control_1602_PORT&=~BIT(0);
control_1602_PORT&=~BIT(1);
data_1602_PORT=com;
control_1602_PORT|=BIT(2);
delay(1);
control_1602_PORT&=~BIT(2);
}
//*************************************
void show_1602(uint x)
{
uchar table1[]="receive:";
uchar ASCII[]={48,49,50,51,52,53,54,55,56,57,114,115,47,46,32,118,100,66};//0 1 2 3 4 5 6 7 8 9 r s . /
uchar m1,n1,m2,n2,k;
write_com(0x80+0x01);
delay(5);
for(n1=0;n1<8;n1++)
{
write_dat(table1);
delay(1);
}
write_com(0x80+0x09);
delay(5);
write_dat(ASCII);
delay(1);
}
//***************************************
void delay(uint ms)
{
uint i,j;
for(i=0;i<ms;i++)
{
for(j=0;j<1141;j++);
}
}
//****************************************
void UART_init()
{
UCSR0B=0X00;
UCSR0A=0X00;//控制和状态寄存器清零
UCSR0B=(1<<RXCIE0)|(1<<RXEN0)|(1<<TXEN0)|(1<<TXCIE0);//接收结束中断使能,接收、发送使能
UCSR0C=(1<<UCSZ01)|(1<<UCSZ00);//八个数据位,一个停止位
UBRR0H=0;
UBRR0L=51;//设置波特率为9600
DDRE|=BIT(1);//PE1口输出 即TXD0为输出
DDRE&=~BIT(0);//PE0口输入 即RXD0为输入
SEI();//开全局中断
}
//***********************************
void UART_transmit(uchar data)
{
while(!(UCSR0A&(1<<UDRE0)));//等待发送缓冲器为空
UDR0=data;//将数据放入缓冲期,发送数据
while(!(UCSR0A&(1<<TXC0)));//等待数据发送结束
UCSR0A|=BIT(TXC0);//对TXC0位写1,清除标志
UDR0=0;
}
//***********************************
void UART_receive()
{
UCSR0B&=~BIT(RXCIE0);
flag=1;
CON_PORT&=~BIT(0);
rdata=UDR0;
UCSR0B|=BIT(RXCIE0);
}
void UART_transmit0()
{
UCSR0B&=~BIT(TXCIE0);
CON_PORT|=BIT(0);
UDR0=0;
UCSR0B|=BIT(TXCIE0);
}
//***********************************
void ADD()
{
tdata=tdata+1;
if(tdata==10)
{
tdata=0;
}
}
//***********************************
int main(void)
{
CON_DDR|=BIT(0);
CON_PORT&=~BIT(0);
DDRD&=~BIT(0);
EIMSK|=BIT(0);
EICRA=0X00;
SEI();
init_1602();
UART_init();
while(1)
{
UART_transmit(tdata);
if(flag==1)
{
flag=0;
show_1602(rdata);
}
}
}
求大神指点啊···如何实现单线半双工 切换用继电器?你的继电器没有开关次数限制? MiniCat 发表于 2013-1-23 09:11 static/image/common/back.gif
切换用继电器?你的继电器没有开关次数限制?
那我该杂办···· xz19921230 发表于 2013-1-23 09:42 static/image/common/back.gif
那我该杂办····
硬件可以考虑用三极管 光耦 MOS等等做切换
页:
[1]