📄 spi_1352.c
字号:
//spi控制程序
//spi 协议: 70 08 读当前CT状态(430返回one_CT_state与two_CT_state两个值
// 70 09 启动初始化
// 70 07 启动检测
#include "msp430x13x.h"
unsigned char receive[16]; //SPI接收缓存区
unsigned char order_right; //命令正确执行状态
unsigned char receive_count=0; //SPI接收计数
unsigned char start_CT_check; //启动CT检测标志 0x01 启动CT检测 0x00关闭CT检测
unsigned char start_CT_save; //启动CT初始化标志 0x01 启动CT初始化 0x00关闭CT初始化
unsigned char receive_start=0; //SPI通讯时收到的起始字节状态位
unsigned char receive_order=0;
unsigned char receive_error_count=0;//SPI中断计数用于除错
extern unsigned char two_CT_state; //二次CT状态字
extern unsigned char ICC; //电流大小判断 0:1.5A 1:5A
extern unsigned int CT_check_data_a;
extern unsigned int CT_check_data_b;
extern unsigned int CT_check_data_c;
extern unsigned int CT_current_A,CT_current_B,CT_current_C;
extern unsigned char second_count; //TB的秒中断计数,用于通讯延时保护
void spi_init(void); //SPI总线初始化程序
extern void clr_wdt(void);
extern void save_ct_check_data(void);
extern void save_all_CT_data(void);
unsigned char temp_H,temp_M,temp_L;
unsigned char temp_aH,temp_aM,temp_aL,temp_bH,temp_bM,temp_bL,temp_cH,temp_cM,temp_cL;
void hex_to_dec(unsigned long int a) //十六进制转十进制BCD
{
unsigned char temp1,temp2;
if (a>=0xf423f)
{
temp_H=0x99;
temp_M=0x99;
temp_L=0x99;
}
else
{
temp1= a / 100000;
temp2= (a % 100000)/10000;
temp_H= (temp1<<4)+temp2;
temp1= (a % 10000)/1000;
temp2= (a % 1000)/100;
temp_M= (temp1<<4)+temp2;
temp1= (a % 100)/10;
temp2= a % 10;
temp_L= (temp1<<4)+temp2;
}
}
//三字节十进制BCD码转换为两字节HEX码
unsigned int BCD_to_HEX(unsigned char H,unsigned char M,unsigned char L)
{
unsigned int temp;//,temp0,temp1,temp2;
temp=(((L>>4)*10)+(L&0x0f))+(((M>>4)*10)+(M&0x0f))*100+(((H>>4)*10)+(H&0x0f))*10000;
return temp;
}
void delay_n_ms(unsigned char a) //延时子程序
{ unsigned char b,c;
for(;a>0;a--)
for(b=100;b>0;b--)
{ clr_wdt();
for(c=100;c>0;c--);}
}
void clr_receive_buff(void) //清接收缓存区数据
{ unsigned char a;
for(a=0;a<6;a++)
receive[a]=0;
receive_count=0;
second_count=0;
while(((IFG1&UTXIFG0)==0)&&(second_count<2)) clr_wdt();
U0TXBUF=0xff; //发送寄存器常为0xff
receive_start=0;
}
void spi_init(void) //SPI总线初始化程序
//配置为从机四线制通讯
{
P3SEL|=0x0f; //开启P3.0~P3.3的第二功能(复用为SPI总线)
UCTL0=CHAR+SYNC+SWRST; //8位数据,SPI从模式,
// UxTCTL //不用配置,SPI数据上升沿输出,输入数据在下降沿初锁存
U0ME=USPIE0;
UCTL0&=~SWRST;
IE1 |=URXIE0;
_EINT();
U0TXBUF=0xff;
}
void scend_spi_data (unsigned char spi_data)
{ second_count=0;
while(((IFG1&UTXIFG0)==0)&&(second_count<1)) clr_wdt();
if(second_count<1) //发送超时判断!
U0TXBUF=spi_data;
else spi_init();
}
void spi_order(void)
{
unsigned char order;
// clr_wdt();
order_right=0;
order=receive[1];
if(receive[0]==0x70)
{
switch (order)
{
//case 0x81 : scend_spi_data(start_CT_check);
// order_right=1;
// break;
case 0x88 : scend_spi_data(two_CT_state); //二次CT状态字
scend_spi_data(0x00); //一次CT状态字只能为0
order_right=1;
break;
case 0x85 : scend_spi_data(ICC+0x20); //读版本号与ICC及A相电流
scend_spi_data((CT_current_A>>8));
scend_spi_data(CT_current_A);
break;
case 0x01 : start_CT_check=0x01; //开启一次CT检测
order_right=1;
break;
//0X02~0X04 写三相电流值
case 0x02 : CT_current_A=BCD_to_HEX(receive[2],receive[3],receive[4]);
order_right=1;
break;
case 0x03 : CT_current_B=BCD_to_HEX(receive[2],receive[3],receive[4]);
order_right=1;
break;
case 0x04 : CT_current_C=BCD_to_HEX(receive[2],receive[3],receive[4]);
order_right=1;
start_CT_check=1;
break;
case 0x05 : //save_ct_check_data();
order_right=1;
break;
case 0x06 : start_CT_save=1; //写CT初始化数据保存程序启动状态字
order_right=1;
break;
case 0x07 : ICC=1; //写台体状态字
order_right=1;
break;
case 0x08 : scend_spi_data(two_CT_state); //二次CT状态字
scend_spi_data(0x00); //一次CT状态字只能为0
order_right=1;
break;
case 0x82 : //0X82~0X84,读三相检测频率
scend_spi_data(temp_aH);
scend_spi_data(temp_aM);
scend_spi_data(temp_aL);
order_right=1;
break;
case 0x83 :
scend_spi_data(temp_bH);
scend_spi_data(temp_bM);
scend_spi_data(temp_bL);
order_right=1;
break;
case 0x84 :
scend_spi_data(temp_cH);
scend_spi_data(temp_cM);
scend_spi_data(temp_cL);
order_right=1;
break;
case 0x09 : start_CT_save=0x01; //写启动标志位
order_right=1;
break;
case 0x89 : scend_spi_data(start_CT_save);
order_right=1;
break;
default : break;
}
}
}
#pragma vector=USART0RX_VECTOR
__interrupt void SPI0_rx (void)
{
if((U0RXBUF==0x70)&&(receive_start==0))
{receive_count=1;
receive[0]=U0RXBUF;
//receive_count++;
receive_start=1;
second_count=0;
receive_error_count=0;
}
else
{
receive[receive_count]=U0RXBUF;
receive_count++;
if(receive[1]==0x02) return;
if(receive[1]==0x03) return;
if(receive[1]==0x04) return;
// if(receive[1]==0x05) return;
if (receive_count>1)
{
spi_order();
receive_error_count=0;
clr_receive_buff();
}
}
receive_error_count++;
}
void receive_n_check(void)
{ if(receive_count>1)
{
if(receive[1]==0x01)
{
spi_order();
receive_order=1;
receive_start=0;
clr_receive_buff();
}
}
if(receive_error_count>5)
{receive_error_count=0;delay_n_ms(10);spi_init();clr_receive_buff();}
if((second_count>1)&&((receive_start==1)||(receive_error_count>=1)))
{
spi_init();
receive_start=0;
clr_receive_buff();
receive_error_count=0;
}
if(receive_count>4)
{
clr_wdt();
spi_order();
receive_order=0;
receive_start=0;
clr_receive_buff();
receive_error_count=0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -