2016-10-19 10:35 AM
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?
2016-10-19 10:53 AM
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 interrupt2016-10-19 11:39 AM
Thanks clive1 for your accompany
I've changed send function as shown belowvoid 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
2016-10-19 12:10 PM
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 bufferhttps://en.wikipedia.org/wiki/Circular_buffer
2016-10-19 01:06 PM
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 linesprintf(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
2016-10-19 01:38 PM
2016-10-20 12:09 AM
Thank you so much clive1
It works fine with your code idea .... Thanks a zillion