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

📄 sle4442.c

📁 用MSP430单片机实现的IC卡计费系统
💻 C
字号:
#include "msp430x41x.h"
#include "Include.h"
#include "string.h"

void main(void)
{
   volatile unsigned int i;
   WDTCTL = WDTPW+WDTHOLD;
   FLL_CTL0 = XCAP18PF;  // DCO+ set so freq = xtal x (N+1)
   for (i = 0; i < 60000; i++);              // Delay for 32 kHz crystal to stabilize

   Init();

   DelayTime(10000);

   P1IFG=P2IFG=0;
   _EINT();


   while(1)
   {
      if  (R_Flag&b_CardEdge)
      {
         DelayTime(100);
         if (((~P1IN) & BIT0)==BIT0)
         {
            IC_Operation();
         }
         R_Flag&=~b_CardEdge;
      }

   }

}

/****************************************************************************
* 名称:
* 功能:
* 入口参数:
* 出口参数:
****************************************************************************/
void IC_Operation(void)
{
  unsigned char tmp[8],i;
   _GREENOn;

   _CardSetPower_HIGH;


   if (IChkpsw_4442()==0)  //密码正确
   {
      memset(tmp,0,sizeof(tmp));
      IRcvdat_4442(MAM,32,8,tmp);  //读数据
      for(i=0;i<8;i++)
         tmp[i]=i;
      ISenddat_4442(MAM,32,8,tmp);  //写数据

   }


   _CardSetPower_LOW;

   _GREENOff;


}

/*******************************************************************
起动总线函数
函数原型: void Start_COM();
功能: 启动发送命令起始条件.
********************************************************************/
void Start_COM(void)
{
   _CardPutIO_HIGH; /*发送起始条件的数据信号*/
   _Nop();
   _Nop();
   _Nop();
   _CardSetCLK_HIGH;
   DELAY5us(); /*起始条件建立时间大于4.7us,延时*/
   _CardPutIO_LOW; /*发送起始信号*/
   DELAY5us(); /*起始条件锁定时间大于4 s*/
   _CardSetCLK_LOW; /*钳住总线准备发送或接收数据 */
   _Nop();
   _Nop();
}

/*******************************************************************
结束总线函数
函数原型: void Stop_COM();
功能: 命令发送结束信号
********************************************************************/
void Stop_COM(void)
{
   _CardPutIO_LOW; /*发送结束条件的数据信号*/
   _Nop(); /*发送结束条件的时钟信号*/
   _Nop();
   _Nop();
   _CardSetCLK_HIGH; /*结束条件建立时间大于4 s*/
   DELAY5us();
   _CardPutIO_HIGH; /*发送总线结束信号*/
   _Nop();
   _Nop();
}


/*******************************************************************
字节数据传送函数
函数原型: void SendByte(unsigned char c);
功能: 将数据c 发送出去,可以是命令,也可以是数据
********************************************************************/
void SendByte(unsigned char c)
{
   unsigned char BitCnt;
   for(BitCnt=0;BitCnt<8;BitCnt++) /*要传送的数据长度为8 位*/
   {
      if((c>>BitCnt)&0x01)
      {
         _CardPutIO_HIGH; /*判断发送位*/
      }
      else
      {
         _CardPutIO_LOW;
      }
     _Nop();_Nop();
     _CardSetCLK_HIGH; /*置时钟线为高通知被控器开始接收数据位*/
     DELAY5us(); /*保证时钟高电平周期大于4 s*/
     _CardSetCLK_LOW;
   }
}

/*******************************************************************
字节数据接收函数
函数原型: unsigned char RcvByte();
功能: 用来接收从卡传来的数据
********************************************************************/
unsigned char RcvByte(void)
{
   unsigned char retc;
   unsigned char BitCnt;
   retc=0;
   for(BitCnt=0;BitCnt<8;BitCnt++)
   {
     _CardSetCLK_LOW; /*置时钟线为低准备接收数据位*/

     DELAY5us(); /*时钟低电平周期大于4.7 s*/
     _CardSetCLK_HIGH; /*置时钟线为高使数据线上数据有效*/
     _Nop();
     _Nop();
     retc=retc>>1;
     if (_CardReadIO())
        retc=retc+0x80; /*读数据位,接收的数据位放入retc 中 */
     _Nop(); _Nop();
   }
   _CardSetCLK_LOW;
   _Nop();_Nop();
   return(retc);
}

