초보의 아웅다웅 설계하기/STM32

GPIO로 딜레이를 사용하여 Uart TX 출력 - Soft Uart

로망와니 2020. 7. 2. 09:49

작번에는 GPIO와 타이머를 사용하여 Uart TX를 출력하였지만 타이머 패리패럴을 사용하지 못하는 경우가 있었습니다.

그래서 딜레이를 사용하여 Uart TX 출력을 만들었습니다. 8Bit 마이컴때는 어셈으로 TX, RX를 만들어서 사용하는 경우도 제법있었는데 요즘은 메모리가 많이 커져서 그런 경우가 없었던 것 같습니다.

딜레이 함수는 맞춰서 값을 변경해주면 되는데 최적화되면서 값이 자꾸 바뀔 수 있어서 그 부분을 잘 확인하여야 합니다.(STM으로 카테고리를 정했지만 사실 Core는 Arm Core 가 아닙니다.) 

#include "gpio.h"

#define SU_TRUE    1
#define SU_FALSE   0

// 1 Startbit, 8 Databits, 1 Stopbit = 10 Bits/Frame
#define TX_NUM_OF_BITS (10)
volatile static unsigned char  flag_tx_busy;
volatile static unsigned char  timer_tx_ctr;
volatile static unsigned char  bits_left_in_tx;
volatile static unsigned short internal_tx_buffer; /* ! mt: was type uchar - this was wrong */

#define set_tx_pin_high()      GPIO_OutputBit(GPIO_BIT0, SET)
#define set_tx_pin_low()       GPIO_OutputBit(GPIO_BIT0, RESET)

/*******************************************************************************
* Function Name :
* Description   : 
* Parameters    : 
* Return        : None
*******************************************************************************/
void Put_Char(void)
{
unsigned char tmp;

while(1){
// /* Transmitter Section */
if ( flag_tx_busy == SU_TRUE ) {
tmp = timer_tx_ctr;
if ( --tmp == 0 ) { // if ( --timer_tx_ctr <= 0 )
if ( internal_tx_buffer & 0x01 ) {
set_tx_pin_high();
}
else {
set_tx_pin_low();
}
internal_tx_buffer >>= 1;
tmp = 3; // timer_tx_ctr = 3;
if ( --bits_left_in_tx == 0 ) {
flag_tx_busy = SU_FALSE;
break;
}
}
timer_tx_ctr = tmp;
}
/* 
14400bps - delay_uart(7);
*/
delay_uart(7);
}
}

/*******************************************************************************
* Function Name :
* Description   : 
* Parameters    : 
* Return        : None
*******************************************************************************/
void delay_uart(__IO uint32_t nCount)
{
nCount *= 4;
    for(; nCount!=0; nCount--);
}

/*******************************************************************************
* Function Name :
* Description   : 
* Parameters    : 
* Return        : None
*******************************************************************************/
static void Gpio_init(void)
{
/* GPIO 초기화 */
GPIO_Init(GPIO_Mode_Out_PP, eInterruptDisable);

set_tx_pin_high(); /* mt: set to high to avoid garbage on init */

flag_tx_busy  = SU_FALSE;
}

/*******************************************************************************
* Function Name :
* Description   : 
* Parameters    : 
* Return        : None
*******************************************************************************/
void softuart_init( void )
{
Gpio_init();
}

/*******************************************************************************
* Function Name :
* Description   : 
* Parameters    : 
* Return        : None
*******************************************************************************/
unsigned char softuart_transmit_busy( void ) 
{
return ( flag_tx_busy == SU_TRUE ) ? 1 : 0;
}

/*******************************************************************************
* Function Name :
* Description   : 
* Parameters    : 
* Return        : None
*******************************************************************************/
void softuart_putchar( const char ch )
{
while ( flag_tx_busy == SU_TRUE ) {
; // wait for transmitter ready
  // add watchdog-reset here if needed;
}

/* invoke_UART_transmit */
timer_tx_ctr       = 3;
bits_left_in_tx    = TX_NUM_OF_BITS;
internal_tx_buffer = ( ch << 1 ) | 0x200;
flag_tx_busy       = SU_TRUE;

Put_Char(); 

}

/*******************************************************************************
* Function Name :
* Description   : 
* Parameters    : 
* Return        : None
*******************************************************************************/
void softuart_puts_P(char *string)
{
while(*string != '\0') softuart_putchar(*(string++));
}

/*******************************************************************************
* Function Name :
* Description   : 
* Parameters    : 
* Return        : None
*******************************************************************************/
void printBlock(unsigned char *b, int len) 
{
int i;
  
for (i=0; i<len; i++, b++){
softuart_putchar(*b);
}
softuart_putchar('\r');
softuart_putchar('\n');
}



 

softuart.c
0.02MB