⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 msp430pc.c

📁 基于MSP430系列单片机的485串口通信程序。
💻 C
字号:
/*2008-9-10*/
#include "include.h"

uchar aTxBuff[12]; //发送数据缓冲区
uchar RxBuff[N_XY_BAO];	//接收数据缓冲区rx_pc
uchar NRxBuff;      //从pc收到数据长度,
uchar re_tx;		//重发次数
uchar ann_tem;
uchar  pre_tem;
uchar coll_tim;
uchar send_len;
//uchar rtu_addr = 10;//下位机地址			

uchar NTxBuff;
extern  uchar txBuffer1[] ; //第一个字节是发送的数据长度,第二个字节是地址
//extern  uchar rxBuffer[];


extern uchar temp_addr;		//测温点地址
uchar alarm;          //报警不用传到测温点,只做声光报警
//uchar guard;		//预警用传到测温点,当温度到达预警值后
uchar collectionInterval ;  //采集间隔<=24
uchar returnIntervalL ;  //回传间隔<=24*6

/*各温度点容量,必须为偶数,注意单个点存储空间应该和每个点的最大存储空间一样*/
extern uchar site1[24];      //温度点1的存储空间存24个整数温度
extern uchar site2[24];
extern uchar site3[24];
extern uchar site4[24];
extern uchar site5[24];
extern uchar site6[24];
extern uchar alarm_tem;		//预警温度

uint  arc,crc;
uchar bWaitRe;	//1:发送数据包后等待PC返回对数据包的校验结果;0:不等待
uchar Command=NONE_COMMAND;  	//收到的指令
uint SendByte=0;					//准备发送的字节数
uchar bUartRxErr; //1:接收数据出错,如帧错、奇偶校验错等;0:没错

void DoCommand(uchar);
void ask_pc(void);

/* CRC 高位字节值表 */
static uchar  auchCRCHi[] = {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40
};

/* CRC低位字节值表*/
static uchar  auchCRCLo[] = {
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4,
0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD,
0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7,
0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE,
0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2,
0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB,
0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91,
0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88,
0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80,
0x40
};

/*****************************************************************************
CRC计算子程序
usDataLen;   消息中字节数
*pushMsg;    要进行CRC校验的消息
******************************************************************************/

uint CRC16(uchar *pushMsg,uint usDataLen)
   {
   uchar uchCRCHi=0xFF;           /*高CRC字节初始化*/
   uchar uchCRCLo=0xFF;           /*低CRC 字节初始化*/
   uint uIndex;                   /*CRC循环中的索引*/
   while (usDataLen--)            /*遍历消息缓冲区*/
        {
        uIndex   = uchCRCHi ^ *pushMsg++; /* 计算CRC */ 
		uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex]; 
		uchCRCLo = auchCRCLo[uIndex] ; 
        }
   return (uchCRCHi<< 8 | uchCRCLo);
   }

/*****************************************************************************
向缓冲区中增加一个数据  预警温度和返回温度不一样
******************************************************************************/
void AddUsData(unsigned char sq0)
{
	if(NRxBuff<N_XY_BAO)
	{
		RxBuff[NRxBuff]=sq0;
		NRxBuff++;
	}
}

/****************************************************************************
其他模块检测到数据包有错时通知本模块数据通讯有错
****************************************************************************/
void SetBaoErr()
{
	bUartRxErr=1;
}

