Ура! Заработала передача данных по КАНУ, правда с использованием Периф драйвера.
Выкладываю код. Кому может пригодится. Для STM32F042F4P6 с кварцем 8 МГЦ и тактовой
частотой самого процессора 48 МГц. На ножках PA10 – TX, PA9 – RX;
Инициализация КАНА: { GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; CAN_InitTypeDef CAN_InitStructure; /*Конфигурация ножек RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; // Тактирования SYSCONFIG SYSCFG->CFGR1 |= SYSCFG_CFGR1_PA11_PA12_RMP; // Ремап ножек PA10 PA9 на PA12 PA11
/CAN Интерфейс на 4 альтернативной функции/ GPIO_PinAFConfig(CAN_GPIO_PORT, CAN_RX_SOURCE, CAN_AF_PORT); GPIO_PinAFConfig(CAN_GPIO_PORT, CAN_TX_SOURCE, CAN_AF_PORT); /* Конфигурация CAN RX и TX */ GPIO_InitStructure.GPIO_Pin = CAN_RX_PIN | CAN_TX_PIN; 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(CAN_GPIO_PORT, &GPIO_InitStructure);
/* CAN NVIC Конфигурация **************************************************/ NVIC_InitStructure.NVIC_IRQChannel = CEC_CAN_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* CAN configuration ********************************************************/ /* Enable CAN clock */ RCC_APB1PeriphClockCmd(CAN_CLK, ENABLE); /* CAN register init */ CAN_DeInit(CANx); 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 = ENABLE; CAN_InitStructure.CAN_TXFP = ENABLE; CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_4tq; //Необходимые предделители CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq; // Необходимые предделители CAN_InitStructure.CAN_Prescaler = 5; //Необходимые предделители CAN_Init(CANx, &CAN_InitStructure);
/* Конфигурация фильтров */ CAN_FilterInitStructure.CAN_FilterNumber = 0; CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdList; 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); /* Transmit Structure preparation */ TxMessage.StdId =200; TxMessage.ExtId = 1998; TxMessage.RTR = CAN_RTR_DATA; TxMessage.IDE = CAN_ID_STD; TxMessage.DLC = 1; /* Enable FIFO 0 full Interrupt */ CAN_ITConfig(CANx, CAN_IT_FF0, ENABLE); /* Enable FIFO 1 full Interrupt */ CAN_ITConfig(CANx, CAN_IT_FF1, ENABLE);
Дефайны в шапке программы:
#define CAN_GPIO_CLK RCC_AHBPeriph_GPIOA #define CAN_GPIO_PORT GPIOA #define CAN_RX_SOURCE GPIO_PinSource11 #define CAN_TX_SOURCE GPIO_PinSource12 #define CAN_AF_PORT GPIO_AF_4 #define CAN_RX_PIN GPIO_Pin_11 #define CAN_TX_PIN GPIO_Pin_12 #define CAN_CLK RCC_APB1Periph_CAN #define CANx CAN uint8_t TxMessages[6] = { 0, 1, 2, 3, 4, 5 }; uint8_t
CAN_DATA0,CAN_DATA1,CAN_DATA2,CAN_DATA3,CAN_DATA4,CAN_DATA5,CAN_DATA6,CAN_DATA7; uint8_t CanFlag,Display;
Ну и передача данных: void transmitt(void) {
TxMessage.StdId = 14; TxMessage.RTR = CAN_RTR_DATA; TxMessage.IDE = CAN_ID_STD; TxMessage.DLC = 8; TxMessage.Data[0] = 'P'; TxMessage.Data[1] = 'R'; TxMessage.Data[2] = 'E'; TxMessage.Data[3] = 'V'; TxMessage.Data[4] = 'E'; TxMessage.Data[5] = 'D'; TxMessage.Data[6] = '!'; TxMessage.Data[7] = ' '; CAN_Transmit(CANx,&TxMessage); }
Передачу данных осуществлял на плату OPEN103V. К ней уже шли готовые примеры. На
плате OPEN103V Прекрасно работает и передача и прерывание по приему данных. Вот у
меня осталась главная проблема как сейчас на моем stm32f042 организовать прием. Функция void CEC_CAN_IRQHandler (void) { LED_1_RED(1); } я так понимаю должна срабатывать по приему любого символа но светодиод не
загорается, стало быть прерывание по приему не срабатывает. В чем может быть ошибка.
Может я опять где что забыл объявить, ну вроде в NVIC прерывание по приему и так
назначено. Что может быть не так ???
|