/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "SysTick/systick.h"
#include "GeneralTim.h"
#include "stmflash.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/* Private variables ---------------------------------------------------------*/
uint8_t CAN1_RxRdy,CAN2_RxRdy;
uint16_t CAN1_Val_Tx,CAN1_Val_Rx,CAN2_Val_Tx,CAN2_Val_Rx;
CanTxMsg Can1TxMessage;
CanTxMsg Can2TxMessage;
CanRxMsg Can1RxMessage;
CanRxMsg Can2RxMessage;
/* Private function prototypes -----------------------------------------------*/
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void CAN_Configuration(void);
void CanWriteData( CAN_TypeDef* CANx ,CanTxMsg *TxMessage );
u8 CAN1_TX_data[128],CAN1_RX_data[128];
u16 CAN1_Tx_Counter,CAN1_Rx_Counter,CAN1_TX_flag,CAN1_RX_flag,CAN1_TX_status,CAN1_RX_status;
u8 CAN2_TX_data[128],CAN2_RX_data[128];
u16 CAN2_Tx_Counter,CAN2_Rx_Counter,CAN2_TX_flag,CAN2_RX_flag,CAN2_TX_status,CAN2_RX_status;
char KEY1_up,KEY2_up,KEY3_up,KEY4_up,KEY5_up,KEY6_up;
char canopen_ID=0x01;
char canopen_start,canopen_reset,canopen_pretreatment;
char canopen_RSDO,canopen_RPDO;
/*******************************************************************************
* Function Name : main
* Description : Main program
* Input : None
* Output : None
* Return : None
* Attention : None
*******************************************************************************/
int main(void)
{
CAN_Configuration();
CAN2_RxRdy = DISABLE;
Can2TxMessage.StdId=0x0700+canopen_ID; //地址
Can2TxMessage.DLC=3;
Can2TxMessage.RTR = CAN_RTR_DATA; /* 设置为数据帧 */
Can2TxMessage.IDE = CAN_ID_STD; /* 使用标准id */
Can2TxMessage.Data[0] = 0x00;
CAN_Transmit(CAN2,&Can2TxMessage);
while (1)
{
if(canopen_pretreatment==1) //高压恢复
{
canopen_pretreatment=0;
CAN2_RxRdy = DISABLE;
Can2TxMessage.StdId=0x0180+canopen_ID; //地址
Can2TxMessage.DLC=8;
Can2TxMessage.RTR = CAN_RTR_DATA; /* 设置为数据帧 */
Can2TxMessage.IDE = CAN_ID_STD; /* 使用标准id */
Can2TxMessage.Data[0] = GPIO_ReadOutputDataBit(GPIOE,GPIO_Pin_0);
Can2TxMessage.Data[1] = GPIO_ReadOutputDataBit(GPIOE,GPIO_Pin_1);
Can2TxMessage.Data[2] = GPIO_ReadOutputDataBit(GPIOE,GPIO_Pin_2);
Can2TxMessage.Data[3] = GPIO_ReadOutputDataBit(GPIOE,GPIO_Pin_3);
Can2TxMessage.Data[4] = GPIO_ReadOutputDataBit(GPIOE,GPIO_Pin_4);
Can2TxMessage.Data[5] = GPIO_ReadOutputDataBit(GPIOE,GPIO_Pin_5);
Can2TxMessage.Data[6] = GPIO_ReadOutputDataBit(GPIOE,GPIO_Pin_6);
Can2TxMessage.Data[7] = GPIO_ReadOutputDataBit(GPIOE,GPIO_Pin_7);
CAN_Transmit(CAN2,&Can2TxMessage);
}
if(CAN1_RX_flag==1)
{
CAN1_RX_flag=0;
if((Can1RxMessage.StdId==0x0000)&&(Can1RxMessage.Data[0]==0x10)&&(Can1RxMessage.Data[1]==0x00))
{
canopen_start=1;
}
if((Can1RxMessage.StdId==0x0000)&&(Can1RxMessage.Data[0]==0x10)&&(Can1RxMessage.Data[1]==canopen_ID))
{
canopen_start=1;
}
if(canopen_start==1)
{
if((Can1RxMessage.StdId==0x0000)&&(Can1RxMessage.Data[0]==0x20)&&(Can1RxMessage.Data[1]==0x00))
{
canopen_start=0;
}
if((Can1RxMessage.StdId==0x0000)&&(Can1RxMessage.Data[0]==0x20)&&(Can1RxMessage.Data[1]==canopen_ID))
{
canopen_start=0;
}
if((Can1RxMessage.StdId==0x0000)&&(Can1RxMessage.Data[0]==0x82)&&(Can1RxMessage.Data[1]==0x00))
{
canopen_reset=1;
}
if((Can1RxMessage.StdId==0x0000)&&(Can1RxMessage.Data[0]==0x81)&&(Can1RxMessage.Data[1]==canopen_ID))
{
canopen_reset=1;
}
if((Can1RxMessage.StdId==0x0000)&&(Can1RxMessage.Data[0]==0x80)&&(Can1RxMessage.Data[1]==0x00))
{
canopen_pretreatment=1;
}
if((Can1RxMessage.StdId==0x0000)&&(Can1RxMessage.Data[0]==0x80)&&(Can1RxMessage.Data[1]==canopen_ID))
{
canopen_pretreatment=1;
}
if((Can1RxMessage.StdId-0x0600)==canopen_ID)
{
canopen_RSDO=1;
if(canopen_RSDO==1)
{
canopen_RSDO=0;
if((Can1RxMessage.Data[0]==0x2F)&&(Can1RxMessage.Data[1]==0x00)&&(Can1RxMessage.Data[2]==0x20)&&(Can1RxMessage.Data[3]==0x00))
{
canopen_ID=Can1RxMessage.Data[4];
}
}
}
if((Can1RxMessage.StdId-0x0200)==canopen_ID)
{
canopen_RPDO=1;
if(canopen_RPDO==1)
{
canopen_RPDO=0;
if(Can1RxMessage.Data[0]==0x31)
{
GPIO_WriteBit(GPIOB,GPIO_Pin_0,1);
}
if(Can1RxMessage.Data[0]==0x30)
{
GPIO_WriteBit(GPIOB,GPIO_Pin_0,0);
}
if(Can1RxMessage.Data[1]==0x31)
{
GPIO_WriteBit(GPIOB,GPIO_Pin_1,1);
}
if(Can1RxMessage.Data[1]==0x30)
{
GPIO_WriteBit(GPIOB,GPIO_Pin_1,0);
}
}
}
}
}
}
}
/*******************************************************************************
* Function Name : GPIO_Configuration
* Description : Configures the different GPIO ports.
* Input : None
* Output : None
* Return : None
* Attention : None
*******************************************************************************/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO ,ENABLE);
/* CAN1 and CAN2 periph clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1 | RCC_APB1Periph_CAN2, ENABLE);
/* Configure CAN1 RX pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure CAN1 pin: 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);
/* Configure CAN2 RX pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Configure CAN2 pin: TX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &GPIO_InitStructure);
}
/*******************************************************************************
* Function Name : NVIC_Configuration
* Description : Configures the nested vectored interrupt controller.
* Input : None
* Output : None
* Return : None
* Attention : None
*******************************************************************************/
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
/* Enable CAN1 RX0 interrupt IRQ channel */
NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable CAN2 RX0 interrupt IRQ channel */
NVIC_InitStructure.NVIC_IRQChannel = CAN2_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/*******************************************************************************
* Function Name : CAN_Configuration
* Description : Configures the CAN
* Input : None
* Output : None
* Return : None
* Attention : None
*******************************************************************************/
void CAN_Configuration(void)
{
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
NVIC_Configuration();
GPIO_Configuration();
/* CAN register init */
CAN_DeInit(CAN1);
CAN_DeInit(CAN2);
CAN_StructInit(&CAN_InitStructure);
CAN1_RxRdy = CAN2_RxRdy = DISABLE;
CAN1_Val_Tx = CAN1_Val_Rx = CAN2_Val_Tx = CAN2_Val_Rx = 0;
/* CAN cell init */
CAN_InitStructure.CAN_TTCM = DISABLE; /* 时间触发禁止, 时间触发:CAN硬件的内部定时器被激活,并且被用于产生时间戳 */
CAN_InitStructure.CAN_ABOM = DISABLE; /* 自动离线禁止,自动离线:一旦硬件监控到128次11个隐性位,就自动退出离线状态。在这里要软件设定后才能退出 */
CAN_InitStructure.CAN_AWUM = DISABLE; /* 自动唤醒禁止,有报文来的时候自动退出休眠 */
CAN_InitStructure.CAN_NART = DISABLE; /* 报文重传, 如果错误一直传到成功止,否则只传一次 */
CAN_InitStructure.CAN_RFLM = DISABLE; /* 接收FIFO锁定, 1--锁定后接收到新的报文摘不要,0--接收到新的报文则覆盖前一报文 */
CAN_InitStructure.CAN_TXFP = ENABLE; /* 发送优先级 0---由标识符决定 1---由发送请求顺序决定 */
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; /* 模式 */
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; /* 重新同步跳宽,只有can硬件处于初始化模式时才能访问这个寄存器 */
CAN_InitStructure.CAN_BS1 = CAN_BS1_9tq; /* 时间段1 */
CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq; /* 时间段2 */
CAN_InitStructure.CAN_Prescaler = 8; /* 波特率预分频数 */
/* 波特率计算方法 */
/* CANbps= Fpclk/((BRP+1)*((Tseg1+1)+(Tseg2+1)+1) 此处计算为 CANbps=36000000/(45*(4+3+1))=1200kHz */ //此处Tseg1+1 = CAN_BS1_8tp
/* 配置大方向: Tseg1>=Tseg2 Tseg2>=tq; Tseg2>=2TSJW */
/*Initializes the CAN1 and CAN2 */
CAN_Init(CAN1, &CAN_InitStructure);
CAN_Init(CAN2, &CAN_InitStructure);
/* CAN1 filter init */
/* 配置CAN过滤器 */
/* 32位对应的id */
/* stdid[10:0],extid[17:0],ide,rtr */
/* 16位对应的id */
/* stdid[10:0],ide,rtr,extid[17:15] */
/* 一般使用屏蔽模式 */
/* 要注意的是fifo接收存满了中断,还有就是fifo的概念,即取的一直是最早那一个数据, 要释放才能取下一个数据 */
/* 常使用的中断有 */
/* 1,有信息中断,即fifo挂号中断 */
/* 2,fifo满中断 */
/* 3,fifo满之后又有信息来则中断,即fifo溢出中断 */
CAN_FilterInitStructure.CAN_FilterNumber = 0; /* 过滤器1 */
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; /* 屏敝模式 */
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; /* 32位 */
CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000; /* 以下四个都为0, 表明不过滤任何id */
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);
/* CAN2 filter init */
CAN_FilterInitStructure.CAN_FilterNumber = 14;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0;
CAN_FilterInit(&CAN_FilterInitStructure);
/* IT Configuration for CAN1 */
CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
/* IT Configuration for CAN2 */
CAN_ITConfig(CAN2, CAN_IT_FMP0, ENABLE);
}
/*******************************************************************************
* Function Name : CanWriteData
* Description : Can Write Date to CAN-BUS
* Input : None
* Output : None
* Return : None
* Attention : None
*******************************************************************************/
void CanWriteData( CAN_TypeDef* CANx ,CanTxMsg *TxMessage )
{
/* transmit */
// TxMessage->StdId = 0xA5A5; /* 设置标准id 注意标准id的最高7位不能全是隐性(1)。共11位 */
//TxMessage->ExtId = 0x00; //设置扩展id 扩展id共18位
TxMessage->RTR = CAN_RTR_DATA; /* 设置为数据帧 */
TxMessage->IDE = CAN_ID_STD; /* 使用标准id */
// TxMessage->DLC = 8; /* 数据长度, can报文规定最大的数据长度为8字节 */
CAN_Transmit(CANx,TxMessage); /* 返回这个信息请求发送的邮箱号0,1,2或没有邮箱申请发送no_box */
}
/*******************************************************************************
* Function Name : CAN1_RX0_IRQHandler
* Description : This function handles CAN1 RX0 interrupts
* Input : None
* Output : None
* Return : None
* Attention : None
*******************************************************************************/
void CAN1_RX0_IRQHandler(void)
{
int i;
CAN_Receive(CAN1,CAN_FIFO0, &Can1RxMessage); /* 此函数包含释放提出报文了的,在非必要时,不需要自己释放 */
CAN1_RxRdy = ENABLE;
CAN1_RX_flag=1;
}
/*******************************************************************************
* Function Name : CAN2_RX0_IRQHandler
* Description : This function handles CAN2 RX0 interrupts
* Input : None
* Output : None
* Return : None
* Attention : None
*******************************************************************************/
void CAN2_RX0_IRQHandler(void)
{
CAN_Receive(CAN2,CAN_FIFO0, &Can2RxMessage); /* 此函数包含释放提出报文了的,在非必要时,不需要自己释放 */
CAN2_RxRdy = ENABLE;
CAN2_RX_flag=1;
}
/*********************************************************************************************************
END FILE
*********************************************************************************************************/