Files
gd32/user/main.c
2025-10-18 16:51:59 +08:00

534 lines
14 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "gd32e23x.h"
#include "gd32e230c_lcd_eval.h"
#include "tft_test.h"
#include "systick.h"
#define ARRAYSIZE 4
uint8_t spi0_send_array[ARRAYSIZE] = {0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA};
uint8_t spi1_send_array[ARRAYSIZE] = {0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA};
uint8_t spi0_receive_array[ARRAYSIZE];
uint8_t spi1_receive_array[ARRAYSIZE];
uint32_t send_n = 0, receive_n = 0;
// 新增全局变量
volatile uint8_t high_level_event = 0; // PA3中断事件标志
/* 新增函数声明 */
void exti_pa3_config(void);
void timer14_config(void);
// PA3外部中断服务函数
void EXTI2_3_IRQHandler(void)
{
if(RESET != exti_interrupt_flag_get(EXTI_3)) // PA3引脚出现高电平 → 触发外部中断
{
/* 清除中断标志位 */
exti_interrupt_flag_clear(EXTI_3);
/* 设置事件标志 */
high_level_event = 1;
/* 启动定时器40ms后清除事件标志 */
// timer_disable(TIMER14);
timer_counter_value_config(TIMER14, 0);
timer_enable(TIMER14);
}
}
// 定时器14中断服务函数
void TIMER14_IRQHandler(void)
{
if(SET == timer_flag_get(TIMER14, TIMER_FLAG_UP))
{
/* 清除定时器中断标志 */
timer_flag_clear(TIMER14, TIMER_FLAG_UP);
/* 禁用定时器 */
// timer_disable(TIMER14);
/* 清除事件标志 */
high_level_event = 0;
}
}
void exti_pa3_config(void)
{
/* 使能GPIOA时钟 */
rcu_periph_clock_enable(RCU_GPIOA);
/* 配置PA3为上拉输入 */
gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, GPIO_PIN_3);
/* 使能SYSCFG时钟 */
// rcu_periph_clock_enable(RCU_CFGCMP);
/* 连接EXTI线3到PA3 */
syscfg_exti_line_config(EXTI_SOURCE_GPIOA, EXTI_SOURCE_PIN3);
/* 配置EXTI线3 */
exti_init(EXTI_3, EXTI_INTERRUPT, EXTI_TRIG_RISING);
exti_interrupt_flag_clear(EXTI_3);
/* 使能并配置EXTI中断 */
nvic_irq_enable(EXTI2_3_IRQn, 2); // 优先级 20~3
}
/* 配置定时器1 */
void timer14_config(void)
{
/* 使能定时器14时钟 */
rcu_periph_clock_enable(RCU_TIMER14);
/* 定时器去初始化 */
timer_deinit(TIMER14);
/* 定时器配置 */
timer_parameter_struct timer_initpara;
timer_struct_para_init(&timer_initpara);
/* 系统时钟为48MHz预分频48计数到40000产生40ms中断 */
timer_initpara.prescaler = 71999; // 72MHz / 72000 = 1kHz
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = 199; // 40ms (0~39)
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TIMER14, &timer_initpara);
/* 使能定时器更新中断 */
timer_interrupt_enable(TIMER14, TIMER_INT_FLAG_UP);
/* 配置定时器中断 */
nvic_irq_enable(TIMER14_IRQn, 1); // 优先级 1高于 EXTI
/* 定时器初始状态为禁用,等待中断触发 */
// timer_disable(TIMER14);
// ✅ 启动定时器,让它一直运行
timer_enable(TIMER14);
}
void test_status_led_init(void);
void flash_led(uint32_t times);
/*!
\brief main function
\param[in] none
\param[out] none
\retval none
*/
void motor_stop(void)
{
/* close all of leds */
gd_eval_led_off(LED1);
gd_eval_led_off(LED2);
gd_eval_led_off(LED3);
gd_eval_led_off(LED4);
}
const uint8_t phasecw[8] =
{0x08, 0x0c, 0x04, 0x06, 0x02, 0x03, 0x01, 0x09};
// 逆时针
// 1000,1100,0100,0110,0010,0011,0001,1001
const uint8_t phaseccw[8] =
{0x09, 0x01, 0x03, 0x02, 0x06, 0x04, 0x0c, 0x08};
// 顺时针
// 1001,0001,0011,0010,0110,0100,1100,1000
// 引脚映射
void SetMotor(uint8_t InputData)
{
if (InputData & 0x01)
{
gd_eval_led_on(LED4);
}
else
{
gd_eval_led_off(LED4);
}
if (InputData & 0x02)
{
gd_eval_led_on(LED3);
}
else
{
gd_eval_led_off(LED3);
}
if (InputData & 0x04)
{
gd_eval_led_on(LED2);
}
else
{
gd_eval_led_off(LED2);
}
if (InputData & 0x08)
{
gd_eval_led_on(LED1);
}
else
{
gd_eval_led_off(LED1);
}
}
// 步距角5.625 360/5.625=64 减速比1/64
// 故64*64个脉冲转一圈
// n圈数
// position 方向
void motorNcircle(int n, uint8_t position,uint32_t cycle) // n为步进电机转动的圈数position为正转或者反转
{
int i, j, k = 0;
for (j = 0; j < n; j++)
{
for (k = 0; k < 8; k++)
{
if (1 == position)
{
SetMotor(phasecw[k]);
}
else
{
SetMotor(phaseccw[k]);
}
delay_ms(cycle);
}
// }
}
}
static void spi1_init(void)
{
/* enable the gpio clock */
rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_SPI1);
rcu_periph_clock_enable(RCU_DMA);
/* configure SPI1 GPIO: NSS/PB12, SCK/PB13, MISO/PB14, MOSI/PB15 */
gpio_af_set(GPIOB, GPIO_AF_0, GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);
dma_parameter_struct dma_init_struct;
dma_struct_para_init(&dma_init_struct);
/* configure SPI0 transmit DMA: DMA_CH2 */
dma_deinit(DMA_CH2);
dma_init_struct.periph_addr = (uint32_t)&SPI_DATA(SPI0);
dma_init_struct.memory_addr = (uint32_t)spi0_send_array;
dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;
dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
dma_init_struct.priority = DMA_PRIORITY_LOW;
dma_init_struct.number = ARRAYSIZE;
dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
dma_init(DMA_CH2, &dma_init_struct);
/* configure DMA mode */
dma_circulation_disable(DMA_CH2);
dma_memory_to_memory_disable(DMA_CH2);
/* configure SPI0 receive DMA: DMA_CH1 */
dma_deinit(DMA_CH1);
dma_init_struct.periph_addr = (uint32_t)&SPI_DATA(SPI0);
dma_init_struct.memory_addr = (uint32_t)spi0_receive_array;
dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
dma_init_struct.priority = DMA_PRIORITY_HIGH;
dma_init(DMA_CH1, &dma_init_struct);
/* configure DMA mode */
dma_circulation_disable(DMA_CH1);
dma_memory_to_memory_disable(DMA_CH1);
/* configure SPI1 transmit DMA: DMA_CH4 */
dma_deinit(DMA_CH4);
dma_init_struct.periph_addr = (uint32_t)&SPI_DATA(SPI1);
dma_init_struct.memory_addr = (uint32_t)spi1_send_array;
dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;
dma_init_struct.priority = DMA_PRIORITY_MEDIUM;
dma_init(DMA_CH4, &dma_init_struct);
/* configure DMA mode */
dma_circulation_disable(DMA_CH4);
dma_memory_to_memory_disable(DMA_CH4);
/* configure SPI1 receive DMA: DMA_CH3 */
dma_deinit(DMA_CH3);
dma_init_struct.periph_addr = (uint32_t)&SPI_DATA(SPI1);
dma_init_struct.memory_addr = (uint32_t)spi1_receive_array;
dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
dma_init(DMA_CH3, &dma_init_struct);
/* configure DMA mode */
dma_circulation_disable(DMA_CH3);
dma_memory_to_memory_disable(DMA_CH3);
//spi
spi_parameter_struct spi_init_struct;
/* deinitilize SPI and the parameters */
spi_i2s_deinit(SPI0);
spi_i2s_deinit(SPI1);
spi_struct_para_init(&spi_init_struct);
/* configure SPI0 parameter */
spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
spi_init_struct.device_mode = SPI_MASTER;
spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT;
spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;
spi_init_struct.nss = SPI_NSS_HARD;
spi_init_struct.prescale = SPI_PSC_8;
spi_init_struct.endian = SPI_ENDIAN_MSB;
/* configure SPI1 parameter */
spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
spi_init_struct.device_mode = SPI_SLAVE;
spi_init(SPI1, &spi_init_struct);
/* configure SPI1 byte access to FIFO */
spi_fifo_access_size_config(SPI1, SPI_BYTE_ACCESS);
spi_enable(SPI1);
/* enable DMA channel */
/* SPI1_Tx DMA channel */
dma_channel_enable(DMA_CH4);
/* SPI0_Tx DMA channel */
dma_channel_enable(DMA_CH2);
/* SPI1_Rx DMA channel */
dma_channel_enable(DMA_CH3);
/* SPI0_Rx DMA channel */
dma_channel_enable(DMA_CH1);
/* enable SPI DMA */
spi_dma_enable(SPI1, SPI_DMA_TRANSMIT);
spi_dma_enable(SPI1, SPI_DMA_RECEIVE);
}
//周六测试的开始
// 全局变量
uint16_t r_num = 80; // 每个方向全行程固定为 192
uint8_t motor_switch = 0; // 开关0 停止1 运动,初始为停止
uint8_t motor_repeat = 0;
uint8_t duration = 0; // 往复运动总秒数
uint32_t r_cycle = 0; // 每个 motorNcircle 的周期
uint8_t spi1_receive_array[4] = {0}; // SPI 接收缓冲区:开关、秒数、保留字节
uint8_t current_direction = 1; // 当前方向10初始右移
uint16_t current_step = 0; // 当前已走步数
// 计算 cycle
static uint32_t calculate_cycle(uint8_t duration) {
if (duration == 0) return 0; // 避免除零
float cycle_float = (duration * 500.0) / (80 * 8); // duration * 500ms / (192 * 8 步)
return (uint32_t)(cycle_float*10);
}
// 检查并更新 SPI 数据
static void check_and_update_spi(void) {
if (dma_flag_get(DMA_CH3, DMA_INT_FLAG_FTF) == SET) {
dma_flag_clear(DMA_CH3, DMA_INT_FLAG_FTF);
motor_switch = spi1_receive_array[0]&0x0f; // 更新开关
motor_repeat = spi1_receive_array[0]>>4;
duration = spi1_receive_array[1]; // 更新秒数
r_cycle = calculate_cycle(duration); // 计算周期
/* 重置 DMA */
dma_channel_disable(DMA_CH3);
dma_memory_address_config(DMA_CH3, (uint32_t)spi1_receive_array);
dma_transfer_number_config(DMA_CH3, 4);
dma_channel_enable(DMA_CH3);
}
}
int main(void)
{
/* 配置 systick */
systick_config();
/* 初始化测试状态 LED */
test_status_led_init();
/****** 初始化PA3外部中断**** */
exti_pa3_config();
/***** 初始化定时器1**** */
timer14_config();
/* 上电步进电机归零125°/0.703125 = 177.7,约 178 个 8 拍,方向 0限位 */
motorNcircle(192, 0, 10); // 1.536s,初始归零 p=1ms;
delay_ms (3000);
motorNcircle(56, 1, 10);
/* 初始化 SPI1 */
spi1_init();
while (1) {
/* 更新SPI发送数据将high_level_event状态放在第一个字节 */
spi1_send_array[0] = high_level_event;
/* 检查开关状态 */
if (motor_switch == 0) {
motor_stop(); // 停止电机
check_and_update_spi(); // 检查 SPI 数据
continue; // 等待开关为 1
}
/* 继续运行:从停止时的方向和步数开始 */
if (current_direction == 1) { // 右移
for (; current_step < r_num; current_step++) {
if (motor_switch == 0) {
motor_stop();
break; // 停止并保留当前步数
}
if(current_step>20){
delay_ms(3);
}
motorNcircle(1, 1, r_cycle); // 右移 1 次
check_and_update_spi(); // 检查 SPI 数据
}
if (current_step >= r_num) { // 右移完成
current_direction = 0; // 切换到左移
current_step = 0; // 重置步数
}
} else { // 左移
for (; current_step < r_num; current_step++) {
if (motor_switch == 0) {
motor_stop();
break; // 停止并保留当前步数
}
if(current_step>20){
delay_ms(3);
}
motorNcircle(1, 0, r_cycle); // 左移 1 次
check_and_update_spi(); // 检查 SPI 数据
}
if (current_step >= r_num) { // 左移完成
current_direction = 1; // 切换到右移
current_step = 0; // 重置步数
// motor_switch = 0;
if(motor_repeat)
motor_switch = 1;
}
}
}
}
/*!
\brief test status led initialize
\param[in] none
\param[out] none
\retval none
*/
void test_status_led_init(void)
{
/* initialize the leds */
gd_eval_led_init(LED1);
gd_eval_led_init(LED2);
gd_eval_led_init(LED3);
gd_eval_led_init(LED4);
/* close all of leds */
gd_eval_led_off(LED1);
gd_eval_led_off(LED2);
gd_eval_led_off(LED3);
gd_eval_led_off(LED4);
}
/*!
\brief flash leds
\param[in] times: leds blink times
\param[out] none
\retval none
*/
void flash_led(uint32_t times)
{
int i;
for (i = 0; i < times; i++)
{
/* insert 200 ms delay */
delay_ms(200);
/* turn on leds */
gd_eval_led_on(LED1);
gd_eval_led_on(LED2);
gd_eval_led_on(LED3);
gd_eval_led_on(LED4);
/* insert 200 ms delay */
delay_ms(200);
/* turn off leds */
gd_eval_led_off(LED1);
gd_eval_led_off(LED2);
gd_eval_led_off(LED3);
gd_eval_led_off(LED4);
}
}