/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2022 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 <stdio.h>
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* 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 ---------------------------------------------------------*/
CAN_HandleTypeDef hcan1;
CAN_HandleTypeDef hcan2;
I2C_HandleTypeDef hi2c2;
TIM_HandleTypeDef htim3;
UART_HandleTypeDef huart4;
/* USER CODE BEGIN PV */
volatile int gTimerCnt = 0;
volatile unsigned int gsec = 0;
volatile unsigned int gmin = 0;
volatile unsigned int ghour = 0;
volatile unsigned int canState = 0;
volatile unsigned int canTime = 0;
/* Private variables ---------------------------------------------------------*/
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_UART4_Init(void);
static void MX_TIM3_Init(void);
static void MX_CAN1_Init(void);
static void MX_CAN2_Init(void);
static void MX_I2C2_Init(void);
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
// USART
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
//
// CAN1 TX
CAN_TxHeaderTypeDef TxHeader;
uint8_t TxData[8];
uint32_t TxMailbox;
//
// CAN1 RX
CAN_FilterTypeDef sFilterConfig;
CAN_RxHeaderTypeDef RxHeader;
uint8_t RxData[8];
// CAN1 callback
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *CanHandle) {
printf("CAN1 %s\r\n", __FUNCTION__);
// Get RX message
if (HAL_CAN_GetRxMessage(CanHandle, CAN_RX_FIFO0, &RxHeader, RxData)
!= HAL_OK) {
// Reception Error
Error_Handler();
}
printf("CAN1 StdID: %04lx, IDE: %ld, DLC: %ld\r\n", RxHeader.StdId,
RxHeader.IDE, RxHeader.DLC);
printf("CAN1 Data: %d %d %d %d %d %d %d %d\r\n", RxData[0], RxData[1],
RxData[2], RxData[3], RxData[4], RxData[5], RxData[6], RxData[7]);
}
//
// CAN2 TX
CAN_TxHeaderTypeDef Tx2Header;
uint8_t Tx2Data[8];
uint32_t Tx2Mailbox;
//
// CAN2 RX
CAN_FilterTypeDef sFilter2Config;
CAN_RxHeaderTypeDef Rx2Header;
uint8_t Rx2Data[8];
// CAN2 callback
void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *CanHandle) {
printf("CAN2 %s\r\n", __FUNCTION__);
// Get RX message
if (HAL_CAN_GetRxMessage(CanHandle, CAN_RX_FIFO1, &Rx2Header, Rx2Data)
!= HAL_OK) {
// Reception Error
Error_Handler();
}
printf("CAN2 StdID: %04lx, IDE: %ld, DLC: %ld\r\n", Rx2Header.StdId,
Rx2Header.IDE, Rx2Header.DLC);
printf("CAN2 Data: %d %d %d %d %d %d %d %d\r\n", Rx2Data[0], Rx2Data[1],
Rx2Data[2], Rx2Data[3], Rx2Data[4], Rx2Data[5], Rx2Data[6],
Rx2Data[7]);
}
// CAN Error callback
void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan) {
printf("%s\r\n", __FUNCTION__);
}
//
// I2C AT24C04
HAL_StatusTypeDef Status;
#define ADDR_AT24C04_WRITE_FIRST_16_PAGES 0xA0
#define ADDR_AT24C04_WRITE_LAST_16_PAGES 0xA2
#define ADDR_AT24C04_READ 0xA1
#define AT24C04_PAGE_SIZE 16
#define AT24C04_TIMEOUT 0xFF
#define BUFFER_SIZE 512
uint8_t WriteBuffer[BUFFER_SIZE] = "COPYRIGHT(c) Waveshare\r\n"
"Replace this string buffer with your own one (512 bytes or less). "
"The string will be saved into the EEPROM.\r\n"
"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" "
"AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE "
"IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE "
"DISCLAIMED.\r\n";
uint8_t ReadBuffer[BUFFER_SIZE];
HAL_StatusTypeDef AT24C04_Write(I2C_HandleTypeDef *hi2c, uint8_t *pData);
HAL_StatusTypeDef AT24C04_Read(I2C_HandleTypeDef *hi2c, uint8_t *pData);
//
/**
* @brief Retargets the C library printf function to the USART
* @param None
* @retval None
*/
PUTCHAR_PROTOTYPE {
if (ch == '\n')
HAL_UART_Transmit(&huart4, (uint8_t*) "\r", 1, 0xFFFF);
HAL_UART_Transmit(&huart4, (uint8_t*) &ch, 1, 0xFFFF);
return ch;
}
/* USER CODE BEGIN PFP */
/* 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_UART4_Init();
//MX_TIM3_Init();
MX_CAN1_Init();
MX_CAN2_Init();
MX_I2C2_Init();
/* USER CODE BEGIN 2 */
//TIM3
HAL_TIM_Base_Start_IT(&htim3);
//
//USART
//uint8_t i =0;
//uint8_t buff[10]="hello\n";
printf("Start!\r\n");
//
//CAN1 Start
if (HAL_CAN_Start(&hcan1) != HAL_OK) {
/* Start Error */
Error_Handler();
}
/* Configure Transmission process */
TxHeader.StdId = 0x321; // Standard Identifier, 0 ~ 0x7FF
TxHeader.ExtId = 0x01; // Extended Identifier, 0 ~ 0x1FFFFFFF
TxHeader.RTR = CAN_RTR_DATA;
TxHeader.IDE = CAN_ID_STD;
TxHeader.DLC = 8; // 길이, 0 ~ 8 byte
TxHeader.TransmitGlobalTime = DISABLE; // timestamp counter 값을 capture.
/* Set the data to be transmitted */
TxData[0] = 1;
TxData[1] = 2;
TxData[2] = 3;
TxData[3] = 4;
TxData[4] = 5;
TxData[5] = 6;
TxData[6] = 7;
TxData[7] = 8;
//
//CAN1 RX
// CAN Filter
sFilterConfig.FilterBank = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.SlaveStartFilterBank = 14;
if (HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK) {
// Filter configuration Error
Error_Handler();
}
// Activate CAN RX notification
if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING)
!= HAL_OK) {
// Notification Error
Error_Handler();
}
//
// CAN2 Start
if (HAL_CAN_Start(&hcan2) != HAL_OK) {
/* Start Error */
Error_Handler();
}
/* Configure Transmission process */
Tx2Header.StdId = 0x123; // Standard Identifier, 0 ~ 0x7FF
Tx2Header.ExtId = 0x01; // Extended Identifier, 0 ~ 0x1FFFFFFF
Tx2Header.RTR = CAN_RTR_DATA;
Tx2Header.IDE = CAN_ID_STD;
Tx2Header.DLC = 8;
Tx2Header.TransmitGlobalTime = DISABLE;
/* Set the data to be transmitted */
Tx2Data[0] = 8;
Tx2Data[1] = 7;
Tx2Data[2] = 6;
Tx2Data[3] = 5;
Tx2Data[4] = 4;
Tx2Data[5] = 3;
Tx2Data[6] = 2;
Tx2Data[7] = 1;
//
// CAN2 RX
// CAN Filter
sFilter2Config.FilterBank = 14;
sFilter2Config.FilterMode = CAN_FILTERMODE_IDMASK;
sFilter2Config.FilterScale = CAN_FILTERSCALE_32BIT;
sFilter2Config.FilterIdHigh = 0x0000;
sFilter2Config.FilterIdLow = 0x0000;
sFilter2Config.FilterMaskIdHigh = 0x0000;
sFilter2Config.FilterMaskIdLow = 0x0000;
sFilter2Config.FilterFIFOAssignment = CAN_RX_FIFO1;
sFilter2Config.FilterActivation = ENABLE;
sFilter2Config.SlaveStartFilterBank = 14;
if (HAL_CAN_ConfigFilter(&hcan2, &sFilter2Config) != HAL_OK) {
// Filter configuration Error
Error_Handler();
}
// Activate CAN RX notification
if (HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO1_MSG_PENDING)
!= HAL_OK) {
// Notification Error
Error_Handler();
}
//
// I2C AT24C04
//a[0]=a[0]+1;
/* Write data to EEPROM */
if((Status = AT24C04_Write(&hi2c2, WriteBuffer)) != HAL_OK)
{
printf("\r\n EEPROM 24C04 write false. Error code: %d\r\n", Status);
}
/* Read data from EEPROM */
if((Status = AT24C04_Read(&hi2c2, ReadBuffer)) == HAL_OK)
{
printf("\r\nReadBuffer = \r\n");
printf("%s", ReadBuffer);
}
else
{
printf("\r\n EEPROM 24C04 read false. Error code: %d\r\n", Status);
}
//
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1) {
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_12);
HAL_Delay(100);
//USART
//printf("printf: hello world!\n");
//HAL_UART_Transmit(&huart4, buff, sizeof(buff), 100);
//
// USART TIM
//printf("RunTime : %d:%d:%d\n",ghour,gmin,gsec);
//
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** 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.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 4;
RCC_OscInitStruct.PLL.PLLN = 168;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** 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_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief CAN1 Initialization Function
* @param None
* @retval None
*/
static void MX_CAN1_Init(void)
{
/* USER CODE BEGIN CAN1_Init 0 */
/* USER CODE END CAN1_Init 0 */
/* USER CODE BEGIN CAN1_Init 1 */
/* USER CODE END CAN1_Init 1 */
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 6;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_11TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_2TQ;
hcan1.Init.TimeTriggeredMode = DISABLE;
hcan1.Init.AutoBusOff = DISABLE;
hcan1.Init.AutoWakeUp = DISABLE;
hcan1.Init.AutoRetransmission = DISABLE;
hcan1.Init.ReceiveFifoLocked = DISABLE;
hcan1.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN CAN1_Init 2 */
/* USER CODE END CAN1_Init 2 */
}
/**
* @brief CAN2 Initialization Function
* @param None
* @retval None
*/
static void MX_CAN2_Init(void)
{
/* USER CODE BEGIN CAN2_Init 0 */
/* USER CODE END CAN2_Init 0 */
/* USER CODE BEGIN CAN2_Init 1 */
/* USER CODE END CAN2_Init 1 */
hcan2.Instance = CAN2;
hcan2.Init.Prescaler = 6;
hcan2.Init.Mode = CAN_MODE_NORMAL;
hcan2.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan2.Init.TimeSeg1 = CAN_BS1_11TQ;
hcan2.Init.TimeSeg2 = CAN_BS2_2TQ;
hcan2.Init.TimeTriggeredMode = DISABLE;
hcan2.Init.AutoBusOff = DISABLE;
hcan2.Init.AutoWakeUp = DISABLE;
hcan2.Init.AutoRetransmission = DISABLE;
hcan2.Init.ReceiveFifoLocked = DISABLE;
hcan2.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN CAN2_Init 2 */
/* USER CODE END CAN2_Init 2 */
}
/**
* @brief I2C2 Initialization Function
* @param None
* @retval None
*/
static void MX_I2C2_Init(void)
{
/* USER CODE BEGIN I2C2_Init 0 */
/* USER CODE END I2C2_Init 0 */
/* USER CODE BEGIN I2C2_Init 1 */
/* USER CODE END I2C2_Init 1 */
hi2c2.Instance = I2C2;
hi2c2.Init.ClockSpeed = 400000;
hi2c2.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c2.Init.OwnAddress1 = 0;
hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c2.Init.OwnAddress2 = 0;
hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN I2C2_Init 2 */
/* USER CODE END I2C2_Init 2 */
}
/**
* @brief TIM3 Initialization Function
* @param None
* @retval None
*/
static void MX_TIM3_Init(void)
{
/* USER CODE BEGIN TIM3_Init 0 */
/* USER CODE END TIM3_Init 0 */
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
/* USER CODE BEGIN TIM3_Init 1 */
/* USER CODE END TIM3_Init 1 */
htim3.Instance = TIM3;
htim3.Init.Prescaler = 42000-1;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 2000;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM3_Init 2 */
/* USER CODE END TIM3_Init 2 */
}
/**
* @brief UART4 Initialization Function
* @param None
* @retval None
*/
static void MX_UART4_Init(void)
{
/* USER CODE BEGIN UART4_Init 0 */
/* USER CODE END UART4_Init 0 */
/* USER CODE BEGIN UART4_Init 1 */
/* USER CODE END UART4_Init 1 */
huart4.Instance = UART4;
huart4.Init.BaudRate = 115200;
huart4.Init.WordLength = UART_WORDLENGTH_8B;
huart4.Init.StopBits = UART_STOPBITS_1;
huart4.Init.Parity = UART_PARITY_NONE;
huart4.Init.Mode = UART_MODE_TX_RX;
huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart4.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart4) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN UART4_Init 2 */
/* USER CODE END UART4_Init 2 */
}
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOD, LED1_Pin|LED2_Pin|LED3_Pin|LED4_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin : PA0 */
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pin : PB1 */
GPIO_InitStruct.Pin = GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pins : LED1_Pin LED2_Pin LED3_Pin LED4_Pin */
GPIO_InitStruct.Pin = LED1_Pin|LED2_Pin|LED3_Pin|LED4_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI1_IRQn);
}
/* USER CODE BEGIN 4 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_PIN) {
switch (GPIO_PIN) {
case GPIO_PIN_0:
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_13);
break;
case GPIO_PIN_1:
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_14);
break;
}
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
if (htim->Instance == htim3.Instance) {
/* Toggle LED1 */
HAL_GPIO_TogglePin(LED4_GPIO_Port, LED4_Pin);
// Time Debug
printf("gTime : %d(h):%d(m):%d(s)\r\n", ghour, gmin, gsec);
gsec++;
canTime++;
if (canTime == 6 && canState == 1) {
canTime = 1;
//CAN1 TX
if (HAL_CAN_AddTxMessage(&hcan1, &TxHeader, TxData, &TxMailbox)
!= HAL_OK) {
printf("Can1 Send Fail\r\n");
Error_Handler();
}
printf("Can1 Send Success\r\n");
//
//CAN2 TX
if (HAL_CAN_AddTxMessage(&hcan2, &Tx2Header, Tx2Data, &Tx2Mailbox)
!= HAL_OK) {
printf("Can2 Send Fail\r\n");
Error_Handler();
}
//HAL_Delay(10);
printf("Can2 Send Success\r\n");
//
}
if (gsec == 60) {
gsec = 0;
gmin++;
if (gmin == 60) {
ghour++;
if (ghour == 24) {
ghour = 0;
}
}
}
}
}
// I2C AT24C04
HAL_StatusTypeDef AT24C04_Write(I2C_HandleTypeDef *hi2c, uint8_t *pData)
{
uint16_t MemAddress;
uint16_t Page = 0;
/** The AT24C04 internally organized with 32 pages of 16 bytes each, the 4K
* requires an 9-bit data word address for random word addressing.
* However, AT24C04 can only receive 8-bit data per period, so the 9-bit
* data word address is actually compromised with the page address bit in
* device address and the 8-bit memory address.
* The device address 0xA0 means the first 16 pages while 0xA2 means the
* last 32 pages.
* The jumpers will also define the address, so the address 0xA0 or 0xA2
* are not always right.
*/
while(Page < 16)
{
MemAddress = Page << 4;
/** A page write is initiated the same as a byte write, but the
* microcontroller does not send a stop condition after the first data word
* is clocked in.
* In AT24C04, 1 page = 16 bytes.
* When the word address, internally generated, reaches the page boundary,
* the following byte is placed at the beginning of the same page.
*/
Status = HAL_I2C_Mem_Write(&hi2c2, ADDR_AT24C04_WRITE_FIRST_16_PAGES, MemAddress, I2C_MEMADD_SIZE_8BIT, pData, AT24C04_PAGE_SIZE, AT24C04_TIMEOUT);
if(Status == HAL_OK)
{
Page++;
pData += AT24C04_PAGE_SIZE;
HAL_Delay(5);
}
else
{
return Status;
}
}
while(Page >= 16 && Page < 32)
{
MemAddress = (Page - 16) << 4;
Status = HAL_I2C_Mem_Write(&hi2c2, ADDR_AT24C04_WRITE_LAST_16_PAGES, MemAddress, I2C_MEMADD_SIZE_8BIT, pData, AT24C04_PAGE_SIZE, AT24C04_TIMEOUT);
if(Status == HAL_OK)
{
Page++;
pData += AT24C04_PAGE_SIZE;
HAL_Delay(5);
}
else
{
return Status;
}
}
return Status;
}
/**
* @brief Read all of the data from the AT24C04 EEPROM.
* @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
* the configuration information for the specified I2C.
* @param pData Pointer to data buffer
* @retval HAL status
*/
HAL_StatusTypeDef AT24C04_Read(I2C_HandleTypeDef *hi2c, uint8_t *pData)
{
uint16_t MemAddress = 0x00;
Status = HAL_I2C_Mem_Read(&hi2c2, ADDR_AT24C04_READ, MemAddress, I2C_MEMADD_SIZE_8BIT, pData, BUFFER_SIZE, AT24C04_TIMEOUT);
return Status;
}
//
/* 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 */
'Project > Open407V-C' 카테고리의 다른 글
Open407V-C CAN1,CAN2 TX/RX (0) | 2022.06.15 |
---|---|
Open407V-C CAN2 TX (0) | 2022.06.15 |
Open407V-C CAN1 RX (0) | 2022.06.15 |
Open407V-C CAN1 TX (0) | 2022.06.15 |
Open407V-C Timer 인터럽트(Timer 84hz Clock) (0) | 2022.06.13 |