查看: 1715|回复: 0
打印 上一主题 下一主题

STM32实现485通信(测试简易485转232模块)

[复制链接]
跳转到指定楼层
沙发
发表于 2016-6-20 19:29:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
STM32学习笔记4 竹天笑

此学习笔记的主要目的是测试一下我刚焊接的简易485转232模块,由于是初学者,当初在买开发板的时候没有想到考虑到485实验。485实验需要一对开发板来测试,或者一个485转232模块接电脑用串口调试助手测试。485实验一直搁置而没有做,面临工作需要,一直想做一下。而今天在逛论坛的时候,看到下图眼睛都冒光了,精神顿时来了,一吃完晚饭就迫不及待的测试起来。(先声明,本人刚开始工作,从未接触485通信,因此本文仅供参考,肯定出现很多错误,请大神指正。)

简易的485转232模块
此图来自阿莫电子论坛的帖子《超级简单的RS485转RS232电路》
本人焊接的实物图如下:

左边是我买的USB转232,右边为我焊接的232转485
硬件搭建完毕,当然要用程序测试才行,使用的开发板是红牛三代,有关485接口的电路图如下:

接下来上程序(程序简单流程:1、串口调试助手发数据->usb转232模块->232转485模块->开发板485接口,2、然后将接收的数据发送出来->232转485模块-> usb转232模块->串口调试助手显示。)
初始化:很晚了,明天还要上班就不注解了(类似注解请看本人上一篇帖子: STM32实现USART+DMA接收未知长度的数据和发送http://www.amobbs.com/thread-5486343-1-1.html
void USART_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  USART_InitTypeDef USART_InitStructure;

  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB| RCC_APB2Periph_AFIO , ENABLE);
  RCC_APB1PeriphClockCmd( RCC_APB1Periph_USART3 , ENABLE);
        
  /*
  *  USART3_TX -> PB10 , USART3_RX -> PB11 , 485_DIR -> PB2
  */                                
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;                 
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);        
            
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;                 
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);                  

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;               
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  USART_InitStructure.USART_BaudRate = 9600;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  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(USART3, &USART_InitStructure);
// USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
  //USART_DMACmd(USART3, USART_DMAReq_Rx, ENABLE);
  USART_ITConfig(USART3, USART_IT_IDLE , ENABLE);//开启空闲,帧错,噪声,校验错中断

  USART_Cmd(USART3, ENABLE);  
  
  USART_ClearFlag(USART3,USART_FLAG_TC);
  
  DMA_InitTypeDef DMA_InitStructure;
  /* DMA clock enable */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//DMA1
  
  /* DMA1 Channel3 (triggered by USART3 Rx event) Config */
  DMA_DeInit(DMA1_Channel3);  
  DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40004804;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART_RECEIVE_DATA;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = 512;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel3, &DMA_InitStructure);
  
  DMA_ITConfig(DMA1_Channel3, DMA_IT_TC, ENABLE);
  DMA_ITConfig(DMA1_Channel3, DMA_IT_TE, ENABLE);
  
  /* Enable USART2 DMA RX request */
  USART_DMACmd(USART3, USART_DMAReq_Rx, ENABLE);
  
  DMA_Cmd(DMA1_Channel3, ENABLE);
  
  NVIC_InitTypeDef NVIC_InitStructure;
  /* Configure one bit for preemption priority */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  
  NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);  
  
  //Enable DMA Channel4 Interrupt
  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}
主程序:好像什么都没有,呵呵,数据接收与发送都在中断中实现。数据接收使用DMA接收,并使用USART空闲总线中断处理接收的数据。
int main(void)
{
        USART_Configuration();
    printf("485to232测试\r\n");
    /* Infinite loop */
    while (1){
    }
}
中断服务函数:下面我加红部分是232通信与485通信不一致的地方。485通信的速度是无法与232相比的。
void USART3_IRQHandler(void)
{
        u16 DATA_LEN;
        u16 i;
        if(USART_GetITStatus(USART3, USART_IT_IDLE) != RESET)
    {
                DMA_Cmd(DMA1_Channel3, DISABLE);//关闭DMA,防止处理其间有数据
                  DATA_LEN=512-DMA_GetCurrDataCounter(DMA1_Channel3);
//由于485是半双工的,所以要么只能接,要么只能发。
                DIR485_Send();//485发送打开
                for(i=0;i<DATA_LEN;i++)
                {
                         USART_SendData(USART3, USART_RECEIVE_DATA);
                        Delay(10000);//此句非常重要,不知道是我这个简易模块的问题,还是485通信速度的问题,删除就出错。
                        while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
                }
                DIR485_Receive();//485发送完,就必须打开        485接收
                DMA_ClearFlag(DMA1_FLAG_GL3 | DMA1_FLAG_TC3 | DMA1_FLAG_TE3 | DMA1_FLAG_HT3);//清标志
                DMA1_Channel3->CNDTR = 512;//重装填
                DMA_Cmd(DMA1_Channel3, ENABLE);//处理完,重开DMA
                //读SR后读DR清除Idle
                i = USART3->SR;
                i = USART3->DR;
        }
        if(USART_GetITStatus(USART3, USART_IT_PE | USART_IT_FE | USART_IT_NE) != RESET)//出错
        {
                USART_ClearITPendingBit(USART3, USART_IT_PE | USART_IT_FE | USART_IT_NE);
        }
          USART_ClearITPendingBit(USART3, USART_IT_IDLE);
}

void DMA1_Channel3_IRQHandler(void)
{
  DMA_ClearITPendingBit(DMA1_IT_TC3);
  DMA_ClearITPendingBit(DMA1_IT_TE3);
  DMA_Cmd(DMA1_Channel3, DISABLE);//关闭DMA,防止处理其间有数据
  DMA1_Channel3->CNDTR = 512;//重装填
  DMA_Cmd(DMA1_Channel3, ENABLE);//处理完,重开DMA
}
结束,呵呵,测试结果,简易模块非常不错,肯定不能用于产品,但是做测试完全是可行的。唯一不足的就是速度上不行。今天只试了9600波特率,明天继续测试,今天PIC开发板测试没通过,打算用我的PIC开发板测试。

程序包下载地址:http://115.com/file/e7csjmze#
USART_485(测试485转232模块).rar
说明文档下载地址:http://115.com/file/anpjl2av#
STM32实现485通信(测试简易485转232模块).doc

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入中科因仑

本版积分规则

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