/*****************************************************************************
*
* UART Driver for PIC24.
*
*****************************************************************************
* FileName: uart2.c
* Dependencies: system.h
* Processor: PIC24
* Compiler: MPLAB C30
* Linker: MPLAB LINK30
* Company: Microchip Technology Incorporated
*
* Software License Agreement
*
* The software supplied herewith by Microchip Technology Incorporated
* (the "Company") is intended and supplied to you, the Company's
* customer, for use solely and exclusively with products manufactured
* by the Company.
*
* The software is owned by the Company and/or its supplier, and is
* protected under applicable copyright laws. All rights are reserved.
* Any use in violation of the foregoing restrictions may subject the
* user to criminal sanctions under applicable laws, as well as to
* civil liability for the breach of the terms and conditions of this
* license.
*
* THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
* TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
* IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
* A simple UART polled driver
*
* Author Date Comment
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Anton Alkhimenok 10/18/05 ...
*****************************************************************************
*/
#include "p24hj256gp210.h"
#include "uart2.h"
#include "Lib.h"
#include "RlyData.h"
#include "set.h"
#include "GlobeDef.h"
#include "Drive.h"
#include "Rly_R311.h"
#include "eeprom.h"
#include "timer_1ms.h"
//本函数使用内存257 BYTE
/*****************************************************************************
* U2BRG register value and baudrate mistake calculation
*****************************************************************************/
#define BAUDRATEREG1 SYSCLK/32/BAUDRATE1-1
#if BAUDRATEREG1 > 65535 //255
#error Cannot set up UART1 for the SYSCLK and BAUDRATE.\
Correct values in main.h and uart2.h files.
#endif
#define BAUDRATE_MISTAKE 1000*(BAUDRATE1-SYSCLK/32/(BAUDRATEREG1+1))/BAUDRATE1
#if (BAUDRATE_MISTAKE > 2)||(BAUDRATE_MISTAKE < -2)
#error UART21baudrate mistake is too big for the SYSCLK\
and BAUDRATE2. Correct values in uart2.c file.
#endif
WORD w_ComTimer;
BYTE ModBus_ack(BYTE *rbuf, WORD wLen, BYTE *sbuf, WORD id, BYTE *buff103);
void SCI_SetBTL(WORD wBTL);
void JK103_Set_clock(BYTE* BUFF103,BYTE commaddress);
/*****************************************************************************
* Function: UART2Init
*
* Precondition: None.
*
* Overview: Setup UART2 module.
*
* Input: None.
*
* Output: None.
*
*****************************************************************************/
void UART1Init()
{
/*
TRISAbits.TRISA15=0;
LATAbits.LATA15=0; //为0表示串口处于接受状态,只有这样才能够不漏掉要接受的信息
*/
IPC2bits.U1RXIP=6;
IPC3bits.U1TXIP=3;
// Set directions of UART IOs
UART1_TX_TRIS = 0;
UART1_RX_TRIS = 1;
SCI_SetBTL(Para_BTL[0]);
U1MODE = 0;
U1STA = 0;
U1MODEbits.UARTEN = 1;
U1STAbits.URXISEL = 0;
U1STAbits.UTXEN = 1;
U1STAbits.UTXINV = 0;
U1MODEbits.URXINV = 0;
// reset RX flag
IFS0bits.U1RXIF = 0;
IEC0bits.U1RXIE = 1; //使能接收中断
IEC0bits.U1TXIE = 0; //禁止发送中断
}
void SCI_SetBTL(WORD wBTL)
{
//设置SCI波特率 64MHz/(32*SCI_BAUDS)=20000000/32*65=9615
switch(wBTL) {
case 0: //1200
case 1200:
U1BRG = 1667;
break;
case 1: //2400
case 2400:
U1BRG = 833;
break;
case 2: //4800
case 4800:
U1BRG = 417;
break;
case 3: //9600
case 9600:
U1BRG = 208;
break;
case 4: //14400
case 14400:
U1BRG = 139;
break;
case 5: //19200
case 19200:
U1BRG = 104;
break;
default: //9600
U1BRG = 208;
}
}
/*****************************************************************************
* Function: UART2GetChar
*
* Precondition: UART2Init must be called before.
*
* Overview: Wait for a byte.
*
* Input: None.
*
* Output: Byte received.
*
*****************************************************************************/
BYTE Rec_BIT=0;
void __attribute__((__interrupt__)) _U1RXInterrupt(void)
{
IFS0bits.U1RXIF = 0;
if (SCI0_RxBuff.sts!='M')
{
SCI0_RxBuff.sts='R'; //正发送数据
SCI0_RxBuff.TimeOver=0; //接收到数据一次,清零一次接受寄存器
while(U1STAbits.URXDA != 0) //判断 接受缓存 是否有数据
{
SCI0_RxBuff.Buff[SCI0_RxBuff.Wptr++]=U1RXREG; //提取 接受缓存 的值
if((SCI0_RxBuff.Buff[0]!=0)&&(SCI0_RxBuff.Buff[0]!=Para_Addr[0])) //判断是否广播地址或者是本机地址
{
SCI0_RxBuff.len=0;
SCI0_RxBuff.Wptr=0;
}
SCI0_RxBuff.len++;
SCI0_RxBuff.Wptr&=255;
}
}
}
/*
*******************************************************************
* Title: void Uart0_Send(UInt16 wRegsts)
* Description: 串口0(RS485通讯口)查询方式发送报文
* InputParameter: UInt16 wRegsts <Uart0状态寄存器输入>
*******************************************************************
*/
#define preUart0_TimeOver 255
void __attribute__((__interrupt__)) _U1TXInterrupt(void)
{
IFS0bits.U1TXIF = 0;
if (SCI0_TxBuff.sts=='M') //若是 响应数据帧 后进入的中断则进入if,若其他原因进入中断则不会继续发送
{
while(U1STAbits.TRMT != 1); //上次的数据发送完毕
U1TXREG = SCI0_TxBuff.Buff[SCI0_TxBuff.Rptr++];
w_ComTimer=0;
SCI0_TxBuff.TimeOver=0; //发送计数器清零
if (SCI0_TxBuff.Rptr==SCI0_TxBuff.Wptr) //报文发送完毕
{
SCI0_TxBuff.sts=' ';
SCI0_TxBuff.len=0;
SCI0_TxBuff.Rptr=0;
SCI0_TxBuff.Wptr=0;
SCI0_TxBuff.TimeOver=0;
IEC0bits.U1RXIE = 1; //接收使能中断
IFS0bits.U1RXIF = 0;
IEC0bits.U1TXIE = 0; //发送禁止中断
IFS0bits.U1TXIF = 0;
}
}
}
void SCI_ComSend(WORD w_LEN) //响应数据帧,后面进入发送缓冲
{
SCI0_RxBuff.sts=' ';
SCI0_RxBuff.len=0;
SCI0_RxBuff.Rptr=0;
SCI0_RxBuff.Wptr=0;
SCI0_RxBuff.TimeOver=0;
SCI0_TxBuff.Rptr=0;
SCI0_TxBuff.Wptr=w_LEN;
SCI0_TxBuff.sts='M';
IEC0bits.U1RXIE = 0; //接收禁止中断
IFS0bits.U1RXIF = 0;
IFS0bits.U1TXIF = 0;
while(U1STAbits.TRMT != 1);
U1TXREG = SCI0_TxBuff.Buff[SCI0_TxBuff.Rptr++];
IEC0bits.U1TXIE = 1; //发送使能中断
}
void Clear_Rev(); //清接受缓冲
//=========================================================================================
// 串口通讯部分
//=========================================================================================
static BYTE by_Com103Buf[10];
void COM_Task()
{
if (SCI0_RxBuff.sts=='M')
{
// RX_485_RET=60;
if (Lib_check_crc16(&SCI0_RxBuff.Buff[0], SCI0_RxBuff.len)) //CRC校验通过
{
// if(ModBus_ack(&SCI0_RxBuff.Buff[0],SCI0_RxBuff.len,&SCI0_TxBuff.Buff[0],0,&by_Com103Buf)==0) //(接受缓冲的起始地址,接收缓冲长度,发送缓冲首地址
if(ModBus_ack(&SCI0_RxBuff.Buff[0],SCI0_RxBuff.len,&SCI0_TxBuff.Buff[0],0,&by_Com103Buf[0])==0)
Clear_Rev() ;
}
else
Clear_Rev();
}
}
void Clear_Rev() //清接受缓冲
{
// IO3CLR =CON_485; //485电平拉低
SCI0_RxBuff.sts=' ';
SCI0_RxBuff.len=0;
SCI0_RxBuff.Rptr=0;
SCI0_RxBuff.Wptr=0;
SCI0_RxBuff.TimeOver=0;
if( U1STAbits.OERR ==1)U1STAbits.OERR=0;
IEC0bits.U1RXIE = 1; //接收使能中断
IFS0bits.U1RXIF = 0;
//灭通讯灯
}
void
评论1