这是我聪明做的一个功能,有一些细节没注意,导致移植没通,现在记下来。
一、硬件部分
STM32F103C8T6:2个,记为STM32(1),STM32(2)
TJA1050(CAN模块) ):2个,记为TJA(1),TJA(2)
STM32(1)的RX接TJA(1)的RX,TX接TX。TJA(1)的CAN_H接另一个TJA(2)的CAN_H, CAN_L接CAN_L。然后TJA(2)的RX接STM32(2)的RX,TX接TX。
二、软件部分
注释:软件参考了网上的一些朋友的代码,如果雷同,纯属参考学习,谢谢!
u8 CAN1_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode)
{
GPIO_InitTypeDef GPIO_InitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
#if CAN1_RX0_INT_ENABLE
NVIC_InitTypeDef NVIC_InitStructure;
#endif
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap1_CAN1,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//100MHz
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//100MHz
GPIO_Init(GPIOA, &GPIO_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=tsjw;
CAN_InitStructure.CAN_BS1=tbs1;
CAN_InitStructure.CAN_BS2=tbs2;
CAN_InitStructure.CAN_Prescaler=brp;
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_Filter_FIFO0;
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
#if CAN1_RX0_INT_ENABLE
CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);
CAN_ITConfig(CAN1,CAN_IT_TME,ENABLE);
CAN_ITConfig(CAN1,CAN_IT_BOF,ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#endif
return 0;
}
#if CAN1_RX0_INT_ENABLE
void USB_LP_CAN1_RX0_IRQHandler(void)
{
int i=0;
CanRxMsg RxMessage;
RxMessage.StdId=0x00;
RxMessage.ExtId=0x00;
RxMessage.IDE=0;
RxMessage.RTR=0;
RxMessage.FMI=0;
for(i=0;i《8;i++)
RxMessage.Data[i]=0;
CAN_Receive(CAN1, 0, &RxMessage);
//USART1_DATA(RxMessage.Data,RxMessage.DLC);
printf(“IRQ RxMessage.Data = %srn”, RxMessage.Data);
}
#endif
u8 CAN1_Send_Msg(u8* msg,u8 len)
{
u8 mbox;
u16 i=0;
CanTxMsg TxMessage;
TxMessage.StdId=0x12;
TxMessage.ExtId=0x12;
TxMessage.IDE=CAN_ID_STD;
TxMessage.RTR=CAN_RTR_Data;
TxMessage.DLC=len;
for(i=0;i《len;i++)
TxMessage.Data[i]=*(msg+i);
mbox= CAN_Transmit(CAN1, &TxMessage);
i=0;
while((CAN_TransmitStatus(CAN1, mbox)==CAN_TxStatus_Failed)&&(i《0XFFF))i++; /
if(i》=0XFFF)return 1;
return 0;
}
int main(void)
{
u8 i,cnt,len,res;
u8 canbuf[8];
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
uart_init();
CAN1_Mode_Init(CAN_SJW_1tq,CAN_BS2_6tq,CAN_BS1_7tq,6,0);
printf(“stm32 startup!rn”);
while(1)
{
#if 1
delay_ms(1000);
len = 8;
cnt = ‘a’;
for(i=0;i《len;i++)
{
canbuf[i]=cnt+i;
}
res = CAN1_Send_Msg(canbuf, len);
#endif
}
}
两个STM32都烧写程序,然后接上字节,1s会收到另一个STM32发来的8个字节的abcdefgh。
注意事项:
1、TJA1050供电5V
2、用printf打印数据,如果使用USART_SendData必须等待发送完成再发送下一个编码。循环打印可以参考如下:
void USART1_DATA(unsigned char *lb,unsigned int len)
{
unsigned int i;
for(i=0;i《len;i++)
{
USART_SendData(USART1,*lb);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
{
}
lb ++;
}
}
3、CAN_TX和CAN_RX的GPIO属性配置不一样,要注意一下。
4、CAN1_RX0_INT_ENABLE置为1。
这是我聪明做的一个功能,有一些细节没注意,导致移植没通,现在记下来。
一、硬件部分
STM32F103C8T6:2个,记为STM32(1),STM32(2)
TJA1050(CAN模块) ):2个,记为TJA(1),TJA(2)
STM32(1)的RX接TJA(1)的RX,TX接TX。TJA(1)的CAN_H接另一个TJA(2)的CAN_H, CAN_L接CAN_L。然后TJA(2)的RX接STM32(2)的RX,TX接TX。
二、软件部分
注释:软件参考了网上的一些朋友的代码,如果雷同,纯属参考学习,谢谢!
u8 CAN1_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode)
{
GPIO_InitTypeDef GPIO_InitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
#if CAN1_RX0_INT_ENABLE
NVIC_InitTypeDef NVIC_InitStructure;
#endif
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap1_CAN1,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//100MHz
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//100MHz
GPIO_Init(GPIOA, &GPIO_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=tsjw;
CAN_InitStructure.CAN_BS1=tbs1;
CAN_InitStructure.CAN_BS2=tbs2;
CAN_InitStructure.CAN_Prescaler=brp;
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_Filter_FIFO0;
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
#if CAN1_RX0_INT_ENABLE
CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);
CAN_ITConfig(CAN1,CAN_IT_TME,ENABLE);
CAN_ITConfig(CAN1,CAN_IT_BOF,ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#endif
return 0;
}
#if CAN1_RX0_INT_ENABLE
void USB_LP_CAN1_RX0_IRQHandler(void)
{
int i=0;
CanRxMsg RxMessage;
RxMessage.StdId=0x00;
RxMessage.ExtId=0x00;
RxMessage.IDE=0;
RxMessage.RTR=0;
RxMessage.FMI=0;
for(i=0;i《8;i++)
RxMessage.Data[i]=0;
CAN_Receive(CAN1, 0, &RxMessage);
//USART1_DATA(RxMessage.Data,RxMessage.DLC);
printf(“IRQ RxMessage.Data = %srn”, RxMessage.Data);
}
#endif
u8 CAN1_Send_Msg(u8* msg,u8 len)
{
u8 mbox;
u16 i=0;
CanTxMsg TxMessage;
TxMessage.StdId=0x12;
TxMessage.ExtId=0x12;
TxMessage.IDE=CAN_ID_STD;
TxMessage.RTR=CAN_RTR_Data;
TxMessage.DLC=len;
for(i=0;i《len;i++)
TxMessage.Data[i]=*(msg+i);
mbox= CAN_Transmit(CAN1, &TxMessage);
i=0;
while((CAN_TransmitStatus(CAN1, mbox)==CAN_TxStatus_Failed)&&(i《0XFFF))i++; /
if(i》=0XFFF)return 1;
return 0;
}
int main(void)
{
u8 i,cnt,len,res;
u8 canbuf[8];
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
uart_init();
CAN1_Mode_Init(CAN_SJW_1tq,CAN_BS2_6tq,CAN_BS1_7tq,6,0);
printf(“stm32 startup!rn”);
while(1)
{
#if 1
delay_ms(1000);
len = 8;
cnt = ‘a’;
for(i=0;i《len;i++)
{
canbuf[i]=cnt+i;
}
res = CAN1_Send_Msg(canbuf, len);
#endif
}
}
两个STM32都烧写程序,然后接上字节,1s会收到另一个STM32发来的8个字节的abcdefgh。
注意事项:
1、TJA1050供电5V
2、用printf打印数据,如果使用USART_SendData必须等待发送完成再发送下一个编码。循环打印可以参考如下:
void USART1_DATA(unsigned char *lb,unsigned int len)
{
unsigned int i;
for(i=0;i《len;i++)
{
USART_SendData(USART1,*lb);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
{
}
lb ++;
}
}
3、CAN_TX和CAN_RX的GPIO属性配置不一样,要注意一下。
4、CAN1_RX0_INT_ENABLE置为1。
举报