Arkadaşlar Merhaba,
Rc522 rfid modülün spi protokolü ayarları nedir? stm32 hal kütüphanesini kullanıyorum rc522 nin kütüphanesini de aşağıdaki linkten aldım haberleşme sağlayamadım.
https://stm32f4-discovery.net/2014/07/library-23-read-rfid-tag-mfrc522-stm32f4xx-devices/
linkteki arkadaşın modülün register inden okuma yapması için bir fonksiyon oluşturmuş fakat tm_spi_send fonksiyonunda register a yazıp değişkene atıyor, hal kütüphanesinde HAL_SPI_Receive fonksiyonu geri bilgi döndürmüyor. tm_spi_send fonksiyonun karşılığı HAL_SPI_TransmitReceive fonksiyonumudur?
uint8_t TM_MFRC522_ReadRegister(uint8_t addr) {
uint8_t val;
//CS low
MFRC522_CS_LOW;
TM_SPI_Send(MFRC522_SPI, ((addr << 1) & 0x7E) | 0x80);
val = TM_SPI_Send(MFRC522_SPI, MFRC522_DUMMY);
//CS high
MFRC522_CS_HIGH;
return val;
}
Evet karşılığı odur.
Önce hangi register'ı okuyacağını bildirmen gerekiyor.
Ben bu adresi okuyacağım diyerek bir adres bilgisi yollarsın ve ardından gelen veriyi beklersin.
TM_SPI_SEND fonksiyonu bu işi yapıyor.
Bu arada arkadaşın kütüphanesi "SPI Mode 00" 'ı kullanıyor.
ilk etapda okunacak register değerini gönderiyorda veri okuyacağı zaman MFRC522_DUMMY değişken değerini gönderiyor değeride 0x00 sonra val değişkenine aktarıyor 0x00 değerini niye yazıyor onu anlayamadım.
Dikkat ettiysen öncelikle fonksiyon parametresi olan "addr"yi gönderiyor.
Bundan bir cevap gelmeyeceği için değişkene atamıyor.
Ardından Dummy göndererek beklemeyi yapıyor.
RC522 için basit bir yapı bu anladığım kadarıyla
SPI fonksiyonlarında sıkça olan bir olaydır bu Dummy Byte gönderme işi. Bir register'a write yapmak istediğinizde 1 byte register adresi ve 1 byte register datası göndeririz.
Okuma işlemi yapılacağı sırada da 1 byte register adresi gönderilir ve 1 byte dummy byte gönderilir. SPI protokolünün çalışabilmesi için bir clock sinyaline ihtiyacı vardır bildiğiniz üzere, Siz register adresini gönderdikten sonra dummy byte'ını göndermezseniz karşı taraftan cevap alamazsınız.
anladım hocam.şuanda hala iletişim kurabilmiş değilim haberleşme kodlarım aşağıda
void TM_MFRC522_WriteRegister(uint8_t addr, uint8_t val) {
//CS low
MFRC522_CS_LOW;
//Send address
HAL_SPI_Transmit(&hspi1,(uint8_t*)((addr << 1) & 0x7E),1,500);
//Send data
HAL_SPI_Transmit(&hspi1,&val,1,500);
//CS high
MFRC522_CS_HIGH;
}
uint8_t TM_MFRC522_ReadRegister(uint8_t addr){
uint8_t val;
//CS low
MFRC522_CS_LOW;
HAL_SPI_Transmit(&hspi1,(uint8_t*)(((addr << 1) & 0x7E) | 0x80),1,500);
HAL_SPI_Transmit(&hspi1,MFRC522_DUMMY,1,500);
HAL_SPI_Receive(&hspi1,&val,1,500);
//CS high
MFRC522_CS_HIGH;
return val;
}
Logic analizör ile gelen giden verileri incelemek lazım. Ona göre bir yorum yapılabilir. Çalışmadığını nasıl anlıyorsun ?
akşam logic analizör den verilerin fotosunu atarım. TM_MFRC522_Check(CardID) == MI_OK fonksiyonu 0 olarak dönmüyor denenmiş bir kütüphane olduğu için spi da problem olduğunu düşünüyorum
@MrDarK logic analizör den gelen veriler şu şekilde
(https://postimg.cc/image/s46x6vxel/)
test için veri gönderdiğimde
adres: 0x22 data:0x87 stm32 spi mode 00 da çalışıyor fakat logic analizör spi mode 10 ayarlandığında datayı algılıyor ayarlar için cubemx kullanıyorum.
(https://postimg.cc/image/7nvwonn4t/)
STM8 için kullandığım SPI ayarları aşağıdaki gibiydi;
SPI_Init(MIFARE_SPI_NO,SPI_FirstBit_MSB, SPI_BaudRatePrescaler_2, SPI_Mode_Master, SPI_CPOL_Low, SPI_CPHA_1Edge, SPI_Direction_2Lines_FullDuplex, SPI_NSS_Soft, 0x07);
Chip ile RC522 arasında bir iletişim var görünüyor ama mantıklı mı değil mi şu noktada tam kestiremiyorum. Önerim MFRC'nin version register adresini okutman.
Register adresi
#define VersionReg 0x37
Bu registerın dönen değeri 0x91 veya 0x92 olabilir. Eğer farklı birşey dönüyorsa SPI konfigürasyonunda hata olmalı. Kullandığın SPI hızını chipe uygun seçtiğine emin ol. 8MHZ'lik SPI kullandım.
Eski çalışmalarımdan gördüğüm üzere örneğin 0x22 0x87 gönderdiysen rc522'ye bir sonraki gönderdiğin ilk byte datada sana son gönderdiğin 87 datasını dönmelidir.
Benim logic analyzer görüntüm aşağıdaki gibi
@MrDarK hocam 0x37 gönderdiğimde ilk 0xFF sonra 0x92 bilgisi geliyor 0xFF in sebebi ne miso pull-up olduğu içinmi ?
(https://postimg.cc/image/h7l4tb6z1/)
sen hex 37'yi gönderdiğinde protokol gereği birşey göndermesi gerektiğinden ve sende o anda adres gönderdiğinden gelen değerin senin tarafınca bir anlamı yok. Lakin dikkatimi 92 datası çekti. Sen Write değil Read yapıyorsun. Haliyle dummy byte göndermen gerekiyordu. 0xEE datasını gönderdikten sonra 1 byte dummy gönderip cevabı alman gerekirdi. Dummy byte olarak hex 92 mi kullanıyorsun ?
Şu kodlarının genelini paylaşırsan daha fazla insan yardım edebilir. Böyle yol alamayız.
@MrDarK hocam kullandığım kütüphane aşağıda dummy datası olarak 0x00 gönderiyorum fakat 0xff olarak görünüyor analizör de
main.c
#include "main.h"
#include "stm32f4xx_hal.h"
/* USER CODE BEGIN Includes */
#include "mfrc522.h"
/* USER CODE END Includes */
/* Private variables ---------------------------------------------------------*/
SPI_HandleTypeDef hspi1;
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SPI1_Init(void);
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE END PFP */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
int main(void)
{
/* USER CODE BEGIN 1 */
uint8_t My_ID[6];
uint8_t veri=0;
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_SPI1_Init();
/* USER CODE BEGIN 2 */
TM_MFRC522_Init();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while(1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
/*if(TM_MFRC522_Check(My_ID)==MI_OK){
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_13,GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_13,GPIO_PIN_RESET);
}
HAL_GPIO_TogglePin(GPIOD,GPIO_PIN_12);
HAL_Delay(100);*/
veri=TM_MFRC522_ReadRegister(MFRC522_REG_VERSION);
/* USER CODE END 3 */
}
}
/** System Clock Configuration
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
/**Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 4;
RCC_OscInitStruct.PLL.PLLN = 168;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure the Systick interrupt time
*/
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
/**Configure the Systick
*/
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
/* SPI1 init function */
static void MX_SPI1_Init(void)
{
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/** Configure pins as
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12|GPIO_PIN_13, GPIO_PIN_RESET);
/*Configure GPIO pin : PC4 */
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pins : PD12 PD13 */
GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @param None
* @retval None
*/
void _Error_Handler(char * file, int line)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
while(1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif
/**
* @}
*/
/**
* @}
*/
mfrc522.h
#ifndef MFRC522_H
#define MFRC522_H
#include "stm32f4xx_hal.h" // Device header
#include "stm32f4xx_hal_gpio.h"
#include "stm32f4xx_hal_spi.h"
extern SPI_HandleTypeDef hspi1;
typedef enum {
MI_OK = 0,
MI_NOTAGERR,
MI_ERR
} TM_MFRC522_Status_t;
#define MFRC522_CS_LOW HAL_GPIO_WritePin(GPIOC,GPIO_PIN_4,GPIO_PIN_RESET);
#define MFRC522_CS_HIGH HAL_GPIO_WritePin(GPIOC,GPIO_PIN_4,GPIO_PIN_SET);
/* MFRC522 Commands */
#define PCD_IDLE 0x00 //NO action; Cancel the current command
#define PCD_AUTHENT 0x0E //Authentication Key
#define PCD_RECEIVE 0x08 //Receive Data
#define PCD_TRANSMIT 0x04 //Transmit data
#define PCD_TRANSCEIVE 0x0C //Transmit and receive data,
#define PCD_RESETPHASE 0x0F //Reset
#define PCD_CALCCRC 0x03 //CRC Calculate
/* Mifare_One card command word */
#define PICC_REQIDL 0x26 // find the antenna area does not enter hibernation
#define PICC_REQALL 0x52 // find all the cards antenna area
#define PICC_ANTICOLL 0x93 // anti-collision
#define PICC_SElECTTAG 0x93 // election card
#define PICC_AUTHENT1A 0x60 // authentication key A
#define PICC_AUTHENT1B 0x61 // authentication key B
#define PICC_READ 0x30 // Read Block
#define PICC_WRITE 0xA0 // write block
#define PICC_DECREMENT 0xC0 // debit
#define PICC_INCREMENT 0xC1 // recharge
#define PICC_RESTORE 0xC2 // transfer block data to the buffer
#define PICC_TRANSFER 0xB0 // save the data in the buffer
#define PICC_HALT 0x50 // Sleep
/* MFRC522 Registers */
//Page 0: Command and Status
#define MFRC522_REG_RESERVED00 0x00
#define MFRC522_REG_COMMAND 0x01
#define MFRC522_REG_COMM_IE_N 0x02
#define MFRC522_REG_DIV1_EN 0x03
#define MFRC522_REG_COMM_IRQ 0x04
#define MFRC522_REG_DIV_IRQ 0x05
#define MFRC522_REG_ERROR 0x06
#define MFRC522_REG_STATUS1 0x07
#define MFRC522_REG_STATUS2 0x08
#define MFRC522_REG_FIFO_DATA 0x09
#define MFRC522_REG_FIFO_LEVEL 0x0A
#define MFRC522_REG_WATER_LEVEL 0x0B
#define MFRC522_REG_CONTROL 0x0C
#define MFRC522_REG_BIT_FRAMING 0x0D
#define MFRC522_REG_COLL 0x0E
#define MFRC522_REG_RESERVED01 0x0F
//Page 1: Command
#define MFRC522_REG_RESERVED10 0x10
#define MFRC522_REG_MODE 0x11
#define MFRC522_REG_TX_MODE 0x12
#define MFRC522_REG_RX_MODE 0x13
#define MFRC522_REG_TX_CONTROL 0x14
#define MFRC522_REG_TX_AUTO 0x15
#define MFRC522_REG_TX_SELL 0x16
#define MFRC522_REG_RX_SELL 0x17
#define MFRC522_REG_RX_THRESHOLD 0x18
#define MFRC522_REG_DEMOD 0x19
#define MFRC522_REG_RESERVED11 0x1A
#define MFRC522_REG_RESERVED12 0x1B
#define MFRC522_REG_MIFARE 0x1C
#define MFRC522_REG_RESERVED13 0x1D
#define MFRC522_REG_RESERVED14 0x1E
#define MFRC522_REG_SERIALSPEED 0x1F
//Page 2: CFG
#define MFRC522_REG_RESERVED20 0x20
#define MFRC522_REG_CRC_RESULT_M 0x21
#define MFRC522_REG_CRC_RESULT_L 0x22
#define MFRC522_REG_RESERVED21 0x23
#define MFRC522_REG_MOD_WIDTH 0x24
#define MFRC522_REG_RESERVED22 0x25
#define MFRC522_REG_RF_CFG 0x26
#define MFRC522_REG_GS_N 0x27
#define MFRC522_REG_CWGS_PREG 0x28
#define MFRC522_REG__MODGS_PREG 0x29
#define MFRC522_REG_T_MODE 0x2A
#define MFRC522_REG_T_PRESCALER 0x2B
#define MFRC522_REG_T_RELOAD_H 0x2C
#define MFRC522_REG_T_RELOAD_L 0x2D
#define MFRC522_REG_T_COUNTER_VALUE_H 0x2E
#define MFRC522_REG_T_COUNTER_VALUE_L 0x2F
//Page 3:TestRegister
#define MFRC522_REG_RESERVED30 0x30
#define MFRC522_REG_TEST_SEL1 0x31
#define MFRC522_REG_TEST_SEL2 0x32
#define MFRC522_REG_TEST_PIN_EN 0x33
#define MFRC522_REG_TEST_PIN_VALUE 0x34
#define MFRC522_REG_TEST_BUS 0x35
#define MFRC522_REG_AUTO_TEST 0x36
#define MFRC522_REG_VERSION 0x37
#define MFRC522_REG_ANALOG_TEST 0x38
#define MFRC522_REG_TEST_ADC1 0x39
#define MFRC522_REG_TEST_ADC2 0x3A
#define MFRC522_REG_TEST_ADC0 0x3B
#define MFRC522_REG_RESERVED31 0x3C
#define MFRC522_REG_RESERVED32 0x3D
#define MFRC522_REG_RESERVED33 0x3E
#define MFRC522_REG_RESERVED34 0x3F
//Dummy byte
#define MFRC522_DUMMY 0x00
#define MFRC522_MAX_LEN 16
/**
* Public functions
*/
/**
* Initialize MFRC522 RFID reader
*
* Prepare MFRC522 to work with RFIDs
*
*/
extern void TM_MFRC522_Init(void);
/**
* Check for RFID card existance
*
* Parameters:
* - uint8_t* id:
* Pointer to 5bytes long memory to store valid card id in.
* ID is valid only if card is detected, so when function returns MI_OK
*
* Returns MI_OK if card is detected
*/
extern TM_MFRC522_Status_t TM_MFRC522_Check(uint8_t* id);
/**
* Compare 2 RFID ID's
* Useful if you have known ID (database with allowed IDs), to compare detected card with with your ID
*
* Parameters:
* - uint8_t* CardID:
* Pointer to 5bytes detected card ID
* - uint8_t* CompareID:
* Pointer to 5bytes your ID
*
* Returns MI_OK if IDs are the same, or MI_ERR if not
*/
extern TM_MFRC522_Status_t TM_MFRC522_Compare(uint8_t* CardID, uint8_t* CompareID);
/**
* Private functions
*/
extern void TM_MFRC522_InitPins(void);
extern void TM_MFRC522_WriteRegister(uint8_t addr, uint8_t val);
extern uint8_t TM_MFRC522_ReadRegister(uint8_t addr);
extern void TM_MFRC522_SetBitMask(uint8_t reg, uint8_t mask);
extern void TM_MFRC522_ClearBitMask(uint8_t reg, uint8_t mask);
extern void TM_MFRC522_AntennaOn(void);
extern void TM_MFRC522_AntennaOff(void);
extern void TM_MFRC522_Reset(void);
extern TM_MFRC522_Status_t TM_MFRC522_Request(uint8_t reqMode, uint8_t* TagType);
extern TM_MFRC522_Status_t TM_MFRC522_ToCard(uint8_t command, uint8_t* sendData, uint8_t sendLen, uint8_t* backData, uint16_t* backLen);
extern TM_MFRC522_Status_t TM_MFRC522_Anticoll(uint8_t* serNum);
extern void TM_MFRC522_CalculateCRC(uint8_t* pIndata, uint8_t len, uint8_t* pOutData);
extern uint8_t TM_MFRC522_SelectTag(uint8_t* serNum);
extern TM_MFRC522_Status_t TM_MFRC522_Auth(uint8_t authMode, uint8_t BlockAddr, uint8_t* Sectorkey, uint8_t* serNum);
extern TM_MFRC522_Status_t TM_MFRC522_Read(uint8_t blockAddr, uint8_t* recvData);
extern TM_MFRC522_Status_t TM_MFRC522_Write(uint8_t blockAddr, uint8_t* writeData);
extern void TM_MFRC522_Halt(void);
#endif
[code]
-------------------------------------------------------------mfrc522.c dosyası----------------------------------------------------------
[code]
#include "mfrc522.h"
void TM_MFRC522_Init(void) {
MFRC522_CS_HIGH;
TM_MFRC522_Reset();
TM_MFRC522_WriteRegister(MFRC522_REG_T_MODE, 0x8D);
TM_MFRC522_WriteRegister(MFRC522_REG_T_PRESCALER, 0x3E);
TM_MFRC522_WriteRegister(MFRC522_REG_T_RELOAD_L, 30);
TM_MFRC522_WriteRegister(MFRC522_REG_T_RELOAD_H, 0);
/* 48dB gain */
TM_MFRC522_WriteRegister(MFRC522_REG_RF_CFG, 0x70);
TM_MFRC522_WriteRegister(MFRC522_REG_TX_AUTO, 0x40);
TM_MFRC522_WriteRegister(MFRC522_REG_MODE, 0x3D);
TM_MFRC522_AntennaOn(); //Open the antenna
}
TM_MFRC522_Status_t TM_MFRC522_Check(uint8_t* id) {
TM_MFRC522_Status_t status;
//Find cards, return card type
status = TM_MFRC522_Request(PICC_REQIDL, id);
if (status == MI_OK) {
//Card detected
//Anti-collision, return card serial number 4 bytes
status = TM_MFRC522_Anticoll(id);
}
TM_MFRC522_Halt(); //Command card into hibernation
return status;
}
TM_MFRC522_Status_t TM_MFRC522_Compare(uint8_t* CardID, uint8_t* CompareID) {
uint8_t i;
for (i = 0; i < 5; i++) {
if (CardID[i] != CompareID[i]) {
return MI_ERR;
}
}
return MI_OK;
}
void TM_MFRC522_WriteRegister(uint8_t addr, uint8_t val) {
//CS low
MFRC522_CS_LOW;
//Send address
addr=addr << 1;
addr=addr & 0x7E;
HAL_SPI_Transmit(&hspi1,&addr,1,500);
//Send data
HAL_SPI_Transmit(&hspi1,&val,1,500);
//CS high
MFRC522_CS_HIGH;
}
uint8_t TM_MFRC522_ReadRegister(uint8_t addr){
uint8_t val;
//CS low
MFRC522_CS_LOW;
addr=addr << 1;
addr=addr & 0x7E;
addr=addr | 0x80;
HAL_SPI_Transmit(&hspi1,&addr,1,500);
HAL_SPI_Transmit(&hspi1,MFRC522_DUMMY,1,500);
HAL_SPI_Receive(&hspi1,&val,1,500);
//CS high
MFRC522_CS_HIGH;
return val;
}
void TM_MFRC522_SetBitMask(uint8_t reg, uint8_t mask) {
TM_MFRC522_WriteRegister(reg, TM_MFRC522_ReadRegister(reg) | mask);
}
void TM_MFRC522_ClearBitMask(uint8_t reg, uint8_t mask){
TM_MFRC522_WriteRegister(reg, TM_MFRC522_ReadRegister(reg) & (~mask));
}
void TM_MFRC522_AntennaOn(void) {
uint8_t temp;
temp = TM_MFRC522_ReadRegister(MFRC522_REG_TX_CONTROL);
if (!(temp & 0x03)) {
TM_MFRC522_SetBitMask(MFRC522_REG_TX_CONTROL, 0x03);
}
}
void TM_MFRC522_AntennaOff(void) {
TM_MFRC522_ClearBitMask(MFRC522_REG_TX_CONTROL, 0x03);
}
void TM_MFRC522_Reset(void) {
TM_MFRC522_WriteRegister(MFRC522_REG_COMMAND, PCD_RESETPHASE);
}
TM_MFRC522_Status_t TM_MFRC522_Request(uint8_t reqMode, uint8_t* TagType) {
TM_MFRC522_Status_t status;
uint16_t backBits; //The received data bits
TM_MFRC522_WriteRegister(MFRC522_REG_BIT_FRAMING, 0x07); //TxLastBists = BitFramingReg[2..0] ???
TagType[0] = reqMode;
status = TM_MFRC522_ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits);
if ((status != MI_OK) || (backBits != 0x10)) {
status = MI_ERR;
}
return status;
}
TM_MFRC522_Status_t TM_MFRC522_ToCard(uint8_t command, uint8_t* sendData, uint8_t sendLen, uint8_t* backData, uint16_t* backLen) {
TM_MFRC522_Status_t status = MI_ERR;
uint8_t irqEn = 0x00;
uint8_t waitIRq = 0x00;
uint8_t lastBits;
uint8_t n;
uint16_t i;
switch (command) {
case PCD_AUTHENT: {
irqEn = 0x12;
waitIRq = 0x10;
break;
}
case PCD_TRANSCEIVE: {
irqEn = 0x77;
waitIRq = 0x30;
break;
}
default:
break;
}
TM_MFRC522_WriteRegister(MFRC522_REG_COMM_IE_N, irqEn | 0x80);
TM_MFRC522_ClearBitMask(MFRC522_REG_COMM_IRQ, 0x80);
TM_MFRC522_SetBitMask(MFRC522_REG_FIFO_LEVEL, 0x80);
TM_MFRC522_WriteRegister(MFRC522_REG_COMMAND, PCD_IDLE);
//Writing data to the FIFO
for (i = 0; i < sendLen; i++) {
TM_MFRC522_WriteRegister(MFRC522_REG_FIFO_DATA, sendData[i]);
}
//Execute the command
TM_MFRC522_WriteRegister(MFRC522_REG_COMMAND, command);
if (command == PCD_TRANSCEIVE) {
TM_MFRC522_SetBitMask(MFRC522_REG_BIT_FRAMING, 0x80); //StartSend=1,transmission of data starts
}
//Waiting to receive data to complete
i = 2000; //i according to the clock frequency adjustment, the operator M1 card maximum waiting time 25ms???
do {
//CommIrqReg[7..0]
//Set1 TxIRq RxIRq IdleIRq HiAlerIRq LoAlertIRq ErrIRq TimerIRq
n = TM_MFRC522_ReadRegister(MFRC522_REG_COMM_IRQ);
i--;
} while ((i!=0) && !(n&0x01) && !(n&waitIRq));
TM_MFRC522_ClearBitMask(MFRC522_REG_BIT_FRAMING, 0x80); //StartSend=0
if (i != 0) {
if (!(TM_MFRC522_ReadRegister(MFRC522_REG_ERROR) & 0x1B)) {
status = MI_OK;
if (n & irqEn & 0x01) {
status = MI_NOTAGERR;
}
if (command == PCD_TRANSCEIVE) {
n = TM_MFRC522_ReadRegister(MFRC522_REG_FIFO_LEVEL);
lastBits = TM_MFRC522_ReadRegister(MFRC522_REG_CONTROL) & 0x07;
if (lastBits) {
*backLen = (n - 1) * 8 + lastBits;
} else {
*backLen = n * 8;
}
if (n == 0) {
n = 1;
}
if (n > MFRC522_MAX_LEN) {
n = MFRC522_MAX_LEN;
}
//Reading the received data in FIFO
for (i = 0; i < n; i++) {
backData[i] = TM_MFRC522_ReadRegister(MFRC522_REG_FIFO_DATA);
}
}
} else {
status = MI_ERR;
}
}
return status;
}
TM_MFRC522_Status_t TM_MFRC522_Anticoll(uint8_t* serNum) {
TM_MFRC522_Status_t status;
uint8_t i;
uint8_t serNumCheck = 0;
uint16_t unLen;
TM_MFRC522_WriteRegister(MFRC522_REG_BIT_FRAMING, 0x00); //TxLastBists = BitFramingReg[2..0]
serNum[0] = PICC_ANTICOLL;
serNum[1] = 0x20;
status = TM_MFRC522_ToCard(PCD_TRANSCEIVE, serNum, 2, serNum, &unLen);
if (status == MI_OK) {
//Check card serial number
for (i = 0; i < 4; i++) {
serNumCheck ^= serNum[i];
}
if (serNumCheck != serNum[i]) {
status = MI_ERR;
}
}
return status;
}
void TM_MFRC522_CalculateCRC(uint8_t* pIndata, uint8_t len, uint8_t* pOutData) {
uint8_t i, n;
TM_MFRC522_ClearBitMask(MFRC522_REG_DIV_IRQ, 0x04); //CRCIrq = 0
TM_MFRC522_SetBitMask(MFRC522_REG_FIFO_LEVEL, 0x80); //Clear the FIFO pointer
//Write_MFRC522(CommandReg, PCD_IDLE);
//Writing data to the FIFO
for (i = 0; i < len; i++) {
TM_MFRC522_WriteRegister(MFRC522_REG_FIFO_DATA, *(pIndata+i));
}
TM_MFRC522_WriteRegister(MFRC522_REG_COMMAND, PCD_CALCCRC);
//Wait CRC calculation is complete
i = 0xFF;
do {
n = TM_MFRC522_ReadRegister(MFRC522_REG_DIV_IRQ);
i--;
} while ((i!=0) && !(n&0x04)); //CRCIrq = 1
//Read CRC calculation result
pOutData[0] = TM_MFRC522_ReadRegister(MFRC522_REG_CRC_RESULT_L);
pOutData[1] = TM_MFRC522_ReadRegister(MFRC522_REG_CRC_RESULT_M);
}
uint8_t TM_MFRC522_SelectTag(uint8_t* serNum) {
uint8_t i;
TM_MFRC522_Status_t status;
uint8_t size;
uint16_t recvBits;
uint8_t buffer[9];
buffer[0] = PICC_SElECTTAG;
buffer[1] = 0x70;
for (i = 0; i < 5; i++) {
buffer[i+2] = *(serNum+i);
}
TM_MFRC522_CalculateCRC(buffer, 7, &buffer[7]); //??
status = TM_MFRC522_ToCard(PCD_TRANSCEIVE, buffer, 9, buffer, &recvBits);
if ((status == MI_OK) && (recvBits == 0x18)) {
size = buffer[0];
} else {
size = 0;
}
return size;
}
TM_MFRC522_Status_t TM_MFRC522_Auth(uint8_t authMode, uint8_t BlockAddr, uint8_t* Sectorkey, uint8_t* serNum) {
TM_MFRC522_Status_t status;
uint16_t recvBits;
uint8_t i;
uint8_t buff[12];
//Verify the command block address + sector + password + card serial number
buff[0] = authMode;
buff[1] = BlockAddr;
for (i = 0; i < 6; i++) {
buff[i+2] = *(Sectorkey+i);
}
for (i=0; i<4; i++) {
buff[i+8] = *(serNum+i);
}
status = TM_MFRC522_ToCard(PCD_AUTHENT, buff, 12, buff, &recvBits);
if ((status != MI_OK) || (!(TM_MFRC522_ReadRegister(MFRC522_REG_STATUS2) & 0x08))) {
status = MI_ERR;
}
return status;
}
TM_MFRC522_Status_t TM_MFRC522_Read(uint8_t blockAddr, uint8_t* recvData) {
TM_MFRC522_Status_t status;
uint16_t unLen;
recvData[0] = PICC_READ;
recvData[1] = blockAddr;
TM_MFRC522_CalculateCRC(recvData,2, &recvData[2]);
status = TM_MFRC522_ToCard(PCD_TRANSCEIVE, recvData, 4, recvData, &unLen);
if ((status != MI_OK) || (unLen != 0x90)) {
status = MI_ERR;
}
return status;
}
TM_MFRC522_Status_t TM_MFRC522_Write(uint8_t blockAddr, uint8_t* writeData) {
TM_MFRC522_Status_t status;
uint16_t recvBits;
uint8_t i;
uint8_t buff[18];
buff[0] = PICC_WRITE;
buff[1] = blockAddr;
TM_MFRC522_CalculateCRC(buff, 2, &buff[2]);
status = TM_MFRC522_ToCard(PCD_TRANSCEIVE, buff, 4, buff, &recvBits);
if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A)) {
status = MI_ERR;
}
if (status == MI_OK) {
//Data to the FIFO write 16Byte
for (i = 0; i < 16; i++) {
buff[i] = *(writeData+i);
}
TM_MFRC522_CalculateCRC(buff, 16, &buff[16]);
status = TM_MFRC522_ToCard(PCD_TRANSCEIVE, buff, 18, buff, &recvBits);
if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A)) {
status = MI_ERR;
}
}
return status;
}
void TM_MFRC522_Halt(void) {
uint16_t unLen;
uint8_t buff[4];
buff[0] = PICC_HALT;
buff[1] = 0;
TM_MFRC522_CalculateCRC(buff, 2, &buff[2]);
TM_MFRC522_ToCard(PCD_TRANSCEIVE, buff, 4, buff, &unLen);
}
Geçen mesajda gösterdiğin resme göre Kanal 2 MOSI , Kanal 3 MISO olmalı yani etiketlerde yazdığı gibi. Fakat Kanal 2'de 0xEE adresinden sonra 92 datası gelmiş. Mantıken EE'nin ardından 0x00 gelmesi gerekirdi. 0xFF gelen kısım MISO yani RC522'den gelen data anladığım kadarı ile. MX_SPI1_Init fonksiyonunu bu verdiğin kodlar içinden göremiyorum. Eklersen onu da inceleyelim.
Şu fonksiyonu çalıştırıp dönüş değerini söyleyebilir misin ?
While kodundan önceye koyarsan sevinirim.
uint8_t Version_Value = 0;
Version_Value = TM_MFRC522_ReadRegister(MFRC522_REG_VERSION);
@MrDarK hocam while in üstüne koyduğumda analizör yakalayamıyor while in içindeykende 0xEE den sonra 0x00 dönüyor şuan,çok tuhaf bir durumdayım. pull_up değil miso ondan olabilirmi ?
(https://postimg.cc/image/f682v58ul/)
mx_spi1_init kodları aşağıda
static void MX_SPI1_Init(void)
{
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
haberleştirdim rc522 yi. kartın id sini okuyabiliyorum fakat karta veri yazıp okumak istiyorum datasheet de anlayamadım tam olarak nasıl veri yazılıp okunacağını karta veri yazıp okuyan arkadaş varmı mantığını anlatabilecek ?
Araştırma yapmıyorsun görkem...
https://www.picproje.org/index.php?topic=52963.0
@MrDarK hocam o yazınızı okudum ve araştırıyorum da data bloklarına ulaşmak için key A ve access bitleri isteniyor fakat key A 6 byte access bitleri 4 byte key A ve access bitleriyle ilgili detaylı açıklama bulamadım o yüzden data bloklarına ulaşamıyorum.
Arkadaşlar hiç bilgisi olan yokmu kartta veri yazıp okuyabilmekle ilgili günlerdir uğraşıyorum key A access bitleri ve key B gönderip onay almakta sıkıntı çekiyorum arduino kodlarınıda inceledim
kullandığım kod bloğu şu şekilde
ilk değişkene 0x60 key A adres bilgisini yazıyorum 2. değişken e hangi sektor e erişeceğimi 3. değişken e 6 byte 0xff key bilgisini ve son olarak kartın id sini yazıyorum ama dönüşü hataya düşüyor sektör izni alamıyorum
M_MFRC522_Status_t TM_MFRC522_Auth(uint8_t authMode, uint8_t BlockAddr, uint8_t* Sectorkey, uint8_t* serNum) {
TM_MFRC522_Status_t status;
uint16_t recvBits;
uint8_t i;
uint8_t buff[12];
//Verify the command block address + sector + password + card serial number
buff[0] = authMode;
buff[1] = BlockAddr;
for (i = 0; i < 6; i++) {
buff[i+2] = *(Sectorkey+i);
}
for (i=0; i<4; i++) {
buff[i+8] = *(serNum+i);
}
status = TM_MFRC522_ToCard(PCD_AUTHENT, buff, 12, buff, &recvBits);
if ((status != MI_OK) || (!(TM_MFRC522_ReadRegister(MFRC522_REG_STATUS2) & 0x08))) {
status = MI_ERR;
}
return status;
}
karta veri yazan fonksiyon aşağıda
TM_MFRC522_Status_t TM_MFRC522_ToCard(uint8_t command, uint8_t* sendData, uint8_t sendLen, uint8_t* backData, uint16_t* backLen) {
TM_MFRC522_Status_t status = MI_ERR;
uint8_t irqEn = 0x00;
uint8_t waitIRq = 0x00;
uint8_t lastBits;
uint8_t n;
uint16_t i;
switch (command) {
case PCD_AUTHENT: {
irqEn = 0x12;
waitIRq = 0x10;
break;
}
case PCD_TRANSCEIVE: {
irqEn = 0x77;
waitIRq = 0x30;
break;
}
default:
break;
}
TM_MFRC522_WriteRegister(MFRC522_REG_COMM_IE_N, irqEn | 0x80);
TM_MFRC522_ClearBitMask(MFRC522_REG_COMM_IRQ, 0x80);
TM_MFRC522_SetBitMask(MFRC522_REG_FIFO_LEVEL, 0x80);
TM_MFRC522_WriteRegister(MFRC522_REG_COMMAND, PCD_IDLE);
//Writing data to the FIFO
for (i = 0; i < sendLen; i++) {
TM_MFRC522_WriteRegister(MFRC522_REG_FIFO_DATA, sendData[i]);
}
//Execute the command
TM_MFRC522_WriteRegister(MFRC522_REG_COMMAND, command);
if (command == PCD_TRANSCEIVE) {
TM_MFRC522_SetBitMask(MFRC522_REG_BIT_FRAMING, 0x80); //StartSend=1,transmission of data starts
}
//Waiting to receive data to complete
i = 2000; //i according to the clock frequency adjustment, the operator M1 card maximum waiting time 25ms???
do {
//CommIrqReg[7..0]
//Set1 TxIRq RxIRq IdleIRq HiAlerIRq LoAlertIRq ErrIRq TimerIRq
n = TM_MFRC522_ReadRegister(MFRC522_REG_COMM_IRQ);
i--;
} while ((i!=0) && !(n&0x01) && !(n&waitIRq));
TM_MFRC522_ClearBitMask(MFRC522_REG_BIT_FRAMING, 0x80); //StartSend=0
if (i != 0) {
if (!(TM_MFRC522_ReadRegister(MFRC522_REG_ERROR) & 0x1B)) {
status = MI_OK;
if (n & irqEn & 0x01) {
status = MI_NOTAGERR;
}
if (command == PCD_TRANSCEIVE) {
n = TM_MFRC522_ReadRegister(MFRC522_REG_FIFO_LEVEL);
lastBits = TM_MFRC522_ReadRegister(MFRC522_REG_CONTROL) & 0x07;
if (lastBits) {
*backLen = (n - 1) * 8 + lastBits;
} else {
*backLen = n * 8;
}
if (n == 0) {
n = 1;
}
if (n > MFRC522_MAX_LEN) {
n = MFRC522_MAX_LEN;
}
//Reading the received data in FIFO
for (i = 0; i < n; i++) {
backData[i] = TM_MFRC522_ReadRegister(MFRC522_REG_FIFO_DATA);
}
}
} else {
status = MI_ERR;
}
}
return status;
}
Kartın ilgili sektörünü nfc içeren bir okuyucu veya telefon ile okuyun. Anahtarının 6 byte ff değeri olduğundan emin olduktan sonra kod konusunda inceleme yapılabilir.
Hocam telefondan okudum görüntüsü aşağıda 6 byte 0xff
(https://postimg.cc/image/a8zas5d11/)
Kodunuzu debug yaparak hatanın nerede olduğunu tespit etmeniz lazım. Bu kod kalabalığı içinde yorum yapılamaz ne yazık ki. Ayrıca library'nin parçalarını atıyorsunuz. mantıken bunları kullandığınız kodun başka olması lazım. Kartın seri numarasını her seferinde okuyabiliyor musun ? Ondan sonra auth işleminde mi yoksa write sonucunda mı hata alıyorsun onu öğrenmek lazım. Birde kullandığın library'i tanımak lazım debug yapmak lazım. Eğer olmuyorsa yapamıyorsan örnek kodla çalışan bir library ara kendine derim.
kartın id sini okumada sorun yok her seferinde okuyabiliyorum. sırasıyla atuh işleminde ve write işlemin de hata alıyorum. dikkatimi çeken birşey var atuh işleminde sadece key a ,sektör ,kart id bilgisi gönderiliyor access bilgisi gönderilmiyor arduino örneklerindede baktım access bilgisi gönderilmeden sadece key a ile işlem başarıya ulaşmış nasıl ulaşabiliyor ?
@MrDarK hocam dan başka uğraşan olmadımı mfrc522 rfid ile bir karta veri yazamadık kesin basit bir noktayı atlıyorum.
Görkem ustam. Yaptıysan okuma için hangi yolu izledin? Bizle de paylaşır mısın?
Arduino ve RFİD ile yapılmış içecek makinesi projeleri var belki fikir verebilir.
http://www.avbrand.com/projects/popcard/
http://blog.tkjelectronics.dk/2015/02/iot-arduino-vending-machine/