#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); // 优先级 2(0~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; // 当前方向:1(右),0(左),初始右移 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); } }