/*******************************************************************
复位和复位响应函数
函数原型 void AnRst();
功能 复位IC 卡并接收响应字节
*******************************************************************/
void AnRst(void)
{
   _CardSetRST_LOW;
   _CardSetCLK_LOW;
   DELAY5us();
   DELAY5us();
   _CardSetRST_HIGH; /*产生复位时序*/
   DELAY5us();
   _CardSetCLK_HIGH;
   DELAY5us();
   DELAY5us();
   DELAY5us();
   _CardSetCLK_LOW;
   DELAY5us();
   _CardSetRST_LOW;
   _Nop();
   RcvByte(); /*读出32 字节响应数据*/
   RcvByte();
   RcvByte();
   RcvByte();
}


/*******************************************************************
发送4442 处理脉冲函数
函数原型 void WrmOption();
功能 发送处理模式指令后要调用此程序发送脉冲
*******************************************************************/
void WrmOption(void)
{
   while(1)
   {
     _CardSetCLK_LOW;
     _Nop();_Nop();_Nop();_Nop();_Nop();_Nop();

     _Nop();_Nop();
     if(_CardReadIO())
        break; /*没有处理完则继续发送脉冲*/
     _CardSetCLK_HIGH;
     _Nop();_Nop();_Nop();_Nop();_Nop();_Nop();
   }
}


/*******************************************************************
中止操作函数
函数原型 void BreakN();
功能 中止当前操作
*******************************************************************/
void BreakN(void)
{
   _CardSetCLK_LOW;
   DELAY5us();
   _CardSetRST_HIGH; /*发出中止操作的时序*/
   DELAY5us();
   _CardSetRST_LOW;
}

/*******************************************************************
命令发送函数
函数原型 void SendCOM(unsigned char com1,unsigned char com2,unsigned char com3);
功能 负责起动命令发送3 字节命令字
结束命令
*******************************************************************/
void SendCOM(unsigned char com1,unsigned char com2,unsigned char com3)
{
   Start_COM();
   SendByte(com1); /*连续发送3 字节指令*/
   SendByte(com2);
   SendByte(com3);
   Stop_COM();
}


/*******************************************************************
SLE4442 卡读数据函数
函数原型: unsigned char IRcvdat_4442(unsigned char area,unsigned char addr,unsigned char num,unsigned char *buf);
功能: 对SLE4442 卡进行读操作area 为存储器类型addr 为起始地址
num 为读取数据字节数buf[]为数据缓冲区指针
说明 操作成功返回1 参数area 错误返回0 使用前用判断卡插好没有
********************************************************************/
unsigned char IRcvdat_4442(unsigned char area,unsigned char addr,unsigned char num,unsigned char *buf)
{
   unsigned char i;

   switch(area)
   {
     case MAM:
       AnRst(); /*复位SLE4442 卡接收复位响应*/
       SendCOM(0x30,addr,0x00); /*读主存储器*/
       for(i=0;i<num;i++)
       {
          *buf=RcvByte();
          buf++;
       }
       BreakN();
       break;
     case SCM:
       AnRst();
       SendCOM(0x31,0x00,0x00);
       for(i=0;i<num;i++)
       {
          *buf=RcvByte();
          buf++;
       }
       BreakN();
       break;
     case PRM:
       AnRst();
       SendCOM(0x34,0x00,0x00);
       for(i=0;i<num;i++)
       {
          *buf=RcvByte();
          buf++;
       }
       BreakN();
       break;
     default:
       return(0);
   }
   return(1);
}


/*******************************************************************
SLE4442 卡写数据函数
函数原型: unsigned char ISenddat_4442(unsigned char area,unsigned char addr,unsigned char num,unsigned char *buf);
功能: 对SLE4442 卡进行写操作area 为存储器类型addr 为起始地址
num 为读取数据字节数buf[]为数据缓冲区指针
说明 操作成功返回1 参数area 错误返回0 使用前用判断卡插好没有
********************************************************************/
unsigned char ISenddat_4442(unsigned char area,unsigned char addr,unsigned char num,unsigned char *buf)
{
   unsigned char i;

   switch(area)
   {
     case MAM:
       AnRst();
       for(i=0;i<num;i++)
       {
          SendCOM(0x38,addr+i,*buf); /*写主存储器*/
          buf++;
          WrmOption(); /*发送操作脉冲*/
       }
       break;
     case SCM:
       AnRst();
       for(i=0;i<num;i++)
       {
          SendCOM(0x39,addr+i,*buf);
          buf++;
          WrmOption();
       }
       break;
     case PRM:
       AnRst();
       for(i=0;i<num;i++)
       {
          SendCOM(0x3c,addr+i,*buf);
          buf++;
          WrmOption();
       }
       break;
     default:
       return(0);
   }
   return(1);
}

