2013-11-07 11:34:23 +08:00
/*
* FreeModbus Libary : STM32 Port
* Copyright ( C ) 2013 Armink < armink . ztl @ gmail . com >
*
* 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_m . c , v 1.60 2013 / 08 / 13 15 : 07 : 05 Armink add Master Functions $
*/
# include "port.h"
/* ----------------------- Modbus includes ----------------------------------*/
# include "mb.h"
# include "mbport.h"
2013-11-25 11:57:59 +08:00
# if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
2013-11-07 11:34:23 +08:00
/* ----------------------- static functions ---------------------------------*/
static void prvvUARTTxReadyISR ( void ) ;
static void prvvUARTRxISR ( void ) ;
/* ----------------------- Start implementation -----------------------------*/
void vMBMasterPortSerialEnable ( BOOL xRxEnable , BOOL xTxEnable )
{
if ( xRxEnable )
{
2013-12-28 09:45:05 +08:00
/* 485ͨ<35> <CDA8> ʱ<EFBFBD> <CAB1> <EFBFBD> ȴ<EFBFBD> <C8B4> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> λ<EFBFBD> Ĵ<EFBFBD> <C4B4> <EFBFBD> <EFBFBD> е <EFBFBD> <D0B5> <EFBFBD> <EFBFBD> ݷ<EFBFBD> <DDB7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ɺ<EFBFBD> <C9BA> <EFBFBD> <EFBFBD> <EFBFBD> ȥʹ <C8A5> <CAB9> 485<38> Ľ<EFBFBD> <C4BD> ա <EFBFBD> ʧ<EFBFBD> <CAA7> 485<38> ķ<EFBFBD> <C4B7> <EFBFBD>
* <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʱ ʱ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Խ <EFBFBD> <EFBFBD> <EFBFBD> CPU <EFBFBD> <EFBFBD> Ƶ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڲ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʵ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* */
vMBDelay ( 1000 ) ;
2013-11-07 11:34:23 +08:00
MASTER_RS485_RECEIVE_MODE ;
USART_ITConfig ( USART2 , USART_IT_RXNE , ENABLE ) ;
}
else
{
MASTER_RS485_SEND_MODE ;
USART_ITConfig ( USART2 , USART_IT_RXNE , DISABLE ) ;
}
if ( xTxEnable )
{
USART_ITConfig ( USART2 , USART_IT_TXE , ENABLE ) ;
}
else
{
USART_ITConfig ( USART2 , USART_IT_TXE , DISABLE ) ;
}
}
void vMBMasterPortClose ( void )
{
USART_ITConfig ( USART2 , USART_IT_TXE | USART_IT_RXNE , DISABLE ) ;
USART_Cmd ( USART2 , DISABLE ) ;
}
//Ĭ<> <C4AC> һ <EFBFBD> <D2BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> 2 <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ʿ<EFBFBD> <CABF> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ż<EFBFBD> <C5BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
BOOL xMBMasterPortSerialInit ( UCHAR ucPORT , ULONG ulBaudRate , UCHAR ucDataBits ,
eMBParity eParity )
{
GPIO_InitTypeDef GPIO_InitStructure ;
USART_InitTypeDef USART_InitStructure ;
NVIC_InitTypeDef NVIC_InitStructure ;
//======================ʱ<> ӳ<EFBFBD> ʼ <EFBFBD> <CABC> =======================================
RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB , ENABLE ) ;
RCC_APB1PeriphClockCmd ( RCC_APB1Periph_USART2 , ENABLE ) ;
//======================IO<49> <4F> ʼ <EFBFBD> <CABC> =======================================
//USART2_TX
GPIO_InitStructure . GPIO_Speed = GPIO_Speed_50MHz ;
GPIO_InitStructure . GPIO_Mode = GPIO_Mode_AF_PP ;
GPIO_InitStructure . GPIO_Pin = GPIO_Pin_2 ;
GPIO_Init ( GPIOA , & GPIO_InitStructure ) ;
//USART2_RX
GPIO_InitStructure . GPIO_Mode = GPIO_Mode_IN_FLOATING ;
GPIO_InitStructure . GPIO_Pin = GPIO_Pin_3 ;
GPIO_Init ( GPIOA , & GPIO_InitStructure ) ;
//<2F> <> <EFBFBD> <EFBFBD> 485<38> <35> <EFBFBD> ͺ ͽ<CDBA> <CDBD> <EFBFBD> ģʽ
// TODO <20> <> ʱ<EFBFBD> <CAB1> дB13 <20> <> ֮<EFBFBD> <D6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD>
GPIO_InitStructure . GPIO_Mode = GPIO_Mode_Out_PP ;
GPIO_InitStructure . GPIO_Pin = GPIO_Pin_13 ;
GPIO_Init ( GPIOB , & GPIO_InitStructure ) ;
//======================<3D> <> <EFBFBD> ڳ<EFBFBD> ʼ <EFBFBD> <CABC> =======================================
USART_InitStructure . USART_BaudRate = ulBaudRate ;
//<2F> <> <EFBFBD> <EFBFBD> У <EFBFBD> <D0A3> ģʽ
switch ( eParity )
{
case MB_PAR_NONE : //<2F> <> У <EFBFBD> <D0A3>
USART_InitStructure . USART_Parity = USART_Parity_No ;
USART_InitStructure . USART_WordLength = USART_WordLength_8b ;
break ;
case MB_PAR_ODD : //<2F> <> У <EFBFBD> <D0A3>
USART_InitStructure . USART_Parity = USART_Parity_Odd ;
USART_InitStructure . USART_WordLength = USART_WordLength_9b ;
break ;
case MB_PAR_EVEN : //żУ <C5BC> <D0A3>
USART_InitStructure . USART_Parity = USART_Parity_Even ;
USART_InitStructure . USART_WordLength = USART_WordLength_9b ;
break ;
default :
return FALSE ;
}
USART_InitStructure . USART_StopBits = USART_StopBits_1 ;
USART_InitStructure . USART_HardwareFlowControl =
USART_HardwareFlowControl_None ;
USART_InitStructure . USART_Mode = USART_Mode_Rx | USART_Mode_Tx ;
if ( ucPORT ! = 2 )
return FALSE ;
ENTER_CRITICAL_SECTION ( ) ; //<2F> <> ȫ<EFBFBD> <C8AB> <EFBFBD> ж<EFBFBD>
USART_Init ( USART2 , & USART_InitStructure ) ;
USART_ITConfig ( USART2 , USART_IT_RXNE , ENABLE ) ;
USART_Cmd ( USART2 , ENABLE ) ;
//=====================<3D> жϳ <D0B6> ʼ <EFBFBD> <CABC> ======================================
//<2F> <> <EFBFBD> <EFBFBD> NVIC<49> <43> <EFBFBD> ȼ<EFBFBD> <C8BC> <EFBFBD> <EFBFBD> <EFBFBD> ΪGroup2<70> <32> 0-3<> <33> ռ ʽ <D5BC> <CABD> <EFBFBD> ȼ<EFBFBD> <C8BC> <EFBFBD> 0-3<> <33> <EFBFBD> <EFBFBD> Ӧʽ <D3A6> <CABD> <EFBFBD> ȼ<EFBFBD>
NVIC_PriorityGroupConfig ( NVIC_PriorityGroup_2 ) ;
NVIC_InitStructure . NVIC_IRQChannel = USART2_IRQn ;
NVIC_InitStructure . NVIC_IRQChannelPreemptionPriority = 0 ;
NVIC_InitStructure . NVIC_IRQChannelSubPriority = 0 ;
NVIC_InitStructure . NVIC_IRQChannelCmd = ENABLE ;
NVIC_Init ( & NVIC_InitStructure ) ;
EXIT_CRITICAL_SECTION ( ) ; //<2F> <> ȫ<EFBFBD> <C8AB> <EFBFBD> ж<EFBFBD>
return TRUE ;
}
BOOL xMBMasterPortSerialPutByte ( CHAR ucByte )
{
USART_SendData ( USART2 , ucByte ) ;
return TRUE ;
}
BOOL xMBMasterPortSerialGetByte ( CHAR * pucByte )
{
* pucByte = USART_ReceiveData ( USART2 ) ;
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 )
{
pxMBMasterFrameCBTransmitterEmpty ( ) ;
}
/*
* 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 )
{
pxMBMasterFrameCBByteReceived ( ) ;
}
/*******************************************************************************
* Function Name : USART2_IRQHandler
* Description : This function handles USART2 global interrupt request .
* Input : None
* Output : None
* Return : None
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void USART2_IRQHandler ( void )
{
rt_interrupt_enter ( ) ;
2014-02-13 16:17:13 +08:00
//<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
if ( USART_GetFlagStatus ( USART2 , USART_FLAG_ORE ) = = SET )
{
prvvUARTRxISR ( ) ;
}
2013-11-07 11:34:23 +08:00
//<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> ж<EFBFBD>
if ( USART_GetITStatus ( USART2 , USART_IT_RXNE ) = = SET )
{
USART_ClearITPendingBit ( USART2 , USART_IT_RXNE ) ;
prvvUARTRxISR ( ) ;
}
//<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> ж<EFBFBD>
if ( USART_GetITStatus ( USART2 , USART_IT_TXE ) = = SET )
{
prvvUARTTxReadyISR ( ) ;
}
rt_interrupt_leave ( ) ;
}
# endif