⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spi_1352.c

📁 基于MSP430的电表终端上的CT检测程序
💻 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 + -