返回列表 发新帖我要提问本帖赏金: 50.00元(功能说明)

[单片机芯片] 基于CH32V103驱动RFID射频阅读器

[复制链接]
9202|12
 楼主| yangjiaxu 发表于 2022-3-31 14:08 | 显示全部楼层 |阅读模式
本帖最后由 yangjiaxu 于 2022-3-31 14:10 编辑
首先感谢21ic和小管家举办的这个[活动] 【第1期】你选开发板,二姨家买单;很荣幸因为脸熟(其实是混子)得到了这次活动的中奖名额,说实话这板子到手挺长时间了,这么晚才发属实是我个人原因,还有就是疫情肆虐,真的让我板子与人相隔两地。哈哈哈,好了闲话少说,还是开启这次主题任务吧。
本次豆包选择的开发板是沁恒的开发板“CH32V103R8”为什么选择这款开发板呢,其实原因有三。第一,因为没怎么接触过沁恒RISC-V内核的开发板,工作中一直都在使用Arm内核的单片机在玩耍,可能接触和体验新鲜事物是做工程师的一种本能吧,所以让我选择了沁恒。第二,因为朋友推荐我玩沁恒的MCU是因为沁恒的MCU较容易好上手,而且这个32位单片机在国产32位的MCU中是比较能打的(主要是有性价比)。第三,主要是我缺了个link调试器,我是一个对调试工具比较有感觉的一个野生工程师,手里的调试器也算是多种多样,所以一看沁恒这个买开发板送调试器的活动,我岂有不buy的道理。因此,众多理由让我选择了沁恒这款开发板。到手之后,果然没让我失望。接下来就来赏析这款开发板的样子吧。
01.jpg
开发板包装

02.jpg
开发板和调试器

其实这次购买还赠送了2片MCU,在这个芯片紧缺,在朋友圈盛行的一句 “芯片和白菜一个价的时代”,送我两片芯片无疑是地主行为。
03.jpg

接下来就是搭环境了,其实Risc-V的环境怎么搭我是真不是很清楚,但是沁恒这个CH32V103这个搭建环境是真的很容易,首先下载个开发环境,下载MounRiver_Studio_Setup_V170.zip即可,下载链接接下来就是安装,然后找沁恒关于CH32V103的资料例程即可,资料链接。通过官网也可以看到CH32V103的开发资源和外设情况。
04.png

产品特点
  • 青稞V3A处理器,最高80MHz系统主频;
  • 支持单周期乘法和硬件除法;
  • 20KB SRAM,64KB CodeFlash;
  • 供电范围:2.7V ~ 5.5V,GPIO同步供电电压;
  • 多种低功耗模式:睡眠/停止/待机;
  • 上电/断电复位(POR/PDR);
  • 可编程电压监测器(PVD);
  • 7通道DMA控制器;
  • 16路TouchKey通道监测;
  • 16路12位ADC转换通道;
  • 7个定时器;
  • 1个USB2.0主机/设备接口(全速和低速);
  • 2个IIC接口(支持SMBus/PMBus);
  • 3个USART接口;
  • 2个SPI接口(支持Master和Slave模式);
  • 51个I/O口,所有的I/O口都可以映射到16个外部中断;
  • CRC计算单元,96位芯片唯一ID;
  • 串行单线调试(SWD)接口;
  • 封装形式:LQFP64M、LQFP48、QFN48。
介绍完硬件,其实就可以写代码来玩玩这款得意的MCU了。
打开一个官方例程,我选择的是GPIO的例程,然后改了个名字,因为我想用这个MCU驱动一下FM17522射频阅读器,所以索性改了工程名字。先看看代码风格之类的,emmm,真香,这不是很熟悉的库函数形式么。

05.png

