test
This commit is contained in:
parent
ac40d80777
commit
fecaa256ca
@ -18,7 +18,11 @@ 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/rs485.c
|
||||||
|
${CMAKE_SOURCE_DIR}/src/led.c
|
||||||
|
${CMAKE_SOURCE_DIR}/src/i2c.c
|
||||||
|
${CMAKE_SOURCE_DIR}/src/soft_i2c.c
|
||||||
|
${CMAKE_SOURCE_DIR}/src/fwdgt.c
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(gd32e23x_template ${TARGET_C_SRC})
|
add_executable(gd32e23x_template ${TARGET_C_SRC})
|
||||||
|
@ -15,7 +15,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
|
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
## 关于链接脚本
|
## 关于链接脚本
|
||||||
|
44
inc/board_config.h
Normal file
44
inc/board_config.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
//
|
||||||
|
// Created by dell on 24-12-28.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef BOARD_CONFIG_H
|
||||||
|
#define BOARD_CONFIG_H
|
||||||
|
|
||||||
|
#define SOFTWARE_IIC
|
||||||
|
|
||||||
|
// #define DEBUG_VERBOES
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
#define RCU_GPIO_I2C RCU_GPIOF
|
||||||
|
#define RCU_I2C RCU_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 RS485_RCU RCU_USART0
|
||||||
|
#define RS485_GPIO_RCU RCU_GPIOA
|
||||||
|
#define RS485_GPIO_PORT GPIOA
|
||||||
|
#define RS485_TX_PIN GPIO_PIN_2
|
||||||
|
#define RS485_RX_PIN GPIO_PIN_3
|
||||||
|
#define RS485_PHY USART0
|
||||||
|
#define RS485_BAUDRATE 115200U
|
||||||
|
#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
|
15
inc/fwdgt.h
Normal file
15
inc/fwdgt.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
//
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
#endif //FWDGT_H
|
48
inc/i2c.h
Normal file
48
inc/i2c.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
//
|
||||||
|
// 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 "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
|
13
inc/led.h
Normal file
13
inc/led.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
//
|
||||||
|
// Created by dell on 24-12-20.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef LED_H
|
||||||
|
#define LED_H
|
||||||
|
|
||||||
|
#include "gd32e23x_it.h"
|
||||||
|
#include "board_config.h"
|
||||||
|
|
||||||
|
void led_config(void);
|
||||||
|
|
||||||
|
#endif //LED_H
|
16
inc/main.h
16
inc/main.h
@ -35,4 +35,20 @@ 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 "rs485.h"
|
||||||
|
#include "led.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
|
|
22
inc/rs485.h
Normal file
22
inc/rs485.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
//
|
||||||
|
// Created by dell on 24-12-3.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef RS485_H
|
||||||
|
#define RS485_H
|
||||||
|
|
||||||
|
#include "gd32e23x_it.h"
|
||||||
|
#include "gd32e23x.h"
|
||||||
|
#include "board_config.h"
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
#define RX_BUFFER_SIZE 32
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
void usart_config(void);
|
||||||
|
|
||||||
|
void rs485_config(void);
|
||||||
|
|
||||||
|
#endif //RS485_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
|
@ -45,7 +45,7 @@
|
|||||||
|
|
||||||
/* select a system clock by uncommenting the following line */
|
/* select a system clock by uncommenting the following line */
|
||||||
//#define __SYSTEM_CLOCK_8M_HXTAL (__HXTAL)
|
//#define __SYSTEM_CLOCK_8M_HXTAL (__HXTAL)
|
||||||
//#define __SYSTEM_CLOCK_8M_IRC8M (__IRC8M)
|
// #define __SYSTEM_CLOCK_8M_IRC8M (__IRC8M)
|
||||||
// #define __SYSTEM_CLOCK_72M_PLL_HXTAL (uint32_t)(72000000)
|
// #define __SYSTEM_CLOCK_72M_PLL_HXTAL (uint32_t)(72000000)
|
||||||
#define __SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2 (uint32_t)(72000000)
|
#define __SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2 (uint32_t)(72000000)
|
||||||
|
|
||||||
|
28
src/fwdgt.c
Normal file
28
src/fwdgt.c
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
//
|
||||||
|
// Created by yelv1 on 24-12-29.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "fwdgt.h"
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
@ -35,6 +35,8 @@ OF SUCH DAMAGE.
|
|||||||
#include "gd32e23x_it.h"
|
#include "gd32e23x_it.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "systick.h"
|
#include "systick.h"
|
||||||
|
#include "rs485.h"
|
||||||
|
#include "led.h"
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief this function handles NMI exception
|
\brief this function handles NMI exception
|
||||||
@ -42,10 +44,9 @@ OF SUCH DAMAGE.
|
|||||||
\param[out] none
|
\param[out] none
|
||||||
\retval none
|
\retval none
|
||||||
*/
|
*/
|
||||||
void NMI_Handler(void)
|
void NMI_Handler(void) {
|
||||||
{
|
|
||||||
/* if NMI exception occurs, go to infinite loop */
|
/* if NMI exception occurs, go to infinite loop */
|
||||||
while(1) {
|
while (1) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,10 +56,9 @@ void NMI_Handler(void)
|
|||||||
\param[out] none
|
\param[out] none
|
||||||
\retval none
|
\retval none
|
||||||
*/
|
*/
|
||||||
void HardFault_Handler(void)
|
void HardFault_Handler(void) {
|
||||||
{
|
|
||||||
/* if Hard Fault exception occurs, go to infinite loop */
|
/* if Hard Fault exception occurs, go to infinite loop */
|
||||||
while(1) {
|
while (1) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,10 +68,9 @@ void HardFault_Handler(void)
|
|||||||
\param[out] none
|
\param[out] none
|
||||||
\retval none
|
\retval none
|
||||||
*/
|
*/
|
||||||
void SVC_Handler(void)
|
void SVC_Handler(void) {
|
||||||
{
|
|
||||||
/* if SVC exception occurs, go to infinite loop */
|
/* if SVC exception occurs, go to infinite loop */
|
||||||
while(1) {
|
while (1) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,10 +80,9 @@ void SVC_Handler(void)
|
|||||||
\param[out] none
|
\param[out] none
|
||||||
\retval none
|
\retval none
|
||||||
*/
|
*/
|
||||||
void PendSV_Handler(void)
|
void PendSV_Handler(void) {
|
||||||
{
|
|
||||||
/* if PendSV exception occurs, go to infinite loop */
|
/* if PendSV exception occurs, go to infinite loop */
|
||||||
while(1) {
|
while (1) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,25 +92,25 @@ void PendSV_Handler(void)
|
|||||||
\param[out] none
|
\param[out] none
|
||||||
\retval none
|
\retval none
|
||||||
*/
|
*/
|
||||||
void SysTick_Handler(void)
|
void SysTick_Handler(void) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TIMER13_IRQHandler(void)
|
/**
|
||||||
{
|
* @brief This function handles TIMER5 interrupt request.
|
||||||
if (timer_interrupt_flag_get(TIMER13, TIMER_INT_FLAG_UP) == SET)
|
* @param[in] none
|
||||||
{
|
* @param[out] none
|
||||||
timer_interrupt_flag_clear(TIMER13, TIMER_INT_FLAG_UP);
|
* @retval None
|
||||||
|
*/
|
||||||
|
void TIMER16_IRQHandler(void) {
|
||||||
|
if (timer_interrupt_flag_get(LED_BLINK_TIMER, TIMER_INT_FLAG_UP) == SET) {
|
||||||
|
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) {
|
||||||
{
|
gpio_bit_write(LED_PORT, LED_PIN, RESET);
|
||||||
//! turn on led & reconfig timer13 period to 19000(1900ms)
|
timer_autoreload_value_config(LED_BLINK_TIMER, 19200);
|
||||||
gpio_bit_write(GPIOB, GPIO_PIN_1, RESET);
|
|
||||||
timer_autoreload_value_config(TIMER13, 19200);
|
|
||||||
} else {
|
} else {
|
||||||
//! turn off led & reconfig timer13 period to 1000(100ms)
|
gpio_bit_write(LED_PORT, LED_PIN, SET);
|
||||||
gpio_bit_write(GPIOB, GPIO_PIN_1, SET);
|
timer_autoreload_value_config(LED_BLINK_TIMER, 800);
|
||||||
timer_autoreload_value_config(TIMER13, 800);
|
|
||||||
}
|
}
|
||||||
led_status = !led_status;
|
led_status = !led_status;
|
||||||
}
|
}
|
||||||
|
491
src/i2c.c
Normal file
491
src/i2c.c
Normal file
@ -0,0 +1,491 @@
|
|||||||
|
//
|
||||||
|
// 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(RCU_GPIO_I2C);
|
||||||
|
|
||||||
|
/* 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(RCU_I2C);
|
||||||
|
/* configure I2C clock */
|
||||||
|
i2c_clock_config(I2C0, I2C_SPEED, I2C_DTCY_2);
|
||||||
|
/* configure I2C address */
|
||||||
|
i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0xA0);
|
||||||
|
/* enable I2CX */
|
||||||
|
i2c_enable(I2C0);
|
||||||
|
/* enable acknowledge */
|
||||||
|
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief reset I2C bus
|
||||||
|
\param[in] none
|
||||||
|
\param[out] none
|
||||||
|
\retval none
|
||||||
|
*/
|
||||||
|
void i2c_bus_reset(void) {
|
||||||
|
i2c_deinit(I2C0);
|
||||||
|
/* 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(I2C0, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT))
|
||||||
|
timeout++;
|
||||||
|
if (timeout >= I2C_TIME_OUT) {
|
||||||
|
continue; // 超时,跳过该地址
|
||||||
|
}
|
||||||
|
i2c_start_on_bus(I2C0);
|
||||||
|
timeout = 0;
|
||||||
|
|
||||||
|
// 等待起始条件发送完成
|
||||||
|
while (!i2c_flag_get(I2C0, I2C_FLAG_SBSEND) && (timeout < I2C_TIME_OUT))
|
||||||
|
timeout++;
|
||||||
|
if (timeout >= I2C_TIME_OUT) {
|
||||||
|
continue; // 超时,跳过该地址
|
||||||
|
}
|
||||||
|
i2c_master_addressing(I2C0, (address << 1), I2C_TRANSMITTER);
|
||||||
|
timeout = 0;
|
||||||
|
|
||||||
|
// 等待地址发送完成
|
||||||
|
while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND) && (timeout < I2C_TIME_OUT))
|
||||||
|
timeout++;
|
||||||
|
if (timeout < I2C_TIME_OUT) {
|
||||||
|
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
|
||||||
|
printf("Found device at 0x%02X\r\n", address);
|
||||||
|
found_devices++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成停止条件
|
||||||
|
i2c_stop_on_bus(I2C0);
|
||||||
|
|
||||||
|
timeout = 0;
|
||||||
|
|
||||||
|
while (i2c_flag_get(I2C0, 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief write 16 bits data to the specified register of the slave device
|
||||||
|
\param[in] slave_addr: slave device address
|
||||||
|
\param[in] reg_addr: register address
|
||||||
|
\param[in] data: data to be written
|
||||||
|
\param[out] none
|
||||||
|
\retval 0: failed, 1: success
|
||||||
|
*/
|
||||||
|
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(I2C0, 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(I2C0, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT)) {
|
||||||
|
timeout++;
|
||||||
|
}
|
||||||
|
if (timeout < I2C_TIME_OUT) {
|
||||||
|
i2c_start_on_bus(I2C0);
|
||||||
|
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(I2C0, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT)) {
|
||||||
|
timeout++;
|
||||||
|
}
|
||||||
|
if (timeout < I2C_TIME_OUT) {
|
||||||
|
i2c_master_addressing(I2C0, 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(I2C0, I2C_FLAG_ADDSEND)) && (timeout < I2C_TIME_OUT)) {
|
||||||
|
timeout++;
|
||||||
|
}
|
||||||
|
if (timeout < I2C_TIME_OUT) {
|
||||||
|
i2c_flag_clear(I2C0, 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(I2C0, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT)) {
|
||||||
|
timeout++;
|
||||||
|
}
|
||||||
|
if (timeout < I2C_TIME_OUT) {
|
||||||
|
/* send IIC register address */
|
||||||
|
i2c_data_transmit(I2C0, 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(I2C0, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT)) {
|
||||||
|
timeout++;
|
||||||
|
}
|
||||||
|
if (timeout < I2C_TIME_OUT) {
|
||||||
|
/* send register MSB value */
|
||||||
|
i2c_data_transmit(I2C0, 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(I2C0, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT)) {
|
||||||
|
timeout++;
|
||||||
|
}
|
||||||
|
if (timeout < I2C_TIME_OUT) {
|
||||||
|
/* send register LSB value */
|
||||||
|
i2c_data_transmit(I2C0, 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(I2C0, 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(I2C0);
|
||||||
|
/* i2c master sends STOP signal successfully */
|
||||||
|
while ((I2C_CTL0(I2C0) & 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief read 16 bits data from the specified register of the slave device
|
||||||
|
\param[in] slave_addr: slave device address
|
||||||
|
\param[in] reg_addr: register address
|
||||||
|
\param[out] data: data to be read
|
||||||
|
\retval 0: failed, 1: success
|
||||||
|
*/
|
||||||
|
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(I2C0, 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(I2C0, 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(I2C0, 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(I2C0);
|
||||||
|
timeout = 0;
|
||||||
|
state = I2C_SEND_ADDRESS;
|
||||||
|
break;
|
||||||
|
case I2C_SEND_ADDRESS:
|
||||||
|
/* i2c master sends START signal successfully */
|
||||||
|
while ((!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT)) {
|
||||||
|
timeout++;
|
||||||
|
}
|
||||||
|
if (timeout < I2C_TIME_OUT) {
|
||||||
|
if (RESET == read_cycle) {
|
||||||
|
i2c_master_addressing(I2C0, slave_addr, I2C_TRANSMITTER);
|
||||||
|
state = I2C_CLEAR_ADDRESS_FLAG;
|
||||||
|
} else {
|
||||||
|
i2c_master_addressing(I2C0, slave_addr, I2C_RECEIVER);
|
||||||
|
i2c_ack_config(I2C0, 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(I2C0, I2C_FLAG_ADDSEND)) && (timeout < I2C_TIME_OUT)) {
|
||||||
|
timeout++;
|
||||||
|
}
|
||||||
|
if (timeout < I2C_TIME_OUT) {
|
||||||
|
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
|
||||||
|
if ((SET == read_cycle) && (1 == number_of_byte)) {
|
||||||
|
/* send a stop condition to I2C bus */
|
||||||
|
i2c_stop_on_bus(I2C0);
|
||||||
|
}
|
||||||
|
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(I2C0, 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(I2C0, 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(I2C0, 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(I2C0, I2C_FLAG_BTC));
|
||||||
|
/* send a stop condition to I2C bus */
|
||||||
|
i2c_stop_on_bus(I2C0);
|
||||||
|
}
|
||||||
|
/* wait until RBNE bit is set */
|
||||||
|
if (i2c_flag_get(I2C0, I2C_FLAG_RBNE)) {
|
||||||
|
/* read a byte from the EEPROM */
|
||||||
|
*data = i2c_data_receive(I2C0);
|
||||||
|
/* 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(I2C0) & 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;
|
||||||
|
}
|
38
src/led.c
Normal file
38
src/led.c
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
//
|
||||||
|
// Created by dell on 24-12-20.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "led.h"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief configure LED
|
||||||
|
\param[in] none
|
||||||
|
\param[out] none
|
||||||
|
\retval none
|
||||||
|
*/
|
||||||
|
void led_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_PP, 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);
|
||||||
|
}
|
25
src/main.c
25
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
|
||||||
@ -18,19 +12,26 @@
|
|||||||
\param[out] none
|
\param[out] none
|
||||||
\retval none
|
\retval none
|
||||||
*/
|
*/
|
||||||
int main(void)
|
int main(void) {
|
||||||
{
|
// setbuf(stdout, NULL);
|
||||||
/* configure systick */
|
/* configure systick */
|
||||||
systick_config();
|
systick_config();
|
||||||
usart_config();
|
/* configure USART */
|
||||||
led_blink_config();
|
// rs485_config();
|
||||||
|
/* configure LED */
|
||||||
|
// led_config();
|
||||||
|
|
||||||
delay_ms(5000);
|
|
||||||
printf("system start!\r\n");
|
printf("system start!\r\n");
|
||||||
|
|
||||||
|
rcu_periph_clock_enable(RCU_GPIOA);
|
||||||
|
|
||||||
|
gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_7);
|
||||||
|
gpio_output_options_set(GPIOA, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
|
||||||
|
gpio_bit_write(GPIOA, GPIO_PIN_7, SET);
|
||||||
|
|
||||||
while(1){
|
while(1){
|
||||||
printf("hello world!\r\n");
|
printf("hello world!\r\n");
|
||||||
delay_ms(5000);
|
delay_ms(1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
|
||||||
}
|
|
49
src/rs485.c
Normal file
49
src/rs485.c
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
//
|
||||||
|
// Created by dell on 24-12-3.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "rs485.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief configure the USART0
|
||||||
|
* @param none
|
||||||
|
* @retval none
|
||||||
|
*/
|
||||||
|
void usart_config(void) {
|
||||||
|
rcu_periph_clock_enable(RS485_GPIO_RCU);
|
||||||
|
rcu_periph_clock_enable(RS485_RCU);
|
||||||
|
|
||||||
|
gpio_af_set(RS485_GPIO_PORT, GPIO_AF_1, GPIO_PIN_2 | GPIO_PIN_3);
|
||||||
|
|
||||||
|
/* configure USART Tx&Rx as alternate function push-pull */
|
||||||
|
gpio_mode_set(RS485_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, RS485_TX_PIN | RS485_RX_PIN);
|
||||||
|
gpio_output_options_set(RS485_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, RS485_TX_PIN | RS485_RX_PIN);
|
||||||
|
|
||||||
|
/* USART configure */
|
||||||
|
usart_deinit(RS485_PHY);
|
||||||
|
usart_baudrate_set(RS485_PHY, RS485_BAUDRATE);
|
||||||
|
usart_receive_config(RS485_PHY, USART_RECEIVE_ENABLE);
|
||||||
|
usart_transmit_config(RS485_PHY, USART_TRANSMIT_ENABLE);
|
||||||
|
|
||||||
|
usart_enable(RS485_PHY);
|
||||||
|
|
||||||
|
nvic_irq_enable(USART0_IRQn, 0);
|
||||||
|
usart_interrupt_enable(RS485_PHY, USART_INT_RBNE);
|
||||||
|
usart_interrupt_enable(RS485_PHY, USART_INT_IDLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief configure the RS485(MAX13487EESA)
|
||||||
|
* @param none
|
||||||
|
* @retval none
|
||||||
|
*/
|
||||||
|
void rs485_config(void) {
|
||||||
|
usart_config();
|
||||||
|
|
||||||
|
rcu_periph_clock_enable(RS485_GPIO_RCU);
|
||||||
|
|
||||||
|
/* configure RS485 EN Pin */
|
||||||
|
gpio_mode_set(RS485_GPIO_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, RS485_EN_PIN);
|
||||||
|
gpio_output_options_set(RS485_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, RS485_EN_PIN);
|
||||||
|
gpio_bit_write(RS485_GPIO_PORT, RS485_EN_PIN, SET); // auto direction control
|
||||||
|
}
|
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(RCU_GPIO_I2C);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user