OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4466|回复: 3

单片机写一个modbus程序 没有任何要求 modbus没有任何要求 但是我不知道怎么下手 求大神教教我

[复制链接]

26

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
159
金钱
159
注册时间
2015-10-12
在线时间
0 小时
发表于 2015-11-4 12:29:10 | 显示全部楼层 |阅读模式
5金钱
我串口已经配置好了 现在想写一个modbus的程序 学习任务 明天给,求大神教教我 我学了半个月的单片机·· 用库函数的呢
拜托啦

最佳答案

查看完整内容[请看2#楼]

先看看协议格式吧,简单了解一下,对你的串口传输数据加一个格式要求而已。把要传输的数据分成保持寄存器和输入寄存器,功能码的功能按照协议里介绍,写对应的处理函数,用到几个写几个,最后再加上CRC校验就可以了。-------我也只是简单用过。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

5

主题

105

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
419
金钱
419
注册时间
2015-9-16
在线时间
122 小时
发表于 2015-11-4 12:29:11 | 显示全部楼层
先看看协议格式吧,简单了解一下,对你的串口传输数据加一个格式要求而已。把要传输的数据分成保持寄存器和输入寄存器,功能码的功能按照协议里介绍,写对应的处理函数,用到几个写几个,最后再加上CRC校验就可以了。-------我也只是简单用过。
回复

使用道具 举报

1

主题

15

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
315
金钱
315
注册时间
2014-11-27
在线时间
88 小时
发表于 2015-11-4 12:29:11 | 显示全部楼层
#include"usart.h"
#include"key.h"
#include"port.h"
#include"crc.h"
#include"exti.h"
#include"eeprom.h"

/*****************************************************
通讯协议采用MODBUS_RTU 通讯协议 
波特率1200
数据位8位
停止位1位
CRC校验
*****************************************************/
//#define baud 95               //波特率 1200  异步正常模式 计算公式 BAUD(波特率)=Fosc/16(UBBR0+1) 误差为0.0%

uchar uart_flag;

uchar RxdBuffer[8];
uchar UartTxdBuffer[6];
uchar pRxdInput=0;
uchar rv_over=0;
uchar tx_addr=0x01;
uchar LERR;
uchar UartSendCounter=0;

uint  crc_tx =0; 
uint  crc_rx = 0;
uchar crc_h,crc_l;

uchar data_addr = 0;
uchar write_data = 0;

//BAUD=(3686400/2)(系统时钟为晶振时钟2分频)/16(95+1)=1200
void Uart_Init(void)
{
UCSR0B = 0x00; //disable while setting baud rate
UCSR0A=0B00000000;
UCSR0C=0B00000110;
UBRR0L = bps_1200;
UBRR0H = 0x00; //set baud rate hi
UCSR0B=0B10011000 ;
//   tx_over_flag = 1;
}

uint CRC16(uchar *pchMsg,uchar wDataLen)     //CRC16 校验
{         
uchar wIndex;         // CRC 循环中的索引
uchar chCRCHi = 0xff; //  高 CRC 字节初始化
uchar chCRCLo = 0xff; //  低 CRC 字节初始化

while (wDataLen--)
{     
wIndex = chCRCLo ^ *pchMsg++ ;
chCRCLo = chCRCHi ^ chCRCHTalbe[wIndex]; 
chCRCHi = chCRCLTalbe[wIndex];
}     
pchMsg = 0;              //指针复位
return (((uint)chCRCHi)<< 8)|chCRCLo;     //高低字节合并返回
}

interrupt [USART_RXC] void  uart0_rx_isr(void)     //发送一个数据 产生一个中断
{    //MOSBUS——RTU协议读取数据
uchar data;

// ri_flag = 1;
// tx_over_flag = 0;
// rx_flag = 1;
data = UDR0;

RxdBuffer[pRxdInput]=data;
pRxdInput++;  
}

void Usart_Data_Judge(void)
{
tx_addr = eeprom_readbyte(2);
delay_us(5);
if(( RxdBuffer[0] != tx_addr)&&(pRxdInput==1))
{
pRxdInput = 0;
RxdBuffer[0]=0;
RxdBuffer[1]=0;
RxdBuffer[2]=0;
RxdBuffer[3]=0;
RxdBuffer[4]=0;
RxdBuffer[5]=0;
RxdBuffer[6]=0;
RxdBuffer[7]=0;
return;
}

if((RxdBuffer[1] != 0x03)&&(RxdBuffer[1] != 0x06)&&(pRxdInput==2))
{
pRxdInput = 0;
RxdBuffer[0]=0;
RxdBuffer[1]=0;
RxdBuffer[2]=0;
RxdBuffer[3]=0;
RxdBuffer[4]=0;
RxdBuffer[5]=0;
RxdBuffer[6]=0;
RxdBuffer[7]=0;  
return;
}
else
{
if(RxdBuffer[1] == 0x03)
{
data_addr = 0x01;
write_addr_flag = 0;
}
else
if(RxdBuffer[1] == 0x06)
{
write_addr_flag = 1;
data_addr = 0x02;
}
}

if(( RxdBuffer[2] != 0x00 )&&(pRxdInput==3))
{
pRxdInput = 0;
RxdBuffer[0]=0;  
RxdBuffer[1]=0;
RxdBuffer[2]=0;
RxdBuffer[3]=0;
RxdBuffer[4]=0;
RxdBuffer[5]=0;
RxdBuffer[6]=0;
RxdBuffer[7]=0; 
return;
}

if(( RxdBuffer[3] != data_addr )&&(pRxdInput==4))
{
pRxdInput = 0;
RxdBuffer[0]=0;  
RxdBuffer[1]=0;
RxdBuffer[2]=0;
RxdBuffer[3]=0;
RxdBuffer[4]=0;
RxdBuffer[5]=0;
RxdBuffer[6]=0;
RxdBuffer[7]=0; 
return;
}

if(( RxdBuffer[4] != 0x00 )&&(pRxdInput==5))
{
pRxdInput = 0;
RxdBuffer[0]=0;  
RxdBuffer[1]=0;
RxdBuffer[2]=0;
RxdBuffer[3]=0;
RxdBuffer[4]=0; 
RxdBuffer[5]=0;
RxdBuffer[6]=0;
RxdBuffer[7]=0;
return;
}
if(write_addr_flag == 1)
{
if(((RxdBuffer[5]>99)||(RxdBuffer[5]<=0))&&(pRxdInput==6))
{
pRxdInput = 0;
RxdBuffer[0]=0;  
RxdBuffer[1]=0;
RxdBuffer[2]=0;
RxdBuffer[3]=0;
RxdBuffer[4]=0; 
return;
}

if(rv_over==0)
{
if(pRxdInput>7)
{
  write_data = RxdBuffer[5];
crc_tx = CRC16(RxdBuffer,6);
crc_l=(uchar)crc_tx;
crc_h=(uchar)(crc_tx>>8);
if((RxdBuffer[6]==crc_l)&&(RxdBuffer[7]==crc_h))
{
rv_over=0xaa;
pRxdInput = 0;
}
else
{
pRxdInput = 0;
RxdBuffer[0]=0;  
RxdBuffer[1]=0;
RxdBuffer[2]=0;
RxdBuffer[3]=0;
RxdBuffer[4]=0;
RxdBuffer[5]=0;
RxdBuffer[6]=0;
RxdBuffer[7]=0; 
}
}
}
}
else
{
if(( RxdBuffer[5] != 0x01 )&&(pRxdInput==6))
{
pRxdInput = 0;
RxdBuffer[0]=0;  
RxdBuffer[1]=0;
RxdBuffer[2]=0;
RxdBuffer[3]=0;
RxdBuffer[4]=0; 
RxdBuffer[5]=0;
RxdBuffer[6]=0;
RxdBuffer[7]=0;
return;
}

if(rv_over==0)
{
if(pRxdInput>7)
{
crc_tx = CRC16(RxdBuffer,6);
crc_l=(uchar)crc_tx;
crc_h=(uchar)(crc_tx>>8);
if((RxdBuffer[6]==crc_l)&&(RxdBuffer[7]==crc_h))
{
rv_over=0xaa;
pRxdInput = 0;

}

else
{
pRxdInput = 0;
RxdBuffer[0]=0;  
RxdBuffer[1]=0;
RxdBuffer[2]=0;
RxdBuffer[3]=0;
RxdBuffer[4]=0;
RxdBuffer[5]=0;
RxdBuffer[6]=0;
RxdBuffer[7]=0; 
}
}
}
}
// ri_flag = 1; 
}

void rece_data(void)
{
if(rv_over==0xaa)
{
if(write_addr_flag == 1)
{
write_addr_flag = 0;
eeprom_write(2,write_data);
delay_us(5);
UartTxdBuffer[0] = eeprom_readbyte(2); //读地址码
delay_us(5);
}
else
{
UartTxdBuffer[0] =tx_addr;
}  
UartTxdBuffer[1] =0x03; 
UartTxdBuffer[2] =0x01;
LERR=l1_flag+(l2_flag<<1)+(l3_flag<<2)+(ef_flag<<3)+(bs_state_flag<<4);     //EF故障变量            
UartTxdBuffer[3] =LERR;
crc_rx = CRC16(UartTxdBuffer,4); 
UartTxdBuffer[4] =(uchar)crc_rx;
UartTxdBuffer[5] =(uchar)(crc_rx>>8);                 
UartSendCounter =0;
rv_over=0x55;  
}
}

void get_data(void)
{
if( rv_over==0x55)
{
if (UartSendCounter < 6)
{
while ( !( UCSR0A & 0x20 ));
UDR0 = UartTxdBuffer[UartSendCounter]; //发送
UartSendCounter++;
              //指向下一位   

else 
if(UartSendCounter==6)
{                          //发完停上串口中断
UartTxdBuffer[0]= 0;
UartTxdBuffer[1] =0; 
UartTxdBuffer[2] =0;  
UartTxdBuffer[3] =0; 
UartTxdBuffer[4] =0; 
UartTxdBuffer[5] =0;   
LERR=0;     //EF故障变量
rv_over=0;                   
UartSendCounter =0;
// tx_over_flag =1; 
// uart_int_flag = 0;
/*
if(system_state == STANDBY_STATE)
{
pd_flag = 1;
TCCR0B = 0x00;
TCNT0 = 0xf7;
}
else
{
pd_flag = 0;
}
*/
}
}
}
回复

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
发表于 2015-11-4 12:55:22 | 显示全部楼层
送你一个“问问题大户”的战功
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-20 04:18

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表