接下来添加FM17522的驱动代码,然后就是移植程序了。
移植过程.jpg
以前换一款MCU来说,移植程序是非常费劲儿的,不过使用沁恒这款MCU的话就不用担心这个问题,基本上一看就会,一用就OK,所以我移植这个工程代码也是非常容易的。因为还需要修改一些变量和参数之类的。所以,大概用了20分钟吧。
分享一下基础代码:
  1. /**********************************以下为用户程序************************************/
  2. void FM17522_IOinit(void)
  3. {
  4.     u8 loop = 0;

  5.     GPIO_InitTypeDef GPIO_InitStructure;
  6. //    GPIO_InitTypeDef GPIO_InitStructure = {0};
  7.     //不要忘记开启AFIO时钟(JTAG复用时RCC_APB2Periph_AFIO)
  8.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  9. //    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);

  10.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6;
  11.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  12.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  13.     GPIO_Init(GPIOB, &GPIO_InitStructure);

  14.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
  15.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;     //输入
  16.     GPIO_Init(GPIOB, &GPIO_InitStructure);

  17.     FM17522_Reset();
  18.     no_fm_flag = 1;

  19.     while(loop++ < 6)
  20.     {
  21.         if(FM17522_TEST())  // 测试读卡芯片FM17522是否在位
  22.         {
  23.             no_fm_flag = 0;
  24.             break;
  25.         }
  26.     }
  27. }
  28. /*********************************************************************************************************
  29. ** 函数名称:FM17522_TEST
  30. ** 函数描述:MCU与读卡芯片通信测试函数
  31. ** 输入参数:无
  32. ** 返回值  :TRUE---测试通过    FALSE----测试失败
  33. ** 说明:不同的读卡芯片的选取用于测试的寄存器不一样,需要更具具体芯片而确定目标寄存器
  34. *********************************************************************************************************/
  35. u8 FM17522_TEST(void)
  36. {
  37.     volatile u8 ucRegVal;

  38.     FM17522_Reset();                                   // 硬件复位
  39.     ucRegVal = FM17522_Read_Reg(ControlReg);
  40.     FM17522_Write_Reg(ControlReg, 0x10);               // 启动读写器模式
  41.     ucRegVal = FM17522_Read_Reg(ControlReg);
  42.     FM17522_Write_Reg(GsNReg, 0xF0 | 0x04);            // CWGsN = 0xF; ModGsN = 0x4
  43.     ucRegVal = FM17522_Read_Reg(GsNReg);

  44.     if(ucRegVal != 0xF4)                               // 验证接口正确
  45.         return FALSE;

  46.     return TRUE;
  47. }
  48. void FM17522_Reset(void)
  49. {
  50.     SPI_SCK_SET;
  51.     Delay_Us(300); // 延时300us
  52.     SPI_RST_CLR;
  53.     Delay_Us(500); // 延时500us
  54.     SPI_RST_SET;
  55.     Delay_Us(1000); // 延时1000us
  56. }
  57. /********************************************
  58. 函数名:            Clear_BitMask
  59. 功能:            清除位寄存器操作

  60. 输入参数:        reg_add,寄存器地址;mask,寄存器清除位
  61. ********************************************/
  62. void Clear_BitMask(u8 reg_add, u8 mask)
  63. {
  64.     FM17522_Write_Reg(reg_add, FM17522_Read_Reg(reg_add) & ~mask); // clear bit mask
  65. }
  66. /*************************************************************/
  67. /*函数名:            Set_BitMask                                                                         */
  68. /*功能:            置位寄存器操作                                                                 */
  69. /*输入参数:        reg_add,寄存器地址;mask,寄存器置位                 */
  70. /*返回值:            TRUE                                                                                         */
  71. /*                                FALSE                                                                                 */
  72. /*************************************************************/
  73. void Set_BitMask(u8 reg_add, u8 mask)
  74. {
  75.     FM17522_Write_Reg(reg_add, FM17522_Read_Reg(reg_add) | mask); // set bit mask
  76. }
  77. /**********************************************/
  78. /** 函数名:            Set_RF                     **/
  79. /** 功能:            设置射频输出                 **/
  80. /** 输入参数:        mode,射频输出模式           **/
  81. /**                                0,关闭输出                        **/
  82. /**       1,仅打开TX1输出                   **/
  83. /**       2,仅打开TX2输出                   **/
  84. /**                                3,TX1,TX2打开输出,TX2为反向输出 **/
  85. /**********************************************/
  86. void Set_Rf(u8 mode)
  87. {
  88.     if((FM17522_Read_Reg(TxControlReg) & 0x03) == mode)
  89.         return;

  90.     if (mode == 0)
  91.     {
  92.         Clear_BitMask(TxControlReg, 0x03); //关闭TX1,TX2输出
  93.     }
  94.     else if (mode == 1)
  95.     {
  96.         Clear_BitMask(TxControlReg, 0x01); //仅打开TX1输出
  97.     }
  98.     else if (mode == 2)
  99.     {
  100.         Clear_BitMask(TxControlReg, 0x02); //仅打开TX2输出
  101.     }
  102.     else if (mode == 3)
  103.     {
  104.         Set_BitMask(TxControlReg, 0x03); //打开TX1,TX2输出
  105.     }

  106.     Delay_Ms(100);
  107. }
  108. void Fm17522_ConfigISOType(u8 type)
  109. {
  110.     if (type == 0)                     //ISO14443_A
  111.     {
  112.         Set_BitMask(ControlReg, 0x10); //ControlReg 0x0C 设置reader模式
  113.         Set_BitMask(TxAutoReg, 0x40);  //TxASKReg 0x15 设置100%ASK有效
  114.         FM17522_Write_Reg(TxModeReg, 0x00);    //TxModeReg 0x12 设置TX CRC无效,TX FRAMING =TYPE A
  115.         FM17522_Write_Reg(RxModeReg, 0x00);    //RxModeReg 0x13 设置RX CRC无效,RX FRAMING =TYPE A
  116.         FM17522_Write_Reg(RFCfgReg, 0x48);     //增益调节至48DB 2021.01.16
  117.     }
  118.     else if (type == 1)                        //ISO14443_B
  119.     {
  120.         FM17522_Write_Reg(ControlReg, 0x10);
  121.         FM17522_Write_Reg(TxModeReg, 0x83); //BIT1~0 = 2'b11:ISO/IEC 14443B
  122.         FM17522_Write_Reg(RxModeReg, 0x83); //BIT1~0 = 2'b11:ISO/IEC 14443B
  123.         FM17522_Write_Reg(TxAutoReg, 0x00);
  124.         FM17522_Write_Reg(RxThresholdReg, 0x55);
  125.         FM17522_Write_Reg(RFCfgReg, 0x48); //?????????????
  126.         FM17522_Write_Reg(TxBitPhaseReg, 0x87); //默认值
  127.         FM17522_Write_Reg(GsNReg, 0x83);
  128.         FM17522_Write_Reg(CWGsPReg, 0x10);
  129.         FM17522_Write_Reg(GsNOffReg, 0x38);
  130.         FM17522_Write_Reg(ModGsPReg, 0x10);
  131.     }

  132.     Delay_Us(1000);
  133. }
  134. /********************************************
  135. 函数名:           Fm17522_SetTimer
  136. 功能:            设置接收延时
  137. 输入参数:        delaytime,延时时间(单位为毫秒)
  138. 返回值:            TRUE
  139. ********************************************/
  140. u8 Fm17522_SetTimer(unsigned long delaytime)//设定超时时间(ms)
  141. {
  142.     unsigned long TimeReload;
  143.     unsigned int Prescaler;

  144.     Prescaler = 0;
  145.     TimeReload = 0;

  146.     while(Prescaler < 0xfff)
  147.     {
  148.         TimeReload = ((delaytime * (long)13560) - 1) / (Prescaler * 2 + 1);

  149.         if( TimeReload < 0xffff)
  150.             break;

  151.         Prescaler++;
  152.     }

  153.     TimeReload = TimeReload & 0xFFFF;
  154.     Set_BitMask(TModeReg, Prescaler >> 8);
  155.     FM17522_Write_Reg(TPrescalerReg, Prescaler & 0xFF);
  156.     FM17522_Write_Reg(TReloadMSBReg, TimeReload >> 8);
  157.     FM17522_Write_Reg(TReloadLSBReg, TimeReload & 0xFF);
  158.     return TRUE;
  159. }
  160. /*************************************************************
  161. 函数名:            Clear_FIFO
  162. 功能:              清空FIFO

  163. 输入参数:          无
  164. 输出参数:
  165. 返回值:            TRUE
  166.                                       FALSE
  167. ************************************************************/
  168. u8 Clear_FIFO(void)
  169. {
  170.     Set_BitMask(FIFOLevelReg, 0x80); //清除FIFO缓冲

  171.     if (FM17522_Read_Reg(FIFOLevelReg) == 0)
  172.         return TRUE;
  173.     else
  174.         return FALSE;
  175. }
  176. //ATQA是只有两个字节,UID却是4个字节加一个BCC校验值所以针对7字节UID防碰撞时就需要最多15字节的UID来存放
  177. //SAK是一个字节的SAK+CRC_A(2字节)
  178. /****************************************************************************************/
  179. /*名称:TypeA_Request                                                                                                                                        */
  180. /*功能:TypeA_Request卡片寻卡                                                                                                                        */
  181. /*输入:                                                                                                                                                                */
  182. /*                                                                                                                                                                */
  183. /*                                                                                                                                                                                */
  184. /*输出:                                                                                                                                                                 */
  185. /*                       pTagType[0],pTagType[1] =ATQA                                                         */
  186. /*               TRUE: 应答正确                                                                      */
  187. /*                         FALSE: 应答错误                                                                                                                                */
  188. /****************************************************************************************/
  189. u8 Fm17522_TypeA_Request(void)
  190. {
  191.     unsigned char  result, send_buff[1], rece_buff[2];
  192.     unsigned int  rece_bitlen;
  193.         
  194.     Clear_BitMask(TxModeReg, 0x80); //关闭TX CRC
  195.     Clear_BitMask(RxModeReg, 0x80); //关闭RX CRC
  196.     Set_BitMask(RxModeReg, 0x08);//关闭位接收
  197.     Clear_BitMask(Status2Reg, 0x08);
  198.     FM17522_Write_Reg(BitFramingReg, 0x07);
  199.     send_buff[0] = 0x26;
  200.     Fm17522_SetTimer(1);
  201.     Clear_FIFO();
  202.     result = Fm17522_Comm(Transceive, send_buff, 1, rece_buff, &rece_bitlen);

  203.     if ((result == TRUE) && (rece_bitlen == 2 * 8))
  204.     {
  205.         memcpy(atqa, rece_buff, 2);
  206.     }

  207.     return result;
  208. }
  209. /*********************************************
  210. 函数名:          Fm17522_Comm (不利用IRQ管脚的情况)
  211. 功能:            读卡器通信

  212. 输入参数:        Command,通信操作命令;
  213.                                                 pInData,发送数据数组;
  214.                                                 InLenByte,发送数据数组字节长度;
  215.                                                 pOutData,接收数据数组;
  216.                                                 pOutLenBit,接收数据的位长度
  217. 返回值:            TRUE
  218.                                 FALSE
  219. ********************************************/
  220. u8 Fm17522_Comm(u8 Command, u8 *pInData, u8 InLenByte, u8 *pOutData, uint *pOutLenBit)
  221. {
  222.     uint8_t status  = FALSE;
  223.     uint8_t irqEn   = 0x00;
  224.     uint8_t waitFor = 0x00;
  225.     uint8_t lastBits;
  226.     uint8_t n;
  227.     uint32_t i;
  228.     FM17522_Write_Reg(ComIrqReg, 0x7F);               //清楚IRQ标记
  229.     FM17522_Write_Reg(TModeReg, 0x80);                //设置TIMER自动启动

  230.     switch (Command)
  231.     {
  232.         case MFAuthent:                                                  /* Mifare认证                   */
  233.             irqEn   = 0x12;
  234.             waitFor = 0x10;
  235.             break;

  236.         case Transceive:                                               /* 发送FIFO中的数据到天线,传输后激活接收电路*/
  237.             irqEn   = 0x77;
  238.             waitFor = 0x30;
  239.             break;

  240.         default:
  241.             break;
  242.     }

  243.     FM17522_Write_Reg(ComIEnReg, irqEn | 0x80);
  244.     FM17522_Write_Reg(CommandReg, Idle);
  245.     Set_BitMask(FIFOLevelReg, 0x80);

  246.     for (i = 0; i < InLenByte; i++)
  247.     {
  248.         FM17522_Write_Reg(FIFODataReg, pInData[i]);
  249.     }

  250.     FM17522_Write_Reg(CommandReg, Command);

  251.     if (Command == Transceive)
  252.     {
  253.         Set_BitMask(BitFramingReg, 0x80);
  254.     }

  255.     i = 20000;                                                            /* 根据时钟频率调整,操作M1卡最大等待时间25ms*/

  256.     do
  257.     {
  258.         n = FM17522_Read_Reg(ComIrqReg);
  259.         i--;
  260.     }
  261.     while ((i != 0) && !(n & 0x01) && !(n & waitFor));           //i==0表示延时到了,n&0x01!=1表示PCDsettimer时间未到

  262.     Clear_BitMask(BitFramingReg, 0x80);

  263.     if (i != 0)
  264.     {
  265.         if(!(FM17522_Read_Reg(ErrorReg) & 0x1B))
  266.         {
  267.             status = TRUE;

  268.             if (n & irqEn & 0x01)
  269.             {
  270.                 status = 0xEE;
  271.             }

  272.             if (Command == Transceive)
  273.             {
  274.                 n = FM17522_Read_Reg(FIFOLevelReg);
  275.                 lastBits = FM17522_Read_Reg(ControlReg) & 0x07;

  276.                 if (lastBits)
  277.                 {
  278.                     *pOutLenBit = (n - 1) * 8 + lastBits;
  279.                 }
  280.                 else
  281.                 {
  282.                     *pOutLenBit = n * 8;
  283.                 }

  284.                 if (n == 0)
  285.                 {
  286.                     n = 1;
  287.                 }

  288.                 if (n > 64)
  289.                 {
  290.                     n = 64;
  291.                 }

  292.                 for (i = 0; i < n; i++)
  293.                 {
  294.                     pOutData[i] = FM17522_Read_Reg(FIFODataReg);
  295.                 }
  296.             }
  297.         }
  298.         else
  299.         {
  300.             status = FALSE;
  301.         }
  302.     }

  303.     Clear_BitMask(BitFramingReg, 0x80); //关闭发送
  304.     return status;
  305. }
  306. /****************************************************************************************/
  307. /*名称:Fm17522_TypeA_Anticollision                                                                                                                                */
  308. /*功能:卡片防冲突                                                                                                        */
  309. /*输入:selcode =0x93,0x95,0x97                                                                                                                */
  310. /*                                                                                                                                                                */
  311. /*                                                                                                                                                                                */
  312. /*输出:                                                                                                                                                                 */
  313. /*      TRUE: 应答正确                                                                      */
  314. /*                 FALSE: 应答错误                                                                                                                                */
  315. /****************************************************************************************/
  316. u8 Fm17522_TypeA_Anticollision(unsigned char selcode)
  317. {
  318.     unsigned char   result, i, send_buff[2], rece_buff[5];
  319.     unsigned int   rece_bitlen;
  320.     Clear_BitMask(TxModeReg, 0x80);
  321.     Clear_BitMask(RxModeReg, 0x80);
  322.     Clear_BitMask(Status2Reg, 0x08);
  323.     FM17522_Write_Reg(BitFramingReg, 0x00);
  324.     Clear_BitMask(CollReg, 0x80);

  325.     send_buff[0] = selcode;
  326.     send_buff[1] = 0x20;             //NVB
  327.     Fm17522_SetTimer(1);
  328.     Clear_FIFO();
  329.     result = Fm17522_Comm(Transceive, send_buff, 2, rece_buff, &rece_bitlen);
  330.     i = ((selcode - 0x93) / 2) * 5;

  331.     if (result == TRUE)
  332.     {
  333. //        memcpy(uid[i], rece_buff, 5);
  334.         for (i = 0; i < 5; ++i) {
  335.             uid[i] = rece_buff[i];
  336.         }

  337.         if (uid[4 + i] != (uid[i]^uid[1 + i]^uid[2 + i]^uid[3 + i])) //UID0、UID1、UID2、UID3、BCC(校验字节)
  338.             result = FALSE;
  339.     }

  340.     return result;
  341. }
  342. /****************************************************************************************/
  343. /*名称:TypeA_Select                                                                                                                                        */
  344. /*功能:TypeA_Select卡片选卡                                                                                                                        */
  345. /*输入:selcode =0x93,0x95,0x97                                                                                                                */
  346. /*      pSnr[0],pSnr[1],pSnr[2],pSnr[3]pSnr[4] =UID                                                                  */
  347. /*                                                                                                                                                                                */
  348. /*输出:                                                                                                                                                                 */
  349. /*                       pSak[0],pSak[1],pSak[2] =SAK                                                                    */
  350. /*               TRUE: 应答正确                                                                      */
  351. /*                         FALSE: 应答错误                                                                                                                                */
  352. /****************************************************************************************/
  353. u8 Fm17522_TypeA_Select(unsigned char selcode)
  354. {
  355.     unsigned char   result, i, send_buff[7], rece_buff[5];
  356.     unsigned int   rece_bitlen;
  357.     FM17522_Write_Reg(BitFramingReg, 0x00);
  358.     Set_BitMask(TxModeReg, 0x80);     //打开TX CRC
  359.     Set_BitMask(RxModeReg, 0x80);       //打开接收RX 的CRC校验
  360.     Clear_BitMask(Status2Reg, 0x08);

  361.     send_buff[0] = selcode;        //SEL
  362.     send_buff[1] = 0x70;         //NVB

  363.     i = ((selcode - 0x93) / 2) * 5;
  364. //    memcpy(&send_buff[2],uid[i], 5);
  365.     for (i = 0; i < 5; ++i) {
  366.         send_buff[i + 2] = uid[i];
  367.     }
  368.     Fm17522_SetTimer(1);
  369.     Clear_FIFO();
  370.     result = Fm17522_Comm(Transceive, send_buff, 7, rece_buff, &rece_bitlen);

  371.     i = (selcode - 0x93) / 2;

  372.     if (result == TRUE)
  373.     {
  374.        sak[i] = rece_buff[0];
  375.     }
  376.     return result;
  377. }
  378. /****************************************************************************************/
  379. /*名称:Fm17522_TypeA_CardActive                                                                        */
  380. /*功能:TypeA_CardActive卡片激活                                        */
  381. /*输入:                                                                                                                                        */
  382. /*输出:        pTagType[0],pTagType[1] =ATQA         */
  383. /*              pSnr[0],pSnr[1],pSnr[2],pSnr[3]pSnr[4] =UID         */
  384. /*              pSak[0],pSak[1],pSak[2] =SAK                                    */
  385. /****************************************************************************************/
  386. u8 Fm17522_TypeA_CardActive(void)
  387. {
  388.     u8 result, i;
  389.     Set_Rf(3);   //turn on radio
  390.     Fm17522_ConfigISOType(0);

  391.     for(i = 0; i < 2; i++)
  392.     {
  393.         result = Fm17522_TypeA_Request(); //寻卡 Standard         send request command Standard mode

  394.         if(result == 1)  break;
  395.     }

  396.     if(i == 2)
  397.         return FALSE;

  398.     if((atqa[0] & 0xC0) == 0x00)    //M1卡,ID号只有4位
  399.     {
  400.         result = Fm17522_TypeA_Anticollision(0x93);

  401.         if (result == FALSE)
  402.         {
  403.             return FALSE;
  404.         }

  405.         result = Fm17522_TypeA_Select(0x93);

  406.         if (result == FALSE)
  407.         {
  408.             return FALSE;
  409.         }
  410.     }
  411.     else if((atqa[0] & 0xC0) == 0x40) //ID号有7位
  412.     {
  413.         result = Fm17522_TypeA_Anticollision(0x93);

  414.         if (result == FALSE)
  415.         {
  416.             return FALSE;
  417.         }

  418.         result = Fm17522_TypeA_Select(0x93);

  419.         if (result == FALSE)
  420.         {
  421.             return FALSE;
  422.         }

  423.         result = Fm17522_TypeA_Anticollision(0x95);

  424.         if (result == FALSE)
  425.         {
  426.             return FALSE;
  427.         }

  428.         result = Fm17522_TypeA_Select(0x95);

  429.         if (result == FALSE)
  430.         {
  431.             return FALSE;
  432.         }
  433.     }
  434.     else if((atqa[0] & 0xC0) == 0x80)   //ID号有10位
  435.     {
  436.         result = Fm17522_TypeA_Anticollision(0x93);

  437.         if (result == FALSE)
  438.         {
  439.             return FALSE;
  440.         }

  441.         result = Fm17522_TypeA_Select(0x93);

  442.         if (result == FALSE)
  443.         {
  444.             return FALSE;
  445.         }

  446.         result = Fm17522_TypeA_Anticollision(0x95);

  447.         if (result == FALSE)
  448.         {
  449.             return FALSE;
  450.         }

  451.         result = Fm17522_TypeA_Select(0x95);

  452.         if (result == FALSE)
  453.         {
  454.             return FALSE;
  455.         }

  456.         result = Fm17522_TypeA_Anticollision(0x97);

  457.         if (result == FALSE)
  458.         {
  459.             return FALSE;
  460.         }

  461.         result = Fm17522_TypeA_Select(0x97);

  462.         if (result == FALSE)
  463.         {
  464.             return FALSE;
  465.         }
  466.     }

  467.     return result;
  468. }

  469. /*****************************************************************************************/
  470. /*名称:Fm17522_Mifare_Auth                                                                                                                                                 */
  471. /*功能:Mifare_Auth卡片认证                                                                                                                                 */
  472. /*输入:mode,认证模式(0:key A认证,1:key B认证);sector,认证的扇区号(0~15)                 */
  473. /*                *mifare_key,6字节认证密钥数组;*card_uid,4字节卡片UID数组                                                 */
  474. /*输出:                                                                                                                                                                         */
  475. /*                TRUE    :认证成功                                                                                                                                         */
  476. /*                FALSE :认证失败                                                                                                                                           */
  477. /*****************************************************************************************/
  478. u8 Fm17522_Mifare_Auth(u8 mode, u8 sector, u8 *mifare_key, u8 *card_uid)
  479. {
  480.     unsigned char  send_buff[12], rece_buff[1], result;
  481.     unsigned int  rece_bitlen;

  482.     if(mode == 0x0)
  483.         send_buff[0] = 0x60; //keyA认证

  484.     if(mode == 0x1)
  485.         send_buff[0] = 0x61; //keyB认证

  486.     send_buff[1] = sector * 4 + 3;
  487.     send_buff[2] = mifare_key[0];
  488.     send_buff[3] = mifare_key[1];
  489.     send_buff[4] = mifare_key[2];
  490.     send_buff[5] = mifare_key[3];
  491.     send_buff[6] = mifare_key[4];
  492.     send_buff[7] = mifare_key[5];
  493.     send_buff[8] = card_uid[0];
  494.     send_buff[9] = card_uid[1];
  495.     send_buff[10] = card_uid[2];
  496.     send_buff[11] = card_uid[3];

  497.     Fm17522_SetTimer(1);
  498.     Clear_FIFO();
  499.     result = Fm17522_Comm(MFAuthent, send_buff, 12, rece_buff, &rece_bitlen); //Authent认证

  500.     if (result == TRUE)
  501.     {
  502.         if(FM17522_Read_Reg(Status2Reg) & 0x08) //判断加密标志位,确认认证结果
  503.             return TRUE;
  504.         else
  505.             return FALSE;
  506.     }

  507.     return FALSE;
  508. }


