Picproje Elektronik Sitesi

MİKRODENETLEYİCİLER => ARM => Cortex ARM => Konuyu başlatan: kkeess - 26 Kasım 2018, 21:46:28

Başlık: STM32F0 ve RDID RC522, SPI ile haberleşme
Gönderen: kkeess - 26 Kasım 2018, 21:46:28
stm32f0 ve rc522 rfid kartını SPI ile haberleştirmeye çalışıyorum. f4 ve f1 için yazılmış kodlar buldum f0 kütüphanede gerekli değişimleri yaptım ama RFİD okuma yapmıyor. SPI ayarlarında F4'ten farklı olarak bi ayar mı vardır acaba? Kodlar aşağıdaki gibidir.

SPI Kütüphanesi
-----------------------------------------------------
#include "stm32f0xx_gpio.h"
#include "stm32f0xx_rcc.h"
#include "stm32f0xx_misc.h"
#include "stm32f0xx_spi.h"
#include "stm32f0xx_tim.h"
#include "stm32f0xx_usart.h"
#include "rc522.h"
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "SPI.h"
#include "tim2_delay.h"


/* SPI1 Enable */
void SPI1_Config(void)
{
SPI_InitTypeDef SPI1_InitStructure;

SPI1_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI1_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI1_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI1_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI1_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI1_InitStructure.SPI_NSS =SPI_NSS_Soft;
SPI1_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
SPI1_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI1_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1,&SPI1_InitStructure);


SPI_SSOutputCmd(SPI1,ENABLE);
SPI_Cmd(SPI1,ENABLE);

//-----------------------------------------------------------------------


} /* SPI1 Config Bitis */
uint8_t SPI1_SendByte(uint8_t data)
    {
while (!(SPI1->SR & SPI_SR_TXE));
SPI1->DR=data;
while (!(SPI1->SR & SPI_SR_RXNE));
return SPI1->DR;
}
void SPI1_WriteReg(uint8_t address, uint8_t value) {
SPI1_NSS_ON(); // CS_Low
SPI1_SendByte(address);
SPI1_SendByte(value);
SPI1_NSS_OFF(); // CS_HIGH
}

uint8_t SPI1_ReadReg(uint8_t address) {
uint8_t val;

SPI1_NSS_ON(); // CS_Low
SPI1_SendByte(address);
val = SPI1_SendByte(0x00);
SPI1_NSS_OFF(); // CS_HIGH
return val;
}

Main
---------------------------------------------------
#include "stm32f0xx_gpio.h"
#include "stm32f0xx_rcc.h"
#include "stm32f0xx_misc.h"
#include "stm32f0xx_spi.h"
#include "stm32f0xx_tim.h"
#include "stm32f0xx_usart.h"
#include "rc522.h"
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "SPI.h"
#include "tim2_delay.h";
#include "stdint.h"

#define SPI1_NSS_ON() GPIO_ResetBits(GPIOC,GPIO_Pin_0)
#define SPI1_NSS_OFF() GPIO_SetBits(GPIOC,GPIO_Pin_0)
#define led_1_ON() GPIO_SetBits(GPIOC,GPIO_Pin_8)
#define led_1_OFF() GPIO_ResetBits(GPIOC,GPIO_Pin_8)
#define led_2_ON() GPIO_SetBits(GPIOC,GPIO_Pin_9)
#define led_2_OFF() GPIO_ResetBits(GPIOC,GPIO_Pin_9)




#define RX_BUF_SIZE 80
volatile char RX_FLAG_END_LINE = 0;
volatile char RXi;
volatile char RXc;
volatile char RX_BUF[RX_BUF_SIZE] = {'\0'};
volatile char buffer[50];


void RCC_Config(void);
void GPIO_Config(void);
void USART1_Config(void);
void USART1_IRQHandler(void);
void clear_RXBuffer(void);
void SPI1_Config(void);

uint8_t CardID[5];

int main(void)
{
TIM2_init();
RCC_Config();
GPIO_Config();
USART1_Config();
SPI1_Config();
TIM2_init();
SPI1_NSS_OFF();
MFRC522_Init();
SPI1_NSS_OFF();
led_1_ON();
delay_ms(100);

USARTSend("Hello\n");
char a="asd";


    while(1)
    {
    if(MFRC522_Check(CardID)==MI_OK)
    {

    led_2_OFF();
    sprintf(buffer, "0x%02x\n0x%02x\n0x%02x\n0x%02x\n0x%02x", CardID[0], CardID[1], CardID[2], CardID[3], CardID[4]);
    USARTSend(buffer);
    char a="asd";

    }
    else if (MFRC522_Check(CardID)==MI_ERR);
    {
    led_2_ON();

    }


}/* while bitis */


} /* Main bitis */

