STM32F4329II Input capture Interrupt is ignored while trying to use the input capture
static void TIM_Config(void)
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOH, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //GPIO_PuPd_NOPULL;
GPIO_PinAFConfig(GPIOH, GPIO_PinSource11, GPIO_AF_TIM5);
GPIO_Init(GPIOH, &GPIO_InitStructure);
/* TIM5 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
TIM_ICInitTypeDef TIM_InputCaptureInitStructure;
TIM_InputCaptureInitStructure.TIM_Channel = TIM_Channel_2;
TIM_InputCaptureInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;
TIM_InputCaptureInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_InputCaptureInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_InputCaptureInitStructure.TIM_ICFilter = 0x0;
TIM_ICInit(TIM5, &TIM_InputCaptureInitStructure);
TIM_ClearFlag(TIM5, TIM_FLAG_CC2 );
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //
NVIC_Init(&NVIC_InitStructure);
TIM_PWMIConfig(TIM2, &TIM_ICInitStructure);
//Enable CC2 interrupt
TIM_ITConfig(TIM5,TIM_IT_CC2,ENABLE);
//EnableTIM5
TIM_Cmd(TIM5,ENABLE);
}
And the following IRQ
extern "C" void TIM5_IRQHandler(void)
{
if (TIM_GetITStatus(TIM5, TIM_IT_CC2) == SET)
{
TIM_ClearITPendingBit(TIM5, TIM_IT_CC2);
rpm4 = TIM_GetCapture2(TIM5);
static char xx[12];
sprintf( xx, " %l", rpm4 );
GUI_DispStringAt(xx,100,150);
}
TIM_ClearITPendingBit(TIM5, TIM_IT_CC2 );
}
I put some breakpoints inside the Interrupt routine but nothing happens...
My external signal is a 5V signal ( this micro is 5V tolerant... ) with negative pulses...
Related
I am having problem with PIC16F877A uart. I am trying to send AT commands to SIM800L but it is returning error. But when I try it with CP2102 module it works fine. Can anybody tell me if something is wrong with my code?
This code with similar logic is working on LPC2148 but having problem on PIC16F877A.
// CONFIG
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = ON // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3/PGM pin has PGM function; low-voltage programming enabled)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define _XTAL_FREQ 20000000
char buff[50], a = 0;
char b, *p;
int conn=0;
int i;
#define RS RD0
#define RW RD1
#define EN RD2
void lcd_cmd(unsigned char cmd)
{
PORTD = (0xF0 & cmd);
RS = 0;
RW = 0;
EN = 1;
__delay_ms(5);
EN = 0;
PORTD = (cmd<<4);
RS = 0;
RW = 0;
EN = 1;
__delay_ms(5);
EN = 0;
}
void lcd_data(unsigned char data)
{
PORTD = (0xF0 & data);
RS = 1;
RW = 0;
EN = 1;
__delay_ms(5);
EN = 0;
PORTD = (data<<4);
RS = 1;
RW = 0;
EN = 1;
__delay_ms(5);
EN = 0;
}
void lcd_string(char *str)
{
while(*str != '\0')
{
lcd_data(*str++);
}
}
void lcd_init()
{
lcd_cmd(0x02);//return to home
lcd_cmd(0x28);///4bitmode
lcd_cmd(0x0C);///cursor off
lcd_cmd(0x06);///increment cursor
lcd_cmd(0x01);///display clear
}
void uart_init()
{
TXSTAbits.TXEN = 1; ////enable transmission
TXSTAbits.BRGH = 1; ////high speed selection bit
RCSTAbits.CREN = 1; ////continuous receive enable
SPBRG = 129; ////baud rate generation 9600 at 20MHz crystal
TRISCbits.TRISC7 = 1; ////enable receive(input) on RC7
TRISCbits.TRISC6 = 0; ////enable transmit(output) on RC6
RCSTAbits.SPEN = 1; ////enable UART
GIE = 1; ///enable UART related interrupts
PEIE = 1;
RCIE = 1;
}
void gsm_send_char(unsigned char data)
{
TXREG = data;
while(PIR1bits.TXIF ==0);
}
char gsm_receive_char()
{
while(PIR1bits.RCIF == 0);
return (RCREG);
}
void gsm_send_string(char *data)
{
while(*data != '\0')
{
gsm_send_char(*data++);
}
}
__interrupt() void uart(void)
{
if(RCIF == 1)
{
b = RCREG;
buff[a] = b;
a++;
//buff[a]='\0';
GIE = 1;
RCIE = 1;
PEIE = 1;
RCIF = 0;
}
}
void gsm_init()
{
if(conn == 0)
{
a=0;
gsm_send_string("AT\r");
__delay_ms(500);
if(strstr(buff, "OK"))
{
lcd_cmd(0x80);
lcd_string(buff);
//a=0;
memset(buff, 0, sizeof(buff));
}
else
{
lcd_cmd(0x80);
lcd_string("AT ERROR");
}
}
}
void main(void)
{
TRISD = 0x00;
lcd_init();
uart_init();
lcd_cmd(0x80);
lcd_string("GSM");
while(1)
{
gsm_init();
__delay_ms(2000);
}
return;
}
I tried with changing code little bit and checked for any errors and tried to execute command on flag condition now it does not receive anything in the buffer because it does not print anything. Can anybody tell me why?
// CONFIG
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = ON // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3/PGM pin has PGM function; low-voltage programming enabled)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
#include <pic16f877a.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#define _XTAL_FREQ 20000000
#define RS RD0
#define RW RD1
#define EN RD2
//#define AT "AT\"
char buff[80], a;
int flag, b, i = 0;
void lcd_cmd(unsigned char cmd)
{
PORTD = (0xF0 & cmd);
RS = 0;
RW = 0;
EN = 1;
__delay_ms(5);
EN = 0;
PORTD = (cmd<<4 & 0xf0);
RS = 0;
RW = 0;
EN = 1;
__delay_ms(5);
EN = 0;
}
void lcd_data(unsigned char data)
{
PORTD = (0xF0 & data);
RS = 1;
RW = 0;
EN = 1;
__delay_ms(5);
EN = 0;
PORTD = (data<<4 & 0xf0);
RS = 1;
RW = 0;
EN = 1;
__delay_ms(5);
EN = 0;
}
void lcd_string(char *str)
{
while(*str != '\0')
{
lcd_data(*str++);
}
}
void lcd_init()
{
lcd_cmd(0x02);//return to home
lcd_cmd(0x28);///4bitmode
lcd_cmd(0x0C);///cursor off
lcd_cmd(0x01);///display clear
lcd_cmd(0x06);///increment cursor
}
void uart_init()
{
SPBRG = 129;
BRGH = 1;
SYNC = 0;
SPEN = 1;
TXEN = 1;
CREN = 1;
GIE = 1;
PEIE = 1;
RCIE = 1;
RCIF = 0;
//TXIE = 1;
TRISC7 = 1;
TRISC6 = 0;
}
void gsm_send_char(unsigned char data)
{
//////////PORTB = 0xff;
TXREG = data;
while(PIR1bits.TXIF == 0);
}
char gsm_receive_char()
{
while(PIR1bits.RCIF == 0);
return RCREG;
}
void gsm_send_string(char *p)
{
while(*p != '\0')
{
gsm_send_char(*p++);
}
}
__interrupt() void isr(void)
{
if(RCIF == 1)
{
a = RCREG;
buff[i] = a;
i++;
if(a == '\r')
{
flag = 1;
}
if(OERR)
{
CREN = 0;
CREN = 1;
}
if(FERR)
{
SPEN = 0;
SPEN = 1;
}
RCIF = 0;
///////PORTB = 0xff;
}
}
void main(void)
{
TRISD = 0x00;
//TRISB = 0x00;
lcd_init();
uart_init();
lcd_cmd(0x80);
lcd_string("GSM TESTING");
while(1)
{
if(flag == 1)
{
i = 0;
gsm_send_string("AT\r\n");
__delay_ms(400);
if(strstr(buff, "OK"))
{
lcd_cmd(0xC0);
lcd_string(buff);
//memset(buff, 0, sizeof(buff));
}
else if(strstr(buff, "ERROR"))
{
lcd_cmd(0xC0);
lcd_string(buff);
// memset(buff, 0, sizeof(buff));
}
flag = 0;
}
}
return;
}
took reference from this link enter link description here
I connected PIC directly to the PC removing SIM800L and ran the code below. It was printing hello when I send hello using putty.
#include <xc.h>
#include <pic16f877a.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#define _XTAL_FREQ 20000000
#define RS RD0
#define RW RD1
#define EN RD2
char buff[80], a;
int flag, b, i = 0;
void lcd_cmd(unsigned char cmd)
{
PORTD = (0xF0 & cmd);
RS = 0;
RW = 0;
EN = 1;
__delay_ms(5);
EN = 0;
PORTD = (cmd<<4 & 0xf0);
RS = 0;
RW = 0;
EN = 1;
__delay_ms(5);
EN = 0;
}
void lcd_data(unsigned char data)
{
PORTD = (0xF0 & data);
RS = 1;
RW = 0;
EN = 1;
__delay_ms(5);
EN = 0;
PORTD = (data<<4 & 0xf0);
RS = 1;
RW = 0;
EN = 1;
__delay_ms(5);
EN = 0;
}
void lcd_string(char *str)
{
while(*str != '\0')
{
lcd_data(*str++);
}
}
void lcd_init()
{
lcd_cmd(0x02);//return to home
lcd_cmd(0x28);///4bitmode
lcd_cmd(0x0C);///cursor off
lcd_cmd(0x01);///display clear
lcd_cmd(0x06);///increment cursor
}
void uart_init()
{
SPBRG = 129;
BRGH = 1;
SYNC = 0;
SPEN = 1;
TXEN = 1;
CREN = 1;
GIE = 1;
PEIE = 1;
RCIE = 1;
RCIF = 0;
//TXIE = 1;
TRISC7 = 1;
TRISC6 = 0;
}
void gsm_send_char(char data)
{
TXREG = data;
while(TXIF == 0);
}
char gsm_receive_char()
{
while(PIR1bits.RCIF == 0);
return RCREG;
}
void gsm_send_string(char *p)
{
while(*p != '\0')
{
gsm_send_char(*p++);
}
}
__interrupt() void isr(void)
{
if(RCIF == 1)
{
a = RCREG;
buff[i] = a;
i++;
RCIF = 0;
}
}
void main(void)
{
TRISD = 0x00;
lcd_init();
uart_init();
lcd_cmd(0x80);
lcd_string("GSM TESTING");
while(1)
{
gsm_send_string("AT");
__delay_ms(400);
//i = 0;
if(strstr(buff, "hello"))
{
lcd_cmd(0xC0);
lcd_string(buff);
}
}
return;
}
You need to add the terminating character to the string you receive from the UART before using the strstr() function.
Something like this should work:
a=0;
gsm_send_string("AT\r");
__delay_ms(500);
buff[sizeof(buff)-1] = '\0'; // Terminate UART buffer with NULL char
if(strstr(buff, "OK"))
{
lcd_cmd(0x80);
lcd_string(buff);
//a=0;
memset(buff, 0, sizeof(buff));
}
else
{
lcd_cmd(0x80);
lcd_string("AT ERROR");
}
Depending on the compiler you are using you might also need to change the way you check for a pattern within a string. In my opinion, it would be better to do:
if(strstr(buff,"OK") != NULL)
when I tried to reinitialize a timer 4 of stm32f303VB, the interrupt routine was no longer called.
static uint32_t delay_val;
uint8_t InitCounter(uint32_t period, uint16_t perscl, void(*inter_handler)(void)) {
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
NVIC_InitTypeDef NVIC_InitStructure;
//check if the timer is occupied
if(TIMx->CR1&TIM_CR1_CEN) {
return 1;
}
//enable clock for apb1
gint_handler = inter_handler;
RCC_APB1PeriphClockCmd(RCC_xPeriph_TIMx,ENABLE);
//interrupt enable
NVIC_InitStructure.NVIC_IRQChannel = TIMx_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 7;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 7;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//deinitialize timer
TIM_DeInit(TIMx);
//initialize, clock frequency 72 MHz
TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct);
TIM_TimeBaseInitStruct.TIM_ClockDivision = 0;
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Down;
TIM_TimeBaseInitStruct.TIM_Period = period;
TIM_TimeBaseInitStruct.TIM_Prescaler = perscl;
TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; //this parameter is only for TIM1 and TIM8
TIM_TimeBaseInit(TIMx,&TIM_TimeBaseInitStruct);
return 0;
}
static void Delay_decrement(void) {
if(delay_val) {
delay_val--;
}
}
static void initGreenLED(void) {
//LED3 red on PE9
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE,ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &GPIO_InitStructure);
}
void UnitTestDelay(void) {
initGreenLED();
Delay(1000000);
GPIOE->ODR ^= GPIO_Pin_11;
Delay(1000000);
}
void StartUSCounter(void(*inter_handler)(void)) {
InitCounter(1,72,inter_handler);
StartCounter();
}
void Delay(uint32_t us) {
delay_val=us;
StartUSCounter(Delay_decrement);
while(delay_val);
StopCounter();
}
void TIM4_IRQHandler(void)
{
// UINT16 temp;
if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
{
TIM4->CR1 &= ~TIM_CR1_CEN;
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
if(gint_handler) {
(*gint_handler)();
}
TIM4->CR1 |= TIM_CR1_CEN;
}
}
int main(void)
{
while(1) {
UnitTestDelay();
}
}
The first call of the UnitTestDelay is correctly decrementing the delay_val, after the Timer is disabled the next initialization is not successful and the TIM4_IRQHandler is never called again. Why and how to reinitialize the timer correctly?
I want to receive data from 2 sensors connected to my STM32F4-Discovery via 2 UARTs. Transmitting data from STM32 to sensors works but receiving doesn´t. Guarantee it isn´t a hardware problem. I found tutorials for 1 connected UART but not for 2 at once. I would like to use new HAL drivers and DMA for receiving. Thanks for help.
UART_HandleTypeDef huart4;
UART_HandleTypeDef huart5;
DMA_HandleTypeDef hdma_uart4_rx;
DMA_HandleTypeDef hdma_uart5_rx;
uint8_t rxBuffer4 = '\000';
uint8_t rxBuffer5 = '\000';
void initGPIOs_UART4(void){
__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Pin = GPIO_PIN_10 | GPIO_PIN_11;
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_MEDIUM;
GPIO_InitStructure.Alternate = GPIO_AF8_UART4;
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
}
void initGPIOs_UART5(void){
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Pin = GPIO_PIN_12;
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_MEDIUM;
GPIO_InitStructure.Alternate = GPIO_AF8_UART5;
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.Pin = GPIO_PIN_2;
HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
}
void initUART4(void){
initGPIOs_UART4();
__HAL_RCC_UART4_CLK_ENABLE();
huart4.Instance = UART4;
huart4.Init.BaudRate = 9600;
huart4.Init.WordLength = UART_WORDLENGTH_8B;
huart4.Init.StopBits = UART_STOPBITS_1;
huart4.Init.Parity = UART_PARITY_NONE;
huart4.Init.Mode = UART_MODE_TX_RX;
huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart4.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&huart4);
__HAL_UART_FLUSH_DRREGISTER(&huart4);
}
void initUART5(void){
initGPIOs_UART5();
__HAL_RCC_UART5_CLK_ENABLE();
huart5.Instance = UART5;
huart5.Init.BaudRate = 9600;
huart5.Init.WordLength = UART_WORDLENGTH_8B;
huart5.Init.StopBits = UART_STOPBITS_1;
huart5.Init.Parity = UART_PARITY_NONE;
huart5.Init.Mode = UART_MODE_TX_RX;
huart5.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart5.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&huart5);
__HAL_UART_FLUSH_DRREGISTER(&huart5);
}
void receive_start_UART4(void){
HAL_UART_Receive_DMA(&huart4, &rxBuffer4, 1);
}
void receive_start_UART5(void){
HAL_UART_Receive_DMA(&huart5, &rxBuffer5, 1);
}
void print_UART4(uint8_t string[], uint8_t length){
HAL_UART_Transmit(&huart4, (uint8_t*)string, length, 5);
}
void print_UART5(uint8_t string[], uint8_t length){
HAL_UART_Transmit(&huart5, (uint8_t*)string, length, 5);
}
void initDMA1_UART4(void){
__HAL_RCC_DMA1_CLK_ENABLE();
hdma_uart4_rx.Instance = DMA1_Stream2;
hdma_uart4_rx.Init.Channel = DMA_CHANNEL_4;
hdma_uart4_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_uart4_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_uart4_rx.Init.MemInc = DMA_MINC_DISABLE;
hdma_uart4_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_uart4_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_uart4_rx.Init.Mode = DMA_CIRCULAR;
hdma_uart4_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_uart4_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_uart4_rx);
__HAL_LINKDMA(&huart4, hdmarx, hdma_uart4_rx);
HAL_NVIC_SetPriority(DMA1_Stream2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream2_IRQn);
}
void initDMA1_UART5(void){
__HAL_RCC_DMA1_CLK_ENABLE();
hdma_uart5_rx.Instance = DMA1_Stream1;
hdma_uart5_rx.Init.Channel = DMA_CHANNEL_5;
hdma_uart5_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_uart5_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_uart5_rx.Init.MemInc = DMA_MINC_DISABLE;
hdma_uart5_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_uart5_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_uart5_rx.Init.Mode = DMA_CIRCULAR;
hdma_uart5_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_uart5_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_uart5_rx);
__HAL_LINKDMA(&huart5, hdmarx, hdma_uart5_rx);
HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
}
void DMA1_Stream2_IRQHandler(void){
HAL_NVIC_ClearPendingIRQ(DMA1_Stream2_IRQn);
HAL_DMA_IRQHandler(&hdma_uart4_rx);
}
void DMA1_Stream1_IRQHandler(void){
HAL_NVIC_ClearPendingIRQ(DMA1_Stream1_IRQn);
HAL_DMA_IRQHandler(&hdma_uart5_rx);
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
__HAL_UART_FLUSH_DRREGISTER(&huart4);
__HAL_UART_FLUSH_DRREGISTER(&huart5);
trace_printf("%d - %d\n",rxBuffer4,rxBuffer5);
//Here I´m able to receive only from UART4
}
Wrong DMA Stream/Channel
DMA1_Stream1 DMA_CHANNEL_5 is assigned to UART7_TX.
The stream/channel for UART5_RX should be DMA1_Stream0 DMA_CHANNEL_4.
See Reference Manual RM0090
page 308
#include <stm32f4xx.h>
#include "stm32f4xx_spi.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "config.h"
void init_GPIO()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOI,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOI , &GPIO_InitStructure);
}
void SPI1_Configuration_master(void)
{
SPI_InitTypeDef SPI_InitStruct;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(Open_SPI1_SCK_GPIO_CLK | Open_SPI1_MISO_GPIO_CLK | Open_SPI1_MOSI_GPIO_CLK |Open_SPI1_NSS_GPIO_CLK ,ENABLE);
RCC_APB2PeriphClockCmd(Open_RCC_APB2Periph_SPI1,ENABLE);
GPIO_PinAFConfig(Open_SPI1_SCK_GPIO_PORT, Open_SPI1_SCK_SOURCE, Open_SPI1_MOSI_AF);
GPIO_PinAFConfig(Open_SPI1_MISO_GPIO_PORT, Open_SPI1_MISO_SOURCE, Open_SPI1_MOSI_AF);
GPIO_PinAFConfig(Open_SPI1_MOSI_GPIO_PORT, Open_SPI1_MOSI_SOURCE, Open_SPI1_MOSI_AF);
GPIO_PinAFConfig(Open_SPI1_NSS_GPIO_PORT, Open_SPI1_NSS_SOURCE, Open_SPI1_NSS_AF);
GPIO_InitStructure.GPIO_Pin = Open_SPI1_SCK_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(Open_SPI1_SCK_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = Open_SPI1_MISO_PIN;
GPIO_Init(Open_SPI1_MISO_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = Open_SPI1_MOSI_PIN;
GPIO_Init(Open_SPI1_MOSI_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = Open_SPI1_NSS_PIN;
GPIO_Init(Open_SPI1_NSS_GPIO_PORT, &GPIO_InitStructure);
SPI_I2S_DeInit(Open_SPI1);
SPI_InitStruct.SPI_Direction= SPI_Direction_2Lines_FullDuplex;
SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;
SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStruct.SPI_NSS = SPI_NSS_Soft ;
SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;
SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStruct.SPI_CRCPolynomial = 7;
SPI_Init(Open_SPI1, &SPI_InitStruct);
SPI_Cmd(Open_SPI1, ENABLE);
}
void SPI_Configuration2_slave(void)
{
SPI_InitTypeDef SPI_InitStruct;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(Open_SPI2_SCK_GPIO_CLK | Open_SPI2_MISO_GPIO_CLK | Open_SPI2_MOSI_GPIO_CLK| Open_SPI2_NSS_GPIO_CLK,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
GPIO_PinAFConfig(Open_SPI2_SCK_GPIO_PORT, Open_SPI2_SCK_SOURCE, Open_SPI2_MOSI_AF);
GPIO_PinAFConfig(Open_SPI2_MISO_GPIO_PORT, Open_SPI2_MISO_SOURCE, Open_SPI2_MOSI_AF);
GPIO_PinAFConfig(Open_SPI2_MOSI_GPIO_PORT, Open_SPI2_MOSI_SOURCE, Open_SPI2_MOSI_AF);
GPIO_PinAFConfig(Open_SPI2_MOSI_GPIO_PORT, Open_SPI2_NSS_SOURCE, Open_SPI2_MOSI_AF);
GPIO_InitStructure.GPIO_Pin = Open_SPI2_SCK_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(Open_SPI2_SCK_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = Open_SPI2_MISO_PIN;
GPIO_Init(Open_SPI2_MISO_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = Open_SPI2_MOSI_PIN;
GPIO_Init(Open_SPI2_MOSI_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = Open_SPI2_NSS_PIN;
GPIO_Init(Open_SPI2_MOSI_GPIO_PORT, &GPIO_InitStructure);
SPI_I2S_DeInit(Open_SPI2);
SPI_InitStruct.SPI_Direction= SPI_Direction_2Lines_FullDuplex;
SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStruct.SPI_Mode = SPI_Mode_Slave;
SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;
SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStruct.SPI_NSS = SPI_NSS_Soft ;
//SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;
SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStruct.SPI_CRCPolynomial = 7;
SPI_Init(Open_SPI2, &SPI_InitStruct);
SPI_Cmd(Open_SPI2, ENABLE);
}
u16 SPI2_Send_byte(u16 data)
{
while(SPI_I2S_GetFlagStatus(Open_SPI2, SPI_I2S_FLAG_TXE)==RESET);
SPI_I2S_SendData(Open_SPI2,data);
while(SPI_I2S_GetFlagStatus(Open_SPI2, SPI_I2S_FLAG_RXNE)==RESET);
return SPI_I2S_ReceiveData(Open_SPI2);
}
u16 SPI2_Receive_byte(void)
{/*
while(SPI_I2S_GetFlagStatus(Open_SPI2, SPI_I2S_FLAG_TXE)==RESET);
SPI_I2S_SendData(Open_SPI2,0x00);
*/
while(SPI_I2S_GetFlagStatus(Open_SPI2, SPI_I2S_FLAG_RXNE)==RESET);
return SPI_I2S_ReceiveData(Open_SPI2);
}
u16 SPI_Send_byte(u16 data)
{
GPIO_ResetBits(GPIOI,GPIO_Pin_10);
while(SPI_I2S_GetFlagStatus(Open_SPI1, SPI_I2S_FLAG_TXE)==RESET);
SPI_I2S_SendData(Open_SPI1,data);
while(SPI_I2S_GetFlagStatus(Open_SPI1, SPI_I2S_FLAG_RXNE)==RESET);
GPIO_SetBits(GPIOI,GPIO_Pin_10);
return SPI_I2S_ReceiveData(Open_SPI1);
}
u16 SPI_Receive_byte(u16 data)
{
/*while(SPI_I2S_GetFlagStatus(Open_SPI1, SPI_I2S_FLAG_TXE)==RESET);
SPI_I2S_SendData(Open_SPI1,data);
*/
while(SPI_I2S_GetFlagStatus(Open_SPI1, SPI_I2S_FLAG_RXNE)==RESET);
return SPI_I2S_ReceiveData(Open_SPI1);
}
int main()
{
char a;
init_GPIO();
SPI_Configuration2_slave();
SPI1_Configuration_master();
GPIO_SetBits(GPIOI,GPIO_Pin_10);
while(1)
{
a =SPI_Send_byte((u16)'a');
a = SPI2_Receive_byte();
}
return 0;
}
I am trying to implement Spi on STM32F407ig
I am currently trying to implement communication between two Spi1 and SPI2 on the same board.
I tried the similar code for communication between boards.
when i loop back mosi and miso of master i get the data transmitted.
but the slave does not receive any thing or it receives zero.
The connections made are right.
also the Macros used like Open_SPI1 are right.
I want to know if my configuration of SPI master and slave is right.
Could someone also elaborate on how the NSS software exactly work.
I had an issue with SPI on STM32F2 series. I had to toggle the NSS line manually and everything worked fine after that. Not sure if F4 has the same problem (maybe it's even by design). Here's my code:
/******************************************************************************/
void SPI_GPIO_init( void )
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure SPI pins SCK and MOSI to be hardware controlled */
GPIO_InitStructure.GPIO_Pin = SPI_PIN_SCK | SPI_PIN_MOSI;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init( SPI_GPIO_PORT, &GPIO_InitStructure );
/* Configure SPI pin MISO to be an input pin since we are master */
GPIO_InitStructure.GPIO_Pin = SPI_PIN_MISO;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init( SPI_GPIO_PORT, &GPIO_InitStructure );
/* Configure SPI pin NSS to be a regular GPIO output. This is due to STM32
* goofy handling of SPI: NSS stays low for the entire duration of SPI being
* enabled instead of being released after outgoing data is completed. This
* is basically a HW bug but it definitely mentiones this in the Ref Manual.
*
* From the reference manual RM0090:
* - NSS output enabled (SSM = 0, SSOE = 1)
* This configuration is used only when the device operates in master mode.
* The NSS signal is driven low when the master starts the communication and
* is kept low until the SPI is disabled.
*
* Instead, we are going to drive this pin manually as CLRC663 chip expects
* */
GPIO_InitStructure.GPIO_Pin = SPI_PIN_NSS;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init( SPI_GPIO_PORT, &GPIO_InitStructure );
SPI_NSS_high();
DelayMS(1);
}
/******************************************************************************/
void SPI_NSS_high( void )
{
GPIO_WriteBit( SPI_GPIO_PORT, SPI_PIN_NSS, Bit_SET);
}
/******************************************************************************/
void SPI_NSS_low( void )
{
GPIO_WriteBit( SPI_GPIO_PORT, SPI_PIN_NSS, Bit_RESET);
}
/******************************************************************************/
void SPI_init( void )
{
SPI_I2S_DeInit( SPI1 );
SPI_NSS_high();
SPI_InitTypeDef SPI_InitStructure;
/* SPI1 configuration */
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 0;
SPI_Init( SPI1, &SPI_InitStructure );
SPI_Cmd( SPI1, ENABLE );
/* Not using interrupts for SPI communication so don't enable the NVIC and
* the ISR for it.*/
}
/******************************************************************************/
Error SPI_send( uint8_t *snd_buf, uint8_t snd_buf_len )
{
uint8_t snd_indx = 0;
uint8_t spi_retry = 0;
SPI_NSS_low(); /* Assert the NSS pin low to become SPI bus master */
for ( snd_indx = 0; snd_indx < snd_buf_len; snd_indx++ )
{
/* When SPI Tx buffer is empty, send data. Make sure we don't get
* stuck in an inf loop while waiting for HW */
spi_retry = 0;
while ( SET != SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_TXE ) )
{
if ( 0xFF == spi_retry++ )
{
err_printf("Reached SPI hardware retries trying to send data over SPI bus\n");
return ( ERR_HW_SPI_TIMEOUT );
}
}
SPI_I2S_SendData( SPI1, snd_buf[ snd_indx ] );
// debug_printf("Sent %02x\n", snd_buf[ snd_indx ]);
/* Get the dummy byte coming back when SPI Rx buffer is empty. Make sure
* we don't get stuck in an inf loop while waiting for HW */
spi_retry = 0;
while ( SET != SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_RXNE ) )
{
if ( 0xFF == spi_retry++ )
{
err_printf("Reached SPI hardware retries trying to receive data over SPI bus\n");
return ( ERR_HW_SPI_TIMEOUT );
}
}
SPI_I2S_ReceiveData( SPI1 ); /* Dummy byte so no need to store it */
}
SPI_NSS_high(); /* Assert the NSS pin high to release SPI bus master */
return ( ERR_NONE );
}
/******************************************************************************/
Error SPI_transceive(
uint8_t *snd_buf,
uint8_t snd_buf_len,
uint8_t *rcv_buf,
uint8_t rcv_buf_len
)
{
uint8_t snd_indx = 0;
uint8_t rcv_indx = 0;
uint16_t spi_retry = 0;
SPI_NSS_low(); /* Assert the NSS pin low to become SPI bus master */
if ( snd_buf_len != rcv_buf_len )
{
err_printf("SPI expects to receive same amount of data that it is sending\n");
return ( ERR_HW_SPI_LENGTH_MISMATCH );
}
for ( snd_indx = 0; snd_indx < snd_buf_len; snd_indx++, rcv_indx++ )
{
/* When SPI Tx buffer is empty, send data. Make sure we don't get
* stuck in an inf loop while waiting for HW */
spi_retry = 0;
while ( SET != SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_TXE ) )
{
if ( 0xFF == spi_retry++ )
{
err_printf("Reached SPI hardware retries trying to send data over SPI bus\n");
return ( ERR_HW_SPI_TIMEOUT );
}
}
SPI_I2S_SendData( SPI1, snd_buf[ snd_indx ] );
/* Now receive the reply when the Rx buffer is empty. Make sure we don't
* get stuck in an inf loop while waiting for HW */
spi_retry = 0;
while ( SET != SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_RXNE ) )
{
if ( 0xFF == spi_retry++ )
{
err_printf("Reached SPI hardware retries trying to receive data over SPI bus\n");
return ( ERR_HW_SPI_TIMEOUT );
}
}
uint8_t data = SPI_I2S_ReceiveData( SPI1 );
rcv_buf[ rcv_indx ] = data;
// debug_printf("Got %02x\n", data );
}
SPI_NSS_high(); /* Assert the NSS pin high to release SPI bus master */
return ( ERR_NONE );
}
I'm using the STM32F373 microcontroller and wrote a simple function to read data from a MPU6050 gyro+accel on i2c 1 (PB7 PB6).
The problem is that when I try to read sensor register data - flag I2C_ISR_TXIS is always equal to RESET (not set).
Why might this happen?
Here is some source code that demonstrates the problem.
void i2c1_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_4);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_4);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOB, &GPIO_InitStructure);
I2C_DeInit(I2C1);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
I2C_InitStructure.I2C_DigitalFilter = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_Timing = 0xC062121F;
I2C_Init(I2C1, &I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
}
uint8_t i2c_read(uint8_t DeviceAddr, uint8_t RegAddr, uint8_t* pBuffer, uint16_t len)
{
/* Test on BUSY Flag */
uint32_t timeout = I2C_TIMEOUT;
while(I2C_GetFlagStatus(I2C1, I2C_ISR_BUSY) != RESET)
{
if((timeout--) == 0) return 0;
}
I2C_TransferHandling(I2C1, DeviceAddr, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
/* !!! Wait until TXIS flag is set !!! */
timeout = I2C_TIMEOUT;
while(I2C_GetFlagStatus(I2C1, I2C_ISR_TXIS) == RESET) // PROBLEM HERE!!!!!!!!!!!!!!!
{
if((timeout--) == 0) return 0;
}
....
....
}
OK,I found the problem. Flag I2C_ISR_TXIS did not get because the device on the i2c did not respond to the sent address. Need to convert the device address to 7 bits.
(DeviceAddr & 0x7f) << 1