portserial.c 9.68 KB
/*
 * FreeModbus Libary: BARE Port
 * Copyright (C) 2006 Christian Walter <wolti@sil.at>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * File: $Id: portserial.c,v 1.1 2006/08/22 21:35:13 wolti Exp $
 */
#include "port.h"

/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"

/* ----------------------- static functions ---------------------------------*/
 void prvvUARTTxReadyISR( void );
 void prvvUARTRxISR( void );

/* ----------------------- Start implementation -----------------------------*/


void
vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )
{
    /* If xRXEnable enable serial receive interrupts. If xTxENable enable
     * transmitter empty interrupts.
     */
    if(TRUE==xRxEnable)
	{
//#ifdef USE_UART3_FOR_MONITOR
		USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
	   GPIO_ResetBits(GPIOD,GPIO_Pin_4);	  //接收
//#else
//        USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
//        GPIO_ResetBits(GPIOF, GPIO_Pin_5);
//#endif
	}
	else
	{
//#ifdef USE_UART3_FOR_MONITOR
		USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);	
		GPIO_SetBits(GPIOD,GPIO_Pin_4);	  //发送
//#else
//		USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
//		GPIO_SetBits(GPIOF, GPIO_Pin_5);
//#endif
		
	}

	if(TRUE==xTxEnable)
	{
//#ifdef USE_UART3_FOR_MONITOR
		USART_ITConfig(USART2, USART_IT_TXE, ENABLE);
//#else
//    	USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
//#endif
	}
	else
	{
//#ifdef USE_UART3_FOR_MONITOR
		USART_ITConfig(USART2, USART_IT_TXE, DISABLE);
//#else
//		USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
//#endif
	}
}

//串口初始化

BOOL
xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE); //使能GPIOF时钟
    
    GPIO_ResetBits(GPIOD, GPIO_Pin_4);//RS485方向选择   读
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_4;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;//普通输出模式
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_DOWN;
    GPIO_Init(GPIOD, &GPIO_InitStructure); 
  
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);//使能USART3时钟
 
	//串口3对应引脚复用映射
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_USART2); //GPIOD8复用为USART3
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource6, GPIO_AF_USART2); //GPIOD9复用为USART3
	
	
    	//USART3端口配置
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	//速度50MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
    GPIO_Init(GPIOD,&GPIO_InitStructure);
	
	
    
    USART_InitStructure.USART_BaudRate   = 115200;//波特率设置

    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为9位数据格式
    
	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); //初始化串口3
	
    	//Usart3 NVIC 配置
    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;//串口3中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 10;//抢占优先级10
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;		
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器?  
    
    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);  //接收
	USART_Cmd(USART2, ENABLE);		

	USART_ClearFlag(USART2, USART_FLAG_TC);  
	
//#else
//	
//	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE); //使能GPIOF时钟
//	GPIO_ResetBits(GPIOF, GPIO_Pin_5);//RS485方向选择
//	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_5;
//	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;//普通输出模式
//	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
//	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
//	GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_DOWN;
//	GPIO_Init(GPIOF, &GPIO_InitStructure);  
//    	
//    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟
//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1时钟
// 
//	//串口1对应引脚复用映射
//	GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //GPIOA9复用为USART1
//	GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //GPIOA10复用为USART1
//	
//	//USART1端口配置
//    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //GPIOA9与GPIOA10
//	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
//	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	//速度50MHz
//	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
//	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
//	GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA9,PA10

//	//Usart1 NVIC 配置
//    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断通道
//	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 10;//抢占优先级3
//	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;		//子优先级3
//	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
//	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器、    
//    
//    //USART1 初始化设置
//	USART_InitStructure.USART_BaudRate   = 115200;//波特率设置
//	USART_InitStructure.USART_WordLength = USART_WordLength_9b;//字长为8位数据格式
//	USART_InitStructure.USART_StopBits   = USART_StopBits_1;//一个停止位
//	USART_InitStructure.USART_Parity     = USART_Parity_Even;//无奇偶校验位
//	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
//	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式
//    USART_Init(USART1, &USART_InitStructure); //初始化串口1
//    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);  //接收
//	USART_Cmd(USART1, ENABLE);		

