FM1722/02NL+STM32硬件SPI调试笔记

1.介绍

FM17XX 系列通用非接触读卡机芯片是复旦微电子股份有限公司设计的,基于 ISO14443 标准的系
列通用非接触卡读卡机芯片,采用 0.6 微米 CMOS EEPROM 工艺。
FM17XX 系列读卡机芯片可分别支持 13.56MHz 频率下的 typeA、typeB、15693 三种非接触通信协
议;支持 MIFARE 和上海标准的加密算法;可兼容飞利浦公司的 RC500、RC530、RC531 及 RC632
等读卡机芯片;芯片内部高度集成了模拟调制解调电路,所以只需最少量的外围电路即可工作;支
持 6 种微处理器接口;其数字电路具有 TTL、CMOS 两种电压工作模式;该芯片适用于各类计费系
统读卡器的应用。
尤其是 FM17XXL 系列芯片,其三路电源的最低工作电压均可达 2.9V,这一特性优于其他公司的同
类产品。

FM17XX型号众多,实际上只是接口、加密算法、协议支的不一样,大部分都是兼容的。

下面是FM17xx的选型表

我使用的是FM1722NL这一款,上面的表里没有,实际上和FM1702NL、FM1724/5兼容,只是FM1722NL相对FM1702NL支持的协议多一点,基本代码(读写ISO 14443A卡)通用。

2.硬件电路(硬件SPI)

FM1722的引脚图如上图所示,特别注意NRD、NWR、A1这三个脚,必须按照上图的要求连接高电平或者低电平,否则可能会导致FM1722无法使用SPI接口通信。

虽然FM1722NL支持3.3V~5V供电,实际使用发现3.3V供电时,天线发射功率很小,

卡片需要紧贴着天线才能读到卡,有时甚至无法读卡,所以建议(主要针对IO口为3.3V单片机)

1.模拟+天线使用 5V供电

2.数字使用3.3V供电

FM1722的SPI时序采用标准SPI时序,主要注意以下几点

  • 注意下CPOL和CPHA的设置
  • NSS在发送时必须拉低,发送完必须拉高。
  • 8位数据位,MSB在前
  • FM1722必须配置为从机

 3.软件调试

软件部分主要是SPI通信,这里采用STM32的硬件SPI(SPI2:PB13、PB14、PB15),需要注意的是前面提到的SPI的CPOL、CPHA和NSS的配置。

主机端SPI配置如下:

void SPI1_Init(void)
{
  GPIO_InitTypeDef     GPIO_InitStructure;	
	SPI_InitTypeDef      SPI_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE );//PORTB 时钟使能
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE );//SPI2 时钟使能

	// 初始化SPI接口引脚	//PB13/14/15 复用推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化 GPIOB	
	
	// 初始化片选、复位引脚   PB12:片选     PB9:复位
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化 PB9/12  
	// 初始化SPI参数	
	GPIO_SetBits(GPIOB,GPIO_Pin_9);//FM17XX NSS拉高 开始复位
	
	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //双线双向全双工
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主 SPI
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // SPI 发送接收 8 位帧结构
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;//CLK空闲为电平
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;//上升沿数据被采样
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS 信号由软件控制
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //预分频 256
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //数据传输从 MSB 位开始
	SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC 值计算的多项式
	SPI_Init(SPI2, &SPI_InitStructure); //根据指定的参数初始化外设 SPIx 寄存器	
	SPI_Cmd(SPI2, ENABLE); //使能 SPI2 外设
  SPI1_ReadWriteByte(0xff); 
}   
u8 SPI1_ReadWriteByte(u8 TxData)
{		
   	u8 retry=0;
	while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) //等待发送区空
	{
		retry++;
		if(retry>200)
			return 0;
	}
	SPI2->DR = TxData;	
	retry=0;
	while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) //等待接收完一个 byte
	{
		retry++;
		if(retry>200)
			return 0;
	}
	return (SPI2->DR); //返回通过 SPIx 最近接收的数据	
}

FM1722主要是初始化函数、读写寄存器函数。

/****************************************************************/
/*名称: WriteReg                                              */
/*功能: 写FM1702寄存器                                           */
/*输入: Address - 寄存器地址; value - 写入的值                  */
/*输出: N/A                                                     */
/****************************************************************/
void SPIWrite(unsigned char Address, unsigned char Data)
{
    Address = ((Address<<1)&0x7E);
    FM1702_CS_L;
    SPI1_ReadWriteByte(Address);
    SPI1_ReadWriteByte(Data);
    FM1702_CS_H;
}
/****************************************************************/
/*名称: ReadReg                                               */
/*功能: 读FM1702寄存器                                           */
/*输入: Address-寄存器地址                                      */
/*输出: 读出的值                                                */
/****************************************************************/
unsigned char SPIRead(unsigned char Address)
{
    unsigned char Temp;
    Address=(Address<<1)|0x80;   
    FM1702_CS_L;
	  SPI1_ReadWriteByte(Address);
    Temp=SPI1_ReadWriteByte(0x0); 
    FM1702_CS_H;
    return Temp;
}

其中FM1702_CS_L就是拉低NSS脚

/****************************************************************/
/*名称: Init_FM1702 */
/*功能: 该函数实现对FM1702初始化操作*/
/*输入: mode:工作模式, 0:TYPEA模式*/
/* 1:TYPEB模式*/
/* 2:上海模式*/
/*输出: N/A */
/****************************************************************/
void Init_FM1702(uchar mode)
{

    uchar temp;
    uint	i;
	  SPI1_Init();//初始化SPI接口
	
    GPIO_SetBits(GPIOB,GPIO_Pin_9);
    delay_ms(10);
    GPIO_ResetBits(GPIOB,GPIO_Pin_9);
    delay_ms(10); //RST引脚下降沿 FM17xx复位 
    
   
    while(SPIRead(Command) != 0)		 // 等待Command = 0,FM1702复位成功 
    { 	
      temp=SPIRead(Command); 			
			printf("复位中...%d\r\n",temp);		
			if(temp==FM1702_OK)break;
			delay_ms(500);
    }

					
    SPIWrite(Page_Sel,0x80);    //往Page寄存器写80hex初始化SPI接口
    for(i = 0; i < 0x1fff; i++) /* 延时 */
    {
        if(SPIRead(Command) == 0x00)
        {
            SPIWrite(Page_Sel,0x00);
        }
    }
		
    if(mode ==2)
    {
        SPIWrite(TypeSH,0x01);
    }
    else
    {
        SPIWrite(TypeSH,0x00);
    }
    
}

这些代码实际上都是根据官方代码修改的。

4.调试

首先调试SPI通信,确保主机和FM1722通信正常,方法如下:

需要找一个FM1722可读可写的寄存器,主机向该寄存器中写入一个数,然后再读出来,如果写入的值与读出来的一样,那么SPI通信基本上没有问题,可以多找几个寄存器试试。

然后就是尝试读卡号,基本流程是Request->AntiColl->Select_Card ,AntiColl成功后就能读到卡号了。

STM32F103调试通过例程:FM1702NL/FM1722硬件SPI读写程序_fm1702-硬件开发文档类资源-CSDN下载

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值