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

📄 通讯ok.c

📁 威伦通触摸屏同51单片机通讯
💻 C
字号:
				
#include<reg52.h>// 包含52单片机头文件,此头文件中包含52单片机中的资源定义,包括IO口,寄存器等
#include"modbus.h"
uchar idata Send_buf[30];//发送数据数组
uchar idata Receive_buf[30];//接收数据数组
uchar count=0;//,time=0;//count为收到数据的次数,time应用于发送03代码时,中间的字数量是多少个数值
uchar flag_finish=0;//,flag_led=0;//是否接收完成位,flag_led暂时不用
uint  begin_address=0;//,address_leg=0;//数值字开始位,数值字长度
uchar sign7,sign6,sign5,sign4,sign3,sign2,sign1,sign0;//用于判定发送的8个位,即0x1-0x8的位状态
//* LED亮灭情况表示相应的位状态,LED0-LED7分别对于0x1-0x8*//
sbit LED0=P1^0;						  
sbit LED1=P1^1;
sbit LED2=P1^2;
sbit LED3=P1^3;
sbit LED4=P1^4;
sbit LED5=P1^5;
sbit LED6=P1^6;
sbit LED7=P1^7;
/*************串口初始化函数***************/
/********设定的参数为9600,N,8,1*********/

void init_uart(void)
{
	TH1=0xfa;
	TL1=0xfa; 			// 波特率设为9600
	TMOD=0x21; 			// 使用T1定时器,模式2
	PCON=PCON | 0x80; 	// 启用波特率加强位
	SCON=0x50; 			// 串口模式为2,即8位数据位,停止位为1,无校验
	PS=1; 				// 设定串口中断优先级为最高
	TR1=1; 				// 开始定时
	ES=1;				// 打开串口中断
	EA=1; 				// 打开总中断
}

/******************发送函数******************/
/***********发送一个字符即一个字节***********/
void send(uchar num)
{
	SBUF=num;		   //把字符放到发送数据缓存区SBUF,num可以是字符也可以是一个字节数据
	while(!TI);		   //当发送完之后,TI自动置位,即TI=1,表示发送完成
	TI=0;			   //当发送完之后TI不会自动置0,所以需手动将其置0,表示还没发送完数据
} 
/**********************发送函数***********************/
/***********发送字符串或者一连串的字节数据************/
/****mydata表示要发送的字符串数组,num表示数组长度****/
void send_word(uchar *mydata,uchar num) 
{ 										
	int i;
	for(i=0;i<num;i++)
	{
		send(*(mydata+i));
	}
	count=0;
}

/********************中断接收函数**********************/
/****当数据接收完时,进入串口中断将接收的值放入数组****/

void comm() interrupt 4 using 1
{
	if(RI)	//当接收完一个字节的数据后,RI会自动置位,即RI=1
	{
		uchar a;
        RI=0;	//接受中断标志软件清零
		a=SBUF;	//把缓存在单片机的数据给a
		Receive_buf[count]=a;	//将接受数据放入预置数组
		count++;				//数组自动递增,用于存储下一个数据
		if(count==8)			//当接收完8个MODBUS的功能码之后,自动清0,从新接收(支持的01、05、03、06命令读取或者写入每次都发送8个字节)
		{
			count=0;
			flag_finish=1;		//接受完8个MODBUS功能码的标志位
		}
	}
}

/**************************MODBUS功能码处理***************************/
/********目前只能识别01,03,05,06功能码,而且只能挂载单台***********/

void command(void)
{
uint crc_end;//CEC校验值
char hi_type,low_type;	//03、06功能码发送字节高低位
if(Receive_buf[1] == 0x01)//01功能码
 {
crc_end=crc16(Receive_buf,6);//校验
 if(crc_end==Receive_buf[6]<<8 | Receive_buf[7])//当校验一致时
	{
	hi_type=0;//高位状态
	low_type=sign0 | sign1 | sign2 | sign3 | sign4 | sign5 | sign6 | sign7;	   //低位状态
	Send_buf[0]=Receive_buf[0]; //站号
	Send_buf[1]=Receive_buf[1];	//功能码
	Send_buf[2]=0x02;//字节数
	Send_buf[3]=low_type;	//低位状态,即LED开关情况
	Send_buf[4]=hi_type;	//高位状态
	crc_end=crc16(Send_buf,5);	//校验
	Send_buf[5]=crc_end%256;//校验低位
	Send_buf[6]=crc_end/256;//校验高位
	send_word(Send_buf,7);//发送返回屏
			}
		} 
if(Receive_buf[1] == 0x05)//05功能码
	{
 begin_address=Receive_buf[3];//开始地址
 crc_end=crc16(Receive_buf,6);//校验
 if(crc_end==Receive_buf[6]<<8|Receive_buf[7])//校验正确时
	{
	if(Receive_buf[4]==0xff)//当为强制打开时
	 {
	  switch(begin_address)//对应的地址
		{
		case 0x00: LED0=0; sign0=0x01; break;//相应的LED点亮,记录下相应的P0位状态
		case 0x01: LED1=0; sign1=0x02; break;
		case 0x02: LED2=0; sign2=0x04; break;
		case 0x03: LED3=0; sign3=0x08; break;
		case 0x04: LED4=0; sign4=0x10; break;
		case 0x05: LED5=0; sign5=0x20; break;
		case 0x06: LED6=0; sign6=0x40; break;
		case 0x07: LED7=0; sign7=0x80; break;
	}					 
}
else//当强制为OFF时
	{
	switch(begin_address)
	 {
	case 0x00: LED0=1; sign0=0; break;//相应的LED熄灭,记录下相应的P0位状态
	case 0x01: LED1=1; sign1=0; break;
	case 0x02: LED2=1; sign2=0; break;
	case 0x03: LED3=1; sign3=0; break;
	case 0x04: LED4=1; sign4=0; break;
	case 0x05: LED5=1; sign5=0; break;
	case 0x06: LED6=1; sign6=0; break;
	case 0x07: LED7=1; sign7=0; break;
	 }
	}					  
Send_buf[0]=Receive_buf[0];	//站号
Send_buf[1]=Receive_buf[1];	//功能码
Send_buf[2]=Receive_buf[2];	//起始高位
Send_buf[3]=Receive_buf[3];	//起始低位
Send_buf[4]=Receive_buf[4];	//返回状态
Send_buf[5]=Receive_buf[5];	//返回状态
crc_end=crc16(Send_buf,6);	//校验
Send_buf[6]=crc_end%256;//校验低位
Send_buf[7]=crc_end/256;//校验高位
send_word(Send_buf,8);//发送返回屏
	}
   }													
}
  
/*------------------ main code following -----------------*/
void main(void)
{
	init_uart();				   //初始化串口
	while(1) 
	{
    while(flag_finish)		   //当接收完成时
	   {
		command();			   //识别相应的功能码
		flag_finish=0;		   //重新接收	
	   }	 			 
	}	  
}

⌨️ 快捷键说明

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