📄 sle4442.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 + -