cancel
Showing results for 
Search instead for 
Did you mean: 

Send and receive simultaneously USART

parisa
Senior
Posted on October 19, 2016 at 19:35

Here is my code:

#include <
stdio.h
>
#include <
string.h
>
#include ''stm32f10x_gpio.h''
#include ''stm32f10x_rcc.h''
#include ''stm32f10x_usart.h''
//##############################
volatile unsigned char bitpos;
volatile unsigned long int stat;
volatile unsigned long int stat1;
volatile unsigned char bufferu[100];
volatile unsigned char buffer1[100];
volatile unsigned char temp;
volatile unsigned char flag;
volatile unsigned char dat;
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;
}
//##############################
int main(){
USARTConfig();
Tim();
flag=0;
stat=0;
dat=0;
while(1){
if(flag==1){
TIM_Cmd(TIM2, DISABLE);
printf(''H%sC\n\r'',buffer1);
delay();
flag=0;
TIM_Cmd(TIM2, ENABLE);
}
}
}
void USARTConfig(void){
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);
}
void USART1_IRQHandler(void){
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
dat=1;
temp=USART_ReceiveData(USART1);
if(temp==65){
stat=1;
bitpos=0;
Erase();
}
else if(temp!=66 && stat==1 && temp>47 && temp<
58
){
bufferu[bitpos]=temp;
bitpos+=1;
}
else if(temp==66 && stat==1)
{
stat
=
0
;
Erase1();
COPY();
flag
=
1
;
}else if(stat==1 && bitpos>100){
bitpos=0;
stat=0;
Erase();
}
}
}
void Erase(void){
char i;
for(i=0;i<100;i++){bufferu[i]='\0';}
}
void Erase1(void){
char i;
for(i=0;i<100;i++){buffer1[i]='\0';}
}
void COPY(void){
char i;
for(i=0;i<100;i++){buffer1[i]=bufferu[i];}
}
void Tim(void){
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);
}
void TIM2_IRQHandler(){
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
if(dat==0){
//some calculations before send
printf(''AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'');
}
else
{
dat=dat-1;
}
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
}

I send a 100 characters each 20ms and I want to receive incoming string.It sends fine but I have been losing some characters in random position or I only receive 5 characters instead of 30 characters. what is my mistake?
6 REPLIES 6
Posted on October 19, 2016 at 19:53

This is a duplicate thread, I'd dig through the stack but I've better things to do.

To recap:

 Don't use printf() in the IRQ

 Create a ring buffer to manage the output of characters using the USART TXE interrupt

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
parisa
Senior
Posted on October 19, 2016 at 20:39

Thanks clive1 for your accompany

I've changed send function as shown below

void TIM2_IRQHandler(){
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
if(dat==0){
//some calculations before send
send();
}
else
{
dat=dat-1;
}
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
}
void send(void){
char msg[200];
int i;
sprintf(msg,''AAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBAAAAAAAAAAAAAAACCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDIIIIIIIIIIUUUUUUU''); 
for(i=0;i<150;i++){
if(msg[i]=='\0')break; 
while(!USART_GetFlagStatus(USART1,USART_FLAG_TXE)); 
if(dat!=0){break;}
USART_SendData(USART1,msg[i]); 
} 
}

But as last code it has the same problem
Posted on October 19, 2016 at 21:10

But as last code it has the same problem

It still blocks, and it still runs in the same interrupt context.

You should add the data to a ring buffer, and leave. You can also check if the ring buffer is full, if it doesn't empty since you last added data to it, then that indicates you're trying to add at a rate which exceeds the output rate.

Ring, Circular or FIFO buffer

https://en.wikipedia.org/wiki/Circular_buffer

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
parisa
Senior
Posted on October 19, 2016 at 22:06

Thanks clive1 for your help

Actually I've read wikipedia for ring buffer however my problem is that I should send each 20ms my each string and incoming string is more important rather than output string. (it means if I'm in receiving my device can stop sending for 20-40 ms). in this line

sprintf(msg,''AAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBAAAAAAAAAAAAAAACCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDIIIIIIIIIIUUUUUUU'');

I've created my fixed buffer size. but I need to receive input characters without any loss.I've tried to cancel sending string by this line and disable timer for 20ms

if(dat!=0){break;}

but unfortunately it doesn't work again.would it be possible to know your approach for sending data each 20ms and receive input data without any loss even stop sending
Posted on October 19, 2016 at 22:38

The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6iK&d=%2Fa%2F0X0000000btp%2FzCBcwrb2U.8AS7ZHF25GK12jA8hWxl3orUlnANP.fhY&asPdf=false
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
parisa
Senior
Posted on October 20, 2016 at 09:09

Thank you so much clive1

It works fine with your code idea ....

Thanks a zillion