STM32F103VCT6 ile can bus çalıştırmaya uğraşıyorum.
HAL kütüphanesi fonksiyonları ile bir türlü çalıştıramadım.
Bulduğum örnek bir kod ile veri alıp vermeyi çalıştırdım.
Projeyi cubemx ile oluşturdum. interrupt ı açtım. cube mx can bus ı şu şekilde init etti.
static void MX_CAN_Init(void)
{
hcan.Instance = CAN1;
hcan.Init.Prescaler = 16;
hcan.Init.Mode = CAN_MODE_NORMAL;
hcan.Init.SJW = CAN_SJW_1TQ;
hcan.Init.BS1 = CAN_BS1_3TQ;
hcan.Init.BS2 = CAN_BS2_5TQ;
hcan.Init.TTCM = DISABLE;
hcan.Init.ABOM = DISABLE;
hcan.Init.AWUM = DISABLE;
hcan.Init.NART = DISABLE;
hcan.Init.RFLM = DISABLE;
hcan.Init.TXFP = DISABLE;
if (HAL_CAN_Init(&hcan) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
filtre ayarları şu şekilde
CAN1->sTxMailBox[0].TIR = 0;
CAN1->sTxMailBox[0].TIR = 0x245<<21;
CAN1->sTxMailBox[0].TDHR = 0;
CAN1->sTxMailBox[0].TDTR = 1;
CAN1->FMR |= 1<<0;
CAN1->FMR |= 13<<8;
CAN1->FS1R |= 1<<13;
CAN1->sFilterRegister[13].FR1 = 0x245<<21;
CAN1->FM1R |= 1<<13;
CAN1->FA1R |= 1<<13;
CAN1->FMR &= ~(1<<0);
alma ve gönderme fonksiyonları
void CAN1_Tx(uint8_t data)
{
CAN1->sTxMailBox[0].TDLR = data;
CAN1->sTxMailBox[0].TIR |= 1;
}
uint8_t CAN1_Rx(void)
{
while(!(CAN1->RF0R&3));
uint8_t RxD = (CAN1->sFIFOMailBox[0].RDLR)&0xFF;
CAN1->RF0R |= 1<<5;
return RxD;
}
while döngüsü içerisinde aşağıdaki şekilde veri alıp gönderebiliyorum.
tus_oku();
if(enter==1)
{
i++;
while(enter==1){tus_oku();}
CAN1_Tx(i);
rx_data=CAN1_Rx();
}
veri alma işini interruptla yapmak istiyorum. ancak veri geldiğinde interrupt rutininine hiç girmiyor.
Neresi eksik acaba?
hocam Cube Mx'den oluşturduğun projede receive interrupt'ı bir kere çağırman gerekiyor. Örnek
HAL_CAN_Receive_IT(&hcan1,CAN_FIFO0);
ardından stm32_hal_can.h header'ından callback fonksiyonunu main.c dosyasında aşağıdaki gibi tanımlarsan oradan kesmeye gidebilirsin.
void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* CanHandle
{
HAL_CAN_Receive_IT(&hcan1,CAN_FIFO0);
}
Not: bende çok bilmiyorum fakat 2 hafta önce bu şekilde çalıştırmıştım
Kodlar içerisinde kesmeyi aktif ettiğin kısım yok sanırım
Kesmeyi ayrıya aktif etmedim. Sadece cubemx den CAN Rx1 interrupt ı seçtim.
NVIC global kesmeyi aktif etmeniz lazım ve main de tanımlanması gereken rx kesmesini enable yapan kod gerekli onuda can kütüphanesinde bulabilirsiniz yanlış hatırlamıyorsam
static void MX_NVIC_Init(void)
{
/* CAN1_RX1_IRQn interrupt configuration */
HAL_NVIC_SetPriority(CAN1_RX1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn);
}
Kesmeyi aktif eden fonksiyonlar bunlar değil mi hocam.
Diğer kesmelerim çalışıyor.
stm32f1xx_it.c içindeki kesme fonksiyonum da bu ama bunun içine hiçbir zaman girmiyor.
void CAN1_RX1_IRQHandler(void)
{
/* USER CODE BEGIN CAN1_RX1_IRQn 0 */
/* USER CODE END CAN1_RX1_IRQn 0 */
HAL_CAN_IRQHandler(&hcan);
/* USER CODE BEGIN CAN1_RX1_IRQn 1 */
HAL_CAN_Receive_IT(&hcan,CAN_FIFO0);
while(1)
{
HAL_GPIO_WritePin(cpu_led_GPIO_Port,cpu_led_Pin,GPIO_PIN_SET);
}
// sprintf(gosterilecek,"%d",hcan.pRxMsg->Data[0]);
/* USER CODE END CAN1_RX1_IRQn 1 */
}
Problemi buldum.
Cube Mx de projeyi oluştururken
CAN RX1 Interrupt ı seçiyordum.
Usb low priority or RX0 Interrupt ı seçince direkt kesme çalıştı.
İlgilenen arkadaşlara çok teşekkür ederim.
Selam
Bende stm32f103c8t6 ile can haberleşmesi gerçekleştirmek istiyorum.
Bir türlü başaramadım. stm32cubex ve keil mdk arm programlarını kullanıyorum.
Yardımcı olursanız sevinirim.