2014-12-04 06:03 PM
Hi ST forum,
I have two separate problems: 1. How do I configure an interrupt to do X on rising edge and Y on falling edge? Currently, I can only do rising edge: (Solved, see below)/*********************************************************************************************************** Function name: EXTI_PA0_Config
** Descriptions: Configures interrupt for PA0
** Parameters: None
*********************************************************************************************************/
void EXTI_PA0_Config(void)
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
GPIO_main.GPIO_Mode = GPIO_Mode_IN;
GPIO_main.GPIO_Speed = GPIO_Speed_25MHz;
GPIO_main.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_main.GPIO_Pin = GPIO_Pin_0; //Output PA0
GPIO_Init(GPIOA,&GPIO_main);
EXTI_main.EXTI_Line = EXTI_Line0;
EXTI_main.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_main.EXTI_Trigger = EXTI_Trigger_Rising; //need raising falling
EXTI_main.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_main);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
NVIC_main.NVIC_IRQChannel = EXTI0_IRQn; //connect EXTI to line 0
NVIC_main.NVIC_IRQChannelPreemptionPriority = 0x01; //set both preemptive priority and sub-priority to lowest
NVIC_main.NVIC_IRQChannelSubPriority = 0x01;
NVIC_main.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_main);
}
void EXTI0_IRQHandler(void){
NVIC_ClearPendingIRQ(EXTI0_IRQn);
if(flag==0)
{
flag=1;
}
else if(flag==1)
{
flag=0;
}
EXTI->PR|=(1<<0); //write 1 to PR to clear - write 1 at bit 0?
}
Problem 2: I want to be able to receive UART. Currently I can only transmit UART. (Partially solved with bugs, see below)/*********************************************************************************************************
** Function name: UART1_Init
** Descriptions: Initializes UART2_TX at PA2
** Parameters: None
*********************************************************************************************************/
void UART1_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
GPIO_main.GPIO_Pin = GPIO_Pin_2;
GPIO_main.GPIO_Mode = GPIO_Mode_AF;
GPIO_main.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_main.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_main.GPIO_OType = GPIO_OType_PP;
GPIO_Init(GPIOA, &GPIO_main);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_USART2);
USART_main.USART_Mode = USART_Mode_Tx; //Transmit Mode, Receiver mode not currently required
USART_main.USART_BaudRate = 115200; //This is right
USART_main.USART_WordLength = USART_WordLength_8b; //8 bit data transmit
USART_main.USART_Parity = USART_Parity_No; //
USART_main.USART_StopBits = USART_StopBits_1; // 1 stop bit
USART_main.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART2,&USART_main);
USART_Cmd(USART2,ENABLE);
}
2014-12-12 10:10 AM
I got the interrupt problem solved by doing this (after entering interrupt, check for port level).
void EXTI9_5_IRQHandler(void){
if (EXTI_GetITStatus(EXTI_Line5) != RESET) //Filter line 5
{
EXTI_ClearITPendingBit(EXTI_Line5);
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5))
{
GPIOD->BSRRL = GPIO_Pin_12; //test and debug only
flag = 1;
}
else if(!GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5))
{
GPIOD->BSRRH = GPIO_Pin_12; //test and debug only
flag = 0;
}
// UART1_Send(Message_StopMotor,5);
}
}
For the UART, I'm stuck on this problem: I'm doing a loopback test, but valid data only displays 3500 baud or below. Over 4000 it displays some nonsense..
Here's my codes:void UART1_Init(void){ RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE); GPIO_main.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; GPIO_main.GPIO_Mode = GPIO_Mode_AF;// GPIO_main.GPIO_PuPd = GPIO_PuPd_UP; GPIO_main.GPIO_Speed = GPIO_Speed_50MHz;// GPIO_main.GPIO_OType = GPIO_OType_PP; GPIO_Init(GPIOA, &GPIO_main); GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); USART_main.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //Transmit Mode, Receiver mode not currently required USART_main.USART_BaudRate = 3500; //Current baud rate 115200 bit/s USART_main.USART_WordLength = USART_WordLength_8b; //8 bit data transmit USART_main.USART_Parity = USART_Parity_No; //No parity bits USART_main.USART_StopBits = USART_StopBits_1; // 1 stop bit USART_main.USART_HardwareFlowControl = USART_HardwareFlowControl_None;// USART_Init(USART1,&USART_main);// USART_Cmd(USART1,ENABLE); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //enables USART_Init(USART1,&USART_main); USART_Cmd(USART1, ENABLE); NVIC_main.NVIC_IRQChannel = USART1_IRQn; // we want to configure the USART1 interrupts NVIC_main.NVIC_IRQChannelPreemptionPriority = 0; // this sets the priority group of the USART1 interrupts NVIC_main.NVIC_IRQChannelSubPriority = 0; // this sets the subpriority inside the group NVIC_main.NVIC_IRQChannelCmd = ENABLE; // the USART1 interrupts are globally enabled NVIC_Init(&NVIC_main); // the properties are passed to the NVIC_Init function which takes care of the low level stuff}void USART1_IRQHandler(void){ if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {// USART_ClearITPendingBit(USART1, USART_IT_RXNE);// rx[rx_index] = USART_ReceiveData(USART1); rx[rx_index] = USART1->DR; if(rx_index>9) { rx_index = 0; } rx_index++; }}in main:int main(void){ LED_Init(); //Initializes LED outputs UART1_Init(); //Initializes UART1 at PA9 EXTI_PB5_Config(); //Configures interrupt for PB5 int k = 0; UART1_Send(Message_SetSpeed,7); while(1) { for(k=0;k<rx_index;k++) { printf(''\n%d: %X'',k,rx[k]); } }}(Set speed was defined as: uint8_t Message_SetSpeed[6] = {0x01,0xA1,0x9C,0x40,0x82,0x04}; //Speed set at 4000RPM)
2014-12-12 12:21 PM
What board are you doing this on? The STM32F4-DISCO has a huge bulk capacitor hung off the USART1 pins, which is going to limit it's rate/usability.
2014-12-12 01:25 PM
I am using the discovery board. Maybe that is the problem? Thus switching to USART2/3 would solve the problem?