void RCC_Config(void)
{
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA|RCC_AHBPeriph_GPIOC,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
} /* RCC end */

void GPIO_Config(void)
{
/* USART1 GPIO Config */
GPIO_InitTypeDef USART1_Pin;

USART1_Pin.GPIO_Mode = GPIO_Mode_AF;
USART1_Pin.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;
USART1_Pin.GPIO_OType=GPIO_OType_PP;
USART1_Pin.GPIO_PuPd = GPIO_PuPd_NOPULL;
USART1_Pin.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&USART1_Pin);

GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_1);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_1);

/* SPI1 GPIO Connfig */
GPIO_InitTypeDef SPI1_Pin;

SPI1_Pin.GPIO_Mode = GPIO_Mode_AF;
SPI1_Pin.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
SPI1_Pin.GPIO_OType = GPIO_OType_PP;
SPI1_Pin.GPIO_PuPd =GPIO_PuPd_NOPULL;
SPI1_Pin.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&SPI1_Pin);

GPIO_PinAFConfig(GPIOA,GPIO_PinSource5,GPIO_AF_0);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource6,GPIO_AF_0);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource7,GPIO_AF_0);

/* LED ve SS/CS pin Config*/
GPIO_InitTypeDef LED;

LED.GPIO_Mode = GPIO_Mode_OUT;
LED.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_8|GPIO_Pin_9;
LED.GPIO_OType = GPIO_OType_PP;
LED.GPIO_PuPd = GPIO_PuPd_NOPULL;
LED.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&LED);

LED.GPIO_Mode = GPIO_Mode_OUT;
LED.GPIO_Pin = GPIO_Pin_4;
LED.GPIO_OType = GPIO_OType_PP;
LED.GPIO_PuPd = GPIO_PuPd_NOPULL;
LED.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&LED);

} /* GPIO END*/

void USART1_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;

/* Enable Usart Interupt*/
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
NVIC_Init(&NVIC_InitStructure);

USART_InitTypeDef USART1_InitStructure;

/*ENABLE Usart1*/
USART1_InitStructure.USART_BaudRate = 9600;
USART1_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
USART1_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART1_InitStructure.USART_Parity = USART_Parity_No;
USART1_InitStructure.USART_StopBits = USART_StopBits_1;
USART1_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_Init(USART1,&USART1_InitStructure);

/* Enable Usart1 */
USART_Cmd(USART1,ENABLE);

/* Enable USART1 Receive interrupt */
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);

} /* USART1 END*/

void USART1_IRQHandler(void)
{
if((USART1->ISR & USART_FLAG_RXNE)!= RESET)
{
RXc=USART_ReceiveData(USART1);
RX_BUF[RXi]= RXc;
RXi++;

USART_SendData(USART1,RXc);
}

} /* USART1 Kesme Bitis */

void USARTSend(char *pucBuffer)
{
    while (*pucBuffer)
    {
        USART_SendData(USART1, *pucBuffer++);
        while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
        {
        }
    }
}

void clear_RXBuffer(void)
{
for (RXi=0; RXi<RX_BUF_SIZE; RXi++)
RX_BUF[RXi] = '\0';
RXi = 0;
}
----------------------------------------------------------------
RC522 Kütüphanesi
---------------------------------------------------------------
// Mifare RC522 RFID Card reader 13.56 MHz
// STM32F103 RFID RC522 SPI1

// PA4  - (OUT) SPI1_NSS
// PA5  - (OUT) SPI1_SCK
// PA6  - (IN) SPI1_MISO (Master In)
// PA7  - (OUT) SPI1_MOSI (Master Out)

// MFRC522 STM32F103 DESCRIPTION
// CS (SDA) PA4 SPI1_NSS Chip select for SPI
// SCK PA5 SPI1_SCK Serial Clock for SPI
// MOSI PA7 SPI1_MOSI Master In Slave Out for SPI
// MISO PA6 SPI1_MISO Master Out Slave In for SPI
// IRQ - Irq
// GND GND Ground
// RST 3.3V Reset pin (3.3V)
// VCC 3.3V 3.3V power

