Bitirme ödevine kaldığım yerden devam ediyorum fakat hatada kaldığı yerden devam ediyor :)
STM32F103C8T6 işlemci ile MCP2551 kullanıyorum fakat CANBus'dan bir türlü veri gönderemiyorum.
CANTX ve CANRX 10K ile Pull-UP(5V)
MCP2551 5V bağlı.
RS pini GND bağlı.
Logic Analyzer ile ölçümlerde hiç bir şey göremiyorum fakat pic ile yaptığımda gayet güzel çalışıyor.
Kod
#include "stm32f10x_conf.h"
#define GPIO_ToggleBit(GPIOx, GPIO_Pin) (GPIOx->ODR ^= 1 << GPIO_Pin)
static void Clock_Config(void);
static void RCC_Config(void);
static void GPIO_Config(void);
static void CAN_Config(void);
static void Delay_ms(uint32_t miliSecond);
CanTxMsg TxMessage;
CanRxMsg RxMessage;
uint32_t systickCounter = 0;
uint32_t systickControl = 0;
int main(void)
{
Clock_Config();
RCC_Config();
GPIO_Config();
CAN_Config();
TxMessage.StdId = 0x7E5;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 8;
TxMessage.Data[0] = 0xFF;
TxMessage.Data[1] = 0xFF;
TxMessage.Data[2] = 0xFF;
TxMessage.Data[3] = 0xFF;
TxMessage.Data[4] = 0xAA;
TxMessage.Data[5] = 0xBB;
TxMessage.Data[6] = 0xCB;
TxMessage.Data[7] = 0x24;
for(;;)
{
CAN_Transmit(CAN1, &TxMessage);
GPIO_ToggleBit(GPIOC, 13);
Delay_ms(1000);
}
}
static void Clock_Config(void)
{
/* Error Status Definition */
ErrorStatus HSEStartUpStatus;
/* RCC system reset(for debug purpose) */
RCC_DeInit();
/* Enable HSE */
RCC_HSEConfig(RCC_HSE_ON);
/* Wait till HSE is ready */
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if(HSEStartUpStatus == SUCCESS)
{
/* Enable Prefetch Buffer */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
/* Flash 2 wait state */
FLASH_SetLatency(FLASH_Latency_2);
/* HCLK = SYSCLK */
RCC_HCLKConfig(RCC_SYSCLK_Div1);
/* PCLK2 = HCLK */
RCC_PCLK2Config(RCC_HCLK_Div1);
/* PCLK1 = HCLK/2 */
RCC_PCLK1Config(RCC_HCLK_Div2);
/* PLLCLK = 8MHz * 9 = 72 MHz */
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
/* Enable PLL */
RCC_PLLCmd(ENABLE);
/* Wait till PLL is ready */
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
/* Select PLL as system clock source */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
/* Wait till PLL is used as system clock source */
while(RCC_GetSYSCLKSource() != 0x08);
}
/*****************************************/
/** SystemFrequency / 1000 1ms */
/** SystemFrequency / 100000 10us */
/** SystemFrequency / 1000000 1us */
/*****************************************/
while (SysTick_Config(SystemCoreClock / 1000) != 0);
}
static void RCC_Config(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
}
static void GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
static void CAN_Config(void)
{
/**
* CAN Baudrate = 200 kBit/s
* Bit Rate = (CanBus Freq = APB1) / (Prescaler * (BS1 + BS2 + SJW))
* SJW must be 1
* 36 MHz / (18 * (5 + 4 + 1))
* 200 kBit/s
**/
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
CAN_DeInit(CAN1);
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 = ENABLE;
CAN_InitStructure.CAN_RFLM = DISABLE;
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_5tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_4tq;
CAN_InitStructure.CAN_Prescaler = 18;
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 = 0;
CAN_FilterInitStructure.CAN_FilterIdLow = 0;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0xFF;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0xFF;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/** CAN1 RX **/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/** CAN1 TX **/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/**
* GPIO_Remap1_CAN1 PINS : PB8 CanRx, PB9 CanTx
* GPIO_Remap2_CAN1 PINS : PD0 CanRx, PD1 CanTx
*/
GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);
}
static void Delay_ms(uint32_t miliSecond)
{
systickCounter = miliSecond;
while (systickControl != 1);
systickControl = 0;
}
void USB_LP_CAN1_RX0_IRQHandler(void)
{
if(CAN_GetITStatus(CAN1, CAN_IT_FMP0) != RESET)
{
CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
if ((RxMessage.IDE == CAN_ID_STD) && (RxMessage.StdId == 0) && (RxMessage.DLC == 8))
{
}
}
CAN_ClearITPendingBit(CAN1, CAN_IT_FMP0);
}
void SysTick_Handler(void)
{
if (systickCounter != 0)
systickCounter--;
else
systickControl = 1;
}
Not : Biraz LoopBack moduna aldığımda canbus çalışıyor. Hemde CanTx pinini gözlemlediğimde Analyzer ile verileri görebiliyorum. Ama CANH veya CANL pinlerinde bir şey göremiyorum.
3v3 konusu olabilir mi
Olabilir hocam sanırım MCP2551 3V3 ile uyumlu değil.
ISO1050 veya SN65HVD232 gibi bir transceiver ile deneme yapacağım artık.
MCP2551 VCC 4.5 ile 5.5V demiş. 3.3V ile besliyorsan problem olabilir
Hocam VCC'sini 5V ile besledim.
CANL-H arasında 120r var mı?
100Ohm var hocam :)
Karşılığında alan bir alıcı olmayınca hataya düşüyor. Hata flaglarini inceledinizmi?
Hocam hangi flagleri kastediyorsunuz ? Karşısına aynı Baud'da pic alıcı ekledim fakat aynı.
aynı baudu ayarlabildiğinize eminmisiniz? çünkü yolladığınız datayı karşıdan 1 alıcı almassa ya surekli yollar yada transmit errora geçer
@skara1214 Hocam kontrol ettim ayni baudda haberlesmeye calisiyorum.
Hata flaglarinin hangisi bumu belirtiyor ?
Bu arafa daha once mcp 2551 stm ile kullandiniz mi ? Galiba 3.3-5V uyumsuzlugundan kaynaklaniyor
MCP yi pic ile kullandım stm ile kullanmadım hiç ama sıkıntı çıkacağını zannetmiyorum
Mcp2551'i 5V ile beslediysen hiçbir sıkıntı çıkmaz, çok sayıda kullanıldı, teknik açıklamasıda, stm32 can pinleri 5V toleranslı ve ttl uyumludur, 2551 girişleride ttl girişli/çıkışlıdır yani kısacası çalışır.
baudda emin değilsen, 2 tane mcp2551 +stm32 ile testini yapabilirsin, 2. mcp2551'in rx pinini tx pine kısa devre edersen, stm32 ne gönderirse, kendisinede o dönecektirr.
@CLR Hocam dediğiniz gibi yaptım fakat durum aynı.
STM32+MCP2551 karşısına sadece MCP2551 bağlayıp bu entegrenin TXD ve RXD kısa devre ediyorum fakat hiç bir veri gidip gelmiyor.
Şöyle bir kod ile test ettiğimde while döngüsüde takılıyor yani gönderme nedense başarısız oluyor. Kafam iyice karıştı. Ben nerede hata yapıyorum bir türlü bulamadım.
CAN_Transmit(CAN1, &TxMessage);
while ((CAN_TransmitStatus(CAN1, 0) != CANTXOK));
LED_On();
Delay_ms(1000);
@CLR ve
@baran123 hocam loopback mode çalışıyor fakat mcp takınca hattan veri göremiyoruz. Logic ile kontrol ediyoruz.
bende bu kodlar çalıştı
/* CAN register init */
CAN_Initialize(void){
CAN_DeInit(CAN1);
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=ENABLE;
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_3tq;
CAN_InitStructure.CAN_BS2=CAN_BS2_5tq;
CAN_InitStructure.CAN_Prescaler=4;
RAM[PARAMETERS+142*2]=CAN_Init(CAN1, &CAN_InitStructure);
/* CAN filter init */
CAN_FilterInitStructure.CAN_FilterNumber=0;
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList;
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh=(0x00001234L<<3)&0xffff0000L;
CAN_FilterInitStructure.CAN_FilterIdLow=((0x00001234L<<3)|0x4)&0x0000ffffL;
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);
/* CAN FIFO0 message pending interrupt enable */ CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
return ;
}
void USB_LP_CAN_RX0_IRQHandler(void)
{
CanRxMsg RxMessage;
RxMessage.StdId=0x00;
RxMessage.ExtId=0x00;
RxMessage.IDE=0;
RxMessage.DLC=0;
RxMessage.FMI=0;
RxMessage.Data[0]=0x00;
RxMessage.Data[1]=0x00;
while(CAN_MessagePending(CAN1, CAN_FIFO0)){
CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);}
RAM[PARAMETERS+140*2]=RxMessage.Data[1];
}
@magnetron verdiğin kodlar sadece alıcı kısmı.
Ben veri gönderme yapamıyorum bir türlü.
Demin loopback moda alıp cantx gözlemledim. ayarladığım baudrate'de veriyi görebiliyorum.Ama verinin sonunda NAK ifadesi mevcut. Bu ne anlama geliyor ?
(http://i.hizliresim.com/YDZ2Xz.png)
stm tx pininde hareket yoksa kurulum hatası vardır mesela remap gerektiren gpioya bağlamış olabilirsin yani kısacası görmek lazım, eklersen kodları inceleyebilirim
Hocam init kodları ektedir.
void main (void)
{
Clock_Config();
RCC_Config();
GPIO_Config();
CAN_Config();
TxMessage.StdId = 0;
TxMessage.ExtId = 0;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 2;
TxMessage.Data[0] = 'A';
TxMessage.Data[1] = 'B';
LED_Off();
for(;;)
{
CAN_Transmit(CAN1, &TxMessage);
while ((CAN_TransmitStatus(CAN1, 0) != CANTXOK));
Delay_ms(500);
}
}
static void RCC_Config(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
}
static void GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_DeInit(GPIOA);
GPIO_DeInit(GPIOB);
GPIO_DeInit(GPIOC);
GPIO_StructInit(&GPIO_InitStructure);
/** ADC Pins **/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/** CAN1 RX **/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/** CAN1 TX **/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/** LED Pin **/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/**
* GPIO_Remap1_CAN1 PINS : PB8 CanRx, PB9 CanTx
* GPIO_Remap2_CAN1 PINS : PD0 CanRx, PD1 CanTx
*/
GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);
}
static void CAN_Config(void)
{
/**
* CAN Baudrate = 200 kBit/s
* Bit Rate = (CanBus Freq = APB1) / (Prescaler * (SJW + BS1 + BS2)
* SJW must be 1
* 36 MHz / (9 * (1 + 11 + 8))
* 200 kBit/s
**/
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
CAN_DeInit(CAN1);
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_InitStructure.CAN_BS1 = CAN_BS1_11tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
CAN_InitStructure.CAN_Prescaler = 9;
canInitStatus = 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 = 0;
CAN_FilterInitStructure.CAN_FilterIdLow = 0;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0xFF;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0xFF;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
Açıkçası buraya yapıştırdığın kodlarda bir sıkıntı yok gibi ama hatanın yerini şöyle bulabilirsin,
1) Öncelikle TX pininden logic analyzer ile bir sinyal okumadığın için sorunun MCP2551 kaynaklı değil
2) Can tx pinine bağlı pull-up'ı sök
3) Can modulü init kısmını kontrol et (canInitStatus == CAN_InitStatus_Success olmalı)
canInitStatus = CAN_Init(CAN1, &CAN_InitStructure);
if(canInitStatus != CAN_InitStatus_Success) //
// fail
Burası fail ( CAN_InitStatus_Failed ) ise can init kısmında gözden kaçan bir hata vardır.
4) Ok ise, tx kısmını kontrol et, CAN_TxStatus_Ok dönmeli
TxMailBox = CAN_Transmit(CAN1, &TxMessage);
while ((CAN_TransmitStatus(CAN1, TxMailBox) != CAN_TxStatus_Ok) && (TimeOut != 0)) {
TimeOut--;
}
Bu şekilde çözebiliyor olmalısın.
@CLR Hocam pull up söktüm ve init kontrolünü yaptım başarılı gözüküyor. STM32+MCP karşıda sadece MCP2551(TX RX kısa devre)
Tx kısmını kontrol ettiğimde while döngüsünde takılıyor yani nedense veri gitmiyor.
while ((CAN_TransmitStatus(CAN1, TxMailBox) != CAN_TxStatus_Ok));
Can init ok olup, loopback'te çalışıp normal modda çalışmaması garip bir durum.
Can portlarını ve remap'i değiştirip/düzenleyip başka bir gpio'da dener misin?
@CLR Hocam işlemcide başka bir pine CANTX-RX atayamam kullandığım işlemcide böyle bir seçenek yok. Büyük pinli modellerde var :/
Olmaz olurmu, sen remap yapmışsın zaten, remap'in amacı asıl pinlerin yerine 2ncil pinleri kullanmak, yani remap varsa başka pinlerde vardır. pa11-pa12 kullanabilirsin.
@CLR Hocam ben onu görmedim kusura bakmayın. Fakat o pinlerde USB ye denk geliyor. Fakat yinede denedim ama sonuç aynı.
Bu arada remap'ı nasıl yapmam lazım ?
GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);
şeklindemi ?
iki türlüde yaptım fakat olmadı ama loopback moda alınca led yandı yani loopback çalışıyor
int main(void)
{
Clock_Config();
RCC_Config();
GPIO_Config();
CAN_Config();
//ADC_Config();
//DMA_Config();
TxMessage.StdId = 0;
TxMessage.ExtId = 0;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 2;
TxMessage.Data[0] = 'A';
TxMessage.Data[1] = 'B';
LED_Off();
/*ADC_SoftwareStartConvCmd(ADC1, ENABLE);
while (!status);
ADC_SoftwareStartConvCmd(ADC1, DISABLE);*/
for(;;)
{
TxMailBox = CAN_Transmit(CAN1, &TxMessage);
while ((CAN_TransmitStatus(CAN1, TxMailBox) != CAN_TxStatus_Ok));
LED_On();
Delay_ms(500);
}
}
static void RCC_Config(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
}
static void GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_DeInit(GPIOA);
GPIO_DeInit(GPIOB);
GPIO_DeInit(GPIOC);
GPIO_StructInit(&GPIO_InitStructure);
/** ADC Pins **/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/** ADC Pins **/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// /** CAN RX **/
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
// GPIO_Init(GPIOB, &GPIO_InitStructure);
//
// /** CAN TX **/
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
// GPIO_Init(GPIOB, &GPIO_InitStructure);
/** CAN RX **/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/** CAN TX **/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/** LED Pin **/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/** LED Pin **/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/**
* GPIO_Remap1_CAN1 PINS : PB8 CanRx, PB9 CanTx
* GPIO_Remap2_CAN1 PINS : PD0 CanRx, PD1 CanTx
*/
GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);
}
static void CAN_Config(void)
{
/**
* CAN Baudrate = 200 kBit/s
* Bit Rate = (CanBus Freq = APB1) / (Prescaler * (SJW + BS1 + BS2)
* SJW must be 1
* 36 MHz / (9 * (1 + 11 + 8))
* 200 kBit/s
**/
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
CAN_DeInit(CAN1);
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_InitStructure.CAN_BS1 = CAN_BS1_11tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
CAN_InitStructure.CAN_Prescaler = 9;
canInitStatus = 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 = 0;
CAN_FilterInitStructure.CAN_FilterIdLow = 0;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0xFF;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0xFF;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
Led ile test yapıyorsan canbus testini anlayamazsın, can modulü init olmuşsa mutlaka tx yapar, senin init fonksiyonun bir kez data gönderiyor, başarısız olursa tekrar tekrar göndermiyor yani datayı ancak lojik analyzer ile görebilirsin pa11 ve pa12 içinse remap fonksiyonunu hiç kullanmaman lazım yani onu kapat ve pinleri ayarla ve derle
@CLR Hocam o satırı aldırdım ve A portunda logicde veriler gözüküyor ama loopbackde normal moda aldım bus da hiçbir şey yok.
Kafayı sıyırıcam :)
Neyse bundan sonrası sana ait, testte vs bir yerlerde hata yapıyorsundur, stm32f103c8t6 ile mcp2551'i 2008'de bir cihaz yaparken kullandım, sorunsuz çalışıyor.
@CLR hocam bu konuda bizimle en azından yapmış olduğunuz cihazınızda bulunan can bus modulunun init , transmit ve receive kısmından paylaşım yapabilir misiniz ? En azından karşılaştırıp hatanın nerede olduğuna karar veririz.
ST'nin sample projelerindeki kod kesinlikle çalışıyordur ama yinede benim yazdığım kısımdan kısmen paylaşayım.
2008'deki aşağıdaki gibi kendi yazdığım bir ST library, muhtemelen işinizi görmez çünkü her şey bit bazında yapılıyor, register düzeyinde programlama yapabiliyor olmanız lazım.
void
Can_Setup(u8 can_mode){
u16 over_time=0xFFFF;
can_reset(); // can ayarları reset
can_enable(); // can modulu enable
// PB8 ve PB9 kullanılacak, remap yapacağız, AFIOEN enable olmalı,
afio_enable();
afio_mapr.bits.CAN_REMAP=0x2; // remap, PB8(RX),PB9(TX) : can için kullanılacak
// afio_mapr.bits.CAN_REMAP=0x0; // default durum zaten, remapsiz, PA11,PA12: can için kullanılacak
// afio_mapr.bits.CAN_REMAP=0x3; // remap, PD0(RX),PD1(TX): can için kullanılacak
// GPIOB enable olmalı, port setupta enable edilmişti
// gpiob_enable();
gpiob_crh.bits.MODE8=GpioMODE_input; // input
gpiob_crh.bits.CNF8=GpioCNF_PUPD_in_APP_out; // pull-up/pulldown input,
gpiob_crh.bits.MODE9=GpioMODE_50mhz_out; // 50mhz out
gpiob_crh.bits.CNF9=GpioCNF_PUPD_in_APP_out; // Alternate push-pull,
// gpiob_odr.bits.ODR8=0; // pull-down
// gpiob_odr.bits.ODR8=1; // pull-up
// sleep modundan çıkılmadıkça sleep bit clear edilemiyor
can_mcr.bits.SLEEP=0;
// can init isteği
can_mcr.bits.INRQ=1;
can_mcr.bits.NART=1; // yeniden otomatik gönderme devre dışı
// init ok mi?
Can_Flags.InitFail=0;
while(!can_msr.bits.INAK){ // 0 iken bekle
if(over_time==0){
Can_Flags.InitFail=1; // hata var
break;
}
over_time--;
}
// 28Mhz'de bitrate 250Kbps
can_btr.bits.SJW=2;
can_btr.bits.TS1=8;
can_btr.bits.TS2=3;
can_btr.bits.BRP=7;
// can modunu ayarla
switch(can_mode&0x3) {
case NormalMode: can_btr.bits.SILM=0; can_btr.bits.LBKM=0; break; // Normal mod
case LoopbackMode: can_btr.bits.SILM=0; can_btr.bits.LBKM=1; break; // loopback mod
case SilentMode: can_btr.bits.SILM=1; can_btr.bits.LBKM=0; break; // silent mod
case TestMode: can_btr.bits.SILM=1; can_btr.bits.LBKM=1; break; // test mod (loop and silent
}
/*
can_mcr.bits.INRQ=0;
over_time=0xFFFF;
while(can_msr.bits.INAK){ // 1 iken bekle
if(over_time==0){
Can_Flags.InitFail=1; // Initial gerçekleşmediyse hata var
break;
}
over_time--;
}
*/
// sadece fifo0'ı kullanacağız dolayısıyla sadece transmit mailbox 0 kullanılacak
can_ier.bits.TMEIE=1; // Transmit mailbox boş olduğunda interrupt oluşsun
can_ier.bits.FMPIE0=1; // fifo0'a mesaj geldiğinde interrupt oluşsun
usbhp_cantx_int_set(pri_2); // 2. öncelikli can tx enable
usb_lp_can_rx0_int_set(pri_1); // 1. öncelikli can rx, data alımı önemli
}
Standart ST lib içeren bir projemden bir paylaşım yapayım. Bu şekilde TX yapabiliyor olmanız lazım
void CAN_GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure CAN pin: RX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure CAN pin: TX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void CAN_NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
// Enable CAN1 RX0 interrupt IRQ channel
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void CAN_Configuration(void)
{
CAN_InitTypeDef CAN_InitStructure;
/* CAN Periph clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
CAN_NVIC_Configuration(); // Can interrupt
CAN_GPIO_Configuration(); // Gpio settings ok
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_8tq; // tBS1=8 olur
CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq; // tBS2=3 olur
CAN_InitStructure.CAN_Prescaler = 30; // 100KBps
// sample point %75 oluyor
if (CAN_Init(CAN1,&CAN_InitStructure) == CANINITFAILED){
}
CanRxFifo_Init();
//int enable
CAN_ITConfig(CAN1,CAN_IT_FMP0, ENABLE);
CanFilterSettings();
}
void CanTxDataSend(MyCanTxMsg_Typedef* CanTxMessage)
{
u8 TxMailBox; u16 TimeOut=0x3FFF;
TxMailBox = CAN_Transmit(CAN1, (CanTxMsg *)CanTxMessage);
while((CAN_TransmitStatus(CAN1,TxMailBox)!=CAN_TxStatus_Ok) && (TimeOut != 0)){
TimeOut--;
}
if(TimeOut == 0 ) { // ACK gelmeşse haberleşmesi kes
//RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);
}
}
@CLR teşekkür ederim paylaşımların için.
@CLR hocam aklıma bişi geldi, sizin bu çalışıyor dediğiniz projede mcp2551 Vref bacağı bağlantısı nasıl ?
Vref boş, RS(slewrate) pini 10K ile ground'a bağlı, yani maksimum slewrate
Teşekkür ederim
Ben RS pinlerini 10K ile çektim GND ye VREF pinlerinde 1.64V falan okuyorum. 120 ohm'larda takılı
Beslemedede sorun yok ama hala çalışmıyor. Çoook enteresan.
Ya bu Trancerecieverlar bozuk yada başka bir problem var
Anladığım kadarıyla stm32'nin can tx pininden çıkış işini çözdünüz, tekrar mcp2551'e döndüğünüze göre, Emin değilseniz Cantx pini ile can Rx pini arası 22ohm-47ohm ile birbirine bağlayın,isterseniz kısadevrede edebilirsiniz ama ben temkinli olmayı severim. can tx yapıyorsa canrx interrupt oluşur. (normal modda, loopback gibi)
o kartlardan elimde 2-3 tane var, fotosunu atacaktım ama fotoda çiplerin yazıları okunmuyor. Üzerlerinde stm32f103c8t6 + mcp2551 dizili, hatta 11 adet kart aynı can bus'ına bağlı, birbirleri ile haberleşiyorlar, O zamanlar 3V3 transceiver kullanmadım çünkü her karta 5V geliyor, bir LDO ile 3V3'e düşüyor, 5V ile mcp2551'ler besleniyorlar, 3V3 ile stm32 ve diğer komponentler(PGA,opamplar vs var)
Şimdiki projelerde herşey 3V3 olduğundan TI'ın 3V3'lük transceiver'larını kullanıyorum, mcp2551'i kullanmam için sistemde 5V olması lazım ve pic18f4580 gibi can module içeren 5V'luk bir işlemci.
Ben forumda baska bir bilgi ararken bu konuda yanlislik oldugunu farkettim konu hortlayacak ama arayan arkadaslarin bilgisi olsun diye ekliyorum STMf103 de usb ve canbus ayni anda calismiyor diye manuelde bilgi var dolayisi ile kullanilamiyor onun yerine spi uzerinden canbus modul kullanilmasi uygun olur
konu biraz eski ama yinede sormak istiyorum. Bende şuanda CAN bus iletişim protokolünü kullanarak bir tasarım gerçekleştiriyorum. Burda belirttiğiniz mikrodenetleyicinin (STM32F103) besleme voltajı 3.3V . bu logic seviyesi 1 = 3.3 V anlamına geliyor galiba. Can Transiver'in (MCP2551) beslemesi ise 5V. MCP2551'in mikroişlemciye giden pinlerinden RXD nin high değeri min 2V - max VDD yazıyor. Yani mikrodentleyicinin pininden 3.3V gelince MCP2551 bunu high olarak algılıycak. Aynı şekilde mikrodenetleyiciye bağlı diğer pin TXD ise mikrodenetleyiciye bilgi göndericek ve high değeri min:0.7xVDD yani 3.5V Mikrodenetleyicinin pinine zarar vermez galiba çünki + tolerans değeri vardır. Ben bu konuda ilk tasarımı yapıacm ve böyle yorumladım. Yanlış mı düşündüm. Tasarımı yaptınız mı ve çalış mı? Başka bir entegre mi kullandınız ?
(https://i.ibb.co/16jBKQd/pin-config1.jpg) (https://ibb.co/16jBKQd)
(https://i.ibb.co/SwjBFBW/pin-config3.jpg) (https://ibb.co/SwjBFBW)
(https://i.ibb.co/2KGhjm8/pin-config2.jpg) (https://ibb.co/2KGhjm8)
Pinler zaten 5V toleranslı. Eğer MCP2551 3.3V toleranslı değilse 3.3V toleranslı bir "CAN Transceiver" kullanabilirsiniz.
Alıntı yapılan: mehmetkazakli - 10 Şubat 2019, 19:01:53konu biraz eski ama yinede sormak istiyorum. Bende şuanda CAN bus iletişim protokolünü kullanarak bir tasarım gerçekleştiriyorum. Burda belirttiğiniz mikrodenetleyicinin (STM32F103) besleme voltajı 3.3V . bu logic seviyesi 1 = 3.3 V anlamına geliyor galiba. Can Transiver'in (MCP2551) beslemesi ise 5V. MCP2551'in mikroişlemciye giden pinlerinden RXD nin high değeri min 2V - max VDD yazıyor. Yani mikrodentleyicinin pininden 3.3V gelince MCP2551 bunu high olarak algılıycak. Aynı şekilde mikrodenetleyiciye bağlı diğer pin TXD ise mikrodenetleyiciye bilgi göndericek ve high değeri min:0.7xVDD yani 3.5V Mikrodenetleyicinin pinine zarar vermez galiba çünki + tolerans değeri vardır. Ben bu konuda ilk tasarımı yapıacm ve böyle yorumladım. Yanlış mı düşündüm. Tasarımı yaptınız mı ve çalış mı? Başka bir entegre mi kullandınız ?
MCP2551 yerine SN65HVD230 kullanın. Doğrudan 3.3V uyumlu.
TJA1050T/CM,118 var. Bunu kullanmayı düşündüm. Fİyatı uygun, 5V ve 3.3V uyumlu ve özdisanda bolca var diye. Daha önceden kullanan var mı bu entegreyi?
@emin.kiran foruma bir süredir bakamadım.
Konuda herhangi bir hata yok çünkü ben USB ve CanBus'ı aynı anda zaten kullanmamıştım.
Bu sorunun asıl sebebi benim kullandığım MCP2551'in "büyük ihtimal" sahte olmasıydı.
Benim tavsiyem direk 3.3V uyumlu Transceiver kullanın olsun bitsin.
Ben bir sürü farklı CAN TJA1050T denedim hepsi düzgün çalışıyor değişik bir durum yok bu yüzden TJA1050 kullanabilirsiniz