This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Send and receive simultaneously via USART

Hello
Here is my USART's settings:


        USART_InitTypeDef USAR;
        GPIO_InitTypeDef GPIOStruc;

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB |RCC_APB2Periph_AFIO,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
        GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);

        GPIOStruc.GPIO_Mode=GPIO_Mode_AF_PP ;
        GPIOStruc.GPIO_Speed=GPIO_Speed_50MHz;
        GPIOStruc.GPIO_Pin=GPIO_Pin_6;
        GPIO_Init(GPIOB,&GPIOStruc);

        GPIOStruc.GPIO_Mode=GPIO_Mode_IN_FLOATING ;
        GPIOStruc.GPIO_Pin=GPIO_Pin_7;
        GPIO_Init(GPIOB,&GPIOStruc);

        USAR.USART_BaudRate=115200;
        USAR.USART_StopBits=USART_StopBits_1;
        USAR.USART_WordLength=USART_WordLength_8b;
        USAR.USART_Parity=USART_Parity_No ;
        USAR.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
        USAR.USART_Mode=USART_Mode_Rx | USART_Mode_Tx;
        USART_Init(USART1,&USAR);
        USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
  NVIC_EnableIRQ(USART1_IRQn);
        USART_Cmd(USART1,ENABLE);

and I send 200 characters with printf function each 20ms(that created by timer).

timer settings

TIM_TimeBaseInitTypeDef TimeStruct;
NVIC_InitTypeDef nvicStructure;
nvicStructure.NVIC_IRQChannel = TIM2_IRQn;
nvicStructure.NVIC_IRQChannelPreemptionPriority = 0;
nvicStructure.NVIC_IRQChannelSubPriority = 1;
nvicStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&nvicStructure);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
TimeStruct.TIM_Prescaler=7200;
TimeStruct.TIM_Period=200;
TimeStruct.TIM_ClockDivision=TIM_CKD_DIV1;
TimeStruct.TIM_CounterMode=     TIM_CounterMode_Up ;
TimeStruct.TIM_RepetitionCounter        =0;
TIM_TimeBaseInit(TIM2, &TimeStruct);
TIM_Cmd(TIM2, ENABLE);
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);

printf("LOng string......");

struct __FILE { int handle;} ;
FILE __stdout;
FILE __stdin;
FILE __stderr;
int fputc(int ch, FILE *f)  {
        while(!USART_GetFlagStatus(USART1,USART_FLAG_TXE));
        USART_SendData(USART1,ch);
        return ch;

but when I send a 120 characters string to my device it doesn't do anything

void USART1_IRQHandler(void){
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
        temp=USART_ReceiveData(USART1);
}
}

but when I increase timer step (for example 100ms) it works fine.
what's wrong with it ? what is my mistake?

Parents
  • char buf1[BUFSIZE];
    char buf2[BUFSIZE];
    
    volatile unsigned delivered_msg_size = 0;
    volatile char *delivered_msg = NULL;
    volatile char *tmp_msg = buf1;
    
    void loop() {
        for (;;) {
            if (delivered_msg) {
                process_msg(delivered_msg,delivered_msg_size);
                delivered_msg = NULL;
            }
            ...
        }
    }
    
    void uart_irq() {
        static unsigned insert_pos = 0;
        static unsigned in_packet = FALSE;
    
        ...
        if (c == START_CHAR) {
            insert_pos = 0;
            in_packet = TRUE;
        } else if (!in_packet) {
            // ignore char
        } else if (c == END_CHAR) {
            if (delivered_msg) {
                // main loop hasn't processed data fast enough...
                // throw away this new packet!
            } else {
                delivered_msg_size = insert_pos;
                delivered_msg = tmp_msg;
                tmp_msg = (tmp_msg == buf1) ? buf2 : buf1;
            }
            in_packet = FALSE;
        } else if (!valid_char(c)) {
            // invalid data - fail packet
            in_packet = FALSE;
         } else if (insert_pos >= BUFSIZE) {
            // too much data - fail packet
            in_packet = FALSE;
         } else {
            tmp_msg[insert_pos++] = c;
         }
         ...
    }
    

    Reserve one additional position in the buffer and zero-terminate just before hand-over, in case you want the final buffer to be zero-terminated so you can directly print it.

    Then you can also decide to not hand over any message size.

Reply
  • char buf1[BUFSIZE];
    char buf2[BUFSIZE];
    
    volatile unsigned delivered_msg_size = 0;
    volatile char *delivered_msg = NULL;
    volatile char *tmp_msg = buf1;
    
    void loop() {
        for (;;) {
            if (delivered_msg) {
                process_msg(delivered_msg,delivered_msg_size);
                delivered_msg = NULL;
            }
            ...
        }
    }
    
    void uart_irq() {
        static unsigned insert_pos = 0;
        static unsigned in_packet = FALSE;
    
        ...
        if (c == START_CHAR) {
            insert_pos = 0;
            in_packet = TRUE;
        } else if (!in_packet) {
            // ignore char
        } else if (c == END_CHAR) {
            if (delivered_msg) {
                // main loop hasn't processed data fast enough...
                // throw away this new packet!
            } else {
                delivered_msg_size = insert_pos;
                delivered_msg = tmp_msg;
                tmp_msg = (tmp_msg == buf1) ? buf2 : buf1;
            }
            in_packet = FALSE;
        } else if (!valid_char(c)) {
            // invalid data - fail packet
            in_packet = FALSE;
         } else if (insert_pos >= BUFSIZE) {
            // too much data - fail packet
            in_packet = FALSE;
         } else {
            tmp_msg[insert_pos++] = c;
         }
         ...
    }
    

    Reserve one additional position in the buffer and zero-terminate just before hand-over, in case you want the final buffer to be zero-terminated so you can directly print it.

    Then you can also decide to not hand over any message size.

Children