#include "modbus.h"
unsigned char sendBuf[50];
const unsigned char code 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低位字节值表*/
const unsigned char code 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校验码生成函数 ***************/
unsigned int CRC16_Check(unsigned char *puchMsg,unsigned int usDataLen)//CRC16校验
{
unsigned char uchCRCHi = 0xFF ; /* 高CRC字节初始化 */
unsigned char uchCRCLo = 0xFF ; /* 低CRC 字节初始化 */
unsigned int uIndex ; /* CRC循环中的索引 */
while (usDataLen--) /* 传输消息缓冲区 */
{
uIndex = uchCRCHi ^ *puchMsg++ ; /* 计算CRC */
uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex] ;
uchCRCLo = auchCRCLo[uIndex] ;
}
return (uchCRCLo << 8 | uchCRCHi) ;
}
void RS485_init()//485初始化
{
UartInit4();
EN_485 = 0;//接收状态
}
void RS485_Send(unsigned char *p,unsigned char len)//485发送字符串
{
unsigned char i;
EN_485 = 1; //处于发送
for(i=0;i<len;i++) //循环发送所有数据
Uart4_f(p[i]);//发送单个数据
EN_485 = 0; //发送完后将485置于接收状态
receCount = 0; //清接收地址偏移寄存器
}
//------------------------------------定时处理--------------------------------
void timeProc(void)
{
if(bt1ms)
{
bt1ms = 0;
if(receTimeOut>0)
{
receTimeOut--;
if(receTimeOut==0 && receCount>0) //判断通讯接收是否超时
{
EN_485 = 0; //将485置为接收状态
receCount = 0;// //将接收地址偏移寄存器清零
}
}
}
}
/************************************************
//fuction:01 读单个或多个线圈状态
//主机发送 地址 + 功能码 + 起始地址(2个字节) + 线圈数量 (2个字节) + 校验码
//从机返回 地址 + 功能码 + 字节数+ 线圈状态 + 校验码
**************************************************/
void readCoils(void) //fuction:01 读单个或多个线圈状态
{
unsigned int addr;
unsigned int tempAddr;
unsigned int byteCount;
unsigned int bitCount;
unsigned int crcData;
unsigned int i,k;
unsigned int tempData;
unsigned char exit = 0;
addr=(receBuf[2]<<8+receBuf[3]);
tempAddr = addr; //读取地址
bitCount = (receBuf[4]<<8) + receBuf[5]; //读取的位个数
byteCount = bitCount / 8; //字节个数
if(bitCount%8 != 0) //不能整除加一个字节
byteCount++;
for(k=0;k<byteCount;k++)
{
sendBuf[k+3]=0;
for(i=0;i<8;i++)
{
getCoilVal(tempAddr,&tempData);//一位一位读取
sendBuf[k+3] |= tempData<<i;//移位完成一个字节
tempAddr++;//地址加1
if(tempAddr>=addr+bitCount)//判读是否要读取的位都读好,读好后设定标志位
{
exit = 1; break; //跳出i语句循环
}
}
if(exit == 1) break ;//跳出k语句循环
}
sendBuf[0]=LocalAddr; //单片机控制板的地址
sendBuf[1]=0x01; //发送功能码
sendBuf[2]=byteCount; //发送字节数
byteCount+=3; //CRC16校验个数
crcData=CRC16_Check(sendBuf,byteCount);//crc16校验
sendBuf[byteCount++] = crcData & 0xff; //发送crc16校验低八位校验码
sendBuf[byteCount++] = crcData >> 8; //发送crc16校验高八位校验码
RS485_Send(sendBuf,byteCount);
}
/************************************************
//fuction:02 读单个或多个线圈状态
//主机发送 地址 + 功能码 + 起始地址(2个字节) + 输入点数量 (2个字节) + 校验码
//从机返回 地址 + 功能码 + 字节数+ 输入点状态 + 校验码
**************************************************/
void readInPutCoils(void) //fuction:02 读取线圈输入(只读寄存器)状态
{
unsigned int addr;
unsigned int tempAddr;
unsigned int byteCount;
unsigned int bitCount;
unsigned int crcData;
unsigned int i,k;
unsigned int tempData;
unsigned char exit = 0;
addr=(receBuf[2]<<8+receBuf[3])+10000;
tempAddr = addr; //读取地址
bitCount = (receBuf[4]<<8) + receBuf[5]; //读取的位个数
byteCount = bitCount / 8; //字节个数
if(bitCount%8 != 0)
byteCount++;
for(k=0;k<byteCount;k++)
{
sendBuf[k+3]=0;
for(i=0;i<8;i++)
{
getCoilVal(tempAddr,&tempData);//一位一位读取
sendBuf[k+3] |= tempData<<i;//移位完成一个字节
tempAddr++;//地址加1
if(tempAddr>=addr+bitCount)//判读是否要读取的位都读好,读好后设定标志位
{
exit = 1; break; //跳出i语句循环
}
}
if(exit == 1) break ;//跳出k语句循环
}
sendBuf[0]=LocalAddr; //单片机控制板的地址
sendBuf[1]=0x02; //发送功能码
sendBuf[2]=byteCount; //发送字节数
byteCount+=3; //CRC16校验个数 //加上前面的地址,功能码,地址 共3+byteCount个字节
crcData=CRC16_Check(sendBuf,byteCount);//crc16校验
sendBuf[byteCount++] = crcData & 0xff; //发送crc16校验低八位校验码
sendBuf[byteCount++] = crcData >> 8; //发送crc16校验高八位校验码
RS485_Send(sendBuf,byteCount);
}
/********function
没有合适的资源?快使用搜索试试~ 我知道了~
光伏电子工程的设计与实施2022 赛题2单片机代码
共36个文件
obj:7个
lst:7个
c:6个
需积分: 5 8 下载量 174 浏览量
2023-03-14
18:19:52
上传
评论 1
收藏 125KB ZIP 举报
温馨提示
光伏电子工程的设计与实施2022 赛题2单片机代码 没用WiFi部分代码,代码没有注释而且命名不规范(因为是练习时随手打的) 思路在博文:https://blog.csdn.net/m0_51247005/article/details/125478010
资源推荐
资源详情
资源评论
收起资源包目录
单片机.zip (36个子文件)
单片机
modbus.h 2KB
1.uvgui.Lenovo 95KB
1.uvproj 15KB
Objects
user.obj 18KB
modbus.obj 28KB
1 89KB
1.build_log.htm 1KB
wifi.obj 405B
STARTUP.obj 819B
1.hex 29KB
EEprom.obj 11KB
main.obj 14KB
1.lnp 205B
send_eg.obj 23KB
user.h 431B
EEprom.h 113B
wifi.h 84B
STARTUP.A51 6KB
1.uvopt 7KB
modbus.c 14KB
send_eg.c 4KB
Listings
wifi.lst 876B
1.m51 67KB
main.lst 3KB
EEprom.lst 3KB
user.lst 7KB
modbus.lst 22KB
send_eg.lst 9KB
STARTUP.lst 14KB
main.h 475B
user.c 3KB
send_eg.h 272B
EEprom.c 1KB
wifi.c 17B
main.c 1KB
1.uvgui.xw 91KB
共 36 条
- 1
资源评论
dz小伟
- 粉丝: 3850
- 资源: 3
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功