|
发表于 2014-4-13 17:02:47
|
显示全部楼层
本帖最后由 nos002 于 2014-4-13 17:20 编辑
/***************************************************************************
* 程序名:UART_RS485_CSMA_CD.c
* RS485通信程序,带冲突检测的载波侦听多路访问
* CSMA/CD(carrier sensemultiple access with collision detection)协议,
* 系统中设置定时器0作为延时计时器,他有两组延时参数。一组用于侦听网络是否空闲。
* 每次接收中断时,给定时器0重装延时参数,并设置网络忙标志。该参数的值应保证
* 在正常的数据发送时,定时器不会溢出。这样,若有节点正在发送数据,定时器0将
* 被反复重装,并设置网络忙标志。若所有节点停止发送数据,定时器将溢出,此时,
* 停止计时并清除网络忙标志,表示网络空闲。发送程序检测到该标志,即可开始发送
* 数据。发送程序每发送1 B数据时,将该数据存入一个临时变量中。此时,接收程序
* 同时也会接收到一个数据,将接收到的数据与临时变量中的数据进行比较,若相等,
* 表示数据发送成功,否则,表示发生冲突,此时立即停止发送,并给定时器0设置一
* 个随机延时值,延时结束后重复上述过程。
*****************************************************************************/
#include<p24F08KL302.h>
#include<stdlib.h>
#include"LED.h"
#include"DisplayBoard.h"
#include"485_DisplayBoard.h"
#define DELAY_50us 200
#define DELAY_2500us 20000
volatile NETWORK_BITS NETWORKbits;
volatile R485RECEIVE R485RX;
/*************************************************************
* 显示板发送数据包结构:
* 包头(0x55,0xaa)、 数据长度、数据类、数据、CRC_H、CRC_L
* 数据类:”参数”、”命令或传感”
* 参数:真空时间,加热时间,恒温时间,温度档位
* 命令或传感: 机器进程、停止命令,气囊开始,加热开始,恒温开始、脚踏状态、气嘴传感、电流传感
***************************************************************/
unsigned char
UartTransEN, //发送允许
TCommandBuf[20]={0x55,0xaa,13,COMMAND,1,2,3,4,5,6}, //命令位置由宏定义指出
RCommandBuf[20],
TParameterBuf[30], //写入UART发送缓冲区之前不能被改写,所以独有
Uart2TBuf[30], //一次数据包发送完之前不能被其他任务函数改写,只能由串口发送函数自己决定
Uart2RBuf[256], //接受数据缓冲,长度可变
AnswerBuf[5] ={3,ANSWER,0}; //应答,COMPLETE,RESEND
unsigned char
TransEND,
TransStart,
LastTrans,
Uart2State,
MachinePowerON,
ReceiveOccur,
TakeDataMSG,
NewDataLocation;
unsigned int
RParameterBuf[10],
ParameterBuf[10]={0x55aa,(20<<8)+PARAMETER,1,2,3,4,5,6};//C30内建EEPROM读写函数原型参数为uint,传递uchar参数无法读写;
//UART传送char数组,传送前要转换成字节数组
/**************************************************************
* 名 称:
* 参 数:
* 返 回:
* 功 能:
***************************************************************/
void T1Init(void)
{
TMR1=0;
PR1 =0xffff;
T1CONbits.TCS=0;
T1CONbits.TCKPS =0b00;
T1CONbits.TGATE =0;
IPC0bits.T1IP =0b011;
IFS0bits.T1IF =0;
IEC0bits.T1IE =1;
}
/**************************************************************
* 名 称:
* 参 数:
* 返 回:
* 功 能:
***************************************************************/
void Uart2Init()
{
U2BRG = 31; // 250K
U2MODEbits.UARTEN = 0; // bit15, TX, RX DISABLED, ENABLE at end of func
U2MODEbits.USIDL = 0; // bit13, Continue operation at Idlestate,0 = 处于空闲模式时继续工作
U2MODEbits.IREN = 0; // bit12, IrDA En/Decoder is disabled
U2MODEbits.RTSMD = 0; // bit11, flow control mode,0 = UxRTS 处于流控制模式
U2MODEbits.UEN = 0b00; // bits8,9,TX,RX enabled, CTS,RTS not
U2MODEbits.WAKE = 0; // Bit7, No Wake up (since we don't sleep here)
U2MODEbits.LPBACK = 0; // bit6, Loop-back is disabled
U2MODEbits.ABAUD = 0; // bit5, auto baud is disabled
U2MODEbits.RXINV = 0; // bit4, IdleState = 1
U2MODEbits.BRGH = 1; // bit3, low boud rate
U2MODEbits.PDSEL = 0b01; // bit2,1,8bit no parity
U2MODEbits.STSEL =1; // bit0, one stop bit
U2STAbits.UTXISEL1 = 1; // bit15, 01 = 当最后一次发送完成(最后一个字符移出发送移位寄存器)且所有的发送操作均完成时,产生中断
U2STAbits.UTXISEL0 = 0; // bit13, Other half of Bit15
U2STAbits.UTXINV = 0; // bit14, IRDA config,发送奇偶校验翻转位
// IREN = 0:1 = UxTX 空闲状态为1,
// 0 = UxTX 空闲状态为0,
U2STAbits.UTXBRK = 0; // bit11, sync break tx is disabled,0 = 同步间隔发送被禁止或已完成
U2STAbits.UTXEN = 0; // bit10, transmit is disabled
U2STAbits.URXISEL = 0b00; // bit7,6,interrupt flag bit is set when RXBUF is filled whith 1 character
// 0x = 当接收到一个字符时,中断标志位置1
U2STAbits.ADDEN = 0; // bit5, address detect mode is disabled,0 = 地址检测模式禁止
IFS1bits.U2RXIF = 0; // clear interrupt flag of rx
IEC1bits.U2RXIE = 1; // enable rx recieved data interrupt
IFS1bits.U2TXIF = 0; // clear interrupt flag of rx
IEC1bits.U2TXIE = 0; // enable rx recieved data interrupt
IPC7bits.U2TXIP=3;
IPC7bits.U2RXIP=5;
U2MODEbits.UARTEN = 1; // UART2 is Enabled
U2STAbits.UTXEN = 0; // bit10,transmit is enabled
oUART2_RE=1; // 上机时,禁止接收、发送
Nop();
Nop();
oUART2_DE=0;
Uart2State =FREE;
MachinePowerON= 1; // 上电串口空接收,给出上电信号以便串口接收中断处理
}
/**************************************************************
* 名 称: StopTransmit
* 参 数:
* 返 回:
* 说 明:获取随机延时数
***************************************************************/
void StopTransmit(void)
{
unsigned int iTime;
U2STAbits.UTXEN =0;
IEC1bits.U2TXIE =1;
iTime =rand()/3 + DELAY_2500us; //随机延时
T1CONbits.TON =0;
TMR1 =65536-iTime;
T1CONbits.TON =1;
NETWORKbits.CollisionWait =1; //网络冲突等待
}
/**************************************************************/
unsigned char HighByte(unsigned int variable)
{
unsigned char temp;
temp = (unsigned char)((variable&0xff00) >>8);
return temp;
}
/**************************************************************/
unsigned char LowByte(unsigned int variable)
{
unsigned char temp;
temp =(unsigned char)(variable &0x00ff);
return temp;
}
/**************************************************************
* 名 称:
* 参 数:
* 返 回:
* 说 明:整形数组转换成高低字节,并存入字节数组,高字节在前,低字节在后;
***************************************************************/
void ConvertIntToByteArray(unsigned char *Target, unsigned int *Source)
{
volatile unsigned char i,j,size;
size = HighByte(Source[1])/2;
for(i=0;i<size;i++)
{
j = i*2;
Target[j] = HighByte(Source);
Target[1+j] = LowByte(Source);
}
}
/**************************************************************
* 名 称:
* 参 数:
* 返 回:
* 说 明:
***************************************************************/
void PowerONSync(void)
{
static unsigned int i;
if(i==400)
{
ConvertIntToByteArray(TParameterBuf,ParameterBuf);
ParameterTransRQ =1; //上机稳定后,为使显示板和驱动板参数同步,显示板将发送一次参数数据
}
if(i>50)
oUART2_RE =0;
if(i<410)
i++;
}
/**************************************************************
* 名 称:
* 参 数:
* 返 回:
* 功 能:清空待发送的命令或参数缓冲区,除固定的数据长度和数据类型字节外,
* 以便更新待发送数据。
**************************************************************/
void ClearBuffer(unsigned char *ptrBuf)
{
unsigned char i;
for(i=0;i<(ptrBuf[2]-4);i++)
{
ptrBuf[4+i] =0;
}
} |
|