forked from SZV10X_Software/SZV103_FM33A0xxEV_SiZhu

周巍
2024-04-11 91ef77c00ed797b1048c5187f416e351e646a009
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
/*
 * 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"
#include "RS485.h"
#include "sizhu_communication_protocol.h"
/* ----------------------- static functions ---------------------------------*/
static void prvvUARTTxReadyISR(void);
static void prvvUARTRxISR(void);
 
/* ----------------------- Start implementation -----------------------------*/
 
/**
  * @brief  ´®¿ÚÊÕ·¢¿ª¹Øº¯Êý
  * @param  ÎÞ
  * @retval ÎÞ
  */
void vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )
{
    /* If xRXEnable enable serial receive interrupts. If xTxENable enable
     * transmitter empty interrupts.
     */
    USART_ITConfig(UARTNUM,USART_IT_RXNE,(xRxEnable==TRUE)?ENABLE:DISABLE);
    
    USART_ITConfig(UARTNUM,USART_IT_TXE,(xTxEnable==TRUE)?ENABLE:DISABLE);
}
 
/**
  * @brief  ´®¿Ú³õʼ»¯º¯Êý
  * @param  ÎÞ
  * @retval ×´Ì¬±êÖ¾
  */
BOOL xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    DMA_InitTypeDef DMA_InitStructure;
    
    //ʹÄÜGPIOºÍUARTʱÖÓ
    RCC_APB2PeriphClockCmd(APB_GPIO_GROUP , ENABLE);
    RCC_APB1PeriphClockCmd( RCC_APB_Periph_UART, ENABLE);
 
 
    USART_DeInit(UARTNUM);
 
    GPIO_InitStructure.GPIO_Pin = V_RS485_TXD_EN_PIN_NUM;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(V_RS485_TXD_EN_PIN_GROUP, &GPIO_InitStructure);
    
 
    GPIO_InitStructure.GPIO_Pin = V_RS485_RXD_EN_PIN_NUM;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(V_RS485_RXD_EN_PIN_GROUP, &GPIO_InitStructure);    
    
    
    GPIO_InitStructure.GPIO_Pin = V_RS485_CON_EN_PIN_NUM;                
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;          
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(V_RS485_CON_EN_PIN_GROUP, &GPIO_InitStructure);
 
    
    //³õʼ»¯USART
    USART_InitStructure.USART_BaudRate = ulBaudRate;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    
    //È·¶¨Ð£Ñ鷽ʽ
    if(eParity == MB_PAR_NONE)
    {
        USART_InitStructure.USART_Parity = USART_Parity_No;
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    }
    else if(eParity == MB_PAR_ODD)
    {
        USART_InitStructure.USART_Parity = USART_Parity_Odd;
        USART_InitStructure.USART_WordLength = USART_WordLength_9b;
    }
    else
    {
        USART_InitStructure.USART_Parity = USART_Parity_Even;
        USART_InitStructure.USART_WordLength = USART_WordLength_9b;
    }
    
    USART_Init(UARTNUM, &USART_InitStructure);
    
    
 
//******************************************************************************************//
 
    
    RCC_AHBPeriphClockCmd(RCC_AHB_Preiph_UART_DMA, ENABLE);
    
    DMA_DeInit(DMA_RS485_Channel); 
        
    DMA_InitStructure.DMA_PeripheralBaseAddr =(u32)(&(UARTNUM->DR)) ;     /*ÉèÖÃDMAÔ´£º´®¿ÚÊý¾Ý¼Ä´æÆ÷µØÖ·*/  
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)(rs485_receive_g.RS485_BUF);/*ÄÚ´æµØÖ·(Òª´«ÊäµÄ±äÁ¿µÄÖ¸Õë)*/    
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;/*·½Ïò£º´ÓË«Ïòµ½ÄÚ´æ*/
    DMA_InitStructure.DMA_BufferSize = REC_LENGTH;/*´«Êä´óСDMA_BufferSize=SENDBUFF_SIZE*/   
    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;    /*ÄÚ´æÊý¾Ýµ¥Î» 8bit*/ 
    //DMA_InitStructure.DMA_Mode = DMA_Mode_Normal ;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;    /*DMAģʽ£º²»¶ÏÑ­»·*/ 
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;      /*ÓÅÏȼ¶£ºÖÐ*/    
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;/*½ûÖ¹ÄÚ´æµ½ÄÚ´æµÄ´«Êä    */
     
    DMA_Init(DMA_RS485_Channel, &DMA_InitStructure); 
        
    USART_DMACmd(UARTNUM, USART_DMAReq_Rx, ENABLE); 
 
    DMA_Cmd(DMA_RS485_Channel, ENABLE);
//*********************************************************************************************//
    USART_Cmd(UARTNUM, ENABLE);    
    //USARTÖжÏÓÅÏȼ¶ÅäÖà¹Ø±Õ´®¿ÚʹÄÜ
//     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/*    NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
    NVIC_Init(&NVIC_InitStructure);*/
//     
     USART_ClearITPendingBit(UARTNUM, USART_IT_TC);//Çå³ýTC±êÖ¾
    USART_ClearFlag(UARTNUM, USART_FLAG_TC);
    
    
    //¿ªÆôTX DMA
//    RS485_TXDMA_Init(log_send_buffer,SEND_BUFFER_LENGTH);
    V_RS485_EN_LOW;
    return TRUE;
}
 
/**
  * @brief  Êä³öÊý¾Ýº¯Êý
  * @param  ÎÞ
  * @retval ÎÞ
  */
BOOL xMBPortSerialPutByte( CHAR ucByte )
{
    extern u8 RS485_status,BT_status;
    /* Put a byte in the UARTs transmit buffer. This function is called
     * by the protocol stack if pxMBFrameCBTransmitterEmpty( ) has been
     * called. */
    if(RS485_status)
    {
        V_RS485_EN_HIGH;
        //while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET);
        USART_SendData(UARTNUM,ucByte);
        
        while(USART_GetFlagStatus(UARTNUM, USART_FLAG_TC) == RESET);
        V_RS485_EN_LOW;
    }
    else
        if(BT_status)
        {
            //while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET);
      USART_SendData(UARTNUM,ucByte);
      while(USART_GetFlagStatus(UARTNUM, USART_FLAG_TC) == RESET);
    }
        
  return TRUE;
}
 
/**
  * @brief  ½ÓÊÕÊý¾Ýº¯Êý
  * @param  ÎÞ
  * @retval Íê³É״̬
  */
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.
     */
    *pucByte=USART_ReceiveData(UARTNUM);
    
    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.
 */
static 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.
 */
static void prvvUARTRxISR(void)
{
    pxMBFrameCBByteReceived();
}
 
/**
  * @brief  ´®¿ÚÖжϺ¯Êý
  * @param  ÎÞ
  * @retval ÎÞ
  */
void UART4_IRQHandler(void)
{
    //½ÓÊÕÖжÏ
    if(USART_GetITStatus(UARTNUM, USART_IT_RXNE)!=RESET)
    {
//        prvvUARTRxISR(); 
        //Çå³ýÖжϱêÖ¾
        USART_ClearITPendingBit(UARTNUM, USART_IT_RXNE); 
    }
 
    //·¢ËÍÍê³ÉÖжÏ
    if(USART_GetITStatus(UARTNUM, USART_IT_TXE)!=RESET)
    {
//        prvvUARTTxReadyISR();
        //Çå³ýÖжϱêÖ¾
        USART_ClearITPendingBit(UARTNUM, USART_IT_TXE);
    }
}