Compare commits
13 Commits
ac40d80777
...
main
Author | SHA1 | Date | |
---|---|---|---|
bdcdcec4ca | |||
e5af1823b0 | |||
1a8f1fa203 | |||
b6d37fcc13 | |||
28be54bc79 | |||
56638ce9ec | |||
8590bf5658 | |||
88fc97d037 | |||
dbbeea4dc7 | |||
5930a19818 | |||
0233fffa4d | |||
7fa633805b | |||
fecaa256ca |
@@ -1,8 +1,23 @@
|
|||||||
cmake_minimum_required(VERSION 3.28)
|
cmake_minimum_required(VERSION 3.28)
|
||||||
include(cmake/toolchain.cmake)
|
include(cmake/toolchain.cmake)
|
||||||
|
|
||||||
|
set(PROJECT_NAME "gd32e23x_template")
|
||||||
project(gd32e23x_template)
|
project(gd32e23x_template)
|
||||||
|
|
||||||
|
set(VERSION_MAJOR 0)
|
||||||
|
set(VERSION_MINOR 0)
|
||||||
|
set(VERSION_PATCH 1)
|
||||||
|
set(VERSION "V${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
|
||||||
|
string(TIMESTAMP CURRENT_DATE "%Y-%m-%d")
|
||||||
|
|
||||||
|
# Options 1
|
||||||
|
set(OPT1 "")
|
||||||
|
#set(OPT1 "_[SW_IIC]")
|
||||||
|
|
||||||
|
# Options 2
|
||||||
|
set(OPT2 "")
|
||||||
|
#set(OPT2 "_[NO_LED]")
|
||||||
|
|
||||||
enable_language(C)
|
enable_language(C)
|
||||||
enable_language(CXX)
|
enable_language(CXX)
|
||||||
enable_language(ASM)
|
enable_language(ASM)
|
||||||
@@ -18,14 +33,18 @@ set(TARGET_C_SRC
|
|||||||
${CMAKE_SOURCE_DIR}/src/main.c
|
${CMAKE_SOURCE_DIR}/src/main.c
|
||||||
${CMAKE_SOURCE_DIR}/src/gd32e23x_it.c
|
${CMAKE_SOURCE_DIR}/src/gd32e23x_it.c
|
||||||
${CMAKE_SOURCE_DIR}/src/systick.c
|
${CMAKE_SOURCE_DIR}/src/systick.c
|
||||||
${CMAKE_SOURCE_DIR}/src/peripheral.c
|
${CMAKE_SOURCE_DIR}/src/led.c
|
||||||
|
${CMAKE_SOURCE_DIR}/src/usart.c
|
||||||
|
${CMAKE_SOURCE_DIR}/src/soft_i2c.c
|
||||||
|
${CMAKE_SOURCE_DIR}/src/i2c.c
|
||||||
|
${CMAKE_SOURCE_DIR}/src/fwdgt.c
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(gd32e23x_template ${TARGET_C_SRC})
|
add_executable(${PROJECT_NAME} ${TARGET_C_SRC})
|
||||||
|
|
||||||
target_link_libraries(gd32e23x_template GD32E23X_SDK)
|
target_link_libraries(${PROJECT_NAME} GD32E23X_SDK)
|
||||||
target_include_directories(gd32e23x_template PUBLIC inc)
|
target_include_directories(${PROJECT_NAME} PUBLIC inc)
|
||||||
|
|
||||||
# Generate .bin and .hex
|
# Generate .bin and .hex
|
||||||
generate_binary_file(gd32e23x_template)
|
generate_binary_file(${PROJECT_NAME})
|
||||||
generate_hex_file(gd32e23x_template)
|
generate_hex_file(${PROJECT_NAME})
|
||||||
|
21
README.md
21
README.md
@@ -1,7 +1,25 @@
|
|||||||
# gd32e23x_template
|
# gd32e23x_template
|
||||||
本项目为GD32E230Fx系列的基于Clion的CMake开发的工程模板。本人暂未入门,强行上强度,放弃keil,拥抱开源。遂尝试使用arm-none-eabi-gcc进行开发。
|
本项目为`GD32E230Fx`系列的基于Clion的CMake开发的工程模板。本人暂未入门,强行上强度,放弃keil,拥抱开源。遂尝试使用arm-none-eabi-gcc进行开发。
|
||||||
有幸寻得[@mo10 ](https://github.com/mo10)大佬的帮助,本项目的基础目录架构与CMakeLists.txt与toolchain.cmake均为大佬提供。
|
有幸寻得[@mo10 ](https://github.com/mo10)大佬的帮助,本项目的基础目录架构与CMakeLists.txt与toolchain.cmake均为大佬提供。
|
||||||
|
|
||||||
|
## 关于本项目
|
||||||
|
本项目默认的芯片型号为`GD32E230F4`,但是可以根据需要修改为其他型号,具体修改方法请参考下方`关于链接脚本`的说明。
|
||||||
|
### 版本号
|
||||||
|
默认版本号为`0.0.1`,在`CMakeLists.txt`中修改`PROJECT_VERSION`即可。
|
||||||
|
### 项目名称
|
||||||
|
默认项目名称为`gd32e23x_template`,在`CMakeLists.txt`中修改`set(PROJECT_NAME "gd32e23x_template")`即可。请先修改项目名称再配置编译环境。
|
||||||
|
### 软件IIC与硬件IIC
|
||||||
|
本项目中提供了软件IIC与硬件IIC的驱动,但是默认使用硬件IIC,如果需要使用软件IIC,请在`board_config.h`中取消注释`// #define SOFTWARE_IIC`(line 8)。
|
||||||
|
### 编译选项
|
||||||
|
本项目预留了两个编译选项,`OPT1`与`OPT2`,默认均为空,请根据需要自行修改,例如`OPT1`为`_[HW_IIC]`,`OPT2`为`_[NO_LED]`。
|
||||||
|
`OPT1`与`OPT2`均在`CMakeLists.txt`中可修改。
|
||||||
|
### 关于编译日期
|
||||||
|
本项目在`CMakeLists.txt`中添加了编译日期。
|
||||||
|
|
||||||
|
### 关于led
|
||||||
|
本项目默认开启了LED闪烁,并使用TIMER16进行定时。
|
||||||
|
|
||||||
|
|
||||||
## 关于C标准库的printf的重写
|
## 关于C标准库的printf的重写
|
||||||
在Keil开发中,ARMClang有自己的microLIB,所以直接调用,然后重写fputc函数即可,但在gcc中需要重写`_write`函数,本项目模板中已经在`main.c`中完成重写。
|
在Keil开发中,ARMClang有自己的microLIB,所以直接调用,然后重写fputc函数即可,但在gcc中需要重写`_write`函数,本项目模板中已经在`main.c`中完成重写。
|
||||||
同时需要添加`--spaces=nano.spaces`编译参数。
|
同时需要添加`--spaces=nano.spaces`编译参数。
|
||||||
@@ -15,7 +33,6 @@ set(TARGET_C_SRC
|
|||||||
${CMAKE_SOURCE_DIR}/src/main.c
|
${CMAKE_SOURCE_DIR}/src/main.c
|
||||||
${CMAKE_SOURCE_DIR}/src/gd32e23x_it.c
|
${CMAKE_SOURCE_DIR}/src/gd32e23x_it.c
|
||||||
${CMAKE_SOURCE_DIR}/src/systick.c
|
${CMAKE_SOURCE_DIR}/src/systick.c
|
||||||
${CMAKE_SOURCE_DIR}/src/peripheral.c
|
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
## 关于链接脚本
|
## 关于链接脚本
|
||||||
|
@@ -41,12 +41,12 @@ function(print_size_of_target TARGET)
|
|||||||
)
|
)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
function(_generate_file TARGET OUTPUT_EXTENSION OBJCOPY_BFD_OUTPUT)
|
function(_generate_file TARGET VERSION CURRENT_DATE OPT1 OPT2 OUTPUT_EXTENSION OBJCOPY_BFD_OUTPUT)
|
||||||
get_target_property(TARGET_OUTPUT_NAME ${TARGET} OUTPUT_NAME)
|
get_target_property(TARGET_OUTPUT_NAME ${TARGET} OUTPUT_NAME)
|
||||||
if (TARGET_OUTPUT_NAME)
|
if (TARGET_OUTPUT_NAME)
|
||||||
set(OUTPUT_FILE_NAME "${TARGET_OUTPUT_NAME}.${OUTPUT_EXTENSION}")
|
set(OUTPUT_FILE_NAME "${TARGET_OUTPUT_NAME}_${VERSION}_${CURRENT_DATE}${OPT1}${OPT2}.${OUTPUT_EXTENSION}")
|
||||||
else()
|
else()
|
||||||
set(OUTPUT_FILE_NAME "${TARGET}.${OUTPUT_EXTENSION}")
|
set(OUTPUT_FILE_NAME "${TARGET}_${VERSION}_${CURRENT_DATE}${OPT1}${OPT2}.${OUTPUT_EXTENSION}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
get_target_property(RUNTIME_OUTPUT_DIRECTORY ${TARGET} RUNTIME_OUTPUT_DIRECTORY)
|
get_target_property(RUNTIME_OUTPUT_DIRECTORY ${TARGET} RUNTIME_OUTPUT_DIRECTORY)
|
||||||
@@ -66,11 +66,11 @@ function(_generate_file TARGET OUTPUT_EXTENSION OBJCOPY_BFD_OUTPUT)
|
|||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
function(generate_binary_file TARGET)
|
function(generate_binary_file TARGET)
|
||||||
_generate_file(${TARGET} "bin" "binary")
|
_generate_file(${TARGET} "${VERSION}" "${CURRENT_DATE}" "${OPT1}" "${OPT2}" "bin" "binary")
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
function(generate_hex_file TARGET)
|
function(generate_hex_file TARGET)
|
||||||
_generate_file(${TARGET} "hex" "ihex")
|
_generate_file(${TARGET} "${VERSION}" "${CURRENT_DATE}" "${OPT1}" "${OPT2}" "hex" "ihex")
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
set(CMAKE_EXECUTABLE_SUFFIX_C .elf)
|
set(CMAKE_EXECUTABLE_SUFFIX_C .elf)
|
||||||
@@ -91,9 +91,15 @@ set(TARGET_CFLAGS_HARDWARE "-mcpu=cortex-m23 -mfloat-abi=soft -mthumb -mthumb-in
|
|||||||
|
|
||||||
# Conditional flags
|
# Conditional flags
|
||||||
# DEBUG
|
# DEBUG
|
||||||
set(CMAKE_C_FLAGS_DEBUG "-DDEBUG=0 -O0 -g")
|
#set(CMAKE_C_FLAGS_DEBUG "-DDEBUG=0 -O0 -g")
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "-DDEBUG=0 -O0 -g")
|
#set(CMAKE_CXX_FLAGS_DEBUG "-DDEBUG=0 -O0 -g")
|
||||||
set(CMAKE_ASM_FLAGS_DEBUG "-DDEBUG=0 -O0 -g")
|
#set(CMAKE_ASM_FLAGS_DEBUG "-DDEBUG=0 -O0 -g")
|
||||||
|
set(CMAKE_C_FLAGS_DEBUG "-DDEBUG=0 -O2 -g")
|
||||||
|
set(CMAKE_CXX_FLAGS_DEBUG "-DDEBUG=0 -O2 -g")
|
||||||
|
set(CMAKE_ASM_FLAGS_DEBUG "-DDEBUG=0 -O2 -g")
|
||||||
|
#set(CMAKE_C_FLAGS_DEBUG "-DDEBUG=0 -Os -g")
|
||||||
|
#set(CMAKE_CXX_FLAGS_DEBUG "-DDEBUG=0 -Os -g")
|
||||||
|
#set(CMAKE_ASM_FLAGS_DEBUG "-DDEBUG=0 -Os -g")
|
||||||
|
|
||||||
# RELEASE
|
# RELEASE
|
||||||
set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG -O3") # -flto
|
set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG -O3") # -flto
|
||||||
|
47
inc/board_config.h
Normal file
47
inc/board_config.h
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
//
|
||||||
|
// Created by dell on 24-12-28.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef BOARD_CONFIG_H
|
||||||
|
#define BOARD_CONFIG_H
|
||||||
|
|
||||||
|
// #define SOFTWARE_IIC
|
||||||
|
|
||||||
|
// #define DEBUG_VERBOES
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
#define I2C_GPIO_RCU RCU_GPIOF
|
||||||
|
#define I2C_RCU RCU_I2C0
|
||||||
|
#define I2C_PHY I2C0
|
||||||
|
#define I2C_SCL_PORT GPIOF
|
||||||
|
#define I2C_SCL_PIN GPIO_PIN_1
|
||||||
|
#define I2C_SDA_PORT GPIOF
|
||||||
|
#define I2C_SDA_PIN GPIO_PIN_0
|
||||||
|
#define I2C_GPIO_AF GPIO_AF_1
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
#define USART_GPIO_RCU RCU_GPIOA
|
||||||
|
#define USART_RCU RCU_USART0
|
||||||
|
#define USART_GPIO_PORT GPIOA
|
||||||
|
#define USART_GPIO_AF GPIO_AF_1
|
||||||
|
#define USART_TX_PIN GPIO_PIN_2
|
||||||
|
#define USART_RX_PIN GPIO_PIN_3
|
||||||
|
#define USART_PHY USART0
|
||||||
|
#define USART_PHY_BAUDRATE 115200U
|
||||||
|
#define RS485_EN_PORT GPIOA
|
||||||
|
#define RS485_EN_PIN GPIO_PIN_1
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
#define LED_PORT GPIOA
|
||||||
|
#define LED_PIN GPIO_PIN_7
|
||||||
|
#define LED_RCU RCU_GPIOA
|
||||||
|
#define LED_BLINK_TIMER_RCU RCU_TIMER16
|
||||||
|
#define LED_BLINK_TIMER TIMER16
|
||||||
|
#define LED_BLINK_IRQ TIMER16_IRQn
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
#endif //BOARD_CONFIG_H
|
17
inc/fwdgt.h
Normal file
17
inc/fwdgt.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// Created by yelv1 on 24-12-29.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef FWDGT_H
|
||||||
|
#define FWDGT_H
|
||||||
|
|
||||||
|
#include "gd32e23x.h"
|
||||||
|
#include "board_config.h"
|
||||||
|
|
||||||
|
void watchdog_init(void);
|
||||||
|
|
||||||
|
void fwdgt_reset_mcu(void);
|
||||||
|
|
||||||
|
void watchdog_reload(void);
|
||||||
|
|
||||||
|
#endif //FWDGT_H
|
@@ -36,6 +36,9 @@ OF SUCH DAMAGE.
|
|||||||
#define GD32E23X_IT_H
|
#define GD32E23X_IT_H
|
||||||
|
|
||||||
#include "gd32e23x.h"
|
#include "gd32e23x.h"
|
||||||
|
#include "main.h"
|
||||||
|
#include "systick.h"
|
||||||
|
#include "board_config.h"
|
||||||
|
|
||||||
/* function declarations */
|
/* function declarations */
|
||||||
/* this function handles NMI exception */
|
/* this function handles NMI exception */
|
||||||
@@ -49,4 +52,6 @@ void PendSV_Handler(void);
|
|||||||
/* this function handles SysTick exception */
|
/* this function handles SysTick exception */
|
||||||
void SysTick_Handler(void);
|
void SysTick_Handler(void);
|
||||||
|
|
||||||
|
void TIMER16_IRQHandler(void);
|
||||||
|
|
||||||
#endif /* GD32E23X_IT_H */
|
#endif /* GD32E23X_IT_H */
|
||||||
|
53
inc/i2c.h
Normal file
53
inc/i2c.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
//
|
||||||
|
// Created by dell on 24-12-20.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef I2C_H
|
||||||
|
#define I2C_H
|
||||||
|
|
||||||
|
#include "gd32e23x_it.h"
|
||||||
|
#include "gd32e23x.h"
|
||||||
|
#include "systick.h"
|
||||||
|
#include "main.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "board_config.h"
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
#define I2C_SPEED 20000
|
||||||
|
|
||||||
|
#define I2C_TIME_OUT (uint16_t)(5000)
|
||||||
|
#define I2C_OK 1
|
||||||
|
#define I2C_FAIL 0
|
||||||
|
#define I2C_END 1
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
I2C_START = 0,
|
||||||
|
I2C_SEND_ADDRESS,
|
||||||
|
I2C_CLEAR_ADDRESS_FLAG,
|
||||||
|
I2C_TRANSMIT_DATA,
|
||||||
|
I2C_STOP
|
||||||
|
} i2c_process_enum;
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
void i2c_gpio_config(void);
|
||||||
|
|
||||||
|
void i2c_config(void);
|
||||||
|
|
||||||
|
void i2c_bus_reset(void);
|
||||||
|
|
||||||
|
void i2c_scan(void);
|
||||||
|
|
||||||
|
uint8_t i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]);
|
||||||
|
|
||||||
|
uint8_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data);
|
||||||
|
|
||||||
|
#endif //I2C_H
|
14
inc/led.h
Normal file
14
inc/led.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
//
|
||||||
|
// Created by yelv1 on 24-12-30.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef LED_H
|
||||||
|
#define LED_H
|
||||||
|
|
||||||
|
#include "gd32e23x_it.h"
|
||||||
|
#include "gd32e23x.h"
|
||||||
|
#include "board_config.h"
|
||||||
|
|
||||||
|
void led_blink_config(void);
|
||||||
|
|
||||||
|
#endif //LED_H
|
15
inc/main.h
15
inc/main.h
@@ -35,4 +35,19 @@ OF SUCH DAMAGE.
|
|||||||
#ifndef MAIN_H
|
#ifndef MAIN_H
|
||||||
#define MAIN_H
|
#define MAIN_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "gd32e23x.h"
|
||||||
|
#include "systick.h"
|
||||||
|
#include "gd32e23x_libopt.h"
|
||||||
|
#include "led.h"
|
||||||
|
#include "usart.h"
|
||||||
|
#include "fwdgt.h"
|
||||||
|
#include "board_config.h"
|
||||||
|
|
||||||
|
#ifdef SOFTWARE_IIC
|
||||||
|
#include "soft_i2c.h"
|
||||||
|
#else
|
||||||
|
#include "i2c.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* MAIN_H */
|
#endif /* MAIN_H */
|
||||||
|
@@ -1,11 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by yelv1 on 24-9-22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef PERIPHERAL_H
|
|
||||||
#define PERIPHERAL_H
|
|
||||||
|
|
||||||
void usart_config(void);
|
|
||||||
void led_blink_config(void);
|
|
||||||
|
|
||||||
#endif //PERIPHERAL_H
|
|
53
inc/soft_i2c.h
Normal file
53
inc/soft_i2c.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
//
|
||||||
|
// Created by dell on 24-12-28.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef SOFT_I2C_H
|
||||||
|
#define SOFT_I2C_H
|
||||||
|
|
||||||
|
#include "gd32e23x_it.h"
|
||||||
|
#include "gd32e23x.h"
|
||||||
|
#include "systick.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
#include "board_config.h"
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
#define I2C_SCL_HIGH() gpio_bit_set(I2C_SCL_PORT, I2C_SCL_PIN)
|
||||||
|
#define I2C_SCL_LOW() gpio_bit_reset(I2C_SCL_PORT, I2C_SCL_PIN)
|
||||||
|
#define I2C_SDA_HIGH() gpio_bit_set(I2C_SDA_PORT, I2C_SDA_PIN)
|
||||||
|
#define I2C_SDA_LOW() gpio_bit_reset(I2C_SDA_PORT, I2C_SDA_PIN)
|
||||||
|
#define I2C_SDA_READ() gpio_input_bit_get(I2C_SDA_PORT, I2C_SDA_PIN)
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
#define SOFT_I2C_OK 1
|
||||||
|
#define SOFT_I2C_FAIL 0
|
||||||
|
#define SOFT_I2C_END 1
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
void soft_i2c_delay(void);
|
||||||
|
|
||||||
|
void soft_i2c_config(void);
|
||||||
|
|
||||||
|
void soft_i2c_start(void);
|
||||||
|
|
||||||
|
void soft_i2c_stop(void);
|
||||||
|
|
||||||
|
void soft_i2c_send_ack(void);
|
||||||
|
|
||||||
|
void soft_i2c_send_nack(void);
|
||||||
|
|
||||||
|
uint8_t soft_i2c_wait_ack(void);
|
||||||
|
|
||||||
|
void soft_i2c_send_byte(uint8_t data);
|
||||||
|
|
||||||
|
uint8_t soft_i2c_receive_byte(uint8_t ack);
|
||||||
|
|
||||||
|
uint8_t soft_i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]);
|
||||||
|
|
||||||
|
uint8_t soft_i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data);
|
||||||
|
|
||||||
|
#endif //SOFT_I2C_H
|
15
inc/usart.h
Normal file
15
inc/usart.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
//
|
||||||
|
// Created by yelv1 on 24-12-30.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef USART_H
|
||||||
|
#define USART_H
|
||||||
|
|
||||||
|
#include "gd32e23x.h"
|
||||||
|
#include "board_config.h"
|
||||||
|
|
||||||
|
void usart_config(void);
|
||||||
|
|
||||||
|
void rs485_config(void);
|
||||||
|
|
||||||
|
#endif //USART_H
|
@@ -1,127 +1,155 @@
|
|||||||
/* memory map */
|
/* Memory Map */
|
||||||
|
|
||||||
|
/* Entry Point */
|
||||||
|
ENTRY(Reset_Handler)
|
||||||
|
|
||||||
|
/* Highest address of the user mode stack */
|
||||||
|
_sp = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */
|
||||||
|
|
||||||
|
_Min_Heap_Size = 0x200; /* required amount of heap */
|
||||||
|
_Min_Stack_Size = 0x400; /* required amount of stack */
|
||||||
|
|
||||||
|
/* Memories definition */
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 16K
|
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 16K
|
||||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 4K
|
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 4K
|
||||||
}
|
}
|
||||||
|
|
||||||
ENTRY(Reset_Handler)
|
/* Sections */
|
||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
__stack_size = DEFINED(__stack_size) ? __stack_size : 2K;
|
/* The startup code into "FLASH" Rom type memory */
|
||||||
|
|
||||||
/* ISR vectors */
|
|
||||||
.vectors :
|
.vectors :
|
||||||
{
|
{
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
KEEP(*(.vectors))
|
KEEP(*(.vectors)) /* Startup code */
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
__Vectors_End = .;
|
|
||||||
__Vectors_Size = __Vectors_End - __gVectors;
|
|
||||||
} >FLASH
|
} >FLASH
|
||||||
|
|
||||||
|
/* The program code and other data into "FLASH" Rom type memory */
|
||||||
.text :
|
.text :
|
||||||
{
|
{
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
*(.text)
|
*(.text) /* .text sections (code) */
|
||||||
*(.text*)
|
*(.text*) /* .text* sections (code) */
|
||||||
*(.glue_7)
|
*(.glue_7) /* glue arm to thumb code */
|
||||||
*(.glue_7t)
|
*(.glue_7t) /* glue thumb to arm code */
|
||||||
*(.eh_frame)
|
*(.eh_frame)
|
||||||
|
|
||||||
KEEP (*(.init))
|
KEEP (*(.init))
|
||||||
KEEP (*(.fini))
|
KEEP (*(.fini))
|
||||||
|
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
/* the symbol '_etext' will be defined at the end of code section */
|
_etext = .; /* define a global symbols at end of code */
|
||||||
_etext = .;
|
|
||||||
} >FLASH
|
} >FLASH
|
||||||
|
|
||||||
|
/* Constant data into "FLASH" Rom type memory */
|
||||||
.rodata :
|
.rodata :
|
||||||
{
|
{
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
*(.rodata)
|
*(.rodata) /* .rodata sections (constants, strings, etc.) */
|
||||||
*(.rodata*)
|
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
} >FLASH
|
} >FLASH
|
||||||
|
|
||||||
.ARM.extab :
|
.ARM.extab (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
|
||||||
{
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||||
|
. = ALIGN(4);
|
||||||
} >FLASH
|
} >FLASH
|
||||||
|
|
||||||
.ARM : {
|
.ARM (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
__exidx_start = .;
|
__exidx_start = .;
|
||||||
*(.ARM.exidx*)
|
*(.ARM.exidx*)
|
||||||
__exidx_end = .;
|
__exidx_end = .;
|
||||||
|
. = ALIGN(4);
|
||||||
} >FLASH
|
} >FLASH
|
||||||
|
|
||||||
.ARM.attributes : { *(.ARM.attributes) } > FLASH
|
.preinit_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
|
||||||
|
|
||||||
.preinit_array :
|
|
||||||
{
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||||
KEEP (*(.preinit_array*))
|
KEEP (*(.preinit_array*))
|
||||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||||
|
. = ALIGN(4);
|
||||||
} >FLASH
|
} >FLASH
|
||||||
|
|
||||||
.init_array :
|
.init_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
|
||||||
{
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
PROVIDE_HIDDEN (__init_array_start = .);
|
PROVIDE_HIDDEN (__init_array_start = .);
|
||||||
KEEP (*(SORT(.init_array.*)))
|
KEEP (*(SORT(.init_array.*)))
|
||||||
KEEP (*(.init_array*))
|
KEEP (*(.init_array*))
|
||||||
PROVIDE_HIDDEN (__init_array_end = .);
|
PROVIDE_HIDDEN (__init_array_end = .);
|
||||||
|
. = ALIGN(4);
|
||||||
} >FLASH
|
} >FLASH
|
||||||
|
|
||||||
.fini_array :
|
.fini_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
|
||||||
{
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||||
KEEP (*(.fini_array*))
|
|
||||||
KEEP (*(SORT(.fini_array.*)))
|
KEEP (*(SORT(.fini_array.*)))
|
||||||
|
KEEP (*(.fini_array*))
|
||||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||||
|
. = ALIGN(4);
|
||||||
} >FLASH
|
} >FLASH
|
||||||
|
|
||||||
/* provide some necessary symbols for startup file to initialize data */
|
/* Used by the startup to initialize data */
|
||||||
_sidata = LOADADDR(.data);
|
_sidata = LOADADDR(.data);
|
||||||
|
|
||||||
|
/* Initialized data sections into "RAM" Ram type memory */
|
||||||
.data :
|
.data :
|
||||||
{
|
{
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
/* the symbol '_sdata' will be defined at the data section end start */
|
_sdata = .; /* create a global symbol at data start */
|
||||||
_sdata = .;
|
*(.data) /* .data sections */
|
||||||
*(.data)
|
*(.data*) /* .data* sections */
|
||||||
*(.data*)
|
*(.RamFunc) /* .RamFunc sections */
|
||||||
|
*(.RamFunc*) /* .RamFunc* sections */
|
||||||
|
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
/* the symbol '_edata' will be defined at the data section end */
|
_edata = .; /* define a global symbol at data end */
|
||||||
_edata = .;
|
|
||||||
} >RAM AT> FLASH
|
} >RAM AT> FLASH
|
||||||
|
|
||||||
|
/* Uninitialized data section into "RAM" Ram type memory */
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
.bss :
|
.bss :
|
||||||
{
|
{
|
||||||
/* the symbol '_sbss' will be defined at the bss section start */
|
/* This is used by the startup in order to initialize the .bss section */
|
||||||
_sbss = .;
|
_sbss = .; /* define a global symbol at bss start */
|
||||||
__bss_start__ = _sbss;
|
__bss_start__ = _sbss;
|
||||||
*(.bss)
|
*(.bss)
|
||||||
*(.bss*)
|
*(.bss*)
|
||||||
*(COMMON)
|
*(COMMON)
|
||||||
|
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
/* the symbol '_ebss' will be defined at the bss section end */
|
_ebss = .; /* define a global symbol at bss end */
|
||||||
_ebss = .;
|
|
||||||
__bss_end__ = _ebss;
|
__bss_end__ = _ebss;
|
||||||
} >RAM
|
} >RAM
|
||||||
|
|
||||||
. = ALIGN(8);
|
/* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */
|
||||||
PROVIDE ( end = _ebss );
|
._user_heap_stack :
|
||||||
PROVIDE ( _end = _ebss );
|
|
||||||
|
|
||||||
.stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size :
|
|
||||||
{
|
{
|
||||||
PROVIDE( _heap_end = . );
|
. = ALIGN(8);
|
||||||
. = __stack_size;
|
PROVIDE ( end = . );
|
||||||
PROVIDE( _sp = . );
|
PROVIDE ( _end = . );
|
||||||
} >RAM AT>RAM
|
. = . + _Min_Heap_Size;
|
||||||
|
. = . + _Min_Stack_Size;
|
||||||
|
. = ALIGN(8);
|
||||||
|
} >RAM
|
||||||
|
|
||||||
|
/* Remove information from the compiler libraries */
|
||||||
|
/DISCARD/ :
|
||||||
|
{
|
||||||
|
libc.a ( * )
|
||||||
|
libm.a ( * )
|
||||||
|
libgcc.a ( * )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* input sections */
|
.ARM.attributes 0 : { *(.ARM.attributes) }
|
||||||
GROUP(libgcc.a libc.a libm.a libnosys.a)
|
}
|
||||||
|
47
src/fwdgt.c
Normal file
47
src/fwdgt.c
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
//
|
||||||
|
// Created by yelv1 on 24-12-29.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "fwdgt.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the watchdog
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void watchdog_init(void) {
|
||||||
|
/* Enable the LSI clock */
|
||||||
|
rcu_osci_on(RCU_IRC40K);
|
||||||
|
rcu_osci_stab_wait(RCU_IRC40K);
|
||||||
|
|
||||||
|
/* Configure FWDGT counter clock: 40KHz(IRC40K) / 64 = 0.625 KHz */
|
||||||
|
fwdgt_config(625, FWDGT_PSC_DIV64); // Set timeout to 1 seconds (625 / 0.625 KHz)
|
||||||
|
|
||||||
|
/* Enable FWDGT */
|
||||||
|
fwdgt_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reset the MCU
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void fwdgt_reset_mcu(void) {
|
||||||
|
/* Enable the write access to the FWDGT_CTL register */
|
||||||
|
FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE;
|
||||||
|
|
||||||
|
/* Configure FWDGT to trigger a system reset */
|
||||||
|
fwdgt_config(50, FWDGT_PSC_DIV4);
|
||||||
|
|
||||||
|
/* Reload the counter to trigger the reset */
|
||||||
|
fwdgt_counter_reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reload the watchdog counter
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void watchdog_reload(void) {
|
||||||
|
fwdgt_counter_reload();
|
||||||
|
}
|
@@ -33,8 +33,6 @@ OF SUCH DAMAGE.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "gd32e23x_it.h"
|
#include "gd32e23x_it.h"
|
||||||
#include "main.h"
|
|
||||||
#include "systick.h"
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief this function handles NMI exception
|
\brief this function handles NMI exception
|
||||||
@@ -98,22 +96,37 @@ void SysTick_Handler(void)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void TIMER13_IRQHandler(void)
|
/*!
|
||||||
|
\brief this function handles TIMER16 interrupt request
|
||||||
|
\param[in] none
|
||||||
|
\param[out] none
|
||||||
|
\retval none
|
||||||
|
*/
|
||||||
|
void TIMER16_IRQHandler(void)
|
||||||
{
|
{
|
||||||
if (timer_interrupt_flag_get(TIMER13, TIMER_INT_FLAG_UP) == SET)
|
if (timer_interrupt_flag_get(LED_BLINK_TIMER, TIMER_INT_FLAG_UP) == SET)
|
||||||
{
|
{
|
||||||
timer_interrupt_flag_clear(TIMER13, TIMER_INT_FLAG_UP);
|
timer_interrupt_flag_clear(LED_BLINK_TIMER, TIMER_INT_FLAG_UP);
|
||||||
static uint8_t led_status = 0;
|
static uint8_t led_status = 0;
|
||||||
if (led_status)
|
if (led_status)
|
||||||
{
|
{
|
||||||
//! turn on led & reconfig timer13 period to 19000(1900ms)
|
//! turn on led & reconfig timer13 period to 19000(1900ms)
|
||||||
gpio_bit_write(GPIOB, GPIO_PIN_1, RESET);
|
gpio_bit_write(LED_PORT, LED_PIN, RESET);
|
||||||
timer_autoreload_value_config(TIMER13, 19200);
|
timer_autoreload_value_config(LED_BLINK_TIMER, 19200);
|
||||||
} else {
|
} else {
|
||||||
//! turn off led & reconfig timer13 period to 1000(100ms)
|
//! turn off led & reconfig timer13 period to 1000(100ms)
|
||||||
gpio_bit_write(GPIOB, GPIO_PIN_1, SET);
|
gpio_bit_write(LED_PORT, LED_PIN, SET);
|
||||||
timer_autoreload_value_config(TIMER13, 800);
|
timer_autoreload_value_config(LED_BLINK_TIMER, 800);
|
||||||
}
|
}
|
||||||
led_status = !led_status;
|
led_status = !led_status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief this function handles USART0 interrupt request
|
||||||
|
\param[in] none
|
||||||
|
\param[out] none
|
||||||
|
\retval none
|
||||||
|
*/
|
||||||
|
void USART0_IRQHandler(void) {
|
||||||
|
}
|
||||||
|
476
src/i2c.c
Normal file
476
src/i2c.c
Normal file
@@ -0,0 +1,476 @@
|
|||||||
|
//
|
||||||
|
// Created by dell on 24-12-20.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "i2c.h"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief configure the GPIO ports
|
||||||
|
\param[in] none
|
||||||
|
\param[out] none
|
||||||
|
\retval none
|
||||||
|
*/
|
||||||
|
void i2c_gpio_config(void) {
|
||||||
|
/* enable IIC GPIO clock */
|
||||||
|
rcu_periph_clock_enable(I2C_GPIO_RCU);
|
||||||
|
|
||||||
|
/* connect I2C_SCL_PIN to I2C_SCL */
|
||||||
|
gpio_af_set(I2C_SCL_PORT, I2C_GPIO_AF, I2C_SCL_PIN);
|
||||||
|
/* connect I2C_SDA_PIN to I2C_SDA */
|
||||||
|
gpio_af_set(I2C_SDA_PORT, I2C_GPIO_AF, I2C_SDA_PIN);
|
||||||
|
/* configure GPIO pins of I2C */
|
||||||
|
gpio_mode_set(I2C_SCL_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, I2C_SCL_PIN);
|
||||||
|
gpio_output_options_set(I2C_SCL_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SCL_PIN);
|
||||||
|
gpio_mode_set(I2C_SDA_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, I2C_SDA_PIN);
|
||||||
|
gpio_output_options_set(I2C_SDA_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SDA_PIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief configure the I2CX interface
|
||||||
|
\param[in] none
|
||||||
|
\param[out] none
|
||||||
|
\retval none
|
||||||
|
*/
|
||||||
|
void i2c_config(void) {
|
||||||
|
/* configure I2C GPIO */
|
||||||
|
i2c_gpio_config();
|
||||||
|
/* enable I2C clock */
|
||||||
|
rcu_periph_clock_enable(I2C_RCU);
|
||||||
|
/* configure I2C clock */
|
||||||
|
i2c_clock_config(I2C_PHY, I2C_SPEED, I2C_DTCY_2);
|
||||||
|
/* configure I2C address */
|
||||||
|
i2c_mode_addr_config(I2C_PHY, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0xA0);
|
||||||
|
/* enable I2CX */
|
||||||
|
i2c_enable(I2C_PHY);
|
||||||
|
/* enable acknowledge */
|
||||||
|
i2c_ack_config(I2C_PHY, I2C_ACK_ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief reset I2C bus
|
||||||
|
\param[in] none
|
||||||
|
\param[out] none
|
||||||
|
\retval none
|
||||||
|
*/
|
||||||
|
void i2c_bus_reset(void) {
|
||||||
|
i2c_deinit(I2C_PHY);
|
||||||
|
/* configure SDA/SCL for GPIO */
|
||||||
|
GPIO_BC(I2C_SCL_PORT) |= I2C_SCL_PIN;
|
||||||
|
GPIO_BC(I2C_SDA_PORT) |= I2C_SDA_PIN;
|
||||||
|
gpio_output_options_set(I2C_SCL_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, I2C_SCL_PIN);
|
||||||
|
gpio_output_options_set(I2C_SDA_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, I2C_SDA_PIN);
|
||||||
|
__NOP();
|
||||||
|
__NOP();
|
||||||
|
__NOP();
|
||||||
|
__NOP();
|
||||||
|
__NOP();
|
||||||
|
GPIO_BOP(I2C_SCL_PORT) |= I2C_SCL_PIN;
|
||||||
|
__NOP();
|
||||||
|
__NOP();
|
||||||
|
__NOP();
|
||||||
|
__NOP();
|
||||||
|
__NOP();
|
||||||
|
GPIO_BOP(I2C_SDA_PORT) |= I2C_SDA_PIN;
|
||||||
|
/* connect I2C_SCL_PIN to I2C_SCL */
|
||||||
|
/* connect I2C_SDA_PIN to I2C_SDA */
|
||||||
|
gpio_output_options_set(I2C_SCL_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SCL_PIN);
|
||||||
|
gpio_output_options_set(I2C_SDA_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SDA_PIN);
|
||||||
|
/* configure the I2CX interface */
|
||||||
|
i2c_config();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 扫描I2C总线,查找连接的设备
|
||||||
|
*
|
||||||
|
* 该函数会扫描I2C总线上的所有地址(1到126),并尝试与每个地址进行通信。
|
||||||
|
* 如果在某个地址上发现了设备,则会打印出该设备的地址。
|
||||||
|
* 最后会打印出找到的设备总数。
|
||||||
|
*/
|
||||||
|
void i2c_scan(void) {
|
||||||
|
uint32_t timeout;
|
||||||
|
uint8_t address;
|
||||||
|
int found_devices = 0;
|
||||||
|
|
||||||
|
printf("Scanning I2C bus...\r\n");
|
||||||
|
|
||||||
|
for (address = 1; address < 127; address++) {
|
||||||
|
timeout = 0;
|
||||||
|
|
||||||
|
// 生成起始条件
|
||||||
|
while (i2c_flag_get(I2C_PHY, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT))
|
||||||
|
timeout++;
|
||||||
|
if (timeout >= I2C_TIME_OUT) {
|
||||||
|
continue; // 超时,跳过该地址
|
||||||
|
}
|
||||||
|
i2c_start_on_bus(I2C_PHY);
|
||||||
|
timeout = 0;
|
||||||
|
|
||||||
|
// 等待起始条件发送完成
|
||||||
|
while (!i2c_flag_get(I2C_PHY, I2C_FLAG_SBSEND) && (timeout < I2C_TIME_OUT))
|
||||||
|
timeout++;
|
||||||
|
if (timeout >= I2C_TIME_OUT) {
|
||||||
|
continue; // 超时,跳过该地址
|
||||||
|
}
|
||||||
|
i2c_master_addressing(I2C_PHY, (address << 1), I2C_TRANSMITTER);
|
||||||
|
timeout = 0;
|
||||||
|
|
||||||
|
// 等待地址发送完成
|
||||||
|
while (!i2c_flag_get(I2C_PHY, I2C_FLAG_ADDSEND) && (timeout < I2C_TIME_OUT))
|
||||||
|
timeout++;
|
||||||
|
if (timeout < I2C_TIME_OUT) {
|
||||||
|
i2c_flag_clear(I2C_PHY, I2C_FLAG_ADDSEND);
|
||||||
|
printf("Found device at 0x%02X\r\n", address);
|
||||||
|
found_devices++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成停止条件
|
||||||
|
i2c_stop_on_bus(I2C_PHY);
|
||||||
|
|
||||||
|
timeout = 0;
|
||||||
|
|
||||||
|
while (i2c_flag_get(I2C_PHY, I2C_FLAG_STPDET) && (timeout < I2C_TIME_OUT))
|
||||||
|
timeout++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found_devices == 0) {
|
||||||
|
printf("No I2C devices found.\r\n");
|
||||||
|
} else {
|
||||||
|
printf("Total %d I2C devices found.\r\n", found_devices);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]) {
|
||||||
|
uint8_t state = I2C_START;
|
||||||
|
uint16_t timeout = 0;
|
||||||
|
uint8_t i2c_timeout_flag = 0;
|
||||||
|
|
||||||
|
/* enable acknowledge */
|
||||||
|
i2c_ack_config(I2C_PHY, I2C_ACK_ENABLE);
|
||||||
|
while (!(i2c_timeout_flag)) {
|
||||||
|
switch (state) {
|
||||||
|
case I2C_START:
|
||||||
|
/* i2c master sends start signal only when the bus is idle */
|
||||||
|
while (i2c_flag_get(I2C_PHY, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT)) {
|
||||||
|
timeout++;
|
||||||
|
}
|
||||||
|
if (timeout < I2C_TIME_OUT) {
|
||||||
|
i2c_start_on_bus(I2C_PHY);
|
||||||
|
timeout = 0;
|
||||||
|
state = I2C_SEND_ADDRESS;
|
||||||
|
} else {
|
||||||
|
timeout = 0;
|
||||||
|
state = I2C_START;
|
||||||
|
#ifdef DEBUG_VERBOES
|
||||||
|
printf("i2c bus is busy in WRITE BYTE!\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case I2C_SEND_ADDRESS:
|
||||||
|
/* i2c master sends START signal successfully */
|
||||||
|
while ((!i2c_flag_get(I2C_PHY, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT)) {
|
||||||
|
timeout++;
|
||||||
|
}
|
||||||
|
if (timeout < I2C_TIME_OUT) {
|
||||||
|
i2c_master_addressing(I2C_PHY, slave_addr, I2C_TRANSMITTER);
|
||||||
|
timeout = 0;
|
||||||
|
state = I2C_CLEAR_ADDRESS_FLAG;
|
||||||
|
} else {
|
||||||
|
timeout = 0;
|
||||||
|
state = I2C_START;
|
||||||
|
#ifdef DEBUG_VERBOES
|
||||||
|
printf("i2c master sends start signal timeout in WRITE BYTE!\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case I2C_CLEAR_ADDRESS_FLAG:
|
||||||
|
/* address flag set means i2c slave sends ACK */
|
||||||
|
while ((!i2c_flag_get(I2C_PHY, I2C_FLAG_ADDSEND)) && (timeout < I2C_TIME_OUT)) {
|
||||||
|
timeout++;
|
||||||
|
}
|
||||||
|
if (timeout < I2C_TIME_OUT) {
|
||||||
|
i2c_flag_clear(I2C_PHY, I2C_FLAG_ADDSEND);
|
||||||
|
timeout = 0;
|
||||||
|
state = I2C_TRANSMIT_DATA;
|
||||||
|
} else {
|
||||||
|
timeout = 0;
|
||||||
|
state = I2C_START;
|
||||||
|
#ifdef DEBUG_VERBOES
|
||||||
|
printf("i2c master clears address flag timeout in WRITE BYTE!\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case I2C_TRANSMIT_DATA:
|
||||||
|
/* wait until the transmit data buffer is empty */
|
||||||
|
while ((!i2c_flag_get(I2C_PHY, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT)) {
|
||||||
|
timeout++;
|
||||||
|
}
|
||||||
|
if (timeout < I2C_TIME_OUT) {
|
||||||
|
/* send IIC register address */
|
||||||
|
i2c_data_transmit(I2C_PHY, reg_addr);
|
||||||
|
timeout = 0;
|
||||||
|
} else {
|
||||||
|
timeout = 0;
|
||||||
|
state = I2C_START;
|
||||||
|
#ifdef DEBUG_VERBOES
|
||||||
|
printf("i2c master sends data timeout in WRITE BYTE!\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* wait until BTC bit is set */
|
||||||
|
while ((!i2c_flag_get(I2C_PHY, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT)) {
|
||||||
|
timeout++;
|
||||||
|
}
|
||||||
|
if (timeout < I2C_TIME_OUT) {
|
||||||
|
/* send register MSB value */
|
||||||
|
i2c_data_transmit(I2C_PHY, data[0]);
|
||||||
|
timeout = 0;
|
||||||
|
} else {
|
||||||
|
timeout = 0;
|
||||||
|
state = I2C_START;
|
||||||
|
#ifdef DEBUG_VERBOES
|
||||||
|
printf("i2c master sends MSB data timeout in WRITE BYTE!\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* wait until BTC bit is set */
|
||||||
|
while ((!i2c_flag_get(I2C_PHY, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT)) {
|
||||||
|
timeout++;
|
||||||
|
}
|
||||||
|
if (timeout < I2C_TIME_OUT) {
|
||||||
|
/* send register LSB value */
|
||||||
|
i2c_data_transmit(I2C_PHY, data[1]);
|
||||||
|
timeout = 0;
|
||||||
|
state = I2C_STOP;
|
||||||
|
} else {
|
||||||
|
timeout = 0;
|
||||||
|
state = I2C_START;
|
||||||
|
#ifdef DEBUG_VERBOES
|
||||||
|
printf("i2c master sends LSB data timeout in WRITE BYTE!\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* wait until BTC bit is set */
|
||||||
|
while ((!i2c_flag_get(I2C_PHY, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT)) {
|
||||||
|
timeout++;
|
||||||
|
}
|
||||||
|
if (timeout < I2C_TIME_OUT) {
|
||||||
|
state = I2C_STOP;
|
||||||
|
timeout = 0;
|
||||||
|
} else {
|
||||||
|
timeout = 0;
|
||||||
|
state = I2C_START;
|
||||||
|
#ifdef DEBUG_VERBOES
|
||||||
|
printf("i2c master sends data timeout in WRITE BYTE!\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case I2C_STOP:
|
||||||
|
/* send a stop condition to I2C bus */
|
||||||
|
i2c_stop_on_bus(I2C_PHY);
|
||||||
|
/* i2c master sends STOP signal successfully */
|
||||||
|
while ((I2C_CTL0(I2C_PHY) & I2C_CTL0_STOP) && (timeout < I2C_TIME_OUT)) {
|
||||||
|
timeout++;
|
||||||
|
}
|
||||||
|
if (timeout < I2C_TIME_OUT) {
|
||||||
|
timeout = 0;
|
||||||
|
state = I2C_END;
|
||||||
|
i2c_timeout_flag = I2C_OK;
|
||||||
|
} else {
|
||||||
|
timeout = 0;
|
||||||
|
state = I2C_START;
|
||||||
|
#ifdef DEBUG_VERBOES
|
||||||
|
printf("i2c master sends stop signal timeout in WRITE BYTE!\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
state = I2C_START;
|
||||||
|
i2c_timeout_flag = I2C_OK;
|
||||||
|
timeout = 0;
|
||||||
|
#ifdef DEBUG_VERBOES
|
||||||
|
printf("i2c master sends start signal in WRITE BYTE.\n");
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return I2C_END;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data) {
|
||||||
|
uint8_t state = I2C_START;
|
||||||
|
uint8_t read_cycle = 0;
|
||||||
|
uint16_t timeout = 0;
|
||||||
|
uint8_t i2c_timeout_flag = 0;
|
||||||
|
uint8_t number_of_byte = 2;
|
||||||
|
|
||||||
|
/* enable acknowledge */
|
||||||
|
i2c_ack_config(I2C_PHY, I2C_ACK_ENABLE);
|
||||||
|
|
||||||
|
while (!(i2c_timeout_flag)) {
|
||||||
|
switch (state) {
|
||||||
|
case I2C_START:
|
||||||
|
if (RESET == read_cycle) {
|
||||||
|
/* i2c master sends start signal only when the bus is idle */
|
||||||
|
while (i2c_flag_get(I2C_PHY, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT)) {
|
||||||
|
timeout++;
|
||||||
|
}
|
||||||
|
if (timeout < I2C_TIME_OUT) {
|
||||||
|
/* whether to send ACK or not for the next byte */
|
||||||
|
i2c_ackpos_config(I2C_PHY, I2C_ACKPOS_NEXT);
|
||||||
|
} else {
|
||||||
|
// i2c_bus_reset();
|
||||||
|
timeout = 0;
|
||||||
|
state = I2C_START;
|
||||||
|
#ifdef DEBUG_VERBOES
|
||||||
|
printf("i2c bus is busy in READ!\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* send the start signal */
|
||||||
|
i2c_start_on_bus(I2C_PHY);
|
||||||
|
timeout = 0;
|
||||||
|
state = I2C_SEND_ADDRESS;
|
||||||
|
break;
|
||||||
|
case I2C_SEND_ADDRESS:
|
||||||
|
/* i2c master sends START signal successfully */
|
||||||
|
while ((!i2c_flag_get(I2C_PHY, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT)) {
|
||||||
|
timeout++;
|
||||||
|
}
|
||||||
|
if (timeout < I2C_TIME_OUT) {
|
||||||
|
if (RESET == read_cycle) {
|
||||||
|
i2c_master_addressing(I2C_PHY, slave_addr, I2C_TRANSMITTER);
|
||||||
|
state = I2C_CLEAR_ADDRESS_FLAG;
|
||||||
|
} else {
|
||||||
|
i2c_master_addressing(I2C_PHY, slave_addr, I2C_RECEIVER);
|
||||||
|
i2c_ack_config(I2C_PHY, I2C_ACK_DISABLE);
|
||||||
|
state = I2C_CLEAR_ADDRESS_FLAG;
|
||||||
|
}
|
||||||
|
timeout = 0;
|
||||||
|
} else {
|
||||||
|
timeout = 0;
|
||||||
|
state = I2C_START;
|
||||||
|
read_cycle = RESET;
|
||||||
|
#ifdef DEBUG_VERBOES
|
||||||
|
printf("i2c master sends start signal timeout in READ!\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case I2C_CLEAR_ADDRESS_FLAG:
|
||||||
|
/* address flag set means i2c slave sends ACK */
|
||||||
|
while ((!i2c_flag_get(I2C_PHY, I2C_FLAG_ADDSEND)) && (timeout < I2C_TIME_OUT)) {
|
||||||
|
timeout++;
|
||||||
|
}
|
||||||
|
if (timeout < I2C_TIME_OUT) {
|
||||||
|
i2c_flag_clear(I2C_PHY, I2C_FLAG_ADDSEND);
|
||||||
|
if ((SET == read_cycle) && (1 == number_of_byte)) {
|
||||||
|
/* send a stop condition to I2C bus */
|
||||||
|
i2c_stop_on_bus(I2C_PHY);
|
||||||
|
}
|
||||||
|
timeout = 0;
|
||||||
|
state = I2C_TRANSMIT_DATA;
|
||||||
|
} else {
|
||||||
|
timeout = 0;
|
||||||
|
state = I2C_START;
|
||||||
|
read_cycle = RESET;
|
||||||
|
#ifdef DEBUG_VERBOES
|
||||||
|
printf("i2c master clears address flag timeout in READ!\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case I2C_TRANSMIT_DATA:
|
||||||
|
if (RESET == read_cycle) {
|
||||||
|
/* wait until the transmit data buffer is empty */
|
||||||
|
while ((!i2c_flag_get(I2C_PHY, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT)) {
|
||||||
|
timeout++;
|
||||||
|
}
|
||||||
|
if (timeout < I2C_TIME_OUT) {
|
||||||
|
/* send the EEPROM's internal address to write to : only one byte address */
|
||||||
|
i2c_data_transmit(I2C_PHY, reg_addr);
|
||||||
|
timeout = 0;
|
||||||
|
} else {
|
||||||
|
timeout = 0;
|
||||||
|
state = I2C_START;
|
||||||
|
read_cycle = RESET;
|
||||||
|
#ifdef DEBUG_VERBOES
|
||||||
|
printf("i2c master wait data buffer is empty timeout in READ!\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/* wait until BTC bit is set */
|
||||||
|
while ((!i2c_flag_get(I2C_PHY, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT)) {
|
||||||
|
timeout++;
|
||||||
|
}
|
||||||
|
if (timeout < I2C_TIME_OUT) {
|
||||||
|
timeout = 0;
|
||||||
|
state = I2C_START;
|
||||||
|
read_cycle = SET;
|
||||||
|
} else {
|
||||||
|
timeout = 0;
|
||||||
|
state = I2C_START;
|
||||||
|
read_cycle = RESET;
|
||||||
|
#ifdef DEBUG_VERBOES
|
||||||
|
printf("i2c master sends register address timeout in READ!\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while (number_of_byte) {
|
||||||
|
timeout++;
|
||||||
|
if (2 == number_of_byte) {
|
||||||
|
/* wait until BTC bit is set */
|
||||||
|
while (!i2c_flag_get(I2C_PHY, I2C_FLAG_BTC));
|
||||||
|
/* send a stop condition to I2C bus */
|
||||||
|
i2c_stop_on_bus(I2C_PHY);
|
||||||
|
}
|
||||||
|
/* wait until RBNE bit is set */
|
||||||
|
if (i2c_flag_get(I2C_PHY, I2C_FLAG_RBNE)) {
|
||||||
|
/* read a byte from the EEPROM */
|
||||||
|
*data = i2c_data_receive(I2C_PHY);
|
||||||
|
/* point to the next location where the byte read will be saved */
|
||||||
|
data++;
|
||||||
|
/* decrement the read bytes counter */
|
||||||
|
number_of_byte--;
|
||||||
|
timeout = 0;
|
||||||
|
}
|
||||||
|
if (timeout > I2C_TIME_OUT) {
|
||||||
|
timeout = 0;
|
||||||
|
state = I2C_START;
|
||||||
|
read_cycle = 0;
|
||||||
|
#ifdef DEBUG_VERBOES
|
||||||
|
printf("i2c master sends data timeout in READ!\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
timeout = 0;
|
||||||
|
state = I2C_STOP;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case I2C_STOP:
|
||||||
|
/* i2c master sends STOP signal successfully */
|
||||||
|
while ((I2C_CTL0(I2C_PHY) & I2C_CTL0_STOP) && (timeout < I2C_TIME_OUT)) {
|
||||||
|
timeout++;
|
||||||
|
}
|
||||||
|
if (timeout < I2C_TIME_OUT) {
|
||||||
|
timeout = 0;
|
||||||
|
state = I2C_END;
|
||||||
|
i2c_timeout_flag = I2C_OK;
|
||||||
|
} else {
|
||||||
|
timeout = 0;
|
||||||
|
state = I2C_START;
|
||||||
|
read_cycle = 0;
|
||||||
|
#ifdef DEBUG_VERBOES
|
||||||
|
printf("i2c master sends stop signal timeout in READ!\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
state = I2C_START;
|
||||||
|
read_cycle = 0;
|
||||||
|
i2c_timeout_flag = I2C_OK;
|
||||||
|
timeout = 0;
|
||||||
|
#ifdef DEBUG_VERBOES
|
||||||
|
printf("i2c master sends start signal in READ.\n");
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return I2C_END;
|
||||||
|
}
|
39
src/led.c
Normal file
39
src/led.c
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
//
|
||||||
|
// Created by yelv1 on 24-12-30.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "led.h"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief led blink configuration
|
||||||
|
\param[in] none
|
||||||
|
\param[out] none
|
||||||
|
\retval none
|
||||||
|
*/
|
||||||
|
void led_blink_config(void)
|
||||||
|
{
|
||||||
|
rcu_periph_clock_enable(LED_RCU);
|
||||||
|
|
||||||
|
gpio_mode_set(LED_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_PIN);
|
||||||
|
gpio_output_options_set(LED_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, LED_PIN);
|
||||||
|
gpio_bit_write(LED_PORT, LED_PIN, SET);
|
||||||
|
|
||||||
|
rcu_periph_clock_enable(LED_BLINK_TIMER_RCU);
|
||||||
|
timer_deinit(LED_BLINK_TIMER);
|
||||||
|
|
||||||
|
timer_parameter_struct timer_initpara;
|
||||||
|
timer_struct_para_init(&timer_initpara);
|
||||||
|
timer_initpara.prescaler =7199;
|
||||||
|
timer_initpara.alignedmode =TIMER_COUNTER_EDGE;
|
||||||
|
timer_initpara.counterdirection =TIMER_COUNTER_UP;
|
||||||
|
timer_initpara.period =9999;
|
||||||
|
timer_initpara.clockdivision =TIMER_CKDIV_DIV1;
|
||||||
|
timer_init(LED_BLINK_TIMER, &timer_initpara);
|
||||||
|
|
||||||
|
timer_auto_reload_shadow_enable(LED_BLINK_TIMER);
|
||||||
|
timer_interrupt_enable(LED_BLINK_TIMER, TIMER_INT_UP);
|
||||||
|
|
||||||
|
timer_enable(LED_BLINK_TIMER);
|
||||||
|
|
||||||
|
nvic_irq_enable(LED_BLINK_IRQ, 2);
|
||||||
|
}
|
24
src/main.c
24
src/main.c
@@ -5,12 +5,6 @@
|
|||||||
\version 2024-02-22, V2.1.0, firmware for GD32E23x
|
\version 2024-02-22, V2.1.0, firmware for GD32E23x
|
||||||
*/
|
*/
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include <stdio.h>
|
|
||||||
#include "gd32e23x.h"
|
|
||||||
#include "systick.h"
|
|
||||||
#include "gd32e23x_libopt.h"
|
|
||||||
|
|
||||||
#include "peripheral.h"
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief main function
|
\brief main function
|
||||||
@@ -20,25 +14,29 @@
|
|||||||
*/
|
*/
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
setbuf(stdout, NULL);
|
||||||
/* configure systick */
|
/* configure systick */
|
||||||
systick_config();
|
systick_config();
|
||||||
usart_config();
|
/* configure USART */
|
||||||
|
rs485_config();
|
||||||
|
/* configure LED */
|
||||||
led_blink_config();
|
led_blink_config();
|
||||||
|
/* configure FWDGT */
|
||||||
|
watchdog_init();
|
||||||
|
|
||||||
delay_ms(5000);
|
|
||||||
printf("system start!\r\n");
|
printf("system start!\r\n");
|
||||||
|
|
||||||
while(1){
|
while(1){
|
||||||
printf("hello world!\r\n");
|
printf("hello world!\r\n");
|
||||||
delay_ms(5000);
|
delay_ms(500);
|
||||||
|
|
||||||
|
watchdog_reload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* retarget the C library printf function to the USART */
|
/* retarget the C library printf function to the USART */
|
||||||
int _write (int fd, char *pBuffer, int size)
|
int _write(int fd, char *pBuffer, int size) {
|
||||||
{
|
for (int i = 0; i < size; i++) {
|
||||||
for (int i = 0; i < size; i++)
|
|
||||||
{
|
|
||||||
usart_data_transmit(USART0, (uint8_t) pBuffer[i]);
|
usart_data_transmit(USART0, (uint8_t) pBuffer[i]);
|
||||||
while (RESET == usart_flag_get(USART0, USART_FLAG_TBE));
|
while (RESET == usart_flag_get(USART0, USART_FLAG_TBE));
|
||||||
}
|
}
|
||||||
|
@@ -1,63 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by yelv1 on 24-9-22.
|
|
||||||
//
|
|
||||||
#include "peripheral.h"
|
|
||||||
#include "gd32e23x.h"
|
|
||||||
|
|
||||||
void usart_config(void)
|
|
||||||
{
|
|
||||||
rcu_periph_clock_enable(RCU_GPIOA);
|
|
||||||
rcu_periph_clock_enable(RCU_USART0);
|
|
||||||
|
|
||||||
gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_3);
|
|
||||||
gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_2);
|
|
||||||
|
|
||||||
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_3);
|
|
||||||
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_3);
|
|
||||||
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_2);
|
|
||||||
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_2);
|
|
||||||
|
|
||||||
usart_deinit(USART0);
|
|
||||||
usart_baudrate_set(USART0, 115200U);
|
|
||||||
usart_receive_config(USART0, USART_RECEIVE_ENABLE);
|
|
||||||
usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
|
|
||||||
|
|
||||||
usart_enable(USART0);
|
|
||||||
|
|
||||||
gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_4);
|
|
||||||
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4);
|
|
||||||
|
|
||||||
gpio_bit_write(GPIOA, GPIO_PIN_4, SET);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief led blink configuration
|
|
||||||
\param[in] none
|
|
||||||
\param[out] none
|
|
||||||
\retval none
|
|
||||||
*/
|
|
||||||
void led_blink_config(void)
|
|
||||||
{
|
|
||||||
rcu_periph_clock_enable(RCU_GPIOB);
|
|
||||||
|
|
||||||
gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_1);
|
|
||||||
gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_1);
|
|
||||||
gpio_bit_write(GPIOB, GPIO_PIN_1, SET);
|
|
||||||
|
|
||||||
rcu_periph_clock_enable(RCU_TIMER13);
|
|
||||||
timer_deinit(RCU_TIMER13);
|
|
||||||
|
|
||||||
timer_parameter_struct timer_initpara;
|
|
||||||
timer_struct_para_init(&timer_initpara);
|
|
||||||
timer_initpara.prescaler =7199;
|
|
||||||
timer_initpara.alignedmode =TIMER_COUNTER_EDGE;
|
|
||||||
timer_initpara.counterdirection =TIMER_COUNTER_UP;
|
|
||||||
timer_initpara.period =999;
|
|
||||||
timer_initpara.clockdivision =TIMER_CKDIV_DIV1;
|
|
||||||
timer_init(TIMER13, &timer_initpara);
|
|
||||||
|
|
||||||
timer_auto_reload_shadow_enable(TIMER13);
|
|
||||||
timer_interrupt_enable(TIMER13, TIMER_INT_UP);
|
|
||||||
nvic_irq_enable(TIMER13_IRQn, 0);
|
|
||||||
timer_enable(TIMER13);
|
|
||||||
}
|
|
217
src/soft_i2c.c
Normal file
217
src/soft_i2c.c
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
//
|
||||||
|
// Created by dell on 24-12-28.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "soft_i2c.h"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief delay
|
||||||
|
\param[in] none
|
||||||
|
\param[out] none
|
||||||
|
\retval none
|
||||||
|
*/
|
||||||
|
void soft_i2c_delay(void) {
|
||||||
|
delay_us(20); // Adjust delay as needed
|
||||||
|
/* delay to freq
|
||||||
|
* 15KHz: delay_us(20);
|
||||||
|
* 65KHz: delay_us(1);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief configure the software IIC GPIO
|
||||||
|
\param[in] none
|
||||||
|
\param[out] none
|
||||||
|
\retval none
|
||||||
|
*/
|
||||||
|
void soft_i2c_config(void) {
|
||||||
|
rcu_periph_clock_enable(I2C_GPIO_RCU);
|
||||||
|
|
||||||
|
gpio_mode_set(I2C_SCL_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, I2C_SCL_PIN);
|
||||||
|
gpio_output_options_set(I2C_SCL_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SCL_PIN);
|
||||||
|
|
||||||
|
gpio_mode_set(I2C_SDA_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, I2C_SDA_PIN);
|
||||||
|
gpio_output_options_set(I2C_SDA_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SDA_PIN);
|
||||||
|
|
||||||
|
I2C_SCL_HIGH();
|
||||||
|
I2C_SDA_HIGH();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief generate I2C start signal
|
||||||
|
\param[in] none
|
||||||
|
\param[out] none
|
||||||
|
\retval none
|
||||||
|
*/
|
||||||
|
void soft_i2c_start(void) {
|
||||||
|
I2C_SDA_HIGH();
|
||||||
|
I2C_SCL_HIGH();
|
||||||
|
soft_i2c_delay();
|
||||||
|
I2C_SDA_LOW();
|
||||||
|
soft_i2c_delay();
|
||||||
|
I2C_SCL_LOW();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief generate I2C stop signal
|
||||||
|
\param[in] none
|
||||||
|
\param[out] none
|
||||||
|
\retval none
|
||||||
|
*/
|
||||||
|
void soft_i2c_stop(void) {
|
||||||
|
// sda_out();
|
||||||
|
I2C_SCL_LOW();
|
||||||
|
I2C_SDA_LOW();
|
||||||
|
soft_i2c_delay();
|
||||||
|
I2C_SCL_HIGH();
|
||||||
|
soft_i2c_delay();
|
||||||
|
I2C_SDA_HIGH();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief send I2C ACK signal
|
||||||
|
\param[in] none
|
||||||
|
\param[out] none
|
||||||
|
\retval none
|
||||||
|
*/
|
||||||
|
void soft_i2c_send_ack(void) {
|
||||||
|
// sda_out();
|
||||||
|
I2C_SDA_LOW();
|
||||||
|
soft_i2c_delay();
|
||||||
|
I2C_SCL_HIGH();
|
||||||
|
soft_i2c_delay();
|
||||||
|
I2C_SCL_LOW();
|
||||||
|
soft_i2c_delay();
|
||||||
|
I2C_SDA_HIGH();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief send I2C NACK signal
|
||||||
|
\param[in] none
|
||||||
|
\param[out] none
|
||||||
|
\retval none
|
||||||
|
*/
|
||||||
|
void soft_i2c_send_nack(void) {
|
||||||
|
I2C_SDA_HIGH();
|
||||||
|
soft_i2c_delay();
|
||||||
|
I2C_SCL_HIGH();
|
||||||
|
soft_i2c_delay();
|
||||||
|
I2C_SCL_LOW();
|
||||||
|
soft_i2c_delay();
|
||||||
|
I2C_SDA_HIGH();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief wait I2C ACK signal
|
||||||
|
\param[in] none
|
||||||
|
\param[out] none
|
||||||
|
\retval 0: ACK received, 1: ACK not received
|
||||||
|
*/
|
||||||
|
uint8_t soft_i2c_wait_ack(void) {
|
||||||
|
I2C_SDA_HIGH();
|
||||||
|
soft_i2c_delay();
|
||||||
|
I2C_SCL_HIGH();
|
||||||
|
soft_i2c_delay();
|
||||||
|
uint8_t ack = !I2C_SDA_READ();
|
||||||
|
I2C_SCL_LOW();
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief send a byte via I2C
|
||||||
|
\param[in] byte: byte to be sent
|
||||||
|
\param[out] none
|
||||||
|
\retval none
|
||||||
|
*/
|
||||||
|
void soft_i2c_send_byte(uint8_t byte) {
|
||||||
|
// sda_out();
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
if (byte & 0x80) {
|
||||||
|
I2C_SDA_HIGH();
|
||||||
|
} else {
|
||||||
|
I2C_SDA_LOW();
|
||||||
|
}
|
||||||
|
byte <<= 1;
|
||||||
|
soft_i2c_delay();
|
||||||
|
I2C_SCL_HIGH();
|
||||||
|
soft_i2c_delay();
|
||||||
|
I2C_SCL_LOW();
|
||||||
|
soft_i2c_delay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief receive a byte via I2C
|
||||||
|
\param[in] ack: 1: send ACK, 0: send NACK
|
||||||
|
\param[out] none
|
||||||
|
\retval received byte
|
||||||
|
*/
|
||||||
|
uint8_t soft_i2c_receive_byte(uint8_t ack) {
|
||||||
|
uint8_t byte = 0;
|
||||||
|
I2C_SDA_HIGH();
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
byte <<= 1;
|
||||||
|
I2C_SCL_HIGH();
|
||||||
|
soft_i2c_delay();
|
||||||
|
if (I2C_SDA_READ()) {
|
||||||
|
byte |= 0x01;
|
||||||
|
}
|
||||||
|
I2C_SCL_LOW();
|
||||||
|
soft_i2c_delay();
|
||||||
|
}
|
||||||
|
if (ack) {
|
||||||
|
soft_i2c_send_ack();
|
||||||
|
} else {
|
||||||
|
soft_i2c_send_nack();
|
||||||
|
}
|
||||||
|
return byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t soft_i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]) {
|
||||||
|
soft_i2c_start();
|
||||||
|
soft_i2c_send_byte(slave_addr);
|
||||||
|
if (!soft_i2c_wait_ack()) {
|
||||||
|
soft_i2c_stop();
|
||||||
|
return SOFT_I2C_FAIL;
|
||||||
|
}
|
||||||
|
soft_i2c_send_byte(reg_addr);
|
||||||
|
if (!soft_i2c_wait_ack()) {
|
||||||
|
soft_i2c_stop();
|
||||||
|
return SOFT_I2C_FAIL;
|
||||||
|
}
|
||||||
|
soft_i2c_send_byte(data[0]);
|
||||||
|
if (!soft_i2c_wait_ack()) {
|
||||||
|
soft_i2c_stop();
|
||||||
|
return SOFT_I2C_FAIL;
|
||||||
|
}
|
||||||
|
soft_i2c_send_byte(data[1]);
|
||||||
|
if (soft_i2c_wait_ack()){}
|
||||||
|
soft_i2c_stop();
|
||||||
|
return SOFT_I2C_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t soft_i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data)
|
||||||
|
{
|
||||||
|
soft_i2c_start();
|
||||||
|
soft_i2c_send_byte(slave_addr);
|
||||||
|
if (!soft_i2c_wait_ack()) {
|
||||||
|
soft_i2c_stop();
|
||||||
|
return SOFT_I2C_FAIL;
|
||||||
|
}
|
||||||
|
soft_i2c_send_byte(reg_addr);
|
||||||
|
if (!soft_i2c_wait_ack()) {
|
||||||
|
soft_i2c_stop();
|
||||||
|
return SOFT_I2C_FAIL;
|
||||||
|
}
|
||||||
|
soft_i2c_start();
|
||||||
|
soft_i2c_send_byte(slave_addr | 0x01);
|
||||||
|
if (!soft_i2c_wait_ack()) {
|
||||||
|
soft_i2c_stop();
|
||||||
|
return SOFT_I2C_FAIL;
|
||||||
|
}
|
||||||
|
soft_i2c_delay();
|
||||||
|
data[0] = soft_i2c_receive_byte(1);
|
||||||
|
data[1] = soft_i2c_receive_byte(0);
|
||||||
|
soft_i2c_stop();
|
||||||
|
return SOFT_I2C_OK;
|
||||||
|
}
|
50
src/usart.c
Normal file
50
src/usart.c
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
//
|
||||||
|
// Created by yelv1 on 24-12-30.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "usart.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief configure the USART
|
||||||
|
* @param none
|
||||||
|
* @retval none
|
||||||
|
*/
|
||||||
|
void usart_config(void)
|
||||||
|
{
|
||||||
|
rcu_periph_clock_enable(USART_GPIO_RCU);
|
||||||
|
rcu_periph_clock_enable(USART_RCU);
|
||||||
|
|
||||||
|
gpio_af_set(USART_GPIO_PORT, USART_GPIO_AF, USART_RX_PIN);
|
||||||
|
gpio_af_set(USART_GPIO_PORT, USART_GPIO_AF, USART_TX_PIN);
|
||||||
|
|
||||||
|
gpio_mode_set(USART_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, USART_RX_PIN);
|
||||||
|
gpio_output_options_set(USART_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, USART_RX_PIN);
|
||||||
|
gpio_mode_set(USART_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, USART_TX_PIN);
|
||||||
|
gpio_output_options_set(USART_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, USART_TX_PIN);
|
||||||
|
|
||||||
|
usart_deinit(USART_PHY);
|
||||||
|
usart_baudrate_set(USART_PHY, USART_PHY_BAUDRATE);
|
||||||
|
usart_receive_config(USART_PHY, USART_RECEIVE_ENABLE);
|
||||||
|
usart_transmit_config(USART_PHY, USART_TRANSMIT_ENABLE);
|
||||||
|
|
||||||
|
usart_enable(USART_PHY);
|
||||||
|
|
||||||
|
nvic_irq_enable(USART0_IRQn, 0);
|
||||||
|
usart_interrupt_enable(USART_PHY, USART_INT_RBNE);
|
||||||
|
usart_interrupt_enable(USART_PHY, USART_INT_IDLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief configure the RS485(MAX13487) driver
|
||||||
|
* @param none
|
||||||
|
* @retval none
|
||||||
|
*/
|
||||||
|
void rs485_config(void)
|
||||||
|
{
|
||||||
|
usart_config();
|
||||||
|
|
||||||
|
gpio_mode_set(RS485_EN_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, RS485_EN_PIN);
|
||||||
|
gpio_output_options_set(RS485_EN_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, RS485_EN_PIN);
|
||||||
|
|
||||||
|
gpio_bit_write(RS485_EN_PORT, RS485_EN_PIN, SET); //auto dircetion control
|
||||||
|
}
|
Reference in New Issue
Block a user