This is my program for CAN transmit. I just want to see through the
oscilloscope wether something is being sent or not. I am using stm32f407
and attolic true studio for it, but i am unable to see any signal on my
tx pin. Kindly tell me where is my mistake. Do i need to connect the transciever externally and also how can i access CAN_H and CAN_L pins.
#include "stm32f4xx.h"
int main(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_ClocksTypeDef RCC_Clocks;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
CanTxMsg TxMessage;
RCC_GetClocksFreq(&RCC_Clocks);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);`
GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_CAN1);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_CAN1);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
CAN_DeInit(CAN1);
CAN_StructInit(&CAN_InitStructure);
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;
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_7tq;
CAN_InitStructure.CAN_Prescaler = 4;
CAN_Init(CAN1, &CAN_InitStructure);
CAN_FilterInitStructure.CAN_FilterNumber = 0;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
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_FIFO0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
// transmit */
TxMessage.StdId= 0x123;
TxMessage.ExtId= 0x00;
TxMessage.RTR= CAN_RTR_DATA;
TxMessage.IDE= CAN_ID_STD;
TxMessage.DLC= 4;
TxMessage.Data[0]= 0x02;
TxMessage.Data[1]= 0x11;
TxMessage.Data[2]=0x11;
TxMessage.Data[3]=0x11;
while(1)
{
volatile uint_t i;
unit8_t TransmitMailbox= 0;
//sprintf(TxMessage.Data, "Imran\n");
TransmitMailbox= CAN_Transmit(CAN1,&TxMessage);
i=0;
while((CAN_TransmitStatus(CAN1,TransmitMailbox) !=CANTXOK)&& (i !=0xFFFFFF))
{
i++;
}
}
}
Try to turn on the Automatic Wake Up by changing to the following line:
CAN_InitStructure.CAN_AWUM = ENABLE;
The stm32f407 has only the CAN Controller without the internal transciever, so you need to connect it externaly. Also you have to connect another device into your CAN Bus to see something (remember about the terminators).
Please explain what do you mean by saying that:
how can i access CAN_H and CAN_L pins
PS. You should not put each functionality into one routine because it is unreadable.
Related
I try to use the CAN bus on an STM32F303 discovery board, and I am using the PD0→RX and PD1→TX pins.
I want to try to send a message and analyse on the oscilloscope. So my configuration is seen below in the code blocks.
When I analyse with the oscilloscope which pins are PD0 and PD1, I can't see anything on the oscilloscope.
Where is my fault?
This is my code:
#include <stm32f30x.h>
#include <stm32f30x_i2c.h>
#include <stm32f30x_rcc.h>
#include <stm32f30x_syscfg.h>
#include <stm32f30x_exti.h>
// #include <stm32f30x_misc.h>
#include "main.h"
#include <stdio.h>
#include "common.h"
#include "io_periph_defs.h"
#include "stm32f30x.h"
#include <stdio.h>
#include "conf.h"
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
CanTxMsg TxMessage;
CanRxMsg RxMessage;
void Init_TxMes(CanTxMsg *TxMessage)
{
/* Transmit INITIALIZATION*/
TxMessage->IDE = CAN_ID_STD;
TxMessage->DLC = 2;
TxMessage->StdId = 0x321;
TxMessage->RTR = CAN_RTR_DATA;
}
void Init_RxMes(CanRxMsg *RxMessage)
{
uint8_t i = 0;
RxMessage->StdId = 0;
RxMessage->IDE = CAN_ID_STD;
RxMessage->DLC = 0;
RxMessage->FMI = 0;
for (i = 0; i < 8; i++)
{
RxMessage->Data[i] = 0;
}
}
void CAN_setup(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); //Enable the clock for CAN
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
/* Configure CAN1 RX pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* Configure CAN1 TX pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
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);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_9);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_9);
/* Enable the CAN global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = CAN1_SCE_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX1_IRQn;
NVIC_Init(&NVIC_InitStructure);
CAN_DeInit(CAN1);
/* Configure CAN1 **************************************************/
/* Struct init*/
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;
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
/* CAN Baudrate = 125kbps (CAN clocked at 36 MHz) */
CAN_InitStructure.CAN_BS1 = CAN_BS1_9tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
CAN_InitStructure.CAN_Prescaler = 16;
CAN_Init(CAN1, &CAN_InitStructure);
/* CAN filter init */
CAN_FilterInitStructure.CAN_FilterNumber = 0;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
}
int main(void)
{
int i;
uint8_t TransmitMailbox = 0;
CAN_setup(); // Set up CAN interface
Init_TxMes(&TxMessage);
init_pin(GPIOA, GPIO_Pin_8, GPIO_Mode_OUT, GPIO_Speed_50MHz, GPIO_OType_PP, GPIO_PuPd_UP);
while (1)
{
TxMessage.Data[0] = 0xAA;
GPIO_SetBits(GPIOA, GPIO_Pin_8); // Transmit data
TransmitMailbox = CAN_Transmit(CAN1, &TxMessage);
i = 0;
while ((CAN_TransmitStatus(CAN1, TransmitMailbox) != CANTXOK))
; // I put a breakpoint here to check
// and found the message is pending.
GPIO_ResetBits(GPIOA, GPIO_Pin_8); // Transmit data
//i++;
}
}
I think there is the problem, but how can I solve it?
Stacking in loop.
while ((CAN_TransmitStatus(CAN1, TransmitMailbox) != CANTXOK)
I try to send data with SPI using DMA channel. When I send without DMA everything is OK, but with DMA sth is wrong. When I debug my program SPI DR register is always 0. I would like to use dma circular mode to send my array all the time. There is my code
GPIO INIT:
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(SPI_PERIPH_CLOCK, ENABLE);
RCC_AHBPeriphClockCmd(GPIO_PERIPH_CLOCK, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
GPIO_PinAFConfig(GPIOB, AF_PIN_SOURCE, GPIO_AF);
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
SPI INIT
SPI_I2S_DeInit(SPI1);
SPI_InitTypeDef SPI_InitStructure;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
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_32;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
SPI_Cmd(SPI1, ENABLE);
DMA INIT:
DMA_InitTypeDef dma;
DMA_DeInit(DMA1_Channel1);
DMA_StructInit(&dma);
dma.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DR;
dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
dma.DMA_MemoryBaseAddr = (uint32_t)spi_tx_buffer;
dma.DMA_MemoryInc = DMA_MemoryInc_Enable;
dma.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
dma.DMA_DIR = DMA_DIR_PeripheralDST;
dma.DMA_BufferSize = BUFFERSIZE;
dma.DMA_Mode = DMA_Mode_Circular;
dma.DMA_M2M = DMA_M2M_Disable;
DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 6;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
DMA_Init(DMA1_Channel1, &dma);
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);
DMA_Cmd(DMA1_Channel1, ENABLE);
simple main
int main(void) {
periph_init();
while (1) {
for(int j=0; j<10000000; j++){
j++;
j--;
}
}
return 0;
}
What I'm doing wrong?
As I mentioned in comments, your SPI has no connection with DMA1_Channel1. According to this data sheet, you should use DMA1_Channel3.
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 am working on the timer of STM32. I need two pulses like in the picture.
Frequency of CLK is 50 kHz and frequency of SI is 381.67 Hz. I need the SI to go low before the rising edge of next clock pulse but in the logic analyzer of Keil I saw the SI was in a different position relatively to CLK for each pulse, like shown on below picture. How can I fix it?
void Init_TIMER(void)
{
TIM_TimeBaseInitTypeDef TIM_BaseInitStructure2, TIM_BaseInitStructure3, TIM_BaseInitStructure4;
TIM_OCInitTypeDef TIM_OCInitStructure2, TIM_OCInitStructure3;
TIM_DeInit(TIM2);
TIM_DeInit(TIM3);
TIM_DeInit(TIM4);
TIM_InternalClockConfig(TIM2);
TIM_InternalClockConfig(TIM3);
TIM_InternalClockConfig(TIM4);
/************************************************/
/********TIMER2**********************************/
/************************************************/
TIM_BaseInitStructure2.TIM_Period = 180; //180/9000000=..ms 50KHZ
TIM_BaseInitStructure2.TIM_Prescaler = 7; //SYSCLK=72M, TIM1_CLK=72/8=9MHz
TIM_BaseInitStructure2.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_BaseInitStructure2.TIM_CounterMode = TIM_CounterMode_Up;
//TIM_BaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, & TIM_BaseInitStructure2);
TIM_ClearFlag(TIM2, TIM_FLAG_Update);
TIM_OCInitStructure2.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure2.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure2.TIM_Pulse = 90;
TIM_OCInitStructure2.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OC2Init(TIM2, & TIM_OCInitStructure2);
TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);
/*****************************************************/
/********TIMER3***************************************/
/*****************************************************/
TIM_BaseInitStructure3.TIM_Period = 23580; //23580/9000000=... ms 381.67HZ 50KHZ/131=381.67HZ
TIM_BaseInitStructure3.TIM_Prescaler = 7; //SYSCLK=72M, TIM1_CLK=72/8=9MHz
TIM_BaseInitStructure3.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_BaseInitStructure3.TIM_CounterMode = TIM_CounterMode_Up;
//TIM_BaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM3, & TIM_BaseInitStructure3);
TIM_ClearFlag(TIM3, TIM_FLAG_Update);
TIM_OCInitStructure3.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure3.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure3.TIM_Pulse = 50;
TIM_OCInitStructure3.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC2Init(TIM3, & TIM_OCInitStructure3);
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
/********************************************************/
/********TIMER4 to make sampling frequency **************/
/*******************************************************/
TIM_BaseInitStructure4.TIM_Period = 90; //90/9000000=0.01ms 100KHZ
TIM_BaseInitStructure4.TIM_Prescaler = 7; //SYSCLK=72M, TIM1_CLK=72/8=9MHz
TIM_BaseInitStructure4.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_BaseInitStructure4.TIM_CounterMode = TIM_CounterMode_Up;
//TIM_BaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM4, & TIM_BaseInitStructure4);
TIM_ARRPreloadConfig(TIM4, DISABLE);
TIM_ClearFlag(TIM4, TIM_FLAG_Update);
/**********************************************/
TIM_ARRPreloadConfig(TIM2, ENABLE);
TIM_Cmd(TIM2, ENABLE);
TIM_ARRPreloadConfig(TIM3, ENABLE);
TIM_Cmd(TIM3, ENABLE);
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM4, ENABLE);
}
void GPIO_Configuration()
{
GPIO_InitTypeDef GPIO_InitStructure;
/*PA1 TIM2_CH2*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, & GPIO_InitStructure);
/*PA7 TIM3_CH2*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, & GPIO_InitStructure);
}
I had similar project where I had used taos TSL1402R matrix.
Instead of timer I used an SPI with circular DMA.
DMA buffer was 0x0, 0x0.....0x0, 0x1.
SI was connected to SPI MISO,
And CLK was connected to SPI_CLK.
Hope this will help.
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.