找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1818|回复: 2
打印 上一主题 下一主题
收起左侧

AVR单片机串口单线半双工

[复制链接]
跳转到指定楼层
楼主
ID:154686 发表于 2019-1-18 13:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
200黑币
之前发了个帖子,没有人回,自己琢磨了几天,基本实现了功能,但是还有问题http://www.51hei.com/bbs/dpj-148913-1.html


实现方法,串口信号线连接单片机的RX脚.然后单片机的RX和TX中间用一个100欧姆的电阻串联


这样做的话,单片机发出的数据可以通过RX脚传输到PC机上

数据显示正常.但是如果PC机向单片机发数据,PC机自己的信号无法收到,(即无法自发自收,此时PC串口的RXTX是用680欧姆的电阻短接的,
如果串口信号单线空置的话,是可以自发自收)

同时,收到单片机返回的信号也是有问题的,比如PC发送123456789,收到的返回数据是13579,中间都漏一位

希望有人能解答我的困惑,多谢了

以下是程序代码,
发送数据时关闭单片机的接收功能,避免单片机自发自收进出串口接收中断
发送完毕后打开单片机的发送功能
#include <avr/io.h>        
#include <util/delay.h>
#include <avr/interrupt.h>   //中断函数头文件

//常量声明
#define BAUD 9600
//全局变量声明
unsigned char Transmit;

//函数声明
void Port_Init(void);   //端口初始化配置
void Usart_Init(void);  //USART寄存器设置
void Usart_PutChar(unsigned char cTXData);  //字节发送函数
void Usart_PutString(unsigned char *pcString);

int main(void)            
{
        Port_Init();
        Usart_Init();

        sei();
        Usart_PutChar(0x31);

        while(1)
        {
                Usart_PutString("ABCC");
                _delay_ms(500);
        }
}

//端口状态初始化设置函数
void Port_Init()
{
        PORTD = 0X00;          //USART的发送接收端口分别为PD0和PD1
        DDRD |= (1 << PD1);   //PD0为接收端口,置为输入口;PD1为发送端口,置为输出口
}

//USART寄存器配置函数
void Usart_Init()
{
    UCSR0C &= ~(1 << UCSZ00) ;  
    UCSR0C |= (1 << USBS0) ;  //异步,数据格式7,N,1
          UCSR0B |= (1 << TXCIE0) |(1 << RXCIE0) | (1 << RXEN0) | (1 << TXEN0);    //发送使能,接收使能,接收中断使能
    unsigned int UBRR;
    UBRR = F_CPU/16/BAUD - 1;
    UBRR0H = (uint8_t)(UBRR>>8);
    UBRR0L = (uint8_t)(UBRR);  //设置波特率
        }

//字节发送函数
void Usart_PutChar(unsigned char cTXData)
{
        UCSR0B &= ~(1 << RXEN0);
        while( !(UCSR0A & (1 << UDRE0)) );  //只有数据寄存器为空时才能发送数据
        {
        UDR0 = cTXData;                         //发送数据送USART I/O数据寄存器-UDR
        }
}

//接收中断函数
ISR(USART0_RX_vect )
{

        unsigned char Rev0;
        Rev0 = UDR0;
        Usart_PutChar(Rev0);
  //从USART I/O数据寄存器-UDR中读出数据
        if (Rev0==0x12)   //将接收到的数据发送
          {
          PORTA=0X00;
        DDRA=0XFF;
          }
}

ISR(USART0_TX_vect )
{
        cli();
        UCSR0B |= (1 << RXEN0 );  
        sei();
}


void Usart_PutString(unsigned char *pcString)
{
        while (*pcString)
        {
                Usart_PutChar(*pcString++);
        }
        Usart_PutChar(0x0D);
        Usart_PutChar(0x0A);  //结尾发送回车换行
}




分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:439075 发表于 2019-1-20 13:22 | 只看该作者
建议你把用电阻的方法改为用电子开关来解决半双工的问题,
回复

使用道具 举报

板凳
ID:154686 发表于 2019-1-21 08:40 | 只看该作者
bucker 发表于 2019-1-20 13:22
建议你把用电阻的方法改为用电子开关来解决半双工的问题,

那样是简单很多,但是项目限定了实现方法,只能加电阻和对程序修改
多谢你的回复了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表