#include "stm32f0xx_gpio.h"
#include "stm32f0xx_rcc.h"
#include "stm32f0xx_misc.h"
#include "stm32f0xx_spi.h"
#include "stm32f0xx_tim.h"
#include "stm32f0xx_usart.h"
#include "rc522.h"
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "SPI.h"
#include "tim2_delay.h";
#include "stdint.h"

void MFRC522_Init(void) {
MFRC522_Reset();
SPI1_NSS_OFF();
MFRC522_WriteRegister(MFRC522_REG_T_MODE, 0x8D);
MFRC522_WriteRegister(MFRC522_REG_T_PRESCALER, 0x3E);
MFRC522_WriteRegister(MFRC522_REG_T_RELOAD_L, 30);
MFRC522_WriteRegister(MFRC522_REG_T_RELOAD_H, 0);
//MFRC522_WriteRegister(MFRC522_REG_RF_CFG, 0x70); // 48dB gain
MFRC522_WriteRegister(MFRC522_REG_TX_AUTO, 0x40);
MFRC522_WriteRegister(MFRC522_REG_MODE, 0x3D);
MFRC522_AntennaOn(); // Open the antenna
}

uint8_t MFRC522_Check(uint8_t * id) {
uint8_t status;
status = MFRC522_Request(PICC_REQIDL, id); // Find cards, return card type
if (status == MI_OK) status = MFRC522_Anticoll(id); // Card detected. Anti-collision, return card serial number 4 bytes
MFRC522_Halt(); // Command card into hibernation
return status;
}

uint8_t 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 MFRC522_WriteRegister(uint8_t addr, uint8_t val) {
addr = (addr << 1) & 0x7E; // Address format: 0XXXXXX0
    SPI1_WriteReg(addr, val);
}

uint8_t MFRC522_ReadRegister(uint8_t addr) {
uint8_t val;

addr = ((addr << 1) & 0x7E) | 0x80;
val = SPI1_ReadReg(addr);
return val;
}

void MFRC522_SetBitMask(uint8_t reg, uint8_t mask) {
MFRC522_WriteRegister(reg, MFRC522_ReadRegister(reg) | mask);
}

void MFRC522_ClearBitMask(uint8_t reg, uint8_t mask){
MFRC522_WriteRegister(reg, MFRC522_ReadRegister(reg) & (~mask));
}

void MFRC522_AntennaOn(void) {
uint8_t temp;

temp = MFRC522_ReadRegister(MFRC522_REG_TX_CONTROL);
if (!(temp & 0x03)) MFRC522_SetBitMask(MFRC522_REG_TX_CONTROL, 0x03);
}

void MFRC522_AntennaOff(void) {
MFRC522_ClearBitMask(MFRC522_REG_TX_CONTROL, 0x03);
}

void MFRC522_Reset(void) {
MFRC522_WriteRegister(MFRC522_REG_COMMAND, PCD_RESETPHASE);
}

uint8_t MFRC522_Request(uint8_t reqMode, uint8_t * TagType) {
uint8_t status;
uint16_t backBits; // The received data bits

MFRC522_WriteRegister(MFRC522_REG_BIT_FRAMING, 0x07); // TxLastBists = BitFramingReg[2..0]
TagType[0] = reqMode;
status = MFRC522_ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits);
if ((status != MI_OK) || (backBits != 0x10)) status = MI_ERR;
return status;
}

uint8_t MFRC522_ToCard(uint8_t command, uint8_t * sendData, uint8_t sendLen, uint8_t * backData, uint16_t * backLen) {
uint8_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;
}

MFRC522_WriteRegister(MFRC522_REG_COMM_IE_N, irqEn | 0x80);
MFRC522_ClearBitMask(MFRC522_REG_COMM_IRQ, 0x80);
MFRC522_SetBitMask(MFRC522_REG_FIFO_LEVEL, 0x80);
MFRC522_WriteRegister(MFRC522_REG_COMMAND, PCD_IDLE);

// Writing data to the FIFO
for (i = 0; i < sendLen; i++) MFRC522_WriteRegister(MFRC522_REG_FIFO_DATA, sendData[i]);

// Execute the command
MFRC522_WriteRegister(MFRC522_REG_COMMAND, command);
if (command == PCD_TRANSCEIVE) 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 = MFRC522_ReadRegister(MFRC522_REG_COMM_IRQ);
i--;
} while ((i!=0) && !(n&0x01) && !(n&waitIRq));

