a441257618 2022-11-25 22:31 采纳率: 0%
浏览 31

使用MAX485实现单片机与PC串口通信

问题遇到的现象和发生背景

给任务要我自己弄个画个PCB板子实现一些功能,我光485和电脑通信就花了20多小时还没成功,目前就是串口接收不到数据

用代码块功能插入代码,请勿粘贴截图

这是我的原理图

img

main.c
 int main(void)
 {
extern uint32_t time1_cntr;
extern uint32_t time2_cntr;     
    u8 i=0;
    u8 cnt=0;
    u8 rs485buf[1];

    delay_init();             //ÑÓʱº¯Êý³õʼ»¯      
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
          
    RS485_Init(9600);    
                                  
    while(1)
    {
            for(i=0;i<5;i++)
            {
                rs485buf[i]=cnt+i;
            }
                RS485_Send_Data(rs485buf,5);
    } 
}
RS485.c
#include "sys.h"            
#include "rs485.h"
#include "delay.h"

//////////////////////////////////////////////////////////////////////////////////     
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK战舰STM32开发板
//RS485驱动 代码       
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//修改日期:2012/9/9
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2009-2019
//All rights reserved                                      
//////////////////////////////////////////////////////////////////////////////////


#ifdef EN_USART1_RX       //如果使能了接收


//接收缓存区     
u8 RS485_RX_BUF[64];      //接收缓冲,最大64个字节.
//接收到的数据长度
u8 RS485_RX_CNT=0;             
  
void USART1_IRQHandler(void)
{
    u8 res;        
 
     if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收到数据
    {     
                  
        res =USART_ReceiveData(USART1);     //读取接收到的数据
        if(RS485_RX_CNT<64)
        {
            RS485_RX_BUF[RS485_RX_CNT]=res;        //记录接收到的值
            RS485_RX_CNT++;                        //接收数据增加1 
        } 
    }                                               
} 
#endif                                         
//初始化IO 串口1
//pclk1:PCLK1时钟频率(Mhz)
//bound:波特率      
void RS485_Init(u32 bound)
{  
  GPIO_InitTypeDef GPIO_InitStructure;
  USART_InitTypeDef USART_InitStructure;
     NVIC_InitTypeDef NVIC_InitStructure;
 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能GPIOA时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1时钟
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;                 //PA8端口配置
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;          //推挽输出
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_Init(GPIOA, &GPIO_InitStructure);
 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;    //PA9
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    //复用推挽
  GPIO_Init(GPIOA, &GPIO_InitStructure);
   
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
  GPIO_Init(GPIOA, &GPIO_InitStructure);  

    RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1,ENABLE);//复位串口2
    RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1,DISABLE);//停止复位
 
    
 #ifdef EN_USART1_RX              //如果使能了接收
    USART_InitStructure.USART_BaudRate = bound;//波特率设置
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8位数据长度
    USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
    USART_InitStructure.USART_Parity = USART_Parity_No;///奇偶校验位
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收发模式

  USART_Init(USART1, &USART_InitStructure);  //初始化串口
  
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //使能串口1中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //先占优先级2级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级2级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
    NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
 
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断
   
  USART_Cmd(USART1, ENABLE);                    //使能串口 

 #endif

  RS485_TX_EN=0;            //默认为接收模式,灯亮
 
}

//RS485发送len个字节.
//buf:发送区首地址
//len:发送的字节数(为了和本代码的接收匹配,这里建议不要超过64个字节)
void RS485_Send_Data(u8 *buf,u8 len)
{
    u8 t;
    RS485_TX_EN=1;            //设置为发送模式 灯不亮 单片机TX引脚可通过485的DI口,数据通过AB线传给电脑
      for(t=0;t<len;t++)        //循环发送数据
    {           
        while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);    //是否发送完成  
        USART_SendData(USART1,buf[t]);
    }     
 
    while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);        
    RS485_RX_CNT=0;     
// delay_ms(100);
    RS485_TX_EN=0;                //设置为接收模式 灯亮 信号由AB进入485,由485RO端输出到单片机RX
//        delay_ms(100);
}
//RS485查询接收到的数据
//buf:接收缓存首地址
//len:读到的数据长度
void RS485_Receive_Data(u8 *buf,u8 *len)
{
    u8 rxlen=RS485_RX_CNT;
    u8 i=0;
    *len=0;                //默认为0
    delay_ms(10);        //等待10ms,连续超过10ms没有接收到一个数据,则认为接收结束
    if(rxlen==RS485_RX_CNT&&rxlen)//接收到了数据,且接收完成了
    {
        for(i=0;i<rxlen;i++)
        {
            buf[i]=RS485_RX_BUF[i];    
        }        
        *len=RS485_RX_CNT;    //记录本次数据长度
        RS485_RX_CNT=0;        //清零
    }
}
RS485.h
#ifndef __RS485_H
#define __RS485_H             
#include "sys.h"                                       
//////////////////////////////////////////////////////////////////////////////////     
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK战舰STM32开发板
//RS485驱动 代码       
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//修改日期:2012/9/9
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2009-2019
//All rights reserved                                      
//////////////////////////////////////////////////////////////////////////////////
                    
extern u8 RS485_RX_BUF[64];         //接收缓冲,最大64个字节
extern u8 RS485_RX_CNT;               //接收到的数据长度

//模式控制
#define RS485_TX_EN        PAout(8)    //485模式控制.0,接收.1,发送.
//如果想串口中断接收,请不要注释以下宏定义
#define EN_USART1_RX     1            //0,不接收;1,接收.




void RS485_Init(u32 bound);
void RS485_Send_Data(u8 *buf,u8 len);
void RS485_Receive_Data(u8 *buf,u8 *len);


#endif       


运行结果及报错内容

代码没报错。电脑打开串口软件接收不到单片机发送的数据

我的解答思路和尝试过的方法

用表笔测过未通电下所有线路都通。通电后485芯片的DI引脚电压变化很小,很短时间内在2.7V和2.8V之间跳变,不符合我的预期,感觉问题出在这里

我想要达到的结果

实现PC与单片机通过485串口通信

  • 写回答

1条回答 默认 最新

  • cyjbj 2022-11-26 11:43
    关注

    先把你的rxd和txd 自环一下看看单片机串口收发是否正常,看看txd的的波形正确与否,没有问题再调485,主要就是你的rs485_en控制了

    评论

报告相同问题?

问题事件

  • 创建了问题 11月25日

悬赏问题

  • ¥20 搭建pt1000三线制高精度测温电路
  • ¥15 使用Jdk8自带的算法,和Jdk11自带的加密结果会一样吗,不一样的话有什么解决方案,Jdk不能升级的情况
  • ¥15 画两个图 python或R
  • ¥15 在线请求openmv与pixhawk 实现实时目标跟踪的具体通讯方法
  • ¥15 八路抢答器设计出现故障
  • ¥15 opencv 无法读取视频
  • ¥15 按键修改电子时钟,C51单片机
  • ¥60 Java中实现如何实现张量类,并用于图像处理(不运用其他科学计算库和图像处理库))
  • ¥20 5037端口被adb自己占了
  • ¥15 python:excel数据写入多个对应word文档