4
0
mirror of https://github.com/armink/FreeModbus_Slave-Master-RTT-STM32.git synced 2025-01-26 16:37:10 +08:00
armink f16856e34c 1、【增加】FreeModbus从机,保持寄存器测试没问题,其余功能有待测试。3个IDE编译运行后,获取的CPU利用率不一致问题,有待进一步解决
2、【修改】IAR、Keil工程中启动文件,及部分CM3相关的文件,解决之前工程配置遗留下来的问题
3、【增加】RTT的CPU利用率更新至Modbus保持寄存器的功能

Signed-off-by: armink <armink.ztl@gmail.com>
2013-08-03 11:39:51 +08:00

191 lines
6.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* FreeModbus Libary: LPC214X Port
* Copyright (C) 2007 Tiago Prado Lone <tiago@maxwellbohr.com.br>
*
* 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 2007/04/24 23:15:18 wolti Exp $
*/
#include "port.h"
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"
/* ----------------------- static functions ---------------------------------*/
static void prvvUARTTxReadyISR(void);
static void prvvUARTRxISR(void);
/* ----------------------- Start implementation -----------------------------*/
void vMBPortSerialEnable(BOOL xRxEnable, BOOL xTxEnable)
{
if (xRxEnable)
{
RS485_RECEIVE_MODE;
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
}
else
{
RS485_SEND_MODE;
USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
}
if (xTxEnable)
{
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
}
else
{
USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
}
}
void vMBPortClose(void)
{
USART_ITConfig(USART1, USART_IT_TXE | USART_IT_RXNE, DISABLE);
USART_Cmd(USART1, DISABLE);
}
//默认一个从机 串口1 波特率可设置 奇偶检验可设置
BOOL xMBPortSerialInit(UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits,
eMBParity eParity)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
//======================时钟初始化=======================================
RCC_APB2PeriphClockCmd(
RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_USART1,
ENABLE);
//======================IO初始化=======================================
//USART1_TX
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//USART1_RX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//配置485发送和接收模式
// TODO 暂时先写B13 等之后组网测试时再修改
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//======================串口初始化=======================================
USART_InitStructure.USART_BaudRate = ulBaudRate;
//设置校验模式
switch (eParity)
{
case MB_PAR_NONE: //无校验
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
break;
case MB_PAR_ODD: //奇校验
USART_InitStructure.USART_Parity = USART_Parity_Odd;
USART_InitStructure.USART_WordLength = USART_WordLength_9b;
break;
case MB_PAR_EVEN: //偶校验
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 > 1)
return FALSE;
ENTER_CRITICAL_SECTION(); //关全局中断
USART_Init(USART1, &USART_InitStructure);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_Cmd(USART1, ENABLE);
//=====================中断初始化======================================
//设置NVIC优先级分组为Group20-3抢占式优先级0-3的响应式优先级
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
EXIT_CRITICAL_SECTION(); //开全局中断
return TRUE;
}
BOOL xMBPortSerialPutByte(CHAR ucByte)
{
USART_SendData(USART1, ucByte);
return TRUE;
}
BOOL xMBPortSerialGetByte(CHAR * pucByte)
{
*pucByte = USART_ReceiveData(USART1);
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();
}
/*******************************************************************************
* Function Name : USART1_IRQHandler
* Description : This function handles USART1 global interrupt request.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void USART1_IRQHandler(void)
{
rt_interrupt_enter();
//接收中断
if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
{
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
prvvUARTRxISR();
}
//发送中断
if (USART_GetITStatus(USART1, USART_IT_TXE) == SET)
{
USART_ClearITPendingBit(USART1, USART_IT_TC);
prvvUARTTxReadyISR();
}
rt_interrupt_leave();
}