/*****************************************************************************
处理Uart数据包,主要用来回复pc
p0: 用来返回发送的数据的字节数
返回值:指向发送缓冲区的指针
******************************************************************************/
void DoUart()
{
  //uchar i;
  uchar Command;  //接收的命令
  //uint iq0;	//判断接收数据
  if(NRxBuff!=0)
  {
    if(RxBuff[0]==HAND_OK&&bWaitRe==1&&bUartRxErr==0)     //发送数据后得接收等待
      //HAND_OK 0x0A 收到数据校验正确;
    {              //bWaitRe=0;1:发送数据包后等待PC返回对数据包的校验结果;0:不等待
       //  bUartRxErr=0; 1:接收数据出错,如帧错、奇偶校验错等;0:没错
      bWaitRe=0;
      NRxBuff=0;
		  //nTX1_Len=0;
      SetAddMod(); //切换到只有地址字符使URXIFG置位的状态
      re_tx = 0; //重发次数
    }
    else if(RxBuff[0]==HAND_ERR&&bWaitRe==1&&bUartRxErr==0&&re_tx!=0 ) //发送数据后得接收等待
    {//HAND_ERR	0xA4  	pc收到数据校验错误 重新发数据
			//发送完数据包,等待PC校验结果,?应该有次数要求
			//nTX1_Len= SendByte;        //N_XY_BAO 5	通讯包的字节数
      	NRxBuff=0;
	re_tx--;////////
    }
    else if(RxBuff[0]==HAND_BAO&&bWaitRe==0&&bUartRxErr==0)//HAND_BAO 0xA0  后跟数据的数据包头
    {
      if(NRxBuff==N_XY_BAO)
      {//数据包接收完毕
	crc = 0xffff;   //2008-9-21
	////////////crc = CRC16(RxBuff,N_XY_BAO);			//算出crc值
	if(crc)              //crc校验正确 校验 //数据校验通过
	{
	  Command=RxBuff[3];
	  aTxBuff[0]=HAND_OK;  //
          ask_pc();  //应答pc
          DoCommand(Command);//处理指令
	}
	else
	{
	  //数据校验错误
	  aTxBuff[0]=HAND_ERR;
          ask_pc();  //应答pc
	}
	NRxBuff=0;
      }
    }
  else
  {
  //aRxBuff[0]不是合法的值或者数据接收错误
    aTxBuff[0]=HAND_ERR;
    ask_pc();  //应答pc
    NRxBuff=0;
    bUartRxErr=0;	
  }
 }
  bWaitRe=1;
}
/*
处理指令
01	读一次下位机温度 1组温度值
F1  确认01
02	读一次传感器温度 1个温度值
F2  确认02
03	/// ??
F3	确认03
04	写上限(报警)温度值   alarm 
F4  确认04
05	写温度预警值   guard
F5  确认05
06	设采集间隔(以10分钟为单位,间隔大小:10分钟----4小时)  collection interval
F6  确认06
07	设采集回传间隔(以10分钟为单位)return interval
F7  确认07

长度  ID柜/点  功能码   数据 ..... 数据    CRCL  CRCH
*/
void DoCommand(uchar ord)
{	
  uchar i;
  switch(ord)
  {
  /* case 0x02:
	txBuffer1[0] = 0x03;
	txBuffer1[1] = aRxBuff[2];
	txBuffer1[2] = aRxBuff[3];
	temp_addr = aRxBuff[1];		//测温点地址
	cc2500发送命令
	串口返回数据到pc
	break;*/	
    case 0x04:
	ann_tem = RxBuff[5];		//报警不用传到测温点,只做声光报警
	break;
    case 0x05:
	 pre_tem = RxBuff[5];		//预警用传到测温点,当温度到达预警值后,每个采集间隔测温点都会回传温度
	break;
    case 0x06:
	coll_tim  = RxBuff[3];  //采集间隔<=24
	break;
  /*case 0x07:
	returnIntervalL = aRxBuff[3];  //回传间隔<=24*6
        returnIntervalH = aRxBuff[4];
        break;*/
    default:
	break;
    }
  for(i = 1;i < cc2500_bao;i++)
  {
    txBuffer1[i] = RxBuff[i+1];    //测温点地址
  } 
  //RFSendPacket(txBuffer1, cc2500_bao);   //cc2500发送命令 需要发几次
}
/*       2008-9-21  应答pc        */
void ask_pc()
{
  uchar i;
  send_len = N_XY_BAO;
  for(i = 1;i<N_XY_BAO;i++)
  {
    aTxBuff[i]=RxBuff[i];//应答PC用,2008-9-21
  }
  SendUart(aTxBuff,send_len);
	/*crc = 0xffff;   //2008-9-21
	crc = CRC16(aTxBuff,send_len);			//算出crc值
	send_len++;
	aTxBuff[send_len] = crc/256;
	send_len--;
	aTxBuff[send_len] = crc%256;*/
}
		//初始化
void UartInit()
{
	USART_DIR |= UTXD0 + UDE;     ////UDE = 1 接收 ,UDE = 0 发送
        USART_DIR &= ~URXD0;
	USART_SEL |= UTXD0 +URXD0;	//设置管脚为第二功能
        
	/*UCA0CTL1 |= UCSSEL_2 + UCDORM + UCSWRST ;    // SMCLK = ACLK 只有地址可以打开接收中断
	UCA0CTL0 |= UCMODE_2;					//无奇偶校验,LSB先发,8bit,1stopBit,地址多机
	UCA0BR0 = 0x03;                           // 32kHz/9600 = 3.41
	UCA0BR1 = 0x00;*/  
        UCA0CTL1 |= UCSSEL_2;                 // CLK = ACLK
        UCA0BR0 = 0x68;                           // 32kHz/9600 = 3.41
        UCA0BR1 = 0x00;                           //
        //UCA0MCTL |=  UCBRS0     ;     // Modulation UCBRSx = 3UCBRS1 + UCBRS0;
	UCA0MCTL = UCBRS1 + UCBRS0;               // Modulation UCBRSx = 3
	UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
	IE2 |= UCA0RXIE ;               // Enable USCI_A0 RX interrupt
}

void SendUart(unsigned char *pBuffer,unsigned char n_byte)
{
	unsigned char q0;
        USART_OUT &=~ UDE;    //UDE = 1 接收 ,UDE = 0 发送
	for(q0=0;q0<n_byte;q0++)
	{
		while (!(IFG2&UCA0TXIFG)); //查询是否发送完毕
		UCA0TXBUF =*pBuffer;
                delay_nus(200);    //重要200+5个机器周期
		pBuffer++;
	}
        USART_OUT |= UDE;  //UDE = 1 接收 ,UDE = 0 发送
}


  

/*****************************************************************************
切换到只有地址字符使URXIFG置位的状态
******************************************************************************/
void SetAddMod()
{
  UCA0CTL1 |= UCDORM;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -