2012-11-30 07:47 AM
Hi!
Just before starting my post, i would like to thanks the people of this very very usefull forum. A lots of topics helps me in my newly design. So, yes, i'm designing a new board, and i'm evaluating my software on the DiscoveryBoard. So my question is :: How can i send and receive several lines using interrupts but, if possible without DMA? I'm using USART3 on PD8 & PD9. I've already made this software below :void Init_Uart3(void){
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
// GPIO_InitTypeDef GPIO_InitStructure;
//configure clock for USART
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
//configure clock for GPIO
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
//configure AF
GPIO_PinAFConfig(GPIOD,GPIO_PinSource8,GPIO_AF_USART3);
GPIO_PinAFConfig(GPIOD,GPIO_PinSource9,GPIO_AF_USART3);
//configure ports, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_Init(GPIOD, &GPIO_InitStructure);
USART_Init(USART3, &USART_InitStructure);
// Enable USART
USART_Cmd(USART3, ENABLE);
}
and with this in my 'main' i can send a character :
while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);
USART_SendData(USART3, 'b');
As you can see, it is just polling for sending, but i've nothing to receive any character...
I would like to use the interrupts, but i've not any hint to start..
And you? Maybe someone have already done it andd can help me? an exemple? Any help will be welcome!
By the way, i should mention that i have as TTL-RS232 translator between the board and my comp.
I'm using IAR EWARM.
Dave.
#usart-stm32
2012-11-30 07:58 AM
I swear I've posted this before, but here's a quick demo
// STM32 USART IRQ TX/RX Loop (USART3 Tx PD.8, Rx PD.9) STM32F4 Discovery - sourcer32@gmail.com
#include ''stm32f4_discovery.h'' volatile char StringLoop[] = ''The quick brown fox jumps over the lazy dog\r\n''; /**************************************************************************************/ void RCC_Configuration(void) { /* --------------------------- System Clocks Configuration -----------------*/ /* USART3 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); /* GPIOD clock enable */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); } /**************************************************************************************/ void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; /*-------------------------- GPIO Configuration ----------------------------*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOD, &GPIO_InitStructure); /* Connect USART pins to AF */ GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_USART3); GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_USART3); } /**************************************************************************************/ void USART3_Configuration(void) { USART_InitTypeDef USART_InitStructure; /* USARTx configuration ------------------------------------------------------*/ /* USARTx configured as follow: - BaudRate = 9600 baud - Word Length = 8 Bits - Two Stop Bit - Odd parity - Hardware flow control disabled (RTS and CTS signals) - Receive and transmit enabled */ USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART3, &USART_InitStructure); USART_Cmd(USART3, ENABLE); USART_ITConfig(USART3, USART_IT_RXNE |USART_IT_TXE, ENABLE); } /**************************************************************************************/ void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; /* Configure the NVIC Preemption Priority Bits */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); /* Enable the USART3 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } /**************************************************************************************/ void USART3_IRQHandler(void) { static int tx_index = 0; static int rx_index = 0; if (USART_GetITStatus(USART3, USART_IT_TXE) != RESET) // Transmit the string in a loop { USART_SendData(USART3, StringLoop[tx_index++]); if (tx_index >= (sizeof(StringLoop) - 1)) tx_index = 0; } if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) // Received characters modify string { StringLoop[rx_index++] = USART_ReceiveData(USART3); if (rx_index >= (sizeof(StringLoop) - 1)) rx_index = 0; } } /**************************************************************************************/ int main(void) { RCC_Configuration(); GPIO_Configuration(); NVIC_Configuration(); USART3_Configuration(); while(1); // Don't want to exit } /**************************************************************************************/2012-11-30 08:02 AM
Great!
Thank you Clive1! But how can i send data and how can i check if there is some data is received?2012-11-30 08:07 AM
But how can i send data and how can i check if there is some data is received?
You'll need to build your own buffering scheme. Typically a FIFO or Ring Buffer, which is then filled/emptied in the interrupt routine. You will need to turn off the TXE interrupt if you do not have data to satiate it. It's beyond the scope of the quick examples I'm willing to post here.2012-11-30 08:07 AM
I have this added after the UART initialization:
/* parametrize USART3-Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init (&NVIC_InitStructure);
/* Interrupt at reception and receive errors */
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
USART_ITConfig(USART3, USART_IT_ERR, ENABLE);
And this is (most of the) interrupt handler:
/* handler for the USART3 interrupt (console)
*/
void USART3_IRQHandler(void)
{
uint8_t databyte;
if(USART_GetITStatus (USART3, USART_IT_RXNE) != RESET)
{
szConBuffer[ConBufCount++] = (uint8_t) USART3->DR;
if (ConBufCount >= CON_BUFSIZE)
ConBufCount = 0;
}
else if (USART_GetITStatus (USART3, USART_IT_ORE) != RESET)
{
// treat error here ...
}
}
Don't configure an interrupt on receive errors if you do not need them. But if you need/use them, don't forget to clear the pending flag ...
The name of the interrupt handler routine is fixed, and must match that defined by the toolchain, as the interrupt vector needs to end up on a specific location. Not sure how IAR-WB handles this. You might need to consult IAR specific headers or the startup code, which usually puts default routines into place.
EDIT: too late ...
2012-11-30 11:42 PM
I'm totally agree with you!
I was meaning that my buffer is ready to send and i don't know how to launch the interrupt.What register i should modify for that?And by the way the interrupt doesn't seems launched when i send data to the Discovery.2016-03-21 02:28 PM
// BLE2 click (RN4020 bluetooth) installed on Discovery Shield MikroBus #1
// Successfully initialize click and receive ''CMD'' from RN4020,// but never get ''data register empty''.// debug loops forever while( !(USART3->SR & 0x00000040) );void USART3_GPIOInit(void){ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); //Enable clock for GPIOB // IMPORTANT Make sure, these lines are before pins configuration! GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_USART3);//Connect PB10 to USART3_Tx GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_USART3);//Connect PB11 to USART3_Rx/* USART3 Tx on PB10 | Rx on PB11 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //GPIO_Mode_Alternate Function GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOB, &GPIO_InitStructure); /* MikroBus #1 PE10 RST to RN4020 SWAKE (pin 7) */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); //Enable clock for GPIOE GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //GPIO_Mode_Output Function GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_Init(GPIOE, &GPIO_InitStructure); /* MikroBus #1 PA1 PWM to RN4020 CMD/MLDP (pin 8) */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //Enable clock for GPIOA GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //GPIO_Mode_Output Function GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); /* MikroBus #1 PC1 AN to RN4020 PI01 (pin 10) */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); //Enable clock for GPIOC GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; //GPIO_Mode_Input no Pull-Up/Down Function GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); }void USART3_Init(void){ /* Enable peripheral clock for USART3 */ /* USART 2, 3, 4 & 5 are on APB1 (up to 5.25Mbit/s) */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);// USART3 configured as RN4020 BLE2 click on MikroBus 1 USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b; // Word Length 8 Bits USART_InitStructure.USART_StopBits = USART_StopBits_1; // 1 Stop Bit USART_InitStructure.USART_Parity = USART_Parity_No; // No parity USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // Hardware flow control disabled USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // Receive and transmit enabled USART_Init(USART3, &USART_InitStructure); // USART configuration USART_Cmd(USART3, ENABLE); // Enable USART}void USART3_NVICInit(void){ NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);}void USART3_puts(volatile char *s){ while(*s) { // wait until data register is empty while( !(USART3->SR & 0x00000040) ); USART_SendData(USART3, *s); *s++; }}void USART3_IRQHandler(void) { static uint16_t RxByte = 0x00; if (USART_GetITStatus(USART3, USART_IT_TC) == SET) {#if(0) // not using BLE_Tx IRQ for now if (USART_GetFlagStatus(USART3, USART_FLAG_TC)) { USART_SendData(USART3, RxByte); USART_ITConfig(USART3, USART_IT_TC, DISABLE); }#endif // end BLE_Tx IRQ USART_ClearITPendingBit(USART3, USART_IT_TC); } if (USART_GetITStatus(USART3, USART_IT_RXNE) == SET) { if (USART_GetFlagStatus(USART3, USART_FLAG_RXNE)) { RxByte = USART_ReceiveData(USART3); USB_BLE_Rx[USB_BLE_msg][USB_BLE_Rx_len] = RxByte; if(USB_BLE_Rx_len > 254) RxByte = '\n'; USB_BLE_Rx_len++; if(RxByte== '\n') { USB_BLE_Rx[USB_BLE_msg][USB_BLE_Rx_len] = 0; // terminate string USB_BLE_msg++; if(USB_BLE_msg>7) USB_BLE_msg = 0; USB_BLE_Rx_len = 0; } USART_ITConfig(USART3, USART_IT_TC, ENABLE); } USART_ClearITPendingBit(USART3, USART_IT_RXNE); }}void BLE_Init(void){ int cmd_ok=1,cur_msg=0; while (cmd_ok!=0) { cur_msg=USB_BLE_msg; BLE_SLEEP(); BLE_MODE_CMD(); Delay_ms(100); BLE_WAKE();//high Delay_ms(100); cmd_ok = strcmp(''CMD\r\n'',USB_BLE_Rx[cur_msg+1]); } USART3_puts(''SF,1\r''); //Factory Reset}#include ''stm32f4xx.h''#include ''stm32f4_discovery.h''#include ''string.h''#define BLE_WAKE() GPIO_WriteBit(GPIOE, GPIO_Pin_10,Bit_SET)#define BLE_SLEEP() GPIO_WriteBit(GPIOE, GPIO_Pin_10,Bit_RESET)#define BLE_MODE_CMD() GPIO_WriteBit(GPIOA, GPIO_Pin_1,Bit_RESET)#define BLE_MODE_DATA() GPIO_WriteBit(GPIOA, GPIO_Pin_1,Bit_SET)#define BLE_CONNECTION_STATUS() GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_1)main(){ USART3_GPIOInit(); USART3_Init(); USART3_NVICInit(); BLE_Init(); //SW_WAKE LOW then HIGH while(1);}2016-03-21 05:16 PM
May be you should be waiting on TXE (Transmit Empty), the current state of things, rather than TC (Transmit Complete), some prior state that may or may not have occurred.
If the buffer is empty you can send a new byte.2016-03-26 04:15 AM
hi i have tried the code and its working very well. now i want to know that how can i receive the data come from USART receiver? i want to say that i am sending 9 times different strings. and each time it gives reply. i have attached SIM900a with it. so i am at the stage where i am sending 9 strings and receives reply accordingly. now i want the receive part as if i want 5 th string reply only. so what to do? Help please.
I am sharing my code here. ________________ Attachments : main.c : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HzWn&d=%2Fa%2F0X0000000bNm%2F2hEsDJTkheRZ5gVc3DdS2IysDopVLZcoBMjrKdD7K4Y&asPdf=falsestm32f4xx_it.c : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HzZW&d=%2Fa%2F0X0000000bNk%2FaLfx_Jdtc6Jcr6jah7FD4xnTJpG8nbxd4JM5SnOuMhQ&asPdf=false2016-03-26 10:33 AM
You'd need to buffer and process the responses from each of the AT commands, you'd expect OK, ERROR, etc. and you need to deal with each one before sending the next. Waiting a brief amount of time is not sufficient to deal with how the modem processes things, as interactions with the network might take up to 150 seconds.
I'd use the IRQ Handler to manage a ring (fifo) buffer, and then have a foreground function send the AT command, and wait for acceptable response lines from the modem in each case. Creating such an example is a bit beyond the level of service I'm planning on providing here.