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

📄 sle4442.c

📁 用MSP430单片机实现的IC卡计费系统
💻 C
字号:
#define MAM 0 /*定义主存储器代号*/
#define SCM 1 /*定义加密存储器代号*/
#define PRM 2 /*定义保护存储器代号*/
#define _Nop() _nop_() /*定义空指令*/
#define DELAY5us() _Nop();_Nop();_Nop();_Nop();_Nop();_Nop();_Nop();_Nop();_Nop();_Nop();dog
sbit RST=P1^4;
sbit IO=P1^6;
sbit CLK=P1^5;

uchar xdata sle_pass[3];
/*******************************************************************
起动总线函数
函数原型: void Start_COM();
功能: 启动发送命令起始条件.
********************************************************************/
void Start_COM(void)
{
 IO=1; /*发送起始条件的数据信号*/
 _Nop();
 _Nop();
 _Nop();
 CLK=1;
 DELAY5us(); /*起始条件建立时间大于4.7us,延时*/
 IO=0; /*发送起始信号*/
 DELAY5us(); /*起始条件锁定时间大于4 s*/
 CLK=0; /*钳住总线准备发送或接收数据 */
 _Nop();
 _Nop();
}
/*******************************************************************
结束总线函数
函数原型: void Stop_COM();
功能: 命令发送结束信号
********************************************************************/
void Stop_COM(void)
{
 IO=0; /*发送结束条件的数据信号*/
 _Nop(); /*发送结束条件的时钟信号*/
 _Nop();
 _Nop();
 CLK=1; /*结束条件建立时间大于4 s*/
 DELAY5us();
 IO=1; /*发送总线结束信号*/
 _Nop();
 _Nop();
}
/*******************************************************************
字节数据传送函数
函数原型: void SendByte(uchar c);
功能: 将数据c 发送出去,可以是命令,也可以是数据
********************************************************************/
void SendByte(uchar c)
{
 uchar BitCnt;
 for(BitCnt=0;BitCnt<8;BitCnt++) /*要传送的数据长度为8 位*/
 {
  if((c>>BitCnt)&0x01)IO=1; /*判断发送位*/
  else IO=0;
  _Nop();_Nop();
  CLK=1; /*置时钟线为高通知被控器开始接收数据位*/
  DELAY5us(); /*保证时钟高电平周期大于4 s*/
  CLK=0;
 }
}
/*******************************************************************
字节数据接收函数
函数原型: uchar RcvByte();
功能: 用来接收从卡传来的数据
********************************************************************/
uchar RcvByte(void)
{
 uchar retc;
 uchar BitCnt;
 retc=0;
 for(BitCnt=0;BitCnt<8;BitCnt++)
 {
  CLK=0; /*置时钟线为低准备接收数据位*/
  IO=1; /*置数据线为输入方式*/
  DELAY5us(); /*时钟低电平周期大于4.7 s*/
  CLK=1; /*置时钟线为高使数据线上数据有效*/
  _Nop();
  _Nop();
  retc=retc>>1;
  if(IO==1)retc=retc+0x80; /*读数据位,接收的数据位放入retc 中 */
  _Nop(); _Nop();
 }
 CLK=0;
 _Nop();_Nop();
 return(retc);
}
/*******************************************************************
复位和复位响应函数
函数原型 void AnRst();
功能 复位IC 卡并接收响应字节
*******************************************************************/
void AnRst(void)
{
 RST=0;
 CLK=0;
 DELAY5us();
 DELAY5us();
 RST=1; /*产生复位时序*/
 DELAY5us();
 CLK=1;
 DELAY5us();
 DELAY5us();
 DELAY5us();
 CLK=0;
 DELAY5us();
 RST=0;
 _Nop();
 RcvByte(); /*读出32 字节响应数据*/
 RcvByte();
 RcvByte();
 RcvByte();
}
/*******************************************************************
发送4442 处理脉冲函数
函数原型 void WrmOption();
功能 发送处理模式指令后要调用此程序发送脉冲
*******************************************************************/
void WrmOption(void)
{
 while(1)
 {
  CLK=0;
  _Nop();_Nop();_Nop();_Nop();_Nop();_Nop();
  IO=1;
  _Nop();_Nop();
  if(IO==1)break; /*没有处理完则继续发送脉冲*/
  CLK=1;
  _Nop();_Nop();_Nop();_Nop();_Nop();_Nop();
 }
}
/*******************************************************************
中止操作函数
函数原型 void BreakN();
功能 中止当前操作
*******************************************************************/
void BreakN(void)
{
 CLK=0;
 DELAY5us();
 RST=1; /*发出中止操作的时序*/
 DELAY5us();
 RST=0;
}
/*******************************************************************
命令发送函数
函数原型 void SendCOM(ucahr com1,ucahr com2,uchar com3);
功能 负责起动命令发送3 字节命令字
结束命令
*******************************************************************/
void SendCOM(uchar com1,uchar com2,uchar com3)
{
 Start_COM();
 SendByte(com1); /*连续发送3 字节指令*/
 SendByte(com2);
 SendByte(com3);
 Stop_COM();
}
/*******************************************************************
SLE4442 卡读数据函数
函数原型: bit IRcvdat_4442(uchar area,ucahr addr,uchar num,uchar idata *buf);
功能: 对SLE4442 卡进行读操作area 为存储器类型addr 为起始地址
num 为读取数据字节数buf[]为数据缓冲区指针
说明 操作成功返回1 参数area 错误返回0 使用前用判断卡插好没有
********************************************************************/
bit IRcvdat_4442(uchar area,uchar addr,uchar num,uchar idata *buf)
{
 uchar i;
 dog;
 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 卡写数据函数
函数原型: bit ISenddat_4442(uchar area,ucahr addr,uchar num,uchar buf[]);
功能: 对SLE4442 卡进行写操作area 为存储器类型addr 为起始地址
num 为读取数据字节数buf[]为数据缓冲区指针
说明 操作成功返回1 参数area 错误返回0 使用前用判断卡插好没有
********************************************************************/
bit ISenddat_4442(uchar area,uchar addr,uchar num,uchar idata *buf)
{
 uchar i;
 dog;
 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 卡校验密码函数
函数原型: uchar IChkpsw_4442(uchar psw1,uchar psw2,uchar psw3);
功能: 进行SLE4442 卡进行密码核对核对后方能进行写操作
说明 操作成功返回0x00 卡无效或卡损坏返回0x01,密码错误返
回0x02 卡只剩1 次机会返回0x03.
********************************************************************/
uchar IChkpsw_4442(void)
{
 uchar 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);
 dog;
 if((ec&0x07)!=0x07) return(0x02);
 return(0x00);
}
// END

⌨️ 快捷键说明

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