MFRC522_ClearBitMask(MFRC522_REG_BIT_FRAMING, 0x80); // StartSend=0

if (i != 0)  {
if (!(MFRC522_ReadRegister(MFRC522_REG_ERROR) & 0x1B)) {
status = MI_OK;
if (n & irqEn & 0x01) status = MI_NOTAGERR;
if (command == PCD_TRANSCEIVE) {
n = MFRC522_ReadRegister(MFRC522_REG_FIFO_LEVEL);
lastBits = 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;
for (i = 0; i < n; i++) backData[i] = MFRC522_ReadRegister(MFRC522_REG_FIFO_DATA); // Reading the received data in FIFO
}
} else status = MI_ERR;
}
return status;
}

uint8_t MFRC522_Anticoll(uint8_t * serNum) {
uint8_t status;
uint8_t i;
uint8_t serNumCheck = 0;
uint16_t unLen;

MFRC522_WriteRegister(MFRC522_REG_BIT_FRAMING, 0x00); // TxLastBists = BitFramingReg[2..0]
serNum[0] = PICC_ANTICOLL;
serNum[1] = 0x20;
status = 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 MFRC522_CalculateCRC(uint8_t *  pIndata, uint8_t len, uint8_t * pOutData) {
uint8_t i, n;

MFRC522_ClearBitMask(MFRC522_REG_DIV_IRQ, 0x04); // CRCIrq = 0
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++) MFRC522_WriteRegister(MFRC522_REG_FIFO_DATA, *(pIndata+i));
MFRC522_WriteRegister(MFRC522_REG_COMMAND, PCD_CALCCRC);

// Wait CRC calculation is complete
i = 0xFF;
do {
n = MFRC522_ReadRegister(MFRC522_REG_DIV_IRQ);
i--;
} while ((i!=0) && !(n&0x04)); // CRCIrq = 1

// Read CRC calculation result
pOutData[0] = MFRC522_ReadRegister(MFRC522_REG_CRC_RESULT_L);
pOutData[1] = MFRC522_ReadRegister(MFRC522_REG_CRC_RESULT_M);
}

uint8_t MFRC522_SelectTag(uint8_t * serNum) {
uint8_t i;
uint8_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);
MFRC522_CalculateCRC(buffer, 7, &buffer[7]); //??
status = MFRC522_ToCard(PCD_TRANSCEIVE, buffer, 9, buffer, &recvBits);
if ((status == MI_OK) && (recvBits == 0x18)) size = buffer[0]; else size = 0;
return size;
}

uint8_t MFRC522_Auth(uint8_t authMode, uint8_t BlockAddr, uint8_t * Sectorkey, uint8_t * serNum) {
uint8_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 = MFRC522_ToCard(PCD_AUTHENT, buff, 12, buff, &recvBits);
if ((status != MI_OK) || (!(MFRC522_ReadRegister(MFRC522_REG_STATUS2) & 0x08))) status = MI_ERR;
return status;
}

uint8_t MFRC522_Read(uint8_t blockAddr, uint8_t * recvData) {
uint8_t status;
uint16_t unLen;

recvData[0] = PICC_READ;
recvData[1] = blockAddr;
MFRC522_CalculateCRC(recvData,2, &recvData[2]);
status = MFRC522_ToCard(PCD_TRANSCEIVE, recvData, 4, recvData, &unLen);
if ((status != MI_OK) || (unLen != 0x90)) status = MI_ERR;
return status;
}

uint8_t MFRC522_Write(uint8_t blockAddr, uint8_t * writeData) {
uint8_t status;
uint16_t recvBits;
uint8_t i;
uint8_t buff[18];

buff[0] = PICC_WRITE;
buff[1] = blockAddr;
MFRC522_CalculateCRC(buff, 2, &buff[2]);
status = 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);
MFRC522_CalculateCRC(buff, 16, &buff[16]);
status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 18, buff, &recvBits);
if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A)) status = MI_ERR;
}
return status;
}

void MFRC522_Halt(void)
{
uint16_t unLen;
uint8_t buff[4];

buff[0] = PICC_HALT;
buff[1] = 0;
MFRC522_CalculateCRC(buff, 2, &buff[2]);
MFRC522_ToCard(PCD_TRANSCEIVE, buff, 4, buff, &unLen);
}