//	USART_ClearFlag(USART1, USART_FLAG_TC);     
//    
//    USART_Cmd(USART1, ENABLE);  //使能串口1
///* 485 引脚的初始化 */   
//#endif
    return TRUE;
}
//发送一个字节
BOOL
xMBPortSerialPutByte( CHAR ucByte )
{
    /* Put a byte in the UARTs transmit buffer. This function is called
     * by the protocol stack if pxMBFrameCBTransmitterEmpty( ) has been
     * called. */
//#ifdef USE_UART3_FOR_MONITOR
  GPIO_SetBits(GPIOD, GPIO_Pin_4);   //发送
     
  USART_SendData(USART2, ucByte);

  while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET)
  {
  }  
 GPIO_ResetBits(GPIOD, GPIO_Pin_4);  //接收
//#else
//    GPIO_SetBits(GPIOF, GPIO_Pin_5);
//    USART_SendData(USART1, ucByte);

//    while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
//    {
//    }
//    GPIO_ResetBits(GPIOF, GPIO_Pin_5);
//#endif
    return TRUE;
}
//接收一个字节

BOOL
xMBPortSerialGetByte( CHAR * pucByte )
{
    /* Return the byte in the UARTs receive buffer. This function is called
     * by the protocol stack after pxMBFrameCBByteReceived( ) has been called.
     */
//#ifdef USE_UART3_FOR_MONITOR
	*pucByte =(unsigned char) USART_ReceiveData(USART2);
//#else
//     *pucByte =(unsigned char) USART_ReceiveData(USART1);
//#endif
    return TRUE;
}

/* Create an interrupt handler for the transmit buffer empty interrupt
 * (or an equivalent) for your target processor. This function should then
 * call pxMBFrameCBTransmitterEmpty( ) which tells the protocol stack that
 * a new character can be sent. The protocol stack will then call 
 * xMBPortSerialPutByte( ) to send the character.
 */
void prvvUARTTxReadyISR( void )
{
    pxMBFrameCBTransmitterEmpty(  );
}

/* Create an interrupt handler for the receive interrupt for your target
 * processor. This function should then call pxMBFrameCBByteReceived( ). The
 * protocol stack will then call xMBPortSerialGetByte( ) to retrieve the
 * character.
 */
void prvvUARTRxISR( void )
{
    pxMBFrameCBByteReceived(  );
}

//串口3 的中断函数
//#ifdef USE_UART3_FOR_MONITOR

//void USART2_IRQHandler(void)
//{
//    CPU_SR_ALLOC();
//    CPU_CRITICAL_ENTER();
//    OSIntEnter();                                          
//    CPU_CRITICAL_EXIT();
//    
//	if(USART_GetITStatus(USART2, USART_IT_RXNE) == SET)
//	{
//		prvvUARTRxISR();
//		USART_ClearITPendingBit(USART2, USART_IT_RXNE);
//	}

//	if(USART_GetITStatus(USART2, USART_IT_TXE) == SET)
//	{
//		prvvUARTTxReadyISR();
// 		USART_ClearITPendingBit(USART2, USART_IT_TXE);
//	}
//    OSIntExit(); 
//}

//#else
//void USART1_IRQHandler(void)
//{
//	CPU_SR_ALLOC();
//    CPU_CRITICAL_ENTER();
//    OSIntEnter();                                          
//    CPU_CRITICAL_EXIT();
//    
//	if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
//	{		
//		prvvUARTRxISR();
//		USART_ClearITPendingBit(USART1, USART_IT_RXNE);
//	}

//	if(USART_GetITStatus(USART1, USART_IT_TXE) == SET)
//	{
//		prvvUARTTxReadyISR();
//        
// 		USART_ClearITPendingBit(USART1, USART_IT_TXE);
//	}
//    OSIntExit(); 
//   
//}
//#endif