?? hart_slave.c
字號(hào):
#include <msp430x16x.h>
#include <string.h>
#include "resp_data.h"
#define byte unsigned char
extern void uart0_init(); //串口初始化 波特率9600
extern void clock_init(); //時(shí)鐘初始化
extern void timer_A_init(); //定時(shí)器A初始化 增模式 定時(shí)時(shí)間30ms
extern byte Checksum(byte *s , byte nbytes);//計(jì)算校驗(yàn)和
extern void com_send(byte *send,byte send_bytes);//通過(guò)串口發(fā)送數(shù)據(jù)
extern void hart_resp( byte *resp_data, byte resp_num, byte *addr ,byte cmd_num);//按HART協(xié)議的格式生成待發(fā)送的數(shù)據(jù)幀send[]
byte x1; //用于區(qū)別長(zhǎng)結(jié)構(gòu)和短結(jié)構(gòu)的變量,x1=1 短,x1=2時(shí)長(zhǎng)
byte receive[100]; //用于存放接收的數(shù)據(jù)
byte send[100]; //用于存放發(fā)送的數(shù)據(jù)
byte cmd_data[25]; //命令數(shù)據(jù)區(qū)
byte byte_count; //數(shù)據(jù)長(zhǎng)度
byte start_short[3]={0xFF,0xFF,0x02}; //用于尋找短結(jié)構(gòu)起始字節(jié)
byte start_long[3]={0xFF,0xFF,0x82}; //用于尋找長(zhǎng)結(jié)構(gòu)起始字節(jié)
byte rec_ptr; //用于給接收到的數(shù)據(jù)編號(hào)
byte received; //recived=1時(shí)表示已接收到一幀數(shù)據(jù),對(duì)數(shù)據(jù)幀解析完recived被置為0
byte rec_bytes; //接收的字節(jié)數(shù)
byte error,comm_error,command_error,old_device,needs_burn;
byte polling_addr; //輪詢地址,初始值為0
byte *p_polling_addr=&polling_addr;//指向輪詢地址的指針
byte short_addr = 0x80 ; //本機(jī)短結(jié)構(gòu)地址,初始值為0x80
byte long_addr[5]={0x81,0x02,0x08,0x09,0x10}; //本機(jī)長(zhǎng)結(jié)構(gòu)地址
byte cmd_num; //命令號(hào)
byte pre_num; //前導(dǎo)符的個(gè)數(shù)
byte status1,status2; //狀態(tài)位
byte send_bytes; //發(fā)送數(shù)據(jù)的字節(jié)數(shù)
byte not_resp; //表示從機(jī)不需要響應(yīng)的標(biāo)志,該變量為1時(shí)表示不響應(yīng)
/*主程序運(yùn)行后,程序一直在等待.當(dāng)串口接收到一個(gè)完整的數(shù)據(jù)幀之后,received置1,主程序?qū)邮盏?的數(shù)據(jù)幀進(jìn)行解析,若解析正確,則根據(jù)數(shù)據(jù)幀中的命令號(hào)執(zhí)行相應(yīng)的操作.*/
void main(void)
{
byte i,j,t;
byte cs_start;
byte *r,*p;
float pv_range_span,f1; //主變量量程跨度
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
uart0_init();
clock_init();
timer_A_init();
_EINT(); // Enable interrupts
received = 0;
error = 0;
status1 = 0;
status2 = 0;
for (;;)
{
while(received==1) //當(dāng)接收到數(shù)據(jù)時(shí)進(jìn)行以下的處理,否則一直在這里等待
{
not_resp=0;
r=receive;
for(j=1;j<=rec_bytes;++j)
{
if (strncmp((const char*)r,(const char*)start_short,3)==0)
{
x1=1; break;
}
if (strncmp((const char*)r,(const char*)start_long,3)==0)
{
x1=2; break;
}
r++;
}
if(j>rec_bytes) //當(dāng)程序未找到0x02或0x82時(shí)
{
++error; break;
}
pre_num = j+1;
j +=2 ; r +=2; //此時(shí)j,r 都指向起始字節(jié)
cs_start = j;
++j; ++r; //指向地址首字節(jié)
if(rec_bytes-j<2) //當(dāng)剩余數(shù)據(jù)數(shù)少于3時(shí)
{
++error; break;
}
if (x1==1) //地址為短結(jié)構(gòu)
{
if(*r != short_addr) //短結(jié)構(gòu)地址與本從機(jī)短地址不同時(shí)
{
++error; break;
}
else
{
++j; ++r; //指向命令號(hào)
}
}
if(x1==2) //地址為長(zhǎng)結(jié)構(gòu)
{
if(strncmp((const char*)r,(const char*)long_addr,5)!=0) //短結(jié)構(gòu)地址與本從機(jī)短地址不同時(shí)
{
++error; break;
}
else
{
j += 5; r +=5; //指向命令號(hào)
}
}
cmd_num = *r;
j++; r++; //指向數(shù)據(jù)長(zhǎng)度字節(jié)
byte_count = *r;
if (byte_count==0)
{
j++; r++; //指向校驗(yàn)位
}
else
{
r++; //指向命令數(shù)據(jù)的第一個(gè)字節(jié)
j += byte_count + 1;
for(int i=0;i<byte_count;i++)
cmd_data[i]=*r++;
}
r = &receive[cs_start-1];
if ((Checksum(r, j-cs_start+1)) != 0) ++error;
if (error==0)
{
p_pv_value = (unsigned char *)&pv_value;
p_pv_current = (unsigned char *)&pv_current;
p_pv_upper = (unsigned char *)&pv_upper_value;
p_pv_lower = (unsigned char *)&pv_lower_value;
p_v2_value = (unsigned char *)&v2_value;
p_v3_value = (unsigned char *)&v3_value;
p_v4_value = (unsigned char *)&v4_value;
p_pv_sensor_upper = (unsigned char *)&pv_sensor_upper;
p_pv_sensor_lower = (unsigned char *)&pv_sensor_lower;
p_pv_min_span = (unsigned char *)&pv_min_span;
p_pv_damping = (unsigned char *)&pv_damping_value; //將指針和對(duì)應(yīng)的數(shù)據(jù)值一一對(duì)應(yīng)
switch(cmd_num)
{
case 0: hart_resp(resp_data_0, resp_num_0,long_addr,cmd_num); //生成待發(fā)送的數(shù)據(jù)幀send[]
break;
case 1: /*將主變量單位代碼和主變量值IEEE754形式填充到1號(hào)命令響應(yīng)數(shù)據(jù)中中*/
resp_data_1[0] = pv_unit_code;
for(i=0;i<4;i++)
resp_data_1[i+1] = pv_754[i] = *p_pv_value++;
hart_resp(resp_data_1, resp_num_1,long_addr,cmd_num);
break;
case 2: hart_resp(resp_data_2, resp_num_2,long_addr,cmd_num);
break;
case 3: /*按命令3響應(yīng)數(shù)據(jù)的格式填充相關(guān)數(shù)據(jù)*/
for(i=0;i<4;i++)
{
resp_data_3[i] = pv_current_754[i] = *p_pv_current++;
resp_data_3[i+5] = pv_754[i] = *p_pv_value++;
resp_data_3[i+10] = v2_754[i] = *p_v2_value++;
resp_data_3[i+15] = v3_754[i] = *p_v3_value++;
resp_data_3[i+20] = v4_754[i] = *p_v4_value++;
}
resp_data_3[4] = pv_unit_code;
resp_data_3[9] = v2_unit_code;
resp_data_3[14] = v3_unit_code;
resp_data_3[19] = v4_unit_code;
hart_resp(resp_data_3, resp_num_3,long_addr,cmd_num);
break;
case 6: polling_addr = cmd_data[0];
short_addr = (0x80|polling_addr);
hart_resp(p_polling_addr, 1,long_addr,cmd_num);
break;
case 11: if(strncmp((const char*)cmd_data,(const char*)tag,6)==0)//當(dāng)主機(jī)發(fā)來(lái)的設(shè)備標(biāo)簽和設(shè)備本身標(biāo)簽相同時(shí)
hart_resp(resp_data_0, resp_num_0,long_addr,cmd_num);
else
not_resp=1; //當(dāng)主機(jī)發(fā)來(lái)的設(shè)備標(biāo)簽和設(shè)備本身標(biāo)簽不相同時(shí),不響應(yīng)主機(jī)的命令
break;
case 12: hart_resp(message, 24,long_addr,cmd_num);
break;
case 13: /*將標(biāo)簽,描述符和日期填充到13號(hào)命令響應(yīng)數(shù)據(jù)中中*/
for(i=0;i<6;i++)
resp_data_13[i]=tag[i];
for(i=6;i<18;i++)
resp_data_13[i]=descriptor[i-6];
for(i=18;i<21;i++)
resp_data_13[i]=date[i-18];
hart_resp(resp_data_13,resp_num_13,long_addr,cmd_num);
break;
/*將傳感器序列號(hào)等內(nèi)容填充到14號(hào)命令響應(yīng)數(shù)據(jù)數(shù)組中*/
case 14: for(i=0;i<3;i++)
resp_data_14[i] = pv_sensor_sn[i]; //填充主變量傳感器序列號(hào)
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -