锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

GD32E23x GPIO 模拟串口

时间:2023-09-01 00:37:01 e23panasonic传感器

三个项目需要使用UART, 但只有两个系列UART.

只好模拟一个使用。

因此,本文通过使用两篇文章GPIO 口,加 定时器, 来达到 模拟串口的 功能。

代码仅供参考:

1. IO_USART.h

#include "gd32e23x.h"  #define Number_Of_softUarts 1 #define SoftUartTxBufferSize 32 #define SoftUartRxBufferSize 64 #define  SoftUart_DATA_LEN       8  // Max 8 Bit  //ADD #ifndef SoftUartID #define SoftUartID 0 #endif  #define SOFTUART_COUNTER_PERIOD  20 //end  typedef enum {     SoftUart_OK,     SoftUart_Error }SoftUartState_E;  typedef struct{     uint8_t Tx[SoftUartTxBufferSize];     uint8_t Rx[SoftUartTxBufferSize]; }SoftUartBuffer_S;  typedef struct{     __IO uint8_t TxNComplated;     uint8_t   TxEnable;  uint8_t   RxEnable;  uint8_t   TxBitShift,TxBitCounter;  uint8_t   RxBitShift,RxBitCounter;  uint8_t   TxIndex,TxSize;  uint8_t   RxIndex;  SoftUartBuffer_S *Buffer;  uint32_t    TxPort;  uint16_t   TxPin;  uint32_t    RxPort;  uint16_t   RxPin;  uint8_t   RxTimingFlag;  uint8_t   RxBitOffset; }SoftUart_S;  void SoftUartHandler(void); void SoftUartWaitUntilTxComplete(uint8_t SoftUartNumber); uint8_t SoftUartRxAlavailable(uint8_t SoftUartNumber); SoftUartState_E SoftUartPuts(uint8_t SoftUartNumber,uint8_t *Str,uint8_t Len); SoftUartState_E SoftUartEnableRx(uint8_t SoftUartNumber); SoftUartState_E SoftUartDisableRx(uint8_t SoftUartNumber); SoftUartState_E SoftUartInit(uint8_t SoftUartNumber,uint32_t TxPort,uint16_t TxPin,uint32_t RxPort,uint16_t RxPin); SoftUartState_E SoftUartReadRxBuffer(uint8_t SoftUartNumber,uint8_t* Buffer,uint8_t Len);  void SoftUart_GPIO_Config(uint32_t TxPort,uint16_t TxPin,uint32_t RxPort,uint16_t RxPin); void SoftUartTimerConfig(uint32_t timer_n,rcu_periph_enum periph,uint32_t periods);

2.IO_USART.c

#include "IO_USART.h"  /**/  // Some internal define #define SoftUart_DATA_LEN_C1 (SoftUart_DATA_LEN 1) #define SoftUart_DATA_LEN_C2 (SoftUart_DATA_LEN 2)  SoftUart_S        SUart[Number_Of_softUarts]; // TX RX Data Buffer SoftUartBuffer_S  SUBuffer[Number_Of_softUarts]; // For timing division __IO  uint8_t   SU_Timer=0;  static FlagStatus SoftUartGpioReadPin(uint32_t gpio_periph, uint32_t pin){     return gpio_input_bit_get(gpio_periph,pin); }  // Write TX single Pin Value static void SoftUartGpioWritePin(uint32_t gpio_periph, uint32_t pin,FlagStatus Pinstate){     gpio_bit_write(gpio_periph,pin,Pinstate); }  // Initial Soft Uart SoftUartState_E SoftUartInit(uint8_t SoftUartNumber,uint32_t TxPort,uint16_t TxPin,uint32_t RxPort,uint16_t RxPin) {  if(SoftUartNumber>=Number_Of_softUarts)return SoftUart_Error;  //ADD  SoftUart_GPIO_Config(TxPort,TxPin,RxPort,RxPin);  SUart[SoftUartNumber].TxNComplated=0;   SUart[SoftUartNumber].RxBitCounter=0;  SUart[SoftUartNumber].RxBitShift=0;  SUart[SoftUartNumber].RxIndex=0;   SUart[SoftUartNumber].TxEnable=0;  SUart[SoftUartNumber].RxEnable=0;   SUart[SoftUartNumber].TxBitCounter=0;  SUart[SoftUartNumber].TxBitShift=0;  SUart[SoftUartNumber].TxIndex=0;   SUart[SoftUartNumber].TxSize=0;   SUart[SoftUartNumber].Buffer=&SUBuffer[SoftUartNumber];   SUart[SoftUartNumber].RxPort=RxPort;  SUart[SoftUartNumber].RxPin=RxPin;   SUart[SoftUartNumber].TxPort=TxPort;  SUart[SoftUartNumber].TxPin=TxPin;   SUart[SoftUartNumber].RxTimingFlag=0;  SUart[SoftUartNumber].RxBitOffset=0;   return SoftUart_OK; }  static void SoftUartTransmitBit(SoftUart_S *SU,uint8_t Bit0_1){     SoftUartGpioWritePin(SU->TxPort,SU->TxPin,(FlagStatus)Bit0_1); }  SoftUartState_E SoftUartEnableRx(uint8_t SoftUartNumber){     if(SoftUartNumber >= Number_Of_softUarts)return SoftUart_Error;     SUart[SoftUartNumber].RxEnable = 1;     return SoftUart_OK; }  SoftUartState_E SoftUartDisableRx(uint8_t SoftUartNumber){     if(SoftUartNumber >= Number_Of_softUarts)return SoftUart_Error;     SUart[SoftUartNumber].RxEnable = 0;     return SoftUart_OK; }  uint8_t SoftUartRxAlavailable(uint8_t SoftUartNumber){     return SUart[SoftUartNumber].RxIndex; }  SoftUartState_E SoftUartReadRxBuffer(uint8_t SoftUartNumber,uint8_t* Buffer,uint8_t Len){     int i;     if(SoftUartNumber >= Number_Of_softUarts)return SoftUart_Error;     for ( i = 0; i < Len; i  )     {         /* code */         Buffer[i] = SUart[SoftUartNumber].Buffer->Rx[i];     }     for ( i = 0; i < SUart[SoftUartNumber].RxIndex; i  )     {         /* code */         SUart[SoftUartNumber].Buffer->Rx[i] = SUart[SoftUartNumber].Buffer->Rx[i Len];      }     SUart[SoftUartNumber].RxIndex -=Len;     return SoftUart_OK;      }  // Soft Uart Transmit Data Process static void SoftUartTxProcess(SoftUart_S *SU) {  if(SU->TxEnable)  {   // Start   if(SU->TxBitCounter==0)   {    SU->TxNComplated=1;    SU->TxBitShift=0;    SoftUartTransmitBit(SU,0);    SU->TxBitCounter  ;   }   // Data   else if(SU->TxBitCounterBuffer->Tx[SU->TxIndex])>>(SU->TxBitShift))&0x01);
			SU->TxBitCounter++;
			SU->TxBitShift++;
		}
		// Stop
		else if(SU->TxBitCounter==SoftUart_DATA_LEN_C1)
		{
			SoftUartTransmitBit(SU,1);
			SU->TxBitCounter++;
		}
		//Complete
		else if(SU->TxBitCounter==SoftUart_DATA_LEN_C2)
		{
			// Reset Bit Counter
			SU->TxBitCounter=0;

			// Ready To Send Another Data
			SU->TxIndex++;
			
			// Check Size of Data
			if(SU->TxSize > SU->TxIndex)
			{
				// Continue Sending
				SU->TxNComplated=1;
				SU->TxEnable=1;
			}
			else
			{
				// Finish
				SU->TxNComplated=0;
				SU->TxEnable=0;
				//printf(" Send Finish\r\n");
			}
		}
	}
}

// Soft Uart Receive Data Process
static void SoftUartRxDataBitProcess(SoftUart_S *SU,uint8_t B0_1)
{
	if(SU->RxEnable)
	{
		// Start
		if(SU->RxBitCounter==0)
		{
			// Start Bit is 0
			if(B0_1)return;

			SU->RxBitShift=0;
			SU->RxBitCounter++;
			SU->Buffer->Rx[SU->RxIndex]=0;
		}
		// Data
		else if(SU->RxBitCounterBuffer->Rx[SU->RxIndex]|=((B0_1&0x01)<RxBitShift);
			SU->RxBitCounter++;
			SU->RxBitShift++;
		}
		// Stop and Complete
		else if(SU->RxBitCounter==SoftUart_DATA_LEN_C1)
		{
			SU->RxBitCounter=0;
			SU->RxTimingFlag=0;

			//Stop Bit must be 1
			if(B0_1)
			{
				// Received successfully
				// Change RX Buffer Index
				if((SU->RxIndex)<(SoftUartRxBufferSize-1))(SU->RxIndex)++;
			}
			// if not : ERROR -> Overwrite data
		}
	}
}

// Wait Until Transmit Completed
// You do not usually need to use this function!
void SoftUartWaitUntilTxComplete(uint8_t SoftUartNumber)
{
	while(SUart[SoftUartNumber].TxNComplated);
}

// Copy Data to Transmit Buffer and Start Sending
SoftUartState_E SoftUartPuts(uint8_t SoftUartNumber,uint8_t *Str,uint8_t Len)
{
	int i;

	if(SoftUartNumber>=Number_Of_softUarts)return SoftUart_Error;
	if(SUart[SoftUartNumber].TxNComplated) return SoftUart_Error;

	SUart[SoftUartNumber].TxIndex=0;
	SUart[SoftUartNumber].TxSize=Len;

	for(i=0;iTx[i]= Str[i];
	}

	SUart[SoftUartNumber].TxNComplated=1;
	SUart[SoftUartNumber].TxEnable=1;
	//printf("SoftUartPuts OK ok \r\n");
	return SoftUart_OK;
}

// Capture RX and Get BitOffset
static uint8_t SoftUartScanRxPorts(void)
{
	int i;
	uint8_t Buffer=0x00,Bit;

	for(i=0;i>i)&0x01));
		}
	}

	// Sending always happens in the first time slot
	if(SU_Timer==0)
	{
		// Transmit Data
		for(i=0;i < Number_Of_softUarts;i++)
		{
			SoftUartTxProcess(&SUart[i]);
		}
	}

	// Timing process
	SU_Timer++;
	if(SU_Timer >= 5){
		SU_Timer=0;
	}
}

void SoftUart_GPIO_Config(uint32_t TxPort,uint16_t TxPin,uint32_t RxPort,uint16_t RxPin){
	gpio_mode_set(TxPort, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, TxPin);
    gpio_output_options_set(TxPort, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, TxPin);
	gpio_mode_set(RxPort, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, RxPin);
    gpio_output_options_set(RxPort, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, RxPin);
}

void SoftUartTimerConfig(uint32_t timer_n,rcu_periph_enum periph,uint32_t periods){
    timer_oc_parameter_struct timer_ocinitpara;
    timer_parameter_struct timer_initpara;

    /* enable the peripherals clock */
    rcu_periph_clock_enable(periph);

    /* deinit a TIMER */
    timer_deinit(timer_n);
    /* initialize TIMER init parameter struct */
    timer_struct_para_init(&timer_initpara);
    /* TIMER2 configuration */
    timer_initpara.prescaler         = 74;
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
    timer_initpara.period            = (periods-1);
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
    timer_init(timer_n, &timer_initpara);

    /* clear channel 0 interrupt bit */
    timer_interrupt_flag_clear(timer_n, TIMER_INT_FLAG_UP);
    /* enable the TIMER interrupt */
    timer_interrupt_enable(timer_n, TIMER_INT_UP);
    /* enable a TIMER */
    timer_enable(timer_n);

    //add ...
    nvic_irq_enable(TIMER16_IRQn, 0);
}

void TIMER16_IRQHandler(void){
    if(SET == timer_interrupt_flag_get(TIMER16, TIMER_INT_FLAG_UP)){
        /* clear channel 0 interrupt bit */
        timer_interrupt_flag_clear(TIMER16, TIMER_INT_FLAG_UP);
        SoftUartHandler();
    }
}

//for example:
//1.  init timer::  
//         SoftUartTimerConfig(TIMER16,RCU_TIMER16,20);
//2.  next :
//         SoftUartInit(0,GPIOA,GPIO_PIN_5,GPIOA,GPIO_PIN_6);
//:

3. main.c

#include "IO_USART.h"

int main()
{
    uint8_t SoftUartRx;
    uint8_t i= 0;
    uint8_t mm_Rx[SoftUartTxBufferSize]={0};
    systick_config();
    gd_eval_com_init(EVAL_COM);

    SoftUartInit(SoftUartID,GPIOA,GPIO_PIN_5,GPIOA,GPIO_PIN_6);//A5->Tx  A6->Rx
    SoftUartTimerConfig(TIMER16,RCU_TIMER16,SOFTUART_COUNTER_PERIOD);
    SoftUartEnableRx(SoftUartID);//使能接收

    while (1)
    {
        delay_1ms(500);
        delay_1ms(500);

        SoftUartRx = SoftUartRxAlavailable(SoftUartID);
        if(SoftUartRx > 0){
            memset(mm_Rx,0,SoftUartTxBufferSize);
            SoftUartReadRxBuffer(SoftUartID,mm_Rx,SoftUartRx);
            for(i=0;i

STM32 见github地址:

STM32 模拟串口 的使用 - github地址

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章