06.jpg

其实用这个软件也就大概用这几个地方,编译,调试和下载,调试的话用官方例程的话几乎不需要修改,所以非常容易就可以上手。
在写代码的时候用memcpy会出现问题,有一些警告,这个可以通过添加#include <string.h>来解决。还有个问题就是我用这个语句赋值的时候,会有警告。memcpy(uid,rece_buff, 5);,警告内容为:warning: passing argument 1 of'memcpy' makes pointer from integer without a cast [-Wint-conversion]。也不知道为什么,最后换了一种方式,采用for循环的方式赋值解决了。

QQ截图20220331004308.jpg
最后分享一下效果吧,小密说如果LED是全亮或者全灭这样效果更加明显,可是我懒了,哈哈哈,就没改。
最后感谢小管家这个给力的活动,还让我学会了新技能,奈斯。

打赏榜单

21小跑堂 打赏了 50.00 元 2022-03-31
理由:恭喜通过原创文章审核!请多多加油哦!

foxsbig 发表于 2022-4-8 15:30 | 显示全部楼层
很nice的帖子,风趣幽默,又有干货
yangxiaor520 发表于 2022-4-13 09:03 来自手机 | 显示全部楼层
下次可以直接上传代码文件
littlelida 发表于 2022-4-15 16:52 | 显示全部楼层
白菜价,哈哈哈
dzfansman 发表于 2022-5-28 15:09 | 显示全部楼层
这个有什么作用呢?
pmp 发表于 2022-5-28 16:47 | 显示全部楼层
性价比比价高的芯片了。  
gygp 发表于 2022-5-29 08:52 | 显示全部楼层
RFID可以识别多远呢?
belindagraham 发表于 2022-5-29 09:24 | 显示全部楼层
CH32V103的驱动效果怎么样?
earlmax 发表于 2022-5-29 09:58 | 显示全部楼层
ch32的价格就是低一些  
andygirl 发表于 2022-6-5 21:01 | 显示全部楼层
射频,阅读器?
yangxiaor520 发表于 2022-8-10 08:00 来自手机 | 显示全部楼层
不错啊,恭喜恭喜。
littlelida 发表于 2022-8-21 13:40 | 显示全部楼层
又看见这个白菜价了,哈哈
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:嵌入式技术专家
简介:擅长电路设计、物联网产品开发、射频产品开发,喜欢打篮球,技术交流,欢迎各位来聊~

794

主题

3350

帖子

10

粉丝
快速回复 在线客服 返回列表 返回顶部