STM32F103C8T6 – Giao tiếp thẻ nhớ – Phần 2

Phần này mình sẽ thử hoạt động của module SPI.
Trên KIT mình có thì thẻ nhớ được gắn với SPI1 theo sơ đồ

Trong project sử dụng Timer để tạo delay

File delay.h

#ifndef DELAY_H_
#define DELAY_H_

#include "stm32f10x.h"

void Delay_Init(void);
void Delay_Us(uint32_t u32DelayInUs);
void Delay_Ms(uint32_t u32DelayInMs);

#endif

File delay.c

#include "delay.h"

static void Timer_Init(void)
{
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

	uint16_t PrescalerValue = 0;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	
	PrescalerValue = (uint16_t) (SystemCoreClock / 1000000) - 1;
	/* Time base configuration */
	TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
	TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
	
	/* TIM3 enable counter */
	TIM_Cmd(TIM3, ENABLE);
}

void Delay_Init(void)
{
	Timer_Init();
}

void Delay_Us(uint32_t u32DelayInUs)
{
	TIM_SetCounter(TIM3, 0);
	while(TIM_GetCounter(TIM3) < u32DelayInUs);
}

void Delay_Ms(uint32_t u32DelayInMs)
{
	while (u32DelayInMs) {
		Delay_Us(1000);
		--u32DelayInMs;
	}
}

Thư viện SPI

File spi.h

#ifndef SPI_H_
#define SPI_H_

#include "stm32f10x.h"

void My_SPI_Init(void);
uint8_t My_SPI_Exchange(uint8_t u8Data);

#endif

File spi.c

#include "spi.h"

void My_SPI_Init(void)
{
	GPIO_InitTypeDef gpioInit;
	SPI_InitTypeDef   SPI_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	gpioInit.GPIO_Mode=GPIO_Mode_AF_PP;
	gpioInit.GPIO_Speed=GPIO_Speed_50MHz;
	gpioInit.GPIO_Pin=GPIO_Pin_5 | GPIO_Pin_7;
	GPIO_Init(GPIOA, &gpioInit);
	
	gpioInit.GPIO_Mode=GPIO_Mode_Out_PP;
	gpioInit.GPIO_Speed=GPIO_Speed_50MHz;
	gpioInit.GPIO_Pin=GPIO_Pin_4;
	GPIO_Init(GPIOA, &gpioInit);
	GPIO_SetBits(GPIOA, GPIO_Pin_4);
	
	gpioInit.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	gpioInit.GPIO_Speed=GPIO_Speed_50MHz;
	gpioInit.GPIO_Pin=GPIO_Pin_6;
	GPIO_Init(GPIOA, &gpioInit);
	
	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
	SPI_InitStructure.SPI_CRCPolynomial = 7;
	SPI_Init(SPI1, &SPI_InitStructure);
	
	SPI_Cmd(SPI1, ENABLE);
}

uint8_t My_SPI_Exchange(uint8_t u8Data)
{
	SPI_I2S_SendData(SPI1, u8Data);
	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET) {
	}
	return SPI_I2S_ReceiveData(SPI1);
}

File main.c

#include "stm32f10x.h"
#include "delay.h"
#include "spi.h"

void My_GPIO_Init(void);

int main() {
	Delay_Init();
	My_SPI_Init();
	My_GPIO_Init();
	
	while(1) {
		GPIO_SetBits(GPIOC, GPIO_Pin_13);
		Delay_Ms(100);
		
		GPIO_ResetBits(GPIOA, GPIO_Pin_4);
		My_SPI_Exchange(0x19);
		GPIO_SetBits(GPIOA, GPIO_Pin_4);
		
		GPIO_ResetBits(GPIOC, GPIO_Pin_13);
		Delay_Ms(100);
		
		GPIO_ResetBits(GPIOA, GPIO_Pin_4);
		My_SPI_Exchange(0x86);
		GPIO_SetBits(GPIOA, GPIO_Pin_4);
	}
}

void My_GPIO_Init(void) {
	GPIO_InitTypeDef gpioInit;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	gpioInit.GPIO_Mode=GPIO_Mode_Out_PP;
	gpioInit.GPIO_Speed=GPIO_Speed_50MHz;
	gpioInit.GPIO_Pin=GPIO_Pin_13;
	GPIO_Init(GPIOC, &gpioInit);
}

Kết quả khi chạy chương trình

Project
https://drive.google.com/open?id=14RfkcCk8VCFRjIfTEDACS_0PaxmuMdnM