实例介绍
【实例简介】stc12c5608ad_ad_da_转换一比一模式
【实例截图】
【核心代码】
/* ******************************************************************************* ******************************************************************************* */ #include "modbus.h" #include "mcp4822.h" unsigned char regGroup[30]=0; //Modbus寄存器组,地址为0x00~0x40 unsigned char data kk_adc_dac_8_H = 0; unsigned char data kk_adc_dac_8_L = 0; unsigned int data kk_adc_dac_16 = 0; /******************************************************************************* 数据数组含义定义 regGroup[0] 是否保存数据到FLASH regGroup[1] regGroup[2] regGroup[3] ad模拟采集过来的数据 高字节 =get_adc_2; regGroup[4] ad模拟采集过来的数据 中间字节 =get_adc_1; regGroup[5] ad模拟采集过来的数据 低字节 =get_adc_0; regGroup[6] ad模拟采集过来的数据 高字节 =(get_adc>>8); regGroup[7] ad模拟采集过来的数据 低字节 =(get_adc); regGroup[8] da输出的数据的高位 最大限制0f regGroup[9] da输出的数据的低位 最小限制00 regGroup[10] 输入输出模式配置 regGroup[11] 输入输出模式配置 regGroup[12] regGroup[13] regGroup[14] regGroup[15] regGroup[16] regGroup[17] regGroup[3]=get_adc_2; regGroup[4]=get_adc_1; regGroup[5]=get_adc_0; regGroup[8]=(get_adc>>8); regGroup[9]=(get_adc); regGroup[12] regGroup[13] ********************************************************************************/ void UartAction(unsigned char *buf, unsigned char len) { /******************************************************************************* 485 modbus 通信RTU命令格式 ************************************************ *******************03读取命令************************** 从机地址为 01的变频器的启始地址 0004连续读取连续 2个值, RTU 格式: 主机命令信息....................................... 帧头START 3.5 个字符时间 ADR 01H CMD 03H 启始地址高位 00H 启始地址低位 04H 数据个数高位 00H 数据个数低位 02H CRC CHK Lo 85H CRC CHK Hi CA H END 3.5 个字符时间 从机返回............................................ 帧头START 3.5 个字符时间 ADR 01H CMD 03H 字节个数 04H 数据地址 0004高位 00H 数据地址 0004低位 00H 数据地址 0005高位 00H 数据地址 0005低位 00H CRC CHK Lo 43H CRC CHK Hi 07H END 3.5 个字符时间 *******************06写入命令************************** 将 5000(1388H )写到从机地址 02H 变频器的 0008H 地址处 , 该帧的结构描述如下 RTU 格式: 主机命令信息........................................ 帧头START 3.5 个字符时间 ADR 02H CMD 06H 启始地址高位 00H 启始地址低位 08H 数据个数高位 13H 数据个数低位 88H CRC CHK Lo 05H CRC CHK Hi 6DH END 3.5 个字符时间 从机回应信息......................................... 帧头START 3.5 个字符时间 ADR 02H CMD 06H 启始地址高位 00H 启始地址低位 08H 数据个数高位 13H 数据个数低位 88H CRC CHK Lo 05H CRC CHK Hi 6DH END 3.5 个字符时间 ************************************************ 串口动作函数,根据接收到的命令帧执行响应的动作 buf-接收到的命令帧指针,len-命令帧长度 ********************************************************************************/ unsigned char data modbus_i;//提取寄存器地址缓冲区 // unsigned char modbus_addr_save_i; unsigned char data modbus_cnt;//提取待读取的寄存器数量缓冲区 // unsigned char modbus_str[4]; unsigned int data modbus_crc; unsigned char data modbus_crch, modbus_crcl; if (buf[0] != 0x02) //本例中的本机地址设定为0x02, { //如数据帧中的地址字节与本机地址不符, return; //则直接退出,即丢弃本帧数据不做任何处理 } //地址相符时,再对本帧数据进行校验 modbus_crc = GetCRC16(buf, len-2); //计算CRC校验值 modbus_crch = modbus_crc >> 8; modbus_crcl = modbus_crc & 0xFF; if ((buf[len-2]!=modbus_crch) || (buf[len-1]!=modbus_crcl)) { return; //如CRC校验不符时直接退出 } //地址和校验字均相符后,解析功能码,执行相关操作 switch (buf[1]) // 03 读 06 写 { case 0x03: //读取一个或连续的寄存器 if ((buf[2]==0x00) && (buf[3]<=0x50)) //只支持0x0000~0x0005 { if (buf[3] <= 0x4f) { modbus_i = buf[3]; //提取寄存器地址 modbus_cnt = buf[5]; //提取待读取的寄存器数量 buf[2] = modbus_cnt*2; //读取数据的字节数,为寄存器数*2 len = 3; //帧前部已有地址、功能码、字节数共3个字节 while (modbus_cnt--) { buf[len ] =0x00;// regGroup[modbus_i ]; //寄存器高字节补0 buf[len ] = regGroup[modbus_i ]; //寄存器低字节 } led3=!led3; } else //地址0x05为蜂鸣器状态 { buf[2] = 2; //读取数据的字节数 buf[3] = 0x00; len = 5; } break; } else //寄存器地址不被支持时,返回错误码 { buf[1] = 0x83; //功能码最高位置1 buf[2] = 0x02; //设置异常码为02-无效地址 len = 3; break; } case 0x06: //写入单个寄存器 if ((buf[2]==0x00) && (buf[3]<=0x50)) //只支持0x0000~0x0005 { if (buf[3] <= 0x4f) { modbus_i = buf[3]; //提取寄存器地址 regGroup[modbus_i] = buf[5]; //保存寄存器数据 modbus_cnt = regGroup[modbus_i] ; switch (buf[3]) { /*********************************************************************************************************/ //系数参数的设定0-7adc的高位和低位 //系数参数的设定8-15dac的高位和低位 case 0: led2=!led2; kk_adc_dac_8_H = buf[5]; break; case 1: led2=!led2; kk_adc_dac_8_L = buf[5]; kk_adc_dac_16 = ( kk_adc_dac_8_H << 8 ) | kk_adc_dac_8_L ; k_define[8]= kk_adc_dac_16 & 0xffff; break; case 2: //H led2=!led2; if(kk_define[8]==0) k_define[0] -= buf[5]; if(kk_define[8]==1) k_define[0] = buf[5]; if(buf[5]) { buf[5]=0; } break; case 3: //L led2=!led2; if(kk_define[8]==0) k_define[1] -= buf[5]; if(kk_define[8]==1) k_define[1] = buf[5]; if(buf[5]) { buf[5]=0; } break; case 4: led2=!led2; if(kk_define[8]==0) k_define[2] -= buf[5]; if(kk_define[8]==1) k_define[2] = buf[5]; if(buf[5]) { buf[5]=0; } break; case 5: led2=!led2; if(kk_define[8]==0) k_define[3] -= buf[5]; if(kk_define[8]==1) k_define[3] = buf[5]; if(buf[5]) { buf[5]=0; } break; case 6: led2=!led2; if(kk_define[8]==0) k_define[4] -= buf[5]; if(kk_define[8]==1) k_define[4] = buf[5]; if(buf[5]) { buf[5]=0; } break; case 7: led2=!led2; if(kk_define[8]==0) k_define[5] -= buf[5]; if(kk_define[8]==1) k_define[5] = buf[5]; if(buf[5]) { buf[5]=0; } break; case 8: led2=!led2; if(kk_define[8]==0) k_define[6] -= buf[5]; if(kk_define[8]==1) k_define[6] = buf[5]; if(buf[5]) { buf[5]=0; } break; case 9: led2=!led2; if(kk_define[8]==0) k_define[7] -= buf[5]; if(kk_define[8]==1) k_define[7] = buf[5]; if(buf[5]) { buf[5]=0; } break; case 17: led2=!led2; kk_define[8] = buf[5]; break; case 18: led2=!led2; kk_define[9] = buf[5]; break; /*********************************************************************************************************/ default: break; } } else //地址0x05为蜂鸣器状态 { ; } len -= 2; //长度-2以重新计算CRC并返回原帧 break; } else //寄存器地址不被支持时,返回错误码 { buf[1] = 0x86; //功能码最高位置1 buf[2] = 0x02; //设置异常码为02-无效地址 len = 3; break; } default: //其它不支持的功能码 buf[1] |= 0x80; //功能码最高位置1 buf[2] = 0x01; //设置异常码为01-无效功能 len = 3; break; } modbus_crc = GetCRC16(buf, len); //计算返回帧的CRC校验值 buf[len ] = modbus_crc >> 8; //CRC高字节 buf[len ] = modbus_crc & 0xFF; //CRC低字节 UartWrite(buf, len); //发送返回帧 }
好例子网口号:伸出你的我的手 — 分享!
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论