initial commit: oled, rc522, exti
This commit is contained in:
97
Core/Src/gpio.c
Normal file
97
Core/Src/gpio.c
Normal file
@ -0,0 +1,97 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file gpio.c
|
||||
* @brief This file provides code for the configuration
|
||||
* of all used GPIO pins.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "gpio.h"
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Configure GPIO */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
|
||||
/** Configure pins as
|
||||
* Analog
|
||||
* Input
|
||||
* Output
|
||||
* EVENT_OUT
|
||||
* EXTI
|
||||
*/
|
||||
void MX_GPIO_Init(void)
|
||||
{
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
|
||||
/* GPIO Ports Clock Enable */
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(LED0_GPIO_Port, LED0_Pin, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOA, RC522_CS_Pin|RC522_RST_Pin, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(LED_BTN1_GPIO_Port, LED_BTN1_Pin, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin : LED0_Pin */
|
||||
GPIO_InitStruct.Pin = LED0_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(LED0_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : RC522_CS_Pin RC522_RST_Pin */
|
||||
GPIO_InitStruct.Pin = RC522_CS_Pin|RC522_RST_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pin : LED_BTN1_Pin */
|
||||
GPIO_InitStruct.Pin = LED_BTN1_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(LED_BTN1_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pin : BTN1_Pin */
|
||||
GPIO_InitStruct.Pin = BTN1_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
HAL_GPIO_Init(BTN1_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/* EXTI interrupt init*/
|
||||
HAL_NVIC_SetPriority(EXTI9_5_IRQn, 1, 0);
|
||||
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
|
||||
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 2 */
|
||||
|
||||
/* USER CODE END 2 */
|
115
Core/Src/i2c.c
Normal file
115
Core/Src/i2c.c
Normal file
@ -0,0 +1,115 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file i2c.c
|
||||
* @brief This file provides code for the configuration
|
||||
* of the I2C instances.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "i2c.h"
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
I2C_HandleTypeDef hi2c1;
|
||||
|
||||
/* I2C1 init function */
|
||||
void MX_I2C1_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN I2C1_Init 0 */
|
||||
|
||||
/* USER CODE END I2C1_Init 0 */
|
||||
|
||||
/* USER CODE BEGIN I2C1_Init 1 */
|
||||
|
||||
/* USER CODE END I2C1_Init 1 */
|
||||
hi2c1.Instance = I2C1;
|
||||
hi2c1.Init.ClockSpeed = 100000;
|
||||
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
|
||||
hi2c1.Init.OwnAddress1 = 0;
|
||||
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
|
||||
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
|
||||
hi2c1.Init.OwnAddress2 = 0;
|
||||
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
|
||||
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
|
||||
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN I2C1_Init 2 */
|
||||
|
||||
/* USER CODE END I2C1_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
|
||||
{
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
if(i2cHandle->Instance==I2C1)
|
||||
{
|
||||
/* USER CODE BEGIN I2C1_MspInit 0 */
|
||||
|
||||
/* USER CODE END I2C1_MspInit 0 */
|
||||
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
/**I2C1 GPIO Configuration
|
||||
PB6 ------> I2C1_SCL
|
||||
PB7 ------> I2C1_SDA
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/* I2C1 clock enable */
|
||||
__HAL_RCC_I2C1_CLK_ENABLE();
|
||||
/* USER CODE BEGIN I2C1_MspInit 1 */
|
||||
|
||||
/* USER CODE END I2C1_MspInit 1 */
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* i2cHandle)
|
||||
{
|
||||
|
||||
if(i2cHandle->Instance==I2C1)
|
||||
{
|
||||
/* USER CODE BEGIN I2C1_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END I2C1_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_I2C1_CLK_DISABLE();
|
||||
|
||||
/**I2C1 GPIO Configuration
|
||||
PB6 ------> I2C1_SCL
|
||||
PB7 ------> I2C1_SDA
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6);
|
||||
|
||||
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_7);
|
||||
|
||||
/* USER CODE BEGIN I2C1_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END I2C1_MspDeInit 1 */
|
||||
}
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
254
Core/Src/main.c
Normal file
254
Core/Src/main.c
Normal file
@ -0,0 +1,254 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : main.c
|
||||
* @brief : Main program body
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
#include "i2c.h"
|
||||
#include "spi.h"
|
||||
#include "usart.h"
|
||||
#include "gpio.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include <stdio.h>
|
||||
|
||||
#include "oled.h"
|
||||
#include "rc522.h"
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PTD */
|
||||
|
||||
/* USER CODE END PTD */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PD */
|
||||
|
||||
/* USER CODE END PD */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PM */
|
||||
|
||||
/* USER CODE END PM */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
/* USER CODE BEGIN PV */
|
||||
uint8_t CardType[2] = {0};
|
||||
uint8_t CardID[4] = {0};
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
void SystemClock_Config(void);
|
||||
/* USER CODE BEGIN PFP */
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* Private user code ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN 0 */
|
||||
void format_hex_string(const uint8_t *values, char *buffer) {
|
||||
const char hex_chars[] = "0123456789ABCDEF";
|
||||
|
||||
// 处理第一个字节
|
||||
buffer[0] = hex_chars[values[0] >> 4];
|
||||
buffer[1] = hex_chars[values[0] & 0x0F];
|
||||
buffer[2] = '-';
|
||||
|
||||
// 处理第二个字节
|
||||
buffer[3] = hex_chars[values[1] >> 4];
|
||||
buffer[4] = hex_chars[values[1] & 0x0F];
|
||||
buffer[5] = '-';
|
||||
|
||||
// 处理第三个字节
|
||||
buffer[6] = hex_chars[values[2] >> 4];
|
||||
buffer[7] = hex_chars[values[2] & 0x0F];
|
||||
buffer[8] = '-';
|
||||
|
||||
// 处理第四个字节并终止字符串
|
||||
buffer[9] = hex_chars[values[3] >> 4];
|
||||
buffer[10] = hex_chars[values[3] & 0x0F];
|
||||
buffer[11] = '\0';
|
||||
}
|
||||
/* USER CODE END 0 */
|
||||
|
||||
/**
|
||||
* @brief The application entry point.
|
||||
* @retval int
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* 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_I2C1_Init();
|
||||
MX_USART1_UART_Init();
|
||||
MX_SPI1_Init();
|
||||
/* USER CODE BEGIN 2 */
|
||||
MFRC_Init();
|
||||
PCD_Reset();
|
||||
|
||||
OLED_Init();
|
||||
OLED_Clear();
|
||||
|
||||
OLED_ShowString(0,0,"Card scan...",12);
|
||||
/* USER CODE END 2 */
|
||||
|
||||
/* Infinite loop */
|
||||
/* USER CODE BEGIN WHILE */
|
||||
while (1)
|
||||
{
|
||||
const char status = PCD_Request(PICC_REQALL, CardType);
|
||||
if (CardType[0] == 0x04 && CardType[1] == 0x00)
|
||||
{
|
||||
OLED_ShowString(0,2,"Type: Classic",13);
|
||||
}
|
||||
else if (CardType[0] == 0x44 && CardType[1] == 0x00)
|
||||
{
|
||||
OLED_ShowString(0,2,"Type: Ultralight",16);
|
||||
}
|
||||
else
|
||||
{
|
||||
OLED_ShowString(0,2,"Type: Unknown",13);
|
||||
}
|
||||
|
||||
if (!status) {
|
||||
PCD_AntiColl(CardID);
|
||||
OLED_ShowString(0,4,"Card ID:",8);
|
||||
// show parsed card id with pattern: %x-%x-%x-%x
|
||||
char buffer[12];
|
||||
format_hex_string(CardID, buffer);
|
||||
OLED_ShowString(0,6,buffer,12);
|
||||
HAL_GPIO_WritePin(LED_BTN1_GPIO_Port, LED_BTN1_Pin, GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
HAL_Delay(200);
|
||||
/* USER CODE END WHILE */
|
||||
|
||||
/* USER CODE BEGIN 3 */
|
||||
}
|
||||
/* USER CODE END 3 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief System Clock Configuration
|
||||
* @retval None
|
||||
*/
|
||||
void SystemClock_Config(void)
|
||||
{
|
||||
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
|
||||
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
|
||||
|
||||
/** Initializes the RCC Oscillators according to the specified parameters
|
||||
* in the RCC_OscInitTypeDef structure.
|
||||
*/
|
||||
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
|
||||
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
|
||||
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
|
||||
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
|
||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
||||
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
|
||||
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Initializes the CPU, AHB and APB buses 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_DIV2;
|
||||
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
|
||||
|
||||
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 4 */
|
||||
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
|
||||
{
|
||||
if(GPIO_Pin == BTN1_Pin)
|
||||
{
|
||||
HAL_GPIO_WritePin(LED_BTN1_GPIO_Port, LED_BTN1_Pin, GPIO_PIN_RESET);
|
||||
CardType[0] = 0;
|
||||
CardType[1] = 0;
|
||||
CardID[0] = 0;
|
||||
CardID[1] = 0;
|
||||
CardID[2] = 0;
|
||||
CardID[3] = 0;
|
||||
OLED_ShowString(0,4, " ",8);
|
||||
OLED_ShowString(0,6, " ",12);
|
||||
}
|
||||
}
|
||||
/* USER CODE END 4 */
|
||||
|
||||
/**
|
||||
* @brief This function is executed in case of error occurrence.
|
||||
* @retval None
|
||||
*/
|
||||
void Error_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN Error_Handler_Debug */
|
||||
/* User can add his own implementation to report the HAL error return state */
|
||||
__disable_irq();
|
||||
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 /* USE_FULL_ASSERT */
|
187
Core/Src/oled.c
Normal file
187
Core/Src/oled.c
Normal file
@ -0,0 +1,187 @@
|
||||
#include "oled.h"
|
||||
#include "i2c.h"
|
||||
#include "oledfont.h" //头文件
|
||||
|
||||
uint8_t CMD_Data[] = {
|
||||
0xAE,
|
||||
0x00,
|
||||
0x10,
|
||||
0x40,
|
||||
0xB0,
|
||||
0x81,
|
||||
0xFF,
|
||||
0xA1,
|
||||
0xA6,
|
||||
0xA8,
|
||||
0x3F,
|
||||
0xC8,
|
||||
0xD3,
|
||||
0x00,
|
||||
0xD5,
|
||||
0x80,
|
||||
0xD8,
|
||||
0x05,
|
||||
0xD9,
|
||||
0xF1,
|
||||
0xDA,
|
||||
0x12,
|
||||
0xD8,
|
||||
0x30,
|
||||
0x8D,
|
||||
0x14,
|
||||
0xAF
|
||||
}; //初始化命令
|
||||
|
||||
|
||||
void WriteCmd(void) {
|
||||
uint8_t i = 0;
|
||||
for (i = 0; i < 27; i++) {
|
||||
HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x00,I2C_MEMADD_SIZE_8BIT, CMD_Data + i, 1, 0x100);
|
||||
}
|
||||
}
|
||||
|
||||
//向设备写控制命令
|
||||
void OLED_WR_CMD(uint8_t cmd) {
|
||||
HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x00,I2C_MEMADD_SIZE_8BIT, &cmd, 1, 0x100);
|
||||
}
|
||||
|
||||
//向设备写数据
|
||||
void OLED_WR_DATA(uint8_t data) {
|
||||
HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x40,I2C_MEMADD_SIZE_8BIT, &data, 1, 0x100);
|
||||
}
|
||||
|
||||
//初始化oled屏幕
|
||||
void OLED_Init(void) {
|
||||
HAL_Delay(200);
|
||||
|
||||
WriteCmd();
|
||||
}
|
||||
|
||||
//清屏
|
||||
void OLED_Clear(void) {
|
||||
uint8_t i, n;
|
||||
for (i = 0; i < 8; i++) {
|
||||
OLED_WR_CMD(0xb0 + i); //设置页地址(0~7)
|
||||
OLED_WR_CMD(0x00); //设置显示位置—列低地址
|
||||
OLED_WR_CMD(0x10); //设置显示位置—列高地址
|
||||
for (n = 0; n < 128; n++)
|
||||
OLED_WR_DATA(0); //更新显示
|
||||
}
|
||||
}
|
||||
|
||||
//开启OLED显示
|
||||
void OLED_Display_On(void) {
|
||||
OLED_WR_CMD(0X8D); //SET DCDC命令
|
||||
OLED_WR_CMD(0X14); //DCDC ON
|
||||
OLED_WR_CMD(0XAF); //DISPLAY ON
|
||||
}
|
||||
|
||||
//关闭OLED显示
|
||||
void OLED_Display_Off(void) {
|
||||
OLED_WR_CMD(0X8D); //SET DCDC命令
|
||||
OLED_WR_CMD(0X10); //DCDC OFF
|
||||
OLED_WR_CMD(0XAE); //DISPLAY OFF
|
||||
}
|
||||
|
||||
//坐标设置
|
||||
void OLED_Set_Pos(uint8_t x, uint8_t y) {
|
||||
OLED_WR_CMD(0xb0 + y);
|
||||
OLED_WR_CMD(((x & 0xf0) >> 4) | 0x10);
|
||||
OLED_WR_CMD(x & 0x0f);
|
||||
}
|
||||
|
||||
void OLED_On(void) {
|
||||
uint8_t i, n;
|
||||
for (i = 0; i < 8; i++) {
|
||||
OLED_WR_CMD(0xb0 + i); //设置页地址(0~7)
|
||||
OLED_WR_CMD(0x00); //设置显示位置—列低地址
|
||||
OLED_WR_CMD(0x10); //设置显示位置—列高地址
|
||||
for (n = 0; n < 128; n++)
|
||||
OLED_WR_DATA(1);
|
||||
} //更新显示
|
||||
}
|
||||
|
||||
unsigned int oled_pow(uint8_t m, uint8_t n) {
|
||||
unsigned int result = 1;
|
||||
while (n--)result *= m;
|
||||
return result;
|
||||
}
|
||||
|
||||
//显示2个数字
|
||||
//x,y :起点坐标
|
||||
//len :数字的位数
|
||||
//size:字体大小
|
||||
//mode:模式 0,填充模式;1,叠加模式
|
||||
//num:数值(0~4294967295);
|
||||
void OLED_ShowNum(uint8_t x, uint8_t y, unsigned int num, uint8_t len, uint8_t size2) {
|
||||
uint8_t t, temp;
|
||||
uint8_t enshow = 0;
|
||||
for (t = 0; t < len; t++) {
|
||||
temp = (num / oled_pow(10, len - t - 1)) % 10;
|
||||
if (enshow == 0 && t < (len - 1)) {
|
||||
if (temp == 0) {
|
||||
OLED_ShowChar(x + (size2 / 2) * t, y, ' ', size2);
|
||||
continue;
|
||||
} else enshow = 1;
|
||||
}
|
||||
OLED_ShowChar(x + (size2 / 2) * t, y, temp + '0', size2);
|
||||
}
|
||||
}
|
||||
|
||||
//在指定位置显示一个字符,包括部分字符
|
||||
//x:0~127
|
||||
//y:0~63
|
||||
//mode:0,反白显示;1,正常显示
|
||||
//size:选择字体 16/12
|
||||
void OLED_ShowChar(uint8_t x, uint8_t y, uint8_t chr, uint8_t Char_Size) {
|
||||
unsigned char c = 0, i = 0;
|
||||
c = chr - ' '; //得到偏移后的值
|
||||
if (x > 128 - 1) {
|
||||
x = 0;
|
||||
y = y + 2;
|
||||
}
|
||||
if (Char_Size == 16) {
|
||||
OLED_Set_Pos(x, y);
|
||||
for (i = 0; i < 8; i++)
|
||||
OLED_WR_DATA(F8X16[c * 16 + i]);
|
||||
OLED_Set_Pos(x, y + 1);
|
||||
for (i = 0; i < 8; i++)
|
||||
OLED_WR_DATA(F8X16[c * 16 + i + 8]);
|
||||
} else {
|
||||
OLED_Set_Pos(x, y);
|
||||
for (i = 0; i < 6; i++)
|
||||
OLED_WR_DATA(F6x8[c][i]);
|
||||
}
|
||||
}
|
||||
|
||||
//显示一个字符号串
|
||||
void OLED_ShowString(uint8_t x, uint8_t y, uint8_t *chr, uint8_t Char_Size) {
|
||||
unsigned char j = 0;
|
||||
while (chr[j] != '\0') {
|
||||
OLED_ShowChar(x, y, chr[j], Char_Size); //一次显示一个字符
|
||||
x += 8;
|
||||
if (x > 120) {
|
||||
x = 0;
|
||||
y += 2;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
//显示汉字
|
||||
//hzk 用取模软件得出的数组
|
||||
void OLED_ShowChinese(uint8_t x, uint8_t y, uint8_t no) {
|
||||
uint8_t t, adder = 0;
|
||||
//定位(0xbx,x为第几行。0x1x ,x为列地址 高四位;0x0x,x为列地址第4位。
|
||||
//比如你想定 位到第3行,第126(0x7e)列,就要写WrCmd(0xb3);WrCmd(0x17);WrCmd(0x0e);)
|
||||
OLED_Set_Pos(x, y);
|
||||
for (t = 0; t < 16; t++) {
|
||||
OLED_WR_DATA(Hzk[2 * no][t]);
|
||||
adder += 1;
|
||||
}
|
||||
OLED_Set_Pos(x, y + 1);
|
||||
for (t = 0; t < 16; t++) {
|
||||
OLED_WR_DATA(Hzk[2 * no + 1][t]);
|
||||
adder += 1;
|
||||
}
|
||||
}
|
814
Core/Src/rc522.c
Normal file
814
Core/Src/rc522.c
Normal file
@ -0,0 +1,814 @@
|
||||
#include "stm32f1xx_hal.h"
|
||||
#include "rc522.h"
|
||||
#include "stdio.h"
|
||||
#include "usart.h"
|
||||
#include <string.h>
|
||||
|
||||
extern SPI_HandleTypeDef hspi1;
|
||||
|
||||
/**************************************************************************************
|
||||
* 函数名称:MFRC_Init
|
||||
* 功能描述:MFRC初始化
|
||||
* 入口参数:无
|
||||
* 出口参数:无
|
||||
* 返 回 值:无
|
||||
* 说 明:MFRC的SPI接口速率为0~10Mbps
|
||||
***************************************************************************************/
|
||||
void MFRC_Init(void)
|
||||
{
|
||||
RS522_NSS(1);
|
||||
RS522_RST(1);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************************
|
||||
* 函数名称: SPI_RW_Byte
|
||||
* 功能描述: 模拟SPI读写一个字节
|
||||
* 入口参数: -byte:要发送的数据
|
||||
* 出口参数: -byte:接收到的数据
|
||||
***************************************************************************************/
|
||||
static uint8_t ret; //这些函数是HAL与标准库不同的地方【读写函数】
|
||||
uint8_t SPI1_RW_Byte(uint8_t byte)
|
||||
{
|
||||
HAL_SPI_TransmitReceive(&hspi1, &byte, &ret, 1, 10);//把byte 写入,并读出一个值,把它存入ret
|
||||
return ret;//入口是byte 的地址,读取时用的也是ret地址,一次只写入一个值10
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************************
|
||||
* 函数名称:MFRC_WriteReg
|
||||
* 功能描述:写一个寄存器
|
||||
* 入口参数:-addr:待写的寄存器地址
|
||||
* -data:待写的寄存器数据
|
||||
* 出口参数:无
|
||||
* 返 回 值:无
|
||||
* 说 明:无
|
||||
***************************************************************************************/
|
||||
void MFRC_WriteReg(uint8_t addr, uint8_t data)
|
||||
{
|
||||
uint8_t AddrByte;
|
||||
AddrByte = (addr << 1 ) & 0x7E; //求出地址字节
|
||||
RS522_NSS(0); //NSS拉低
|
||||
SPI1_RW_Byte(AddrByte); //写地址字节
|
||||
SPI1_RW_Byte(data); //写数据
|
||||
RS522_NSS(1); //NSS拉高
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************************
|
||||
* 函数名称:MFRC_ReadReg
|
||||
* 功能描述:读一个寄存器
|
||||
* 入口参数:-addr:待读的寄存器地址
|
||||
* 出口参数:无
|
||||
* 返 回 值:-data:读到寄存器的数据
|
||||
* 说 明:无
|
||||
***************************************************************************************/
|
||||
uint8_t MFRC_ReadReg(uint8_t addr)
|
||||
{
|
||||
uint8_t AddrByte, data;
|
||||
AddrByte = ((addr << 1 ) & 0x7E ) | 0x80; //求出地址字节
|
||||
RS522_NSS(0); //NSS拉低
|
||||
SPI1_RW_Byte(AddrByte); //写地址字节
|
||||
data = SPI1_RW_Byte(0x00); //读数据
|
||||
RS522_NSS(1); //NSS拉高
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************************
|
||||
* 函数名称:MFRC_SetBitMask
|
||||
* 功能描述:设置寄存器的位
|
||||
* 入口参数:-addr:待设置的寄存器地址
|
||||
* -mask:待设置寄存器的位(可同时设置多个bit)
|
||||
* 出口参数:无
|
||||
* 返 回 值:无
|
||||
* 说 明:无
|
||||
***************************************************************************************/
|
||||
void MFRC_SetBitMask(uint8_t addr, uint8_t mask)
|
||||
{
|
||||
uint8_t temp;
|
||||
temp = MFRC_ReadReg(addr); //先读回寄存器的值
|
||||
MFRC_WriteReg(addr, temp | mask); //处理过的数据再写入寄存器
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************************
|
||||
* 函数名称:MFRC_ClrBitMask
|
||||
* 功能描述:清除寄存器的位
|
||||
* 入口参数:-addr:待清除的寄存器地址
|
||||
* -mask:待清除寄存器的位(可同时清除多个bit)
|
||||
* 出口参数:无
|
||||
* 返 回 值:无
|
||||
* 说 明:无
|
||||
***************************************************************************************/
|
||||
void MFRC_ClrBitMask(uint8_t addr, uint8_t mask)
|
||||
{
|
||||
uint8_t temp;
|
||||
temp = MFRC_ReadReg(addr); //先读回寄存器的值
|
||||
MFRC_WriteReg(addr, temp & ~mask); //处理过的数据再写入寄存器
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************************
|
||||
* 函数名称:MFRC_CalulateCRC
|
||||
* 功能描述:用MFRC计算CRC结果
|
||||
* 入口参数:-pInData:带进行CRC计算的数据
|
||||
* -len:带进行CRC计算的数据长度
|
||||
* -pOutData:CRC计算结果
|
||||
* 出口参数:-pOutData:CRC计算结果
|
||||
* 返 回 值:无
|
||||
* 说 明:无
|
||||
***************************************************************************************/
|
||||
void MFRC_CalulateCRC(uint8_t *pInData, uint8_t len, uint8_t *pOutData)
|
||||
{
|
||||
//0xc1 1 2 pInData[2]
|
||||
uint8_t temp;
|
||||
uint32_t i;
|
||||
MFRC_ClrBitMask(MFRC_DivIrqReg, 0x04); //使能CRC中断
|
||||
MFRC_WriteReg(MFRC_CommandReg, MFRC_IDLE); //取消当前命令的执行
|
||||
MFRC_SetBitMask(MFRC_FIFOLevelReg, 0x80); //清除FIFO及其标志位
|
||||
for(i = 0; i < len; i++) //将待CRC计算的数据写入FIFO
|
||||
{
|
||||
MFRC_WriteReg(MFRC_FIFODataReg, *(pInData + i));
|
||||
}
|
||||
MFRC_WriteReg(MFRC_CommandReg, MFRC_CALCCRC); //执行CRC计算
|
||||
i = 100000;
|
||||
do
|
||||
{
|
||||
temp = MFRC_ReadReg(MFRC_DivIrqReg); //读取DivIrqReg寄存器的值
|
||||
i--;
|
||||
}
|
||||
while((i != 0) && !(temp & 0x04)); //等待CRC计算完成
|
||||
pOutData[0] = MFRC_ReadReg(MFRC_CRCResultRegL); //读取CRC计算结果
|
||||
pOutData[1] = MFRC_ReadReg(MFRC_CRCResultRegM);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************************
|
||||
* 函数名称:MFRC_CmdFrame
|
||||
* 功能描述:MFRC522和ISO14443A卡通讯的命令帧函数
|
||||
* 入口参数:-cmd:MFRC522命令字
|
||||
* -pIndata:MFRC522发送给MF1卡的数据的缓冲区首地址
|
||||
* -InLenByte:发送数据的字节长度
|
||||
* -pOutdata:用于接收MF1卡片返回数据的缓冲区首地址
|
||||
* -pOutLenBit:MF1卡返回数据的位长度
|
||||
* 出口参数:-pOutdata:用于接收MF1卡片返回数据的缓冲区首地址
|
||||
* -pOutLenBit:用于MF1卡返回数据位长度的首地址
|
||||
* 返 回 值:-status:错误代码(MFRC_OK、MFRC_NOTAGERR、MFRC_ERR)
|
||||
* 说 明:无
|
||||
***************************************************************************************/
|
||||
char MFRC_CmdFrame(uint8_t cmd, uint8_t *pInData, uint8_t InLenByte, uint8_t *pOutData, uint16_t *pOutLenBit)
|
||||
{
|
||||
uint8_t lastBits;
|
||||
uint8_t n;
|
||||
uint32_t i;
|
||||
char status = MFRC_ERR;
|
||||
uint8_t irqEn = 0x00;
|
||||
uint8_t waitFor = 0x00;
|
||||
|
||||
/*根据命令设置标志位*/
|
||||
switch(cmd)
|
||||
{
|
||||
case MFRC_AUTHENT: //Mifare认证
|
||||
irqEn = 0x12;
|
||||
waitFor = 0x10; //idleIRq中断标志
|
||||
break;
|
||||
case MFRC_TRANSCEIVE: //发送并接收数据
|
||||
irqEn = 0x77;
|
||||
waitFor = 0x30; //RxIRq和idleIRq中断标志
|
||||
break;
|
||||
}
|
||||
|
||||
/*发送命令帧前准备*/
|
||||
MFRC_WriteReg(MFRC_ComIEnReg, irqEn | 0x80); //开中断
|
||||
MFRC_ClrBitMask(MFRC_ComIrqReg, 0x80); //清除中断标志位SET1
|
||||
MFRC_WriteReg(MFRC_CommandReg, MFRC_IDLE); //取消当前命令的执行
|
||||
MFRC_SetBitMask(MFRC_FIFOLevelReg, 0x80); //清除FIFO缓冲区及其标志位
|
||||
|
||||
/*发送命令帧*/
|
||||
for(i = 0; i < InLenByte; i++) //写入命令参数
|
||||
{
|
||||
MFRC_WriteReg(MFRC_FIFODataReg, pInData[i]);
|
||||
}
|
||||
MFRC_WriteReg(MFRC_CommandReg, cmd); //执行命令
|
||||
if(cmd == MFRC_TRANSCEIVE)
|
||||
{
|
||||
MFRC_SetBitMask(MFRC_BitFramingReg, 0x80); //启动发送
|
||||
}
|
||||
i = 300000; //根据时钟频率调整,操作M1卡最大等待时间25ms
|
||||
do
|
||||
{
|
||||
n = MFRC_ReadReg(MFRC_ComIrqReg);
|
||||
i--;
|
||||
}
|
||||
while((i != 0) && !(n & 0x01) && !(n & waitFor)); //等待命令完成
|
||||
MFRC_ClrBitMask(MFRC_BitFramingReg, 0x80); //停止发送
|
||||
|
||||
/*处理接收的数据*/
|
||||
if(i != 0)
|
||||
{
|
||||
if(!(MFRC_ReadReg(MFRC_ErrorReg) & 0x1B))
|
||||
{
|
||||
status = MFRC_OK;
|
||||
if(n & irqEn & 0x01)
|
||||
{
|
||||
status = MFRC_NOTAGERR;
|
||||
}
|
||||
if(cmd == MFRC_TRANSCEIVE)
|
||||
{
|
||||
n = MFRC_ReadReg(MFRC_FIFOLevelReg);
|
||||
lastBits = MFRC_ReadReg(MFRC_ControlReg) & 0x07;
|
||||
if (lastBits)
|
||||
{
|
||||
*pOutLenBit = (n - 1) * 8 + lastBits;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pOutLenBit = n * 8;
|
||||
}
|
||||
if(n == 0)
|
||||
{
|
||||
n = 1;
|
||||
}
|
||||
if(n > MFRC_MAXRLEN)
|
||||
{
|
||||
n = MFRC_MAXRLEN;
|
||||
}
|
||||
for(i = 0; i < n; i++)
|
||||
{
|
||||
pOutData[i] = MFRC_ReadReg(MFRC_FIFODataReg);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = MFRC_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
MFRC_SetBitMask(MFRC_ControlReg, 0x80); //停止定时器运行
|
||||
MFRC_WriteReg(MFRC_CommandReg, MFRC_IDLE); //取消当前命令的执行
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************************
|
||||
* 函数名称:PCD_Reset
|
||||
* 功能描述:PCD复位
|
||||
* 入口参数:无
|
||||
* 出口参数:无
|
||||
* 返 回 值:无
|
||||
* 说 明:无
|
||||
***************************************************************************************/
|
||||
void PCD_Reset(void)
|
||||
{
|
||||
/*硬复位*/
|
||||
RS522_RST(1);//用到复位引脚
|
||||
osDelay(2);
|
||||
RS522_RST(0);
|
||||
osDelay(2);
|
||||
RS522_RST(1);
|
||||
osDelay(2);
|
||||
|
||||
/*软复位*/
|
||||
MFRC_WriteReg(MFRC_CommandReg, MFRC_RESETPHASE);
|
||||
osDelay(2);
|
||||
|
||||
/*复位后的初始化配置*/
|
||||
MFRC_WriteReg(MFRC_ModeReg, 0x3D); //CRC初始值0x6363
|
||||
MFRC_WriteReg(MFRC_TReloadRegL, 30); //定时器重装值
|
||||
MFRC_WriteReg(MFRC_TReloadRegH, 0);
|
||||
MFRC_WriteReg(MFRC_TModeReg, 0x8D); //定时器设置
|
||||
MFRC_WriteReg(MFRC_TPrescalerReg, 0x3E); //定时器预分频值
|
||||
MFRC_WriteReg(MFRC_TxAutoReg, 0x40); //100%ASK
|
||||
|
||||
PCD_AntennaOff(); //关天线
|
||||
osDelay(2);
|
||||
PCD_AntennaOn(); //开天线
|
||||
|
||||
printf("初始化完成\n");
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************************
|
||||
* 函数名称:PCD_AntennaOn
|
||||
* 功能描述:开启天线,使能PCD发送能量载波信号
|
||||
* 入口参数:无
|
||||
* 出口参数:无
|
||||
* 返 回 值:无
|
||||
* 说 明:每次开启或关闭天线之间应至少有1ms的间隔
|
||||
***************************************************************************************/
|
||||
void PCD_AntennaOn(void)
|
||||
{
|
||||
uint8_t temp;
|
||||
temp = MFRC_ReadReg(MFRC_TxControlReg);
|
||||
if (!(temp & 0x03))
|
||||
{
|
||||
MFRC_SetBitMask(MFRC_TxControlReg, 0x03);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************************
|
||||
* 函数名称:PCD_AntennaOff
|
||||
* 功能描述:关闭天线,失能PCD发送能量载波信号
|
||||
* 入口参数:无
|
||||
* 出口参数:无
|
||||
* 返 回 值:无
|
||||
* 说 明:每次开启或关闭天线之间应至少有1ms的间隔
|
||||
***************************************************************************************/
|
||||
void PCD_AntennaOff(void)
|
||||
{
|
||||
MFRC_ClrBitMask(MFRC_TxControlReg, 0x03);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
* 函数名称:PCD_Init
|
||||
* 功能描述:读写器初始化
|
||||
* 入口参数:无
|
||||
* 出口参数:无
|
||||
* 返 回 值:无
|
||||
* 说 明:无
|
||||
***************************************************************************************/
|
||||
void PCD_Init(void)
|
||||
{
|
||||
MFRC_Init(); //MFRC管脚配置
|
||||
PCD_Reset(); //PCD复位 并初始化配置
|
||||
PCD_AntennaOff(); //关闭天线
|
||||
PCD_AntennaOn(); //开启天线
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
* 函数名称:PCD_Request
|
||||
* 功能描述:寻卡
|
||||
* 入口参数: -RequestMode:讯卡方式
|
||||
* PICC_REQIDL:寻天线区内未进入休眠状态
|
||||
* PICC_REQALL:寻天线区内全部卡
|
||||
* -pCardType:用于保存卡片类型
|
||||
* 出口参数:-pCardType:卡片类型
|
||||
* 0x4400:Mifare_UltraLight
|
||||
* 0x0400:Mifare_One(S50)
|
||||
* 0x0200:Mifare_One(S70)
|
||||
* 0x0800:Mifare_Pro(X)
|
||||
* 0x4403:Mifare_DESFire
|
||||
* 返 回 值:-status:错误代码(PCD_OK、PCD_NOTAGERR、PCD_ERR)
|
||||
* 说 明:无
|
||||
***************************************************************************************/
|
||||
char PCD_Request(uint8_t RequestMode, uint8_t *pCardType)
|
||||
{
|
||||
int status;
|
||||
uint16_t unLen;
|
||||
uint8_t CmdFrameBuf[MFRC_MAXRLEN];
|
||||
|
||||
MFRC_ClrBitMask(MFRC_Status2Reg, 0x08);//关内部温度传感器
|
||||
MFRC_WriteReg(MFRC_BitFramingReg, 0x07); //存储模式,发送模式,是否启动发送等
|
||||
MFRC_SetBitMask(MFRC_TxControlReg, 0x03);//配置调制信号13.56MHZ
|
||||
|
||||
CmdFrameBuf[0] = RequestMode;
|
||||
|
||||
status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 1, CmdFrameBuf, &unLen);
|
||||
|
||||
if((status == PCD_OK) && (unLen == 0x10))
|
||||
{
|
||||
*pCardType = CmdFrameBuf[0];
|
||||
*(pCardType + 1) = CmdFrameBuf[1];
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
* 函数名称:PCD_Anticoll
|
||||
* 功能描述:防冲突,获取卡号
|
||||
* 入口参数:-pSnr:用于保存卡片序列号,4字节
|
||||
* 出口参数:-pSnr:卡片序列号,4字节
|
||||
* 返 回 值:-status:错误代码(PCD_OK、PCD_NOTAGERR、PCD_ERR)
|
||||
* 说 明:无
|
||||
***************************************************************************************/
|
||||
char PCD_AntiColl(uint8_t *pSnr)
|
||||
{
|
||||
char status;
|
||||
uint8_t i, snr_check = 0;
|
||||
uint16_t unLen;
|
||||
uint8_t CmdFrameBuf[MFRC_MAXRLEN];
|
||||
|
||||
MFRC_ClrBitMask(MFRC_Status2Reg, 0x08);
|
||||
MFRC_WriteReg(MFRC_BitFramingReg, 0x00);
|
||||
MFRC_ClrBitMask(MFRC_CollReg, 0x80);
|
||||
|
||||
CmdFrameBuf[0] = PICC_ANTICOLL1;
|
||||
CmdFrameBuf[1] = 0x20;
|
||||
|
||||
status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 2, CmdFrameBuf, &unLen);
|
||||
|
||||
if(status == PCD_OK)
|
||||
{
|
||||
for(i = 0; i < 4; i++)
|
||||
{
|
||||
*(pSnr + i) = CmdFrameBuf[i];
|
||||
snr_check ^= CmdFrameBuf[i];
|
||||
}
|
||||
if(snr_check != CmdFrameBuf[i])
|
||||
{
|
||||
status = PCD_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
MFRC_SetBitMask(MFRC_CollReg, 0x80);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
* 函数名称:PCD_Select
|
||||
* 功能描述:选卡
|
||||
* 入口参数:-pSnr:卡片序列号,4字节
|
||||
* 出口参数:无
|
||||
* 返 回 值:-status:错误代码(PCD_OK、PCD_NOTAGERR、PCD_ERR)
|
||||
* 说 明:无
|
||||
***************************************************************************************/
|
||||
char PCD_Select(uint8_t *pSnr)
|
||||
{
|
||||
char status;
|
||||
uint8_t i;
|
||||
uint16_t unLen;
|
||||
uint8_t CmdFrameBuf[MFRC_MAXRLEN];
|
||||
|
||||
CmdFrameBuf[0] = PICC_ANTICOLL1;
|
||||
CmdFrameBuf[1] = 0x70;
|
||||
CmdFrameBuf[6] = 0;
|
||||
for(i = 0; i < 4; i++)
|
||||
{
|
||||
CmdFrameBuf[i + 2] = *(pSnr + i);
|
||||
CmdFrameBuf[6] ^= *(pSnr + i);
|
||||
}
|
||||
MFRC_CalulateCRC(CmdFrameBuf, 7, &CmdFrameBuf[7]);
|
||||
|
||||
MFRC_ClrBitMask(MFRC_Status2Reg, 0x08);
|
||||
|
||||
status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 9, CmdFrameBuf, &unLen);
|
||||
|
||||
if((status == PCD_OK) && (unLen == 0x18))
|
||||
{
|
||||
status = PCD_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = PCD_ERR;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
* 函数名称:PCD_AuthState
|
||||
* 功能描述:验证卡片密码
|
||||
* 入口参数:-AuthMode:验证模式
|
||||
* PICC_AUTHENT1A:验证A密码
|
||||
* PICC_AUTHENT1B:验证B密码
|
||||
* -BlockAddr:块地址(0~63)
|
||||
* -pKey:密码
|
||||
* -pSnr:卡片序列号,4字节
|
||||
* 出口参数:无
|
||||
* 返 回 值:-status:错误代码(PCD_OK、PCD_NOTAGERR、PCD_ERR)
|
||||
* 说 明:验证密码时,以扇区为单位,BlockAddr参数可以是同一个扇区的任意块
|
||||
***************************************************************************************/
|
||||
char PCD_AuthState(uint8_t AuthMode, uint8_t BlockAddr, uint8_t *pKey, uint8_t *pSnr)
|
||||
{
|
||||
char status;
|
||||
uint16_t unLen;
|
||||
uint8_t i, CmdFrameBuf[MFRC_MAXRLEN];
|
||||
CmdFrameBuf[0] = AuthMode;
|
||||
CmdFrameBuf[1] = BlockAddr;
|
||||
for(i = 0; i < 6; i++)
|
||||
{
|
||||
CmdFrameBuf[i + 2] = *(pKey + i);
|
||||
}
|
||||
for(i = 0; i < 4; i++)
|
||||
{
|
||||
CmdFrameBuf[i + 8] = *(pSnr + i);
|
||||
}
|
||||
|
||||
status = MFRC_CmdFrame(MFRC_AUTHENT, CmdFrameBuf, 12, CmdFrameBuf, &unLen);
|
||||
if((status != PCD_OK) || (!(MFRC_ReadReg(MFRC_Status2Reg) & 0x08)))
|
||||
{
|
||||
status = PCD_ERR;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
* 函数名称:PCD_WriteBlock
|
||||
* 功能描述:读MF1卡数据块
|
||||
* 入口参数:-BlockAddr:块地址
|
||||
* -pData: 用于保存待写入的数据,16字节
|
||||
* 出口参数:无
|
||||
* 返 回 值:-status:错误代码(PCD_OK、PCD_NOTAGERR、PCD_ERR)
|
||||
* 说 明:无
|
||||
***************************************************************************************/
|
||||
char PCD_WriteBlock(uint8_t BlockAddr, uint8_t *pData)
|
||||
{
|
||||
char status;
|
||||
uint16_t unLen;
|
||||
uint8_t i, CmdFrameBuf[MFRC_MAXRLEN];
|
||||
|
||||
CmdFrameBuf[0] = PICC_WRITE;
|
||||
CmdFrameBuf[1] = BlockAddr;
|
||||
MFRC_CalulateCRC(CmdFrameBuf, 2, &CmdFrameBuf[2]);
|
||||
|
||||
status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 4, CmdFrameBuf, &unLen);
|
||||
|
||||
if((status != PCD_OK) || (unLen != 4) || ((CmdFrameBuf[0] & 0x0F) != 0x0A))
|
||||
{
|
||||
status = PCD_ERR;
|
||||
}
|
||||
|
||||
if(status == PCD_OK)
|
||||
{
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
CmdFrameBuf[i] = *(pData + i);
|
||||
}
|
||||
MFRC_CalulateCRC(CmdFrameBuf, 16, &CmdFrameBuf[16]);
|
||||
|
||||
status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 18, CmdFrameBuf, &unLen);
|
||||
|
||||
if((status != PCD_OK) || (unLen != 4) || ((CmdFrameBuf[0] & 0x0F) != 0x0A))
|
||||
{
|
||||
status = PCD_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
* 函数名称:PCD_ReadBlock
|
||||
* 功能描述:读MF1卡数据块
|
||||
* 入口参数:-BlockAddr:块地址
|
||||
* -pData: 用于保存读出的数据,16字节
|
||||
* 出口参数:-pData: 用于保存读出的数据,16字节
|
||||
* 返 回 值:-status:错误代码(PCD_OK、PCD_NOTAGERR、PCD_ERR)
|
||||
* 说 明:无
|
||||
***************************************************************************************/
|
||||
char PCD_ReadBlock(uint8_t BlockAddr, uint8_t *pData)
|
||||
{
|
||||
char status;
|
||||
uint16_t unLen;
|
||||
uint8_t i, CmdFrameBuf[MFRC_MAXRLEN];
|
||||
|
||||
CmdFrameBuf[0] = PICC_READ;
|
||||
CmdFrameBuf[1] = BlockAddr;
|
||||
MFRC_CalulateCRC(CmdFrameBuf, 2, &CmdFrameBuf[2]);
|
||||
|
||||
status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 4, CmdFrameBuf, &unLen);
|
||||
if((status == PCD_OK) && (unLen == 0x90))
|
||||
{
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
*(pData + i) = CmdFrameBuf[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = PCD_ERR;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
* 函数名称:PCD_Value
|
||||
* 功能描述:对MF1卡数据块增减值操作
|
||||
* 入口参数:
|
||||
* -BlockAddr:块地址
|
||||
* -pValue:四字节增值的值,低位在前
|
||||
* -mode:数值块操作模式
|
||||
* PICC_INCREMENT:增值
|
||||
* PICC_DECREMENT:减值
|
||||
* 出口参数:无
|
||||
* 返 回 值:-status:错误代码(PCD_OK、PCD_NOTAGERR、PCD_ERR)
|
||||
* 说 明:无
|
||||
***************************************************************************************/
|
||||
char PCD_Value(uint8_t mode, uint8_t BlockAddr, uint8_t *pValue)
|
||||
{
|
||||
//0XC1 1 Increment[4]={0x03, 0x01, 0x01, 0x01};
|
||||
char status;
|
||||
uint16_t unLen;
|
||||
uint8_t i, CmdFrameBuf[MFRC_MAXRLEN];
|
||||
|
||||
CmdFrameBuf[0] = mode;
|
||||
CmdFrameBuf[1] = BlockAddr;
|
||||
MFRC_CalulateCRC(CmdFrameBuf, 2, &CmdFrameBuf[2]);
|
||||
|
||||
status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 4, CmdFrameBuf, &unLen);
|
||||
|
||||
if((status != PCD_OK) || (unLen != 4) || ((CmdFrameBuf[0] & 0x0F) != 0x0A))
|
||||
{
|
||||
status = PCD_ERR;
|
||||
}
|
||||
|
||||
if(status == PCD_OK)
|
||||
{
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
CmdFrameBuf[i] = *(pValue + i);
|
||||
}
|
||||
MFRC_CalulateCRC(CmdFrameBuf, 4, &CmdFrameBuf[4]);
|
||||
unLen = 0;
|
||||
status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 6, CmdFrameBuf, &unLen);
|
||||
if(status != PCD_ERR)
|
||||
{
|
||||
status = PCD_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if(status == PCD_OK)
|
||||
{
|
||||
CmdFrameBuf[0] = PICC_TRANSFER;
|
||||
CmdFrameBuf[1] = BlockAddr;
|
||||
MFRC_CalulateCRC(CmdFrameBuf, 2, &CmdFrameBuf[2]);
|
||||
|
||||
status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 4, CmdFrameBuf, &unLen);
|
||||
|
||||
if((status != PCD_OK) || (unLen != 4) || ((CmdFrameBuf[0] & 0x0F) != 0x0A))
|
||||
{
|
||||
status = PCD_ERR;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
* 函数名称:PCD_BakValue
|
||||
* 功能描述:备份钱包(块转存)
|
||||
* 入口参数:-sourceBlockAddr:源块地址
|
||||
* -goalBlockAddr :目标块地址
|
||||
* 出口参数:无
|
||||
* 返 回 值:-status:错误代码(PCD_OK、PCD_NOTAGERR、PCD_ERR)
|
||||
* 说 明:只能在同一个扇区内转存
|
||||
***************************************************************************************/
|
||||
char PCD_BakValue(uint8_t sourceBlockAddr, uint8_t goalBlockAddr)
|
||||
{
|
||||
char status;
|
||||
uint16_t unLen;
|
||||
uint8_t CmdFrameBuf[MFRC_MAXRLEN];
|
||||
|
||||
CmdFrameBuf[0] = PICC_RESTORE;
|
||||
CmdFrameBuf[1] = sourceBlockAddr;
|
||||
MFRC_CalulateCRC(CmdFrameBuf, 2, &CmdFrameBuf[2]);
|
||||
status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 4, CmdFrameBuf, &unLen);
|
||||
if((status != PCD_OK) || (unLen != 4) || ((CmdFrameBuf[0] & 0x0F) != 0x0A))
|
||||
{
|
||||
status = PCD_ERR;
|
||||
}
|
||||
|
||||
if(status == PCD_OK)
|
||||
{
|
||||
CmdFrameBuf[0] = 0;
|
||||
CmdFrameBuf[1] = 0;
|
||||
CmdFrameBuf[2] = 0;
|
||||
CmdFrameBuf[3] = 0;
|
||||
MFRC_CalulateCRC(CmdFrameBuf, 4, &CmdFrameBuf[4]);
|
||||
status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 6, CmdFrameBuf, &unLen);
|
||||
if(status != PCD_ERR)
|
||||
{
|
||||
status = PCD_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if(status != PCD_OK)
|
||||
{
|
||||
return PCD_ERR;
|
||||
}
|
||||
|
||||
CmdFrameBuf[0] = PICC_TRANSFER;
|
||||
CmdFrameBuf[1] = goalBlockAddr;
|
||||
MFRC_CalulateCRC(CmdFrameBuf, 2, &CmdFrameBuf[2]);
|
||||
status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 4, CmdFrameBuf, &unLen);
|
||||
if((status != PCD_OK) || (unLen != 4) || ((CmdFrameBuf[0] & 0x0F) != 0x0A))
|
||||
{
|
||||
status = PCD_ERR;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
* 函数名称:PCD_Halt
|
||||
* 功能描述:命令卡片进入休眠状态
|
||||
* 入口参数:无
|
||||
* 出口参数:无
|
||||
* 返 回 值:-status:错误代码(PCD_OK、PCD_NOTAGERR、PCD_ERR)
|
||||
* 说 明:无
|
||||
***************************************************************************************/
|
||||
char PCD_Halt(void)
|
||||
{
|
||||
char status;
|
||||
uint16_t unLen;
|
||||
uint8_t CmdFrameBuf[MFRC_MAXRLEN];
|
||||
|
||||
CmdFrameBuf[0] = PICC_HALT;
|
||||
CmdFrameBuf[1] = 0;
|
||||
MFRC_CalulateCRC(CmdFrameBuf, 2, &CmdFrameBuf[2]);
|
||||
|
||||
status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 4, CmdFrameBuf, &unLen);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
// uint8_t readUid[5]; //卡号
|
||||
// uint8_t CT[3]; //卡类型
|
||||
// uint8_t DATA[16]; //存放数据
|
||||
//
|
||||
// uint8_t KEY_A[6]= {0xff,0xff,0xff,0xff,0xff,0xff};
|
||||
// uint8_t KEY_B[6]= {0xff,0xff,0xff,0xff,0xff,0xff};
|
||||
// unsigned char buf[16]={0x01,0x02,0x03,0x04,0x05,0x06,0xff
|
||||
// ,0x07,0x80,0x69,0x18,0x17,0x16,0x15,0x14,0x13};
|
||||
//
|
||||
// uint8_t status;
|
||||
// uint8_t addr = 0x01*4 + 0x03; // 总共16个扇区。一个扇区4个块,从0开始算,表示第一扇区第三块
|
||||
|
||||
// void CardCompare(void)
|
||||
// {
|
||||
// uint8_t i;
|
||||
// //status = PCD_WriteBlock(addr, buf);
|
||||
// status = PCD_Request(0x52, CT); //找到卡返回0
|
||||
// if(!status) //寻卡成功
|
||||
// {
|
||||
// status = PCD_ERR;
|
||||
// status = PCD_AntiColl(readUid); //防冲撞
|
||||
// }
|
||||
//
|
||||
// if(!status) //防冲撞成功
|
||||
// {
|
||||
// status = PCD_ERR;
|
||||
// printf("卡的类型为:%x%x%x\r\n",CT[0],CT[1],CT[2]); /* 读取卡的类型 */
|
||||
// printf("卡号:%x-%x-%x-%x\r\n",readUid[0],readUid[1],readUid[2],readUid[3]);
|
||||
// HAL_Delay(1000);
|
||||
// status=PCD_Select(readUid); /* 选卡 */
|
||||
// }
|
||||
//
|
||||
// if(!status) //选卡成功
|
||||
// {
|
||||
// status = PCD_ERR;
|
||||
// // 验证A密钥 块地址 密码 SN
|
||||
// status = PCD_AuthState(PICC_AUTHENT1A, addr, KEY_A, readUid);
|
||||
// if(status == PCD_OK)//验证A成功
|
||||
// {
|
||||
// printf("A密钥验证成功\r\n");
|
||||
// HAL_Delay(1000);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// printf("A密钥验证失败\r\n");
|
||||
// HAL_Delay(1000);
|
||||
// }
|
||||
//
|
||||
// // 验证B密钥 块地址 密码 SN
|
||||
// status = PCD_AuthState(PICC_AUTHENT1B, addr, KEY_B, readUid);
|
||||
// if(status == PCD_OK)//验证B成功
|
||||
// {
|
||||
// printf("B密钥验证成功\r\n");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// printf("B密钥验证失败\r\n");
|
||||
// }
|
||||
// HAL_Delay(1000);
|
||||
// }
|
||||
//
|
||||
// if(status == PCD_OK)//验证密码成功,接着读取3块
|
||||
// {
|
||||
// status = PCD_ERR;
|
||||
// status = PCD_ReadBlock(addr, DATA);
|
||||
//
|
||||
// if(status == PCD_OK)//读卡成功
|
||||
// {
|
||||
// printf("1扇区3块DATA:");
|
||||
// for(i = 0; i < 16; i++)
|
||||
// {
|
||||
// printf("%02x", DATA[i]);
|
||||
// }
|
||||
// printf("\r\n");
|
||||
//
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// printf("读卡失败\r\n");
|
||||
// }
|
||||
// HAL_Delay(1000);
|
||||
// }
|
||||
//
|
||||
// }
|
122
Core/Src/spi.c
Normal file
122
Core/Src/spi.c
Normal file
@ -0,0 +1,122 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file spi.c
|
||||
* @brief This file provides code for the configuration
|
||||
* of the SPI instances.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "spi.h"
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
SPI_HandleTypeDef hspi1;
|
||||
|
||||
/* SPI1 init function */
|
||||
void MX_SPI1_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN SPI1_Init 0 */
|
||||
|
||||
/* USER CODE END SPI1_Init 0 */
|
||||
|
||||
/* USER CODE BEGIN SPI1_Init 1 */
|
||||
|
||||
/* USER CODE END SPI1_Init 1 */
|
||||
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_4;
|
||||
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();
|
||||
}
|
||||
/* USER CODE BEGIN SPI1_Init 2 */
|
||||
|
||||
/* USER CODE END SPI1_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
|
||||
{
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
if(spiHandle->Instance==SPI1)
|
||||
{
|
||||
/* USER CODE BEGIN SPI1_MspInit 0 */
|
||||
|
||||
/* USER CODE END SPI1_MspInit 0 */
|
||||
/* SPI1 clock enable */
|
||||
__HAL_RCC_SPI1_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
/**SPI1 GPIO Configuration
|
||||
PA5 ------> SPI1_SCK
|
||||
PA6 ------> SPI1_MISO
|
||||
PA7 ------> SPI1_MOSI
|
||||
*/
|
||||
GPIO_InitStruct.Pin = RC522_SCK_Pin|RC522_MOSI_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = RC522_MISO_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(RC522_MISO_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN SPI1_MspInit 1 */
|
||||
|
||||
/* USER CODE END SPI1_MspInit 1 */
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle)
|
||||
{
|
||||
|
||||
if(spiHandle->Instance==SPI1)
|
||||
{
|
||||
/* USER CODE BEGIN SPI1_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END SPI1_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_SPI1_CLK_DISABLE();
|
||||
|
||||
/**SPI1 GPIO Configuration
|
||||
PA5 ------> SPI1_SCK
|
||||
PA6 ------> SPI1_MISO
|
||||
PA7 ------> SPI1_MOSI
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOA, RC522_SCK_Pin|RC522_MISO_Pin|RC522_MOSI_Pin);
|
||||
|
||||
/* USER CODE BEGIN SPI1_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END SPI1_MspDeInit 1 */
|
||||
}
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
86
Core/Src/stm32f1xx_hal_msp.c
Normal file
86
Core/Src/stm32f1xx_hal_msp.c
Normal file
@ -0,0 +1,86 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f1xx_hal_msp.c
|
||||
* @brief This file provides code for the MSP Initialization
|
||||
* and de-Initialization codes.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN TD */
|
||||
|
||||
/* USER CODE END TD */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Define */
|
||||
|
||||
/* USER CODE END Define */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Macro */
|
||||
|
||||
/* USER CODE END Macro */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PV */
|
||||
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* USER CODE BEGIN PFP */
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* External functions --------------------------------------------------------*/
|
||||
/* USER CODE BEGIN ExternalFunctions */
|
||||
|
||||
/* USER CODE END ExternalFunctions */
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
/**
|
||||
* Initializes the Global MSP.
|
||||
*/
|
||||
void HAL_MspInit(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN MspInit 0 */
|
||||
|
||||
/* USER CODE END MspInit 0 */
|
||||
|
||||
__HAL_RCC_AFIO_CLK_ENABLE();
|
||||
__HAL_RCC_PWR_CLK_ENABLE();
|
||||
|
||||
/* System interrupt init*/
|
||||
|
||||
/** NOJTAG: JTAG-DP Disabled and SW-DP Enabled
|
||||
*/
|
||||
__HAL_AFIO_REMAP_SWJ_NOJTAG();
|
||||
|
||||
/* USER CODE BEGIN MspInit 1 */
|
||||
|
||||
/* USER CODE END MspInit 1 */
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
217
Core/Src/stm32f1xx_it.c
Normal file
217
Core/Src/stm32f1xx_it.c
Normal file
@ -0,0 +1,217 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f1xx_it.c
|
||||
* @brief Interrupt Service Routines.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
#include "stm32f1xx_it.h"
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN TD */
|
||||
|
||||
/* USER CODE END TD */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PD */
|
||||
|
||||
/* USER CODE END PD */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PM */
|
||||
|
||||
/* USER CODE END PM */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PV */
|
||||
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* USER CODE BEGIN PFP */
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* Private user code ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
|
||||
/* USER CODE BEGIN EV */
|
||||
|
||||
/* USER CODE END EV */
|
||||
|
||||
/******************************************************************************/
|
||||
/* Cortex-M3 Processor Interruption and Exception Handlers */
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* @brief This function handles Non maskable interrupt.
|
||||
*/
|
||||
void NMI_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
|
||||
|
||||
/* USER CODE END NonMaskableInt_IRQn 0 */
|
||||
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
/* USER CODE END NonMaskableInt_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Hard fault interrupt.
|
||||
*/
|
||||
void HardFault_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN HardFault_IRQn 0 */
|
||||
|
||||
/* USER CODE END HardFault_IRQn 0 */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
|
||||
/* USER CODE END W1_HardFault_IRQn 0 */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Memory management fault.
|
||||
*/
|
||||
void MemManage_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
|
||||
|
||||
/* USER CODE END MemoryManagement_IRQn 0 */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
|
||||
/* USER CODE END W1_MemoryManagement_IRQn 0 */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Prefetch fault, memory access fault.
|
||||
*/
|
||||
void BusFault_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN BusFault_IRQn 0 */
|
||||
|
||||
/* USER CODE END BusFault_IRQn 0 */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE BEGIN W1_BusFault_IRQn 0 */
|
||||
/* USER CODE END W1_BusFault_IRQn 0 */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Undefined instruction or illegal state.
|
||||
*/
|
||||
void UsageFault_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN UsageFault_IRQn 0 */
|
||||
|
||||
/* USER CODE END UsageFault_IRQn 0 */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE BEGIN W1_UsageFault_IRQn 0 */
|
||||
/* USER CODE END W1_UsageFault_IRQn 0 */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles System service call via SWI instruction.
|
||||
*/
|
||||
void SVC_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN SVCall_IRQn 0 */
|
||||
|
||||
/* USER CODE END SVCall_IRQn 0 */
|
||||
/* USER CODE BEGIN SVCall_IRQn 1 */
|
||||
|
||||
/* USER CODE END SVCall_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Debug monitor.
|
||||
*/
|
||||
void DebugMon_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
|
||||
|
||||
/* USER CODE END DebugMonitor_IRQn 0 */
|
||||
/* USER CODE BEGIN DebugMonitor_IRQn 1 */
|
||||
|
||||
/* USER CODE END DebugMonitor_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Pendable request for system service.
|
||||
*/
|
||||
void PendSV_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN PendSV_IRQn 0 */
|
||||
|
||||
/* USER CODE END PendSV_IRQn 0 */
|
||||
/* USER CODE BEGIN PendSV_IRQn 1 */
|
||||
|
||||
/* USER CODE END PendSV_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles System tick timer.
|
||||
*/
|
||||
void SysTick_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN SysTick_IRQn 0 */
|
||||
|
||||
/* USER CODE END SysTick_IRQn 0 */
|
||||
HAL_IncTick();
|
||||
/* USER CODE BEGIN SysTick_IRQn 1 */
|
||||
|
||||
/* USER CODE END SysTick_IRQn 1 */
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* STM32F1xx Peripheral Interrupt Handlers */
|
||||
/* Add here the Interrupt Handlers for the used peripherals. */
|
||||
/* For the available peripheral interrupt handler names, */
|
||||
/* please refer to the startup file (startup_stm32f1xx.s). */
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief This function handles EXTI line[9:5] interrupts.
|
||||
*/
|
||||
void EXTI9_5_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN EXTI9_5_IRQn 0 */
|
||||
|
||||
/* USER CODE END EXTI9_5_IRQn 0 */
|
||||
HAL_GPIO_EXTI_IRQHandler(BTN1_Pin);
|
||||
/* USER CODE BEGIN EXTI9_5_IRQn 1 */
|
||||
|
||||
/* USER CODE END EXTI9_5_IRQn 1 */
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
176
Core/Src/syscalls.c
Normal file
176
Core/Src/syscalls.c
Normal file
@ -0,0 +1,176 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file syscalls.c
|
||||
* @author Auto-generated by STM32CubeIDE
|
||||
* @brief STM32CubeIDE Minimal System calls file
|
||||
*
|
||||
* For more information about which c-functions
|
||||
* need which of these lowlevel functions
|
||||
* please consult the Newlib libc-manual
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2020-2025 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes */
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/times.h>
|
||||
|
||||
|
||||
/* Variables */
|
||||
extern int __io_putchar(int ch) __attribute__((weak));
|
||||
extern int __io_getchar(void) __attribute__((weak));
|
||||
|
||||
|
||||
char *__env[1] = { 0 };
|
||||
char **environ = __env;
|
||||
|
||||
|
||||
/* Functions */
|
||||
void initialise_monitor_handles()
|
||||
{
|
||||
}
|
||||
|
||||
int _getpid(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int _kill(int pid, int sig)
|
||||
{
|
||||
(void)pid;
|
||||
(void)sig;
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void _exit (int status)
|
||||
{
|
||||
_kill(status, -1);
|
||||
while (1) {} /* Make sure we hang here */
|
||||
}
|
||||
|
||||
__attribute__((weak)) int _read(int file, char *ptr, int len)
|
||||
{
|
||||
(void)file;
|
||||
int DataIdx;
|
||||
|
||||
for (DataIdx = 0; DataIdx < len; DataIdx++)
|
||||
{
|
||||
*ptr++ = __io_getchar();
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
__attribute__((weak)) int _write(int file, char *ptr, int len)
|
||||
{
|
||||
(void)file;
|
||||
int DataIdx;
|
||||
|
||||
for (DataIdx = 0; DataIdx < len; DataIdx++)
|
||||
{
|
||||
__io_putchar(*ptr++);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int _close(int file)
|
||||
{
|
||||
(void)file;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int _fstat(int file, struct stat *st)
|
||||
{
|
||||
(void)file;
|
||||
st->st_mode = S_IFCHR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _isatty(int file)
|
||||
{
|
||||
(void)file;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int _lseek(int file, int ptr, int dir)
|
||||
{
|
||||
(void)file;
|
||||
(void)ptr;
|
||||
(void)dir;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _open(char *path, int flags, ...)
|
||||
{
|
||||
(void)path;
|
||||
(void)flags;
|
||||
/* Pretend like we always fail */
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _wait(int *status)
|
||||
{
|
||||
(void)status;
|
||||
errno = ECHILD;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _unlink(char *name)
|
||||
{
|
||||
(void)name;
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _times(struct tms *buf)
|
||||
{
|
||||
(void)buf;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _stat(char *file, struct stat *st)
|
||||
{
|
||||
(void)file;
|
||||
st->st_mode = S_IFCHR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _link(char *old, char *new)
|
||||
{
|
||||
(void)old;
|
||||
(void)new;
|
||||
errno = EMLINK;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _fork(void)
|
||||
{
|
||||
errno = EAGAIN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _execve(char *name, char **argv, char **env)
|
||||
{
|
||||
(void)name;
|
||||
(void)argv;
|
||||
(void)env;
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
79
Core/Src/sysmem.c
Normal file
79
Core/Src/sysmem.c
Normal file
@ -0,0 +1,79 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file sysmem.c
|
||||
* @author Generated by STM32CubeIDE
|
||||
* @brief STM32CubeIDE System Memory calls file
|
||||
*
|
||||
* For more information about which C functions
|
||||
* need which of these lowlevel functions
|
||||
* please consult the newlib libc manual
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes */
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* Pointer to the current high watermark of the heap usage
|
||||
*/
|
||||
static uint8_t *__sbrk_heap_end = NULL;
|
||||
|
||||
/**
|
||||
* @brief _sbrk() allocates memory to the newlib heap and is used by malloc
|
||||
* and others from the C library
|
||||
*
|
||||
* @verbatim
|
||||
* ############################################################################
|
||||
* # .data # .bss # newlib heap # MSP stack #
|
||||
* # # # # Reserved by _Min_Stack_Size #
|
||||
* ############################################################################
|
||||
* ^-- RAM start ^-- _end _estack, RAM end --^
|
||||
* @endverbatim
|
||||
*
|
||||
* This implementation starts allocating at the '_end' linker symbol
|
||||
* The '_Min_Stack_Size' linker symbol reserves a memory for the MSP stack
|
||||
* The implementation considers '_estack' linker symbol to be RAM end
|
||||
* NOTE: If the MSP stack, at any point during execution, grows larger than the
|
||||
* reserved size, please increase the '_Min_Stack_Size'.
|
||||
*
|
||||
* @param incr Memory size
|
||||
* @return Pointer to allocated memory
|
||||
*/
|
||||
void *_sbrk(ptrdiff_t incr)
|
||||
{
|
||||
extern uint8_t _end; /* Symbol defined in the linker script */
|
||||
extern uint8_t _estack; /* Symbol defined in the linker script */
|
||||
extern uint32_t _Min_Stack_Size; /* Symbol defined in the linker script */
|
||||
const uint32_t stack_limit = (uint32_t)&_estack - (uint32_t)&_Min_Stack_Size;
|
||||
const uint8_t *max_heap = (uint8_t *)stack_limit;
|
||||
uint8_t *prev_heap_end;
|
||||
|
||||
/* Initialize heap end at first call */
|
||||
if (NULL == __sbrk_heap_end)
|
||||
{
|
||||
__sbrk_heap_end = &_end;
|
||||
}
|
||||
|
||||
/* Protect heap from growing into the reserved MSP stack */
|
||||
if (__sbrk_heap_end + incr > max_heap)
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return (void *)-1;
|
||||
}
|
||||
|
||||
prev_heap_end = __sbrk_heap_end;
|
||||
__sbrk_heap_end += incr;
|
||||
|
||||
return (void *)prev_heap_end;
|
||||
}
|
406
Core/Src/system_stm32f1xx.c
Normal file
406
Core/Src/system_stm32f1xx.c
Normal file
@ -0,0 +1,406 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_stm32f1xx.c
|
||||
* @author MCD Application Team
|
||||
* @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Source File.
|
||||
*
|
||||
* 1. This file provides two functions and one global variable to be called from
|
||||
* user application:
|
||||
* - SystemInit(): Setups the system clock (System clock source, PLL Multiplier
|
||||
* factors, AHB/APBx prescalers and Flash settings).
|
||||
* This function is called at startup just after reset and
|
||||
* before branch to main program. This call is made inside
|
||||
* the "startup_stm32f1xx_xx.s" file.
|
||||
*
|
||||
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
|
||||
* by the user application to setup the SysTick
|
||||
* timer or configure other parameters.
|
||||
*
|
||||
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
|
||||
* be called whenever the core clock is changed
|
||||
* during program execution.
|
||||
*
|
||||
* 2. After each device reset the HSI (8 MHz) is used as system clock source.
|
||||
* Then SystemInit() function is called, in "startup_stm32f1xx_xx.s" file, to
|
||||
* configure the system clock before to branch to main program.
|
||||
*
|
||||
* 4. The default value of HSE crystal is set to 8 MHz (or 25 MHz, depending on
|
||||
* the product used), refer to "HSE_VALUE".
|
||||
* When HSE is used as system clock source, directly or through PLL, and you
|
||||
* are using different crystal you have to adapt the HSE value to your own
|
||||
* configuration.
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017-2021 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** @addtogroup CMSIS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup stm32f1xx_system
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_Includes
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "stm32f1xx.h"
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if !defined (HSE_VALUE)
|
||||
#define HSE_VALUE 8000000U /*!< Default value of the External oscillator in Hz.
|
||||
This value can be provided and adapted by the user application. */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined (HSI_VALUE)
|
||||
#define HSI_VALUE 8000000U /*!< Default value of the Internal oscillator in Hz.
|
||||
This value can be provided and adapted by the user application. */
|
||||
#endif /* HSI_VALUE */
|
||||
|
||||
/*!< Uncomment the following line if you need to use external SRAM */
|
||||
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
||||
/* #define DATA_IN_ExtSRAM */
|
||||
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
|
||||
|
||||
/* Note: Following vector table addresses must be defined in line with linker
|
||||
configuration. */
|
||||
/*!< Uncomment the following line if you need to relocate the vector table
|
||||
anywhere in Flash or Sram, else the vector table is kept at the automatic
|
||||
remap of boot address selected */
|
||||
/* #define USER_VECT_TAB_ADDRESS */
|
||||
|
||||
#if defined(USER_VECT_TAB_ADDRESS)
|
||||
/*!< Uncomment the following line if you need to relocate your vector Table
|
||||
in Sram else user remap will be done in Flash. */
|
||||
/* #define VECT_TAB_SRAM */
|
||||
#if defined(VECT_TAB_SRAM)
|
||||
#define VECT_TAB_BASE_ADDRESS SRAM_BASE /*!< Vector Table base address field.
|
||||
This value must be a multiple of 0x200. */
|
||||
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
|
||||
This value must be a multiple of 0x200. */
|
||||
#else
|
||||
#define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field.
|
||||
This value must be a multiple of 0x200. */
|
||||
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
|
||||
This value must be a multiple of 0x200. */
|
||||
#endif /* VECT_TAB_SRAM */
|
||||
#endif /* USER_VECT_TAB_ADDRESS */
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* This variable is updated in three ways:
|
||||
1) by calling CMSIS function SystemCoreClockUpdate()
|
||||
2) by calling HAL API function HAL_RCC_GetHCLKFreq()
|
||||
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
|
||||
Note: If you use this function to configure the system clock; then there
|
||||
is no need to call the 2 first functions listed above, since SystemCoreClock
|
||||
variable is updated automatically.
|
||||
*/
|
||||
uint32_t SystemCoreClock = 8000000;
|
||||
const uint8_t AHBPrescTable[16U] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
|
||||
const uint8_t APBPrescTable[8U] = {0, 0, 0, 0, 1, 2, 3, 4};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
||||
#ifdef DATA_IN_ExtSRAM
|
||||
static void SystemInit_ExtMemCtl(void);
|
||||
#endif /* DATA_IN_ExtSRAM */
|
||||
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Setup the microcontroller system
|
||||
* Initialize the Embedded Flash Interface, the PLL and update the
|
||||
* SystemCoreClock variable.
|
||||
* @note This function should be used only after reset.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SystemInit (void)
|
||||
{
|
||||
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
||||
#ifdef DATA_IN_ExtSRAM
|
||||
SystemInit_ExtMemCtl();
|
||||
#endif /* DATA_IN_ExtSRAM */
|
||||
#endif
|
||||
|
||||
/* Configure the Vector Table location -------------------------------------*/
|
||||
#if defined(USER_VECT_TAB_ADDRESS)
|
||||
SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
|
||||
#endif /* USER_VECT_TAB_ADDRESS */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update SystemCoreClock variable according to Clock Register Values.
|
||||
* The SystemCoreClock variable contains the core clock (HCLK), it can
|
||||
* be used by the user application to setup the SysTick timer or configure
|
||||
* other parameters.
|
||||
*
|
||||
* @note Each time the core clock (HCLK) changes, this function must be called
|
||||
* to update SystemCoreClock variable value. Otherwise, any configuration
|
||||
* based on this variable will be incorrect.
|
||||
*
|
||||
* @note - The system frequency computed by this function is not the real
|
||||
* frequency in the chip. It is calculated based on the predefined
|
||||
* constant and the selected clock source:
|
||||
*
|
||||
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
|
||||
*
|
||||
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
|
||||
*
|
||||
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
|
||||
* or HSI_VALUE(*) multiplied by the PLL factors.
|
||||
*
|
||||
* (*) HSI_VALUE is a constant defined in stm32f1xx.h file (default value
|
||||
* 8 MHz) but the real value may vary depending on the variations
|
||||
* in voltage and temperature.
|
||||
*
|
||||
* (**) HSE_VALUE is a constant defined in stm32f1xx.h file (default value
|
||||
* 8 MHz or 25 MHz, depending on the product used), user has to ensure
|
||||
* that HSE_VALUE is same as the real frequency of the crystal used.
|
||||
* Otherwise, this function may have wrong result.
|
||||
*
|
||||
* - The result of this function could be not correct when using fractional
|
||||
* value for HSE crystal.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SystemCoreClockUpdate (void)
|
||||
{
|
||||
uint32_t tmp = 0U, pllmull = 0U, pllsource = 0U;
|
||||
|
||||
#if defined(STM32F105xC) || defined(STM32F107xC)
|
||||
uint32_t prediv1source = 0U, prediv1factor = 0U, prediv2factor = 0U, pll2mull = 0U;
|
||||
#endif /* STM32F105xC */
|
||||
|
||||
#if defined(STM32F100xB) || defined(STM32F100xE)
|
||||
uint32_t prediv1factor = 0U;
|
||||
#endif /* STM32F100xB or STM32F100xE */
|
||||
|
||||
/* Get SYSCLK source -------------------------------------------------------*/
|
||||
tmp = RCC->CFGR & RCC_CFGR_SWS;
|
||||
|
||||
switch (tmp)
|
||||
{
|
||||
case 0x00U: /* HSI used as system clock */
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
case 0x04U: /* HSE used as system clock */
|
||||
SystemCoreClock = HSE_VALUE;
|
||||
break;
|
||||
case 0x08U: /* PLL used as system clock */
|
||||
|
||||
/* Get PLL clock source and multiplication factor ----------------------*/
|
||||
pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
|
||||
pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
|
||||
|
||||
#if !defined(STM32F105xC) && !defined(STM32F107xC)
|
||||
pllmull = ( pllmull >> 18U) + 2U;
|
||||
|
||||
if (pllsource == 0x00U)
|
||||
{
|
||||
/* HSI oscillator clock divided by 2 selected as PLL clock entry */
|
||||
SystemCoreClock = (HSI_VALUE >> 1U) * pllmull;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(STM32F100xB) || defined(STM32F100xE)
|
||||
prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1U;
|
||||
/* HSE oscillator clock selected as PREDIV1 clock entry */
|
||||
SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
|
||||
#else
|
||||
/* HSE selected as PLL clock entry */
|
||||
if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET)
|
||||
{/* HSE oscillator clock divided by 2 */
|
||||
SystemCoreClock = (HSE_VALUE >> 1U) * pllmull;
|
||||
}
|
||||
else
|
||||
{
|
||||
SystemCoreClock = HSE_VALUE * pllmull;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
pllmull = pllmull >> 18U;
|
||||
|
||||
if (pllmull != 0x0DU)
|
||||
{
|
||||
pllmull += 2U;
|
||||
}
|
||||
else
|
||||
{ /* PLL multiplication factor = PLL input clock * 6.5 */
|
||||
pllmull = 13U / 2U;
|
||||
}
|
||||
|
||||
if (pllsource == 0x00U)
|
||||
{
|
||||
/* HSI oscillator clock divided by 2 selected as PLL clock entry */
|
||||
SystemCoreClock = (HSI_VALUE >> 1U) * pllmull;
|
||||
}
|
||||
else
|
||||
{/* PREDIV1 selected as PLL clock entry */
|
||||
|
||||
/* Get PREDIV1 clock source and division factor */
|
||||
prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC;
|
||||
prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1U;
|
||||
|
||||
if (prediv1source == 0U)
|
||||
{
|
||||
/* HSE oscillator clock selected as PREDIV1 clock entry */
|
||||
SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
|
||||
}
|
||||
else
|
||||
{/* PLL2 clock selected as PREDIV1 clock entry */
|
||||
|
||||
/* Get PREDIV2 division factor and PLL2 multiplication factor */
|
||||
prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4U) + 1U;
|
||||
pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8U) + 2U;
|
||||
SystemCoreClock = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull;
|
||||
}
|
||||
}
|
||||
#endif /* STM32F105xC */
|
||||
break;
|
||||
|
||||
default:
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Compute HCLK clock frequency ----------------*/
|
||||
/* Get HCLK prescaler */
|
||||
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)];
|
||||
/* HCLK clock frequency */
|
||||
SystemCoreClock >>= tmp;
|
||||
}
|
||||
|
||||
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
||||
/**
|
||||
* @brief Setup the external memory controller. Called in startup_stm32f1xx.s
|
||||
* before jump to __main
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
#ifdef DATA_IN_ExtSRAM
|
||||
/**
|
||||
* @brief Setup the external memory controller.
|
||||
* Called in startup_stm32f1xx_xx.s/.c before jump to main.
|
||||
* This function configures the external SRAM mounted on STM3210E-EVAL
|
||||
* board (STM32 High density devices). This SRAM will be used as program
|
||||
* data memory (including heap and stack).
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SystemInit_ExtMemCtl(void)
|
||||
{
|
||||
__IO uint32_t tmpreg;
|
||||
/*!< FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is
|
||||
required, then adjust the Register Addresses */
|
||||
|
||||
/* Enable FSMC clock */
|
||||
RCC->AHBENR = 0x00000114U;
|
||||
|
||||
/* Delay after an RCC peripheral clock enabling */
|
||||
tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_FSMCEN);
|
||||
|
||||
/* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */
|
||||
RCC->APB2ENR = 0x000001E0U;
|
||||
|
||||
/* Delay after an RCC peripheral clock enabling */
|
||||
tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPDEN);
|
||||
|
||||
(void)(tmpreg);
|
||||
|
||||
/* --------------- SRAM Data lines, NOE and NWE configuration ---------------*/
|
||||
/*---------------- SRAM Address lines configuration -------------------------*/
|
||||
/*---------------- NOE and NWE configuration --------------------------------*/
|
||||
/*---------------- NE3 configuration ----------------------------------------*/
|
||||
/*---------------- NBL0, NBL1 configuration ---------------------------------*/
|
||||
|
||||
GPIOD->CRL = 0x44BB44BBU;
|
||||
GPIOD->CRH = 0xBBBBBBBBU;
|
||||
|
||||
GPIOE->CRL = 0xB44444BBU;
|
||||
GPIOE->CRH = 0xBBBBBBBBU;
|
||||
|
||||
GPIOF->CRL = 0x44BBBBBBU;
|
||||
GPIOF->CRH = 0xBBBB4444U;
|
||||
|
||||
GPIOG->CRL = 0x44BBBBBBU;
|
||||
GPIOG->CRH = 0x444B4B44U;
|
||||
|
||||
/*---------------- FSMC Configuration ---------------------------------------*/
|
||||
/*---------------- Enable FSMC Bank1_SRAM Bank ------------------------------*/
|
||||
|
||||
FSMC_Bank1->BTCR[4U] = 0x00001091U;
|
||||
FSMC_Bank1->BTCR[5U] = 0x00110212U;
|
||||
}
|
||||
#endif /* DATA_IN_ExtSRAM */
|
||||
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
117
Core/Src/usart.c
Normal file
117
Core/Src/usart.c
Normal file
@ -0,0 +1,117 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usart.c
|
||||
* @brief This file provides code for the configuration
|
||||
* of the USART instances.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usart.h"
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
UART_HandleTypeDef huart1;
|
||||
|
||||
/* USART1 init function */
|
||||
|
||||
void MX_USART1_UART_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN USART1_Init 0 */
|
||||
|
||||
/* USER CODE END USART1_Init 0 */
|
||||
|
||||
/* USER CODE BEGIN USART1_Init 1 */
|
||||
|
||||
/* USER CODE END USART1_Init 1 */
|
||||
huart1.Instance = USART1;
|
||||
huart1.Init.BaudRate = 115200;
|
||||
huart1.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
huart1.Init.StopBits = UART_STOPBITS_1;
|
||||
huart1.Init.Parity = UART_PARITY_NONE;
|
||||
huart1.Init.Mode = UART_MODE_TX_RX;
|
||||
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||
if (HAL_UART_Init(&huart1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN USART1_Init 2 */
|
||||
|
||||
/* USER CODE END USART1_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
|
||||
{
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
if(uartHandle->Instance==USART1)
|
||||
{
|
||||
/* USER CODE BEGIN USART1_MspInit 0 */
|
||||
|
||||
/* USER CODE END USART1_MspInit 0 */
|
||||
/* USART1 clock enable */
|
||||
__HAL_RCC_USART1_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
/**USART1 GPIO Configuration
|
||||
PA9 ------> USART1_TX
|
||||
PA10 ------> USART1_RX
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_9;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_10;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN USART1_MspInit 1 */
|
||||
|
||||
/* USER CODE END USART1_MspInit 1 */
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
|
||||
{
|
||||
|
||||
if(uartHandle->Instance==USART1)
|
||||
{
|
||||
/* USER CODE BEGIN USART1_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END USART1_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_USART1_CLK_DISABLE();
|
||||
|
||||
/**USART1 GPIO Configuration
|
||||
PA9 ------> USART1_TX
|
||||
PA10 ------> USART1_RX
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
|
||||
|
||||
/* USER CODE BEGIN USART1_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END USART1_MspDeInit 1 */
|
||||
}
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
Reference in New Issue
Block a user