OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3416|回复: 1

485实验整合版:F103战舰USART2之485通讯

[复制链接]
回帖奖励 2 金钱 回复本帖可获得 2 金钱奖励! 每人限 1 次(中奖概率 20%)

81

主题

269

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
449
金钱
449
注册时间
2014-8-11
在线时间
86 小时
发表于 2016-4-17 11:03:47 | 显示全部楼层 |阅读模式
实验内容:
      stm32串口2的485通讯测试实验
实验平台:
      F103ZET6战舰开发板;千目电子USB-RS485转换器;串口调试工具
硬件连接:
      开发板上P9跳帽选择PA3-48R  PA2-48T;
      转换器的A接开发板A   转换器的B接开发板B(以实际模块的定义为准)
485程序概要:
1、头文件
#ifndef __RS485_H
#define __RS485_H            
#include "sys.h"                                       
//////////////////////////////////////////////////////////////////////////////////     
//本程序只供学习使用,如有错误敬请见谅
//Author:SVS_LEE
//////////////////////////////////////////////////////////////////////////////////
//模式控制
#define RS485_TX_EN        PGout(9)                                   //485模式控制.0,接收;1,发送.
//如果想串口中断接收,请不要注释以下宏定义
#define EN_USART2_RX     1                                              //0,不接收;1,接收.
#define USART2_MAX_RECV_LEN        600                           //最大接收缓存字节数
#define USART2_MAX_SEND_LEN        600                          //最大发送缓存字节数
extern u8  USART2_RX_BUF[USART2_MAX_RECV_LEN];         //接收缓冲,最大USART2_MAX_RECV_LEN字节
extern u8  USART2_TX_BUF[USART2_MAX_SEND_LEN];        //发送缓冲,最大USART2_MAX_SEND_LEN字节
extern vu16 USART2_RX_STA;                                          //接收数据状态
void RS485_Init(u32 bound);                                             //串口2初始化
void u2_printf(char* fmt,...);                                            //串口2的printf功能
#endif   

2、c文件
//////////////////////////////////////////////////////////////////////////////////     
//本程序只供学习使用,如有错误敬请见谅
//Author:SVS_LEE
//////////////////////////////////////////////////////////////////////////////////
#include "delay.h"
#include "stdarg.h"         
#include "stdio.h"         
#include "string.h"     
#include "timer.h"
//#include "includes.h"
#include "rs485.h"
#ifdef EN_USART2_RX       //如果使能了接收
//串口接收缓存区     
u8 USART2_RX_BUF[USART2_MAX_RECV_LEN];                 //接收缓冲,最大USART2_MAX_RECV_LEN个字节.
u8  USART2_TX_BUF[USART2_MAX_SEND_LEN];             //发送缓冲,最大USART2_MAX_SEND_LEN字节
//通过判断接收连续2个字符之间的时间差不大于10ms来决定是不是一次连续的数据.
//如果2个字符接收间隔超过10ms,则认为不是1次连续数据.也就是超过10ms没有接收到
//任何数据,则表示此次接收完毕.
//接收到的数据状态
//[15]:0,没有接收到数据;1,接收到了一批数据.
//[14:0]:接收到的数据长度
vu16 USART2_RX_STA=0;

void USART2_IRQHandler(void)
{
    u8 res;
//    OSIntEnter();         
    if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)//接收到数据
    {     
        res =USART_ReceiveData(USART2);         
        if((USART2_RX_STA&(1<<15))==0)//接收完的一批数据,还没有被处理,则不再接收其他数据
        {
            if(USART2_RX_STA<USART2_MAX_RECV_LEN)    //还可以接收数据
            {
                TIM_SetCounter(TIM7,0);//计数器清空                          //计数器清空
                if(USART2_RX_STA==0)                 //使能定时器7的中断
                {
                    TIM_Cmd(TIM7,ENABLE);//使能定时器7
                }
                USART2_RX_BUF[USART2_RX_STA++]=res;    //记录接收到的值     
            }else
            {
                USART2_RX_STA|=1<<15;                //强制标记接收完成
            }
        }
    }
//    OSIntExit();                                                               
}  
#endif
                                       
//初始化IO 串口2
//pclk1CLK1时钟频率(Mhz)
//bound:波特率      
void RS485_Init(u32 bound)
{  
    GPIO_InitTypeDef GPIO_InitStructure;
      USART_InitTypeDef USART_InitStructure;
     NVIC_InitTypeDef NVIC_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOG, ENABLE);//使能GPIOA,G时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);//使能USART2时钟
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;                 //PG9端口配置
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;          //推挽输出
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_Init(GPIOG, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;    //PA2
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    //复用推挽
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA3
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);  
    RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2,ENABLE);//复位串口2
    RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2,DISABLE);//停止复位
#ifdef EN_USART2_RX              //如果使能了接收
    USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;
    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(USART2, &USART_InitStructure); ; //初始化串口
    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; //使能串口2中断
    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(USART2, USART_IT_RXNE, ENABLE);//开启中断
    USART_Cmd(USART2, ENABLE);                    //使能串口     
    TIM7_Int_Init(99,7199);        //10ms中断
    USART2_RX_STA=0;        //清零
    TIM_Cmd(TIM7,DISABLE);            //关闭定时器7
#endif
RS485_TX_EN=0;            //默认为接收模式
}


//串口2,printf 函数
//确保一次发送数据不超过USART2_MAX_SEND_LEN字节
void u2_printf(char* fmt,...)  
{  
    u16 i,j;
    va_list ap;
    va_start(ap,fmt);
    vsprintf((char*)USART2_TX_BUF,fmt,ap);
    va_end(ap);
    i=strlen((const char*)USART2_TX_BUF);        //此次发送数据的长度
    RS485_TX_EN=1;
    for(j=0;j<i;j++)                            //循环发送数据
    {
      while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET); //循环发送,直到发送完毕   
        USART_SendData(USART2,USART2_TX_BUF[j]);
    }
    while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);//在这里加了这一句,测试发现没有这一句最后一个
    //字节无法发送出去,因为在关闭发送模式之前务必要确保都成功发送出去了,232模式下不加这一句应该没问题
    RS485_TX_EN=0;
}

























     

485实验.rar

2.27 MB, 下载次数: 166

我是一只菜鸟,但我会大鹏展翅
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

9

主题

507

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3347
金钱
3347
注册时间
2013-4-10
在线时间
333 小时
发表于 2016-4-17 11:51:00 | 显示全部楼层
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-17 03:56

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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