高级会员

- 积分
- 840
- 金钱
- 840
- 注册时间
- 2016-8-23
- 在线时间
- 116 小时
|

楼主 |
发表于 2022-7-29 15:49:05
|
显示全部楼层
本帖最后由 紫气东升 于 2022-8-4 16:22 编辑
使用IO模拟串口是可以正常收发指令的。现在我分享代码给大家,有需要的可以参考下。
/ ***** 在usart.h头文件定义如下: *****/
#define USART_TXD(n) (n?gpio_bit_set(GPIOA, GPIO_PIN_2):gpio_bit_reset(GPIOA, GPIO_PIN_2))
#define USART_RXD gpio_input_bit_get(GPIOA, GPIO_PIN_3)
#define BuadRate_9600 104
#define Receive_byte 21
enum{
COM_START_BIT = 0,
COM_D0_BIT,
COM_D1_BIT,
COM_D2_BIT,
COM_D3_BIT,
COM_D4_BIT,
COM_D5_BIT,
COM_D6_BIT,
COM_D7_BIT,
COM_STOP_BIT,
};
extern uint8_t USART_buf[Receive_byte];
void softusart_config(void);
void softusart_SendByte(uint8_t byte);
void USART_SendData(uint8_t* data_buffer, uint16_t length);
void Start_RecData(void);
void ReceiveData(void);
void timer6_config(void);
/ ***** 在usart.c源文件编写函数如下: *****/
void softusart_config(void)
{
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_SYSCFG);
gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_2);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
gpio_bit_set(GPIOA, GPIO_PIN_2);
gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_3);
/* configure EXTI priority */
nvic_irq_enable(EXTI3_IRQn, 2, 0);
/* connect IO EXTI line to IO GPIO pin */
syscfg_exti_line_config(EXTI_SOURCE_GPIOA, EXTI_SOURCE_PIN3);
/* configure IO EXTI line */
exti_init(EXTI_3, EXTI_INTERRUPT, EXTI_TRIG_FALLING); //Falling edge interruption
exti_interrupt_flag_clear(EXTI_3);
}
void timer6_config(void)
{
timer_parameter_struct timer_initpara6; //Timer initialization parameters
rcu_periph_clock_enable(RCU_TIMER6);
/* Timer frequency CK_TIMER6 = CK_APB1*4 = CK_SYS = 120MHz */
rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);
nvic_irq_enable(TIMER6_IRQn, 2, 0);
timer_deinit(TIMER6);
/* Set the counting clock frequency CLK to 1MHz, indicating that the timer counts once every 1us */
timer_initpara6.prescaler = 119; //prescaler = CK_SYS/clk - 1, 120/1 - 1=119
timer_initpara6.alignedmode = TIMER_COUNTER_EDGE; //Edge alignment mode
timer_initpara6.counterdirection = TIMER_COUNTER_UP; //Counting up
timer_initpara6.clockdivision = TIMER_CKDIV_DIV1; //DTS=TIMER_CK
timer_initpara6.period = 104; //Automatic reloading value
timer_initpara6.repetitioncounter = 0; //Repeat counter value
timer_init(TIMER6, &timer_initpara6); //Initializing timer
/* auto reload preload enable */
timer_auto_reload_shadow_enable(TIMER6);
/* clear update interrupt bit */
timer_interrupt_flag_clear(TIMER6, TIMER_INT_UP);
/* update interrupt enable */
timer_interrupt_enable(TIMER6, TIMER_INT_UP); //Enable count overflow update interrupt
/* TIMER counter enable */
timer_disable(TIMER6);
}
void delay_us(uint32_t nus)
{
uint32_t ticks;
uint32_t told, tnow, tcnt = 0;
uint32_t reload = SysTick->LOAD; /* The reload value of the tick timer */
ticks = nus * 120; /* The number of beats required */
told = SysTick->VAL; /* The counter value at entry is */
while(1)
{
tnow = SysTick->VAL;
if(tnow != told)
{
if(tnow < told)tcnt += told - tnow;
else tcnt += reload - tnow + told;
if(tcnt >= ticks)break; /* If the time exceeds or is equal to the required delay, exit */
told = tnow;
}
}
}
void softusart_SendByte(uint8_t byte)
{
uint8_t Bit = 0;
USART_TXD(0);
delay_us(BuadRate_9600);
for(Bit = 0; Bit < 8; Bit++)
{
if(byte & 0x01){
USART_TXD(1);
}else{
USART_TXD(0);
}
delay_us(BuadRate_9600);
byte >>= 1;
}
USART_TXD(1);
delay_us(BuadRate_9600);
}
void USART_SendData(uint8_t* data_buffer, uint16_t length)
{
uint8_t i = 0;
for(i = 0; i > length; i++)
{
softusart_SendByte(data_buffer);
}
}
void Start_RecData(void) //进入EXTI外部中断是调用该函数
{
if(USART_RXD == 0)
{
if(recvState == COM_STOP_BIT)
{
recvState = COM_START_BIT;
timer_counter_value_config(TIMER6, 0);
timer_enable(TIMER6);
}
}
}
void ReceiveData(void) //在定时器TIMER6中断中调用该函数
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
recvState++;
if(recvState == COM_STOP_BIT)
{
timer_disable(TIMER6);
USART_buf[len] = recvData;
len++;
if(0xEA == USART_buf[0])
{
if(USART_buf[1] == len)
{
if(0x0D == USART_buf[USART_buf[1]-1])
{
len = 0;
xSemaphoreGiveFromISR(Semaphore_softusart_rec, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
else
{
len = 0;
}
}
}
else
{
len = 0;
}
}
if(USART_RXD){
recvData |= (1 << (recvState - 1));
}else{
recvData &= ~(1 << (recvState - 1));
}
}
/ ***** 在gd32f4xx_it.c源文件添加函数如下: *****/
void EXTI3_IRQHandler(void)
{
if(RESET != exti_interrupt_flag_get(EXTI_3))
{
Start_RecData();
}
exti_interrupt_flag_clear(EXTI_3);
}
void TIMER6_IRQHandler(void)
{
if(RESET != timer_interrupt_flag_get(TIMER6, TIMER_INT_UP))
{
timer_interrupt_flag_clear(TIMER6, TIMER_INT_UP);
ReceiveData();
}
}
|
|