/*******************************************************************
SLE4442 卡校验密码函数
函数原型: unsigned char IChkpsw_4442(void);
功能: 进行SLE4442 卡进行密码核对核对后方能进行写操作
说明 操作成功返回0x00 卡无效或卡损坏返回0x01,密码错误返
回0x02 卡只剩1 次机会返回0x03.
********************************************************************/
unsigned char IChkpsw_4442(void)
{
   unsigned char ec;
   IRcvdat_4442(SCM,0x00,1,&ec);
   switch(ec&0x7)
   {
     case 1:
     case 2:
     case 4: return 0x3;
     case 3:
     case 5: ec=0x1; break;
     case 6: ec=0x2; break;
     case 7: ec=0x3; break;
     default: return 0x1;
   }
   AnRst();
   SendCOM(0x39,0x00,ec); //回写EC 字节
   WrmOption();
   SendCOM(0x33,0x01,sle_pass[0]);
   WrmOption();
   SendCOM(0x33,0x02,sle_pass[1]);
   WrmOption();
   SendCOM(0x33,0x03,sle_pass[2]);
   WrmOption();
   SendCOM(0x39,0x00,0xff); //修改EC值
   WrmOption();
   ec=0;
   IRcvdat_4442(SCM,0x00,1,&ec);

   if((ec&0x07)!=0x07) return(0x02);
   return(0x00);
}



unsigned char _CardReadIO(void)
{
   unsigned char i;
   _CardPutIO_HIGH;
   i=((P6IN&BIT5)>>5);
   return i;
}



void Init(void)
{
   SCFI0  = FLLD_1;  //FLLDx=1;

   SCFQCTL = 121;                  // (121+1) x 32768 = 3.99 Mhz

   BTCTL  = BTFRFQ1;// set LCD frame freq  flcd=ACLK/128

   LCDCTL = LCDON+LCD4MUX+LCDSG0_1; //4-mux;s0-s15 are lcd function;

   TACTL = TASSEL0 + TACLR;  // ACLK, clr.

   CCTL0 = CCIE;    // CCR0 interrupt enabled

   CCR0 = C_50Ms;

   TACTL |= MC0;

   P1SEL =0;
   P1DIR =BIT2+BIT7;
   //P1IE  =BIT0+BIT1+BIT3+BIT4+BIT5+BIT6;
   P1IE=BIT0;
   P1IES =BIT0+BIT1+BIT4;
   P1IFG =0;
   P1OUT =BIT7;

   P2SEL =BIT6+BIT7;
   P2DIR =BIT1+BIT3+BIT4+BIT5+BIT6+BIT7;
   //P2IE  =BIT0+BIT2;
   P2IE=0;
   P2IES =BIT0+BIT2;
   P2IFG =0;
   P2OUT =0X18;

   P3SEL =BIT0+BIT1+BIT2+BIT3+BIT4+BIT5+BIT6+BIT7;
   P3DIR =BIT0+BIT1+BIT2+BIT3+BIT4+BIT5+BIT6+BIT7;

   P4SEL =BIT0+BIT1+BIT2+BIT3+BIT4+BIT5+BIT6+BIT7;
   P4DIR =BIT0+BIT1+BIT2+BIT3+BIT4+BIT5+BIT6+BIT7;

   P5SEL = 0xFC;// set Rxx and COM pins for LCD

   P6SEL =0;
   P6DIR =BIT0+BIT1+BIT2+BIT3+BIT4+BIT6+BIT7;
   P6OUT =0;

}


#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
   _DINT();


   _EINT();

}

#pragma vector=PORT1_VECTOR
__interrupt void PORT_1 (void)
{
   _DINT();

   if (P1IFG & BIT0)      //插卡中断
   {
      R_Flag|=b_CardEdge;
      P1IFG &=~BIT0;
      LPM3_EXIT;

   }



   _EINT();
}

#pragma vector=PORT2_VECTOR
__interrupt void PORT_2 (void)
{
   _DINT();

   P2IFG==0;

   _EINT();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -