I'm trying to get ADC with DMA working on my STM32F411RE nucleo board.
the signal is connected to the PC0 pin (ADC channel 10, DMA2), but whenever I check, the uhADC1ConvertedValue is 0. Am I missing something? Is my config wrong?
__IO uint32_t uhADC1ConvertedValue;
unsigned int getADCVal(){
return uhADC1ConvertedValue;
}
void ADC2_Init(){
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
DMA_InitTypeDef DMA_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
uhADC1ConvertedValue = 1;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&uhADC1ConvertedValue;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = 1;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream0, &DMA_InitStructure);
DMA_Cmd(DMA2_Stream0, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOC, &GPIO_InitStructure);
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_3Cycles);
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
ADC_DMACmd(ADC1, ENABLE);
ADC_Cmd(ADC1, ENABLE);
ADC_EOCOnEachRegularChannelCmd(ADC1, ENABLE);
}
int main(void)
{
int rev = 0;
uC_Init();
rev = getADCVal(); //enc28j60getrev();
simple_server();
return rev;
}
I can't really tell what was wrong with my previous code (probably the part where i didn't start the timer that would start the ADC), but here is a working one (this code keeps ADC doing conversions continously (well, started by a timer) and loads the measured value into a variable):
volatile uint32_t uhADC1ConvertedValue;
uint32_t getADCVal(){
return uhADC1ConvertedValue;
}
void adc_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOC, &GPIO_InitStructure);
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;
//konfiguracja ADC
ADC1->CR2 = ADC_CR2_ADON | //włącz ADC
ADC_CR2_EXTEN_0 | //wyzwalanie przetwornika zboczem opadającym i narastającym
ADC_CR2_EXTSEL_3 | ADC_CR2_EXTSEL_0 | //wyzwalanie przetwornika kanałem 4 timera 4
ADC_CR2_DDS | //kontynuuj przesył DMA po ostatnim przesyle (konieczne dla circular mode)
ADC_CR2_DMA; //włącz DMA dla ADC
//włączenie skanowania i przerwania dla zakonczonej konwersji
ADC1->CR1 = ADC_CR1_SCAN; //| ADC_CR1_EOCIE;
//Ustawienie czasu konwersji na 3 + 12 cykli zegara ADC, zegar ADC == 42MHz częstotliwosć próbkowania ~1Ms
ADC1->SMPR1 = 0;//ADC_SMPR1_SMP11_1 | ADC_SMPR1_SMP12_1;
//Ustawienie ilosci kanałów do skanowania
ADC1->SQR1 = (1)<<20;
//Ustawienie kanałów 11 i 12 do skanowania
ADC1->SQR3 = 10<<5;
//Konfiguracja DMA dla przetwornika ADC1
DMA2_Stream0->NDTR = 1; //ilosc bajtów do przesłania
DMA2_Stream0->PAR = (uint32_t)&ADC1->DR;
DMA2_Stream0->M0AR = (uint32_t)&uhADC1ConvertedValue;
DMA2_Stream0->CR = DMA_SxCR_PL_1 | //priority high
DMA_SxCR_MSIZE_0 | //memory size 16bit
DMA_SxCR_PSIZE_0 | //pheriperial size 16bit
DMA_SxCR_MINC | //inkrementuj wskaźnik po stronie pamięci
DMA_SxCR_CIRC | //zapętlenie bufora pamięci
DMA_SxCR_EN; //włączenie kontrolera DMA
//konfiguracja timera dla przetwornika
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
TIM4->CR1 = 0; //resetowanie rejestru konfiguracji
TIM4->PSC = 0; //prescaller na 0
TIM4->ARR = 167; //reload register na 83
TIM4->CCR4 = 167; //rejesrt compare dla wyzwalania przetwornika
TIM4->CCMR2 |= TIM_CCMR2_OC4M_0 | TIM_CCMR2_OC4M_1; //przełączanie wyjcia przy compare
TIM4->CCER |= TIM_CCER_CC4E; //włączenie wyjcia 4
//konfiguracja NVIC
NVIC_EnableIRQ(ADC_IRQn); //przerwanie od zakonczenia konwersji ADC
//uruchom przetwornik
ADC1->CR2 |= ADC_CR2_ADON;
//uruchom timer
TIM4->CR1 = TIM_CR1_CEN;
}
int main(void)
{
uint32_t rev;
int bb= 0;
uC_Init();
//ADC2_Init();
adc_init();
rev = uhADC1ConvertedValue;
rev = uhADC1ConvertedValue;
rev = uhADC1ConvertedValue;
for (bb=0; bb< 100000; bb++) // tu dociera i sie wywala
{;;}
rev = uhADC1ConvertedValue;
rev = uhADC1ConvertedValue;
rev = uhADC1ConvertedValue;
rev = uhADC1ConvertedValue;
// rev = 20;
/**/
simple_server(); //petla nieskonczona
return rev;
}
Related
Trying to get some simple DAC output before
moving forward. Have a multimeter on the output A2
but this seems to never change from about 1V6 for whatever value
I put into the DAC2 output function.
#include "stm32f4xx.h"
#include "stm32f4xx_dac.h"
void io_config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* DMA1 & DMA2 clock and GPIOA & GPIOC clock enable */
RCC_AHB1PeriphClockCmd( /*RCC_AHB1Periph_DMA1 | RCC_AHB1Periph_DMA2 |*/
RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOB, ENABLE);
/* DAC Periph clock, TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC | RCC_APB1Periph_TIM2, ENABLE);
/* ADC1 Periph Clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
DAC_InitTypeDef dac_init_s;
int main(void)
{
unsigned int i, adcr;
i = adcr = 0;
io_config ();
DAC_StructInit(&dac_init_s);
//dac_init_s.DAC_OutputBuffer = DAC_OutputBuffer_Disable;
DAC_Init(DAC_Channel_2, &dac_init_s);
while(1) {
DAC_SetChannel2Data(DAC_Align_12b_R,500);
}
}
I do not use HAL for such a simple peripheral
Enable clock, configure GPIO pin
for channel 1
DAC -> CR |= DAC_CR_EN1;
DAC -> DHR12R1 = 454 /* your value */
for channel 2
DAC -> CR |= DAC_CR_EN2;
DAC -> DHR12R2 = 454 /* your value */
For waveform generation (using TIM6 and DAC Channel 1)
TIM6 -> DIER &= ~(TIM_DIER_UDE);
TIM6 -> DIER |= TIM_DIER_UDE;
TIM6 -> PSC = /* PSC value */
TIM6 -> ARR = /* PSC value */
TIM6 -> CR2 |= TIM_CR2_MMS_1;
DAC -> CR &= ~(DAC_CR_MAMP1 | DAC_CR_WAVE1);
DAC -> CR = DAC_CR_DMAEN1 | DAC_SR_DMAUDR1 | DAC_CR_TEN1 | DAC_CR_BOFF1;
DAC -> CR |= DAC_CR_EN1;
DMA1_Stream5 -> NDTR = /* Number of samples */
DMA1_Stream5 -> PAR = (uint32_t)&(DAC -> DHR12R1);
DMA1_Stream5 -> M0AR = (uint32_t)(/* address of the waveform data */);
DMA1_Stream5 -> CR = (DMA_SxCR_TEIE | DMA_SxCR_CHSEL | DMA_SxCR_CIRC | DMA_SxCR_DIR_0 | DMA_SxCR_EN | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_MINC | DMA_SxCR_PL_0);
TIM6 -> CR1 |= TIM_CR1_CEN;
OK this WORKS! STM32F446RE NUCLEO DAC OUTPUT simple example
not tied to timers and/or DMA etc. SOLVED !!!
http://imgur.com/a/wuq4a
varsågod!
#include "stm32f4xx.h"
#include "stm32f4xx_dac.h"
void io_config2 (void) {
// Enable clocks for port A and DAC
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* DAC channel 2 Configuration */
DAC_InitTypeDef DAC_InitStructure2;
DAC_InitStructure2.DAC_Trigger = DAC_Trigger_None;
DAC_InitStructure2.DAC_WaveGeneration = DAC_WaveGeneration_None;
DAC_InitStructure2.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
DAC_Init(DAC_Channel_2, &DAC_InitStructure2);
/* DAC channel 1 Configuration */
DAC_InitTypeDef DAC_InitStructure1;
DAC_InitStructure1.DAC_Trigger = DAC_Trigger_None;
DAC_InitStructure1.DAC_WaveGeneration = DAC_WaveGeneration_None;
DAC_InitStructure1.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
DAC_Init(DAC_Channel_1, &DAC_InitStructure1);
/* Enable DAC Channel 1 and 2 */
DAC_Cmd(DAC_Channel_2, ENABLE);
DAC_Cmd(DAC_Channel_1, ENABLE);
}
DAC_InitTypeDef dac_init_s;
int main(void)
{
unsigned int i, adcr, j, k;
i = adcr = j = k = 0;
io_config2 ();
//DAC_Cmd( DAC_Channel_2, ENABLE);
DAC_Cmd( DAC_Channel_1, ENABLE);
while(1) {
#define OVAL 4095
//DAC_Cmd( DAC_Channel_2, DISABLE);
//DAC_SetChannel2Data(DAC_Align_12b_R, OVAL );
DAC_SetChannel1Data(DAC_Align_12b_R, OVAL ); /* 1000/4096 * 3V3 == 0V8 */
//if ( OVAL != DAC_GetDataOutputValue (DAC_Channel_2)) {
j = DAC_GetDataOutputValue (DAC_Channel_1);
k = DAC_GetDataOutputValue (DAC_Channel_2);
//}
}
}
I want to create firmware to stm32f4 discovery which flashes the lights, when the board moves. But SPI_I2S_ReceiveData always returns 0xff or 0x00. I think the problem is in my SPI initialization but I do not know where exactly it is.
Here is my code.
#include <stm32f4xx.h>
#include <stm32f4xx_rcc.h>
#include <stm32f4xx_gpio.h>
#include <stm32f4xx_spi.h>
#include <stm32f4xx_i2c.h>
void InitLEDs(void);
void InitSPI(void);
void Delay(int iTicks);
void DiodeFlash(void);
unsigned short ReadACCELEROMETER(void);
unsigned char WriteSPI(unsigned char cbData);
int main(void)
{
unsigned short cbPrevRead = 0;
unsigned short cbCurrentRead = 0;
InitLEDs();
InitSPI();
while(1)
{
cbCurrentRead = ReadACCELEROMETER();
if (cbCurrentRead != cbPrevRead)
{
DiodeFlash();
cbPrevRead = cbCurrentRead;
}
}
}
void InitLEDs(void)
{
GPIO_InitTypeDef PortD;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
PortD.GPIO_Mode = GPIO_Mode_OUT;
PortD.GPIO_OType = GPIO_OType_PP;
PortD.GPIO_PuPd = GPIO_PuPd_NOPULL;
PortD.GPIO_Speed = GPIO_Speed_100MHz;
PortD.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_Init(GPIOD, &PortD);
}
void InitSPI(void)
{
GPIO_InitTypeDef PortA;
GPIO_InitTypeDef PortE;
SPI_InitTypeDef SPI1Conf;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
PortA.GPIO_Mode = GPIO_Mode_AF;
PortA.GPIO_OType = GPIO_OType_PP;
PortA.GPIO_Speed = GPIO_Speed_50MHz;
PortA.GPIO_PuPd = GPIO_PuPd_NOPULL;
PortA.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_Init(GPIOA, &PortA);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);
PortE.GPIO_Mode = GPIO_Mode_OUT;
PortE.GPIO_OType = GPIO_OType_PP;
PortE.GPIO_Speed = GPIO_Speed_50MHz;
PortE.GPIO_PuPd = GPIO_PuPd_NOPULL;
PortE.GPIO_Pin = GPIO_Pin_3;
GPIO_Init(GPIOE, &PortE);
GPIOE->ODR = 0x0008; // Disable CS
SPI1Conf.SPI_DataSize = SPI_DataSize_8b;
SPI1Conf.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;
SPI1Conf.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI1Conf.SPI_FirstBit = SPI_FirstBit_MSB; // ACCELEROMETER PROTOCOL
SPI1Conf.SPI_Mode = SPI_Mode_Master;
SPI1Conf.SPI_CPHA = SPI_CPHA_2Edge;
SPI1Conf.SPI_CPOL = SPI_CPOL_High;
SPI1Conf.SPI_CRCPolynomial = 7;
SPI1Conf.SPI_NSS = SPI_NSS_Soft;
SPI_Init(SPI1, &SPI1Conf);
SPI_Cmd(SPI1, ENABLE);
WriteSPI(0x23); WriteSPI(0xc9);
WriteSPI(0x20); WriteSPI(0x97);
WriteSPI(0x24); WriteSPI(0x00);
WriteSPI(0x10); WriteSPI(0x00);
WriteSPI(0x11); WriteSPI(0x00);
WriteSPI(0x12); WriteSPI(0x00);
}
void Delay(int iTicks)
{
while ((iTicks--) > 0);
}
void DiodeFlash(void)
{
GPIO_Write(GPIOD, 1UL << 12);
Delay(100000);
GPIO_Write(GPIOD, 1UL << 13);
Delay(100000);
GPIO_Write(GPIOD, 1UL << 14);
Delay(100000);
GPIO_Write(GPIOD, 1UL << 15);
Delay(100000);
GPIO_Write(GPIOD, 0x0000);
}
unsigned short ReadACCELEROMETER(void)
{
unsigned short nAxisX = 0x0000;
unsigned short nAxisY = 0x0000;
unsigned short nAxisZ = 0x0000;
unsigned char cbAddress = 0x80;
//**********************************************************
// Forming X Value
WriteSPI(cbAddress | 0x0f);
nAxisX |= WriteSPI(0x00);
WriteSPI(cbAddress | 0x2A);
nAxisX |= WriteSPI(0x00) << 8;
//**********************************************************
// Forming Y Value
WriteSPI(cbAddress | 0x2B);
nAxisX |= WriteSPI(0x00);
WriteSPI(cbAddress | 0x2C);
nAxisX |= WriteSPI(0x00) << 8;
//**********************************************************
// Forming Z Value
WriteSPI(cbAddress | 0x2D);
nAxisX |= WriteSPI(0x00);
WriteSPI(cbAddress | 0x2E);
nAxisX |= WriteSPI(0x00) << 8;
return nAxisX ^ nAxisY ^ nAxisZ;
}
unsigned char WriteSPI(unsigned char cbData)
{
unsigned char cbResult = 0x00;
GPIOE->ODR = 0x0000; // Enable CS
// Wait for ready status
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET);
SPI_I2S_SendData(SPI1, cbData);
// Wait for ready status
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET);
cbResult = SPI_I2S_ReceiveData(SPI1);
GPIOE->ODR = 0x0008; // Disable CS
return cbResult;
}
First, you don't specify your accelerometer. I can guess, that it is ST LISxx.
In this case, there is incorrect data transfer to accelerometer.
Correct write sequence:
- activate chipselect
- write register number
- write register value
- deactivate chipselect
Use similar sequence to read each register.
Next, ST not recommend your algo for low-level SPI transfer:
Do not use the BSY flag to handle each data transmission or reception. It is better to use the TXE and RXNE flags instead
(see Reference manual). Use simply
SPIx->DR = out;
while (!(SPIx->SR & SPI_SR_RXNE)) ;
return SPIx->DR;
Also, i am working with LIS3DH with CPOL=0 & CPHA = 0 SPI settings (i don't know, how it will work with your CPOL=1, CPHA=1).
Hint: to check SPI communication, try to read WHO_AM_I register - it is alawys enabled and always have known value.
It is beacuse you writes address of register, after deselects your device, so wrote address is clean up. In this case you must do something like this.
unsigned char WriteSPI(unsigned char cbData)
{
unsigned char cbResult = 0x00;
// Wait for ready status
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET);
SPI_I2S_SendData(SPI1, cbData);
// Wait for ready status
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET);
cbResult = SPI_I2S_ReceiveData(SPI1);
return cbResult;
}
unsigned char WriteReg(unsigned char cbAddress, unsigned char cbData)
{
unsigned char cbResult = 0x00;
GPIOE->ODR = 0x0000; // select device
WriteSPI(cbAddress);
cbResult = WriteSPI(cbData);
GPIOE->ODR = 0x0008; // deselect device
return cbResult;
}
unsigned char ReadReg(unsigned char cbAddress)
{
unsigned char cbResult = 0x00;
GPIOE->ODR = 0x0000; // select device
WriteSPI(cbAddress);
cbResult = WriteSPI(0x00);
GPIOE->ODR = 0x0008; // deselect device
return cbResult;
}
There is nothing wrong with your SPI initialization. The main mistake is in writing register addresses. You must not deselect device before reading register values, instead you must perform write address - reading values in one batch. It mean
Select device.
Write register address.
Read register value.
Deselect device.
I am using STM32F429 CAN bus Program with TJA1041A as CAN
Transreciver.The Problem is the messages are not getting acknowledged and herewith I
am attaching the code for further reference.I am using PCAN View to see
the messages.I kindly request to check the code and tell me if there are any faults.
Code:-
int main(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);
// SystemInit();
GPIO_InitTypeDef GPIO_InitDef;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
GPIO_InitDef.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13;
GPIO_InitDef.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitDef.GPIO_OType = GPIO_OType_PP;
GPIO_InitDef.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitDef.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOB, &GPIO_InitDef);
/* Connect CAN pins to AF */
GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_CAN2); // CAN2_RX
GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_CAN2); // CAN2_TX
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
GPIO_InitDef.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
GPIO_InitDef.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitDef.GPIO_OType = GPIO_OType_PP;
GPIO_InitDef.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitDef.GPIO_Speed = GPIO_Speed_100MHz;
/* Connect PD5 and PD7 pins for CAN Transreceiver to enable and
stanby */
GPIO_Init(GPIOD, &GPIO_InitDef);
GPIO_SetBits(GPIOD, GPIO_Pin_5|GPIO_Pin_7);
RCC_ClocksTypeDef RCC_Clocks;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
RCC_GetClocksFreq(&RCC_Clocks);
CAN_DeInit(CAN2);
CAN_StructInit(&CAN_InitStructure);
/* CAN cell init */
CAN_InitStructure.CAN_TTCM = DISABLE;
CAN_InitStructure.CAN_ABOM = DISABLE;
CAN_InitStructure.CAN_AWUM = DISABLE;
CAN_InitStructure.CAN_NART = DISABLE;
CAN_InitStructure.CAN_RFLM = DISABLE;
CAN_InitStructure.CAN_TXFP = DISABLE;
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal ;
/* quanta 1+14+6 = 21, 21 * 4 = 84, 42000000 / 84 = 5000000 */
/* CAN Baudrate = 500Kbps (CAN clocked at 42 MHz) Prescale = 4 */
/* Requires a clock with integer division into APB clock */
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; // 1+6+7 = 14, 1+14+6 = 21,
1+15+5 = 21
CAN_InitStructure.CAN_BS1 = CAN_BS1_14tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_6tq;
CAN_InitStructure.CAN_Prescaler = 4; // quanta by baudrate - 125kbps
CAN_Init(CAN2, &CAN_InitStructure);
/* CAN filter init */
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; //
IdMask or IdList
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_16bit; // 16
or 32
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000; // Everything,
otherwise 11-bit in top bits
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0; // Rx
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
//CAN_FilterInitStructure.CAN_FilterNumber = 0; // CAN1 [ 0..13]
// CAN_FilterInit(&CAN_FilterInitStructure);
CAN_FilterInitStructure.CAN_FilterNumber = 14; // CAN2 [14..27]
CAN_FilterInit(&CAN_FilterInitStructure);
CAN_ITConfig(CAN2, CAN_IT_FMP0, ENABLE);
CanTxMsg TxMessage;
// transmit */
TxMessage.StdId = 0x321;
TxMessage.ExtId = 0x00;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 8;
TxMessage.Data[0] = 0x02;
TxMessage.Data[1] = 0x11;
TxMessage.Data[2] = 0x11;
TxMessage.Data[3] = 0x11;
while(1)
{
uint32_t i;
int j = 0;
uint8_t TransmitMailbox = 0;
TxMessage.Data[4] = (j >> 0) & 0xFF; // Cycling
TxMessage.Data[5] = (j >> 8) & 0xFF;
TxMessage.Data[6] = (j >> 16) & 0xFF;
TxMessage.Data[7] = (j >> 24) & 0xFF;
j++;
TransmitMailbox = CAN_Transmit(CAN2, &TxMessage);
i = 0;
while((CAN_TransmitStatus(CAN2, TransmitMailbox) != CANTXOK) && (i
!= 0xFFFF)) // Wait on Transmit
{
i++;
CAN2RX();// Pump RX
}
}
}
This is the default behavior of any CAN bus. You need at least two CAN controllers on the bus to establish communication. If there is just one node, you will get nothing but error frames.
For debugging purposes, all CAN controllers have a "loop back" debug feature which allows them to acknowledge and listen to their own frames. You must enable this if you are alone on the bus.
Alternatively, if you have two CAN controllers in the same MCU, you can enable both of them and wire them together.
Probably you should enable the transeiver : It should have some voltage in input (Vbat = 12V) and Vi/o and also you need to enable the EN Pin.
I'm trying to generate a 2MHz PWM with a duty-cycle of 50%. My problem is that I can't clear the interrupt flag. Here is my code:
#include "includes.h"
TIM_TimeBaseInitTypeDef TIM1_InitStruncture;
TIM_TimeBaseInitTypeDef TIM3_InitStruncture;
TIM_OCInitTypeDef TIM3_OCInitStructure;
SPI_InitTypeDef SPI_InitStructure;
void Timer3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3, TIM_IT_CC3) != RESET)
{
TIM_ClearFlag(TIM3, TIM_IT_CC3);
//dummy code
++StatusReg;
}
}
void CLK_init()
{
//activez HSI
RCC_HSICmd(ENABLE);
//astepst sa se activeze HSI
while( RCC_GetFlagStatus( RCC_FLAG_HSIRDY) == RESET );
//setez HSI ca sursa de clock
RCC_SYSCLKConfig( RCC_SYSCLKSource_HSI );
//activez HSE
RCC_HSEConfig( RCC_HSE_ON );
//astept sa se termine secventa de activare
while( RCC_GetFlagStatus( RCC_FLAG_HSERDY) == RESET );
//setez HSE (8MHz) ca input py PLL
//setez factotul de multiplicare 9
RCC_PLLConfig( RCC_PLLSource_HSE_Div1, RCC_PLLMul_9 );
//activez PLL-ul
RCC_PLLCmd(ENABLE);
//astept sa se termine secventa de activare
while( RCC_GetFlagStatus( RCC_FLAG_PLLRDY) == RESET );
#ifdef EMB_FLASH
// 5. Init Embedded Flash
// Zero wait state, if 0 < HCLK 24 MHz
// One wait state, if 24 MHz < HCLK 56 MHz
// Two wait states, if 56 MHz < HCLK 72 MHz
// Flash wait state
FLASH_SetLatency(FLASH_Latency_2);
// Half cycle access
FLASH_HalfCycleAccessCmd(FLASH_HalfCycleAccess_Disable);
// Prefetch buffer
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
#endif // EMB_FLASH
//setez iesirea de la PLL ca sursa de CLK
RCC_SYSCLKConfig( RCC_SYSCLKSource_PLLCLK );
}
void Port_C_Enable()
{
//GPIO_InitTypeDef GPIOC_InitStructure;
//resetez portul C (just in case)
RCC->APB2RSTR |= RCC_APB2RSTR_IOPCRST;
RCC->APB2RSTR &= ~RCC_APB2RSTR_IOPCRST;
//activez CLK-ul pentru portul C
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
/*
GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIOC_InitStructure);
*/
}
void Timer3_Init()
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//reset Timer3 (just in case)
//RCC->APB1RSTR |= RCC_APB1RSTR_TIM3RST;
//RCC->APB1RSTR &= ~RCC_APB1RSTR_TIM3RST;
//give clock to Timer-ul 3
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
//frequency 2Mhz
TIM3_InitStruncture.TIM_Period = 36;
TIM3_InitStruncture.TIM_Prescaler = 0;
TIM3_InitStruncture.TIM_ClockDivision = 0;//TIM_CKD_DIV1;
TIM3_InitStruncture.TIM_CounterMode = TIM_CounterMode_CenterAligned3;
TIM_TimeBaseInit(TIM3, &TIM3_InitStruncture);
TIM_ITConfig(TIM3, TIM_IT_CC3, ENABLE);
TIM_Cmd(TIM3, ENABLE);
//dutycicle 50%
TIM3_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM3_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM3_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM3_OCInitStructure.TIM_Pulse = 18;
TIM_OC3Init(TIM3, &TIM3_OCInitStructure);
TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM3, ENABLE);
TIM_Cmd(TIM3, ENABLE);
}
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*GPIOB Configuration: TIM3 channel1, 2, 3 and 4
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;*/
//GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE);
/* GPIOA Configuration:TIM3 Channel1, 2, 3 and 4 as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void NVIC_init(void)
{
// NVIC init
#ifndef EMB_FLASH
/* Set the Vector Table base location at 0x20000000 */
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else /* VECT_TAB_FLASH */
/* Set the Vector Table base location at 0x08000000 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
}
void SPI_init()
{
SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
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(SPI2, &SPI_InitStructure);
}
void main(void)
{
#ifdef DEBUG
debug();
#endif
// NVIC_SETPRIMASK();
CLK_init();
NVIC_init();
Port_C_Enable();
GPIO_Configuration();
//Timer1_Init();
Timer3_Init();
TIM_Cmd(TIM1, ENABLE);
unsigned int j=0;
while(1)
{
//dummy code
++j;
if(j == 0xff)
{
j=0;
}
}
}
Can anyone tell me why the CCR3 (Capture/Compare Register 3 Flag) stays high?
Thanks.
Pay attention to not mixing the following:
TIM_ClearFlag which shall be used together with TIM_FLAG_CC1
TIM_ClearITPendingBit which shall be used together with TIM_IT_CC1
as far as I understand. Otherwise you could have some masks which avoid to flag to be set.
Thanks aamxip for your answer.
I found the problem. It seems that the configuration is correct but i don't have enough time to execute the ISR(interrupt service routine). Once every 36 CLK's a new interrupt is generated and it takes me somewhere around 30 instructions or more only to enter in the ISR.
After more research i found out that i don't really need that frequency and i adopted a different approach, bit-banging.
I am lost on how to receive CAN message on STM32F4Discovery. I have it in Silent_Loopback mode, meaning all sent messages should arrive in CAN controller itself. I get Transmit_OK status when I send the message, however, nothing appears in the FIFO mailbox. I have skipped CAN filter configuration in order to receive all messages and not to filter any of them out. What am I doing wrong?
/* Includes */
#include "stm32f4xx.h"
#include "stm32f4_discovery.h"
void Delay(__IO uint32_t nCount) {
while(nCount--) {
}
}
void RCC_Configuration(void) {
/* ENABLE CLOCKS */
/* GPIOB clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
/* USART3 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
/* CAN1 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
/* CAN2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);
}
void GPIO_Configuration(void) {
GPIO_InitTypeDef GPIO_InitStructureUSART;
GPIO_InitTypeDef GPIO_InitStructureCAN_RX;
GPIO_InitTypeDef GPIO_InitStructureCAN_TX;
/* GPIO USART Configuration */
GPIO_InitStructureUSART.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
GPIO_InitStructureUSART.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructureUSART.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructureUSART.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructureUSART.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructureUSART);
/* Connect USART to AF */
GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_USART3); //USART_TX = PB10
GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_USART3); //USART_RX = PB11
/* GPIO CAN_RX Configuration */
GPIO_InitStructureCAN_RX.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructureCAN_RX.GPIO_Mode = GPIO_Mode_AF;
//GPIO_InitStructureCAN_TX.GPIO_OType = GPIO_OType_PP;
//GPIO_InitStructureCAN_TX.GPIO_PuPd = GPIO_PuPd_NOPULL;
//GPIO_InitStructureCAN_TX.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructureCAN_RX);
/* GPIO CAN_TX Configuration */
GPIO_InitStructureCAN_TX.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructureCAN_TX.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructureCAN_TX.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructureCAN_TX.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructureCAN_TX.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructureCAN_TX);
/* Connect CAN_RX & CAN_TX to AF9 */
GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_CAN2); //CAN_RX = PB12
GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_CAN2); //CAN_TX = PB13
}
void USART_Configuration(void) {
USART_InitTypeDef USART_InitStructure;
/* USART3 configuration */
/* 256000 baud, window 8 data bits, one stop bit, no parity, no hardware flow control, rx/tx enabled */
USART_InitStructure.USART_BaudRate = 256000;
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);
}
void CAN_Configuration(void) {
CAN_InitTypeDef CAN_InitStructure;
/* CAN2 reset */
CAN_DeInit(CAN2);
/* CAN2 configuration */
CAN_InitStructure.CAN_TTCM = DISABLE; // Time-triggered communication mode = DISABLED
CAN_InitStructure.CAN_ABOM = DISABLE; // Automatic bus-off management mode = DISABLED
CAN_InitStructure.CAN_AWUM = DISABLE; // Automatic wake-up mode = DISABLED
CAN_InitStructure.CAN_NART = DISABLE; // Non-automatic retransmission mode = DISABLED
CAN_InitStructure.CAN_RFLM = DISABLE; // Receive FIFO locked mode = DISABLED
CAN_InitStructure.CAN_TXFP = DISABLE; // Transmit FIFO priority = DISABLED
CAN_InitStructure.CAN_Mode = CAN_Mode_Silent_LoopBack; // Normal CAN mode
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; // Synchronization jump width = 1
CAN_InitStructure.CAN_BS1 = CAN_BS1_14tq; //14
CAN_InitStructure.CAN_BS2 = CAN_BS2_6tq; //6
CAN_InitStructure.CAN_Prescaler = 4; // Baudrate 500 kbps
//CAN_InitStructure.CAN_Prescaler = 16; // Baudrate 125 kbps
if (CAN_Init(CAN2, &CAN_InitStructure)) { // Initialize CAN
STM_EVAL_LEDInit(LED6); // Initialize and
STM_EVAL_LEDOn(LED6); // Turn ON blue LED if CAN initialization is successful
}
}
void CAN_FilterConfiguration(void) {
CAN_FilterInitTypeDef CAN_FilterInitStructure;
/* CAN2 filter configuration */
CAN_FilterInitStructure.CAN_FilterNumber = 0; // Filter number = 0 (0<=x<=13)
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; // Filter mode = identifier mask based filtering
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_16bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0300 << 5; //0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x03FF << 5;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0; // FIFO = 0
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
}
void CAN_TxMessage(void) {
CanTxMsg TxMessage;
/* CAN message to send */
TxMessage.StdId = 0x321;
TxMessage.ExtId = 0x01;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 8;
TxMessage.Data[0] = 0x04;
TxMessage.Data[1] = 0x01;
TxMessage.Data[2] = 0x00;
TxMessage.Data[3] = 0x00;
TxMessage.Data[4] = 0x00;
TxMessage.Data[5] = 0x00;
TxMessage.Data[6] = 0x00;
TxMessage.Data[7] = 0x00;
//while (1) {
CAN_TransmitStatus(CAN2, 0);
CAN_Transmit(CAN2, &TxMessage);
if(CAN_TransmitStatus(CAN2, 0)){
STM_EVAL_LEDInit(LED4); // Initialize and
STM_EVAL_LEDOn(LED4); // turn ON green LED if transmit was successful
}
//}
}
void CAN_OBDII_RequestCurrentData(int PIDNumber) {
CanTxMsg TxMessage;
TxMessage.StdId = 0x7DF; // PID request identifier
TxMessage.ExtId = 0x7DF;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 8;
TxMessage.Data[0] = 0x02; // Number of additional bytes = 2
TxMessage.Data[1] = 0x01; // Show current data = 1
TxMessage.Data[2] = PIDNumber; // PID code number
TxMessage.Data[3] = 0x00;
TxMessage.Data[4] = 0x00;
TxMessage.Data[5] = 0x00;
TxMessage.Data[6] = 0x00;
TxMessage.Data[7] = 0x00;
CAN_Transmit(CAN2, &TxMessage); // Transmit OBDII PID request via CAN2/mailbox0
}
void CAN_RxMessage(void) {
CanRxMsg RxMessage;
int d0=0;
while(1) {
CAN_Receive(CAN2,CAN_FIFO0,&RxMessage);
d0 = RxMessage.Data[0];
d0 = RxMessage.Data[1];
d0 = RxMessage.Data[2];
d0 = RxMessage.Data[3];
d0 = RxMessage.Data[4];
d0 = RxMessage.Data[5];
d0 = RxMessage.Data[6];
d0 = RxMessage.Data[7];
}
}
int main(void)
{
/* Initialize Clocks */
RCC_Configuration();
/* Initialize GPIO */
GPIO_Configuration();
/* Initialize USART */
USART_Configuration();
/* Initialize CAN */
CAN_Configuration();
/* Initialize CAN Reception Filter */
//CAN_FilterConfiguration();
/* Transfer CAN message */
CAN_TxMessage();
/* Receive CAN message */
CAN_RxMessage();
You have to configure filter to accept all messages (if you don't have any filter, no message will be accepted). But in your example you use CAN2, so FilterNumber must be 14 or higher.
#define CAN_FIFO_ID 0
#define CAN_FIFO CAN_FIFO0
#define CAN_FIFO_IN CAN_IT_FMP0
/**
* #brief Default filter - accept all to CAN_FIFO
*/
void CAN_SetFilter()
{
/* Default filter - accept all to CAN_FIFO*/
CAN_FilterInitTypeDef CAN_FilterInitStructure;
CAN_FilterInitStructure.CAN_FilterNumber = 14; // 0..13 for CAN1, 14..27 for CAN2
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_16bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO_ID;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
}
The number of filters assigned to CAN1 and CAN2 is defined in the CAN_FMR register which by default is set to 14 which is the start of the CAN2 filters.
This can be set to 28 which would mean no filters to CAN2 and all 28 to CAN1 or if set to 0 all 28 filters are assigned to CAN2.
Normally (if you have a valid Filter Number) in mask mode any mask = zero will let everything through.