这是一篇入门帖,高手请指点一下,主要是记录我对CANOPEN协议的理解以及使用。图片还没研究好怎么上传,等后面研究好了补上。第一步;新建一个工程,配置好各种时钟之类的。当然你用的是原子的板子, 你也可以拿一个LED实验或者蜂鸣器实验的工程 直接来改,你把其他的注释掉就好了。
第二步;到网上下载CanFestival源码CanFestival-3-10,解压出来,并将文件夹名字改为CanFestival-3-10。移植需要用到的源文件在CanFestival-3-10src目录下,头文件在CanFestival-3-10include目录下。
第三部;开始移植。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
看附件
接下来实现刚才定义的3个空函数,函数void setTimer(TIMEVAL value)主要被源码用来定时的,时间到了就需要调用一下函数TimeDispatch(),函数TIMEVAL getElapsedTime(void)主要被源码用来查询距离下一个定时触发还有多少时间。
我们在stm32_canfestival.c文件里定义几个变量如下:
unsigned int TimeCNT=0;//时间计数
unsigned int NextTime=0;//下一次触发时间计数
unsigned int TIMER_MAX_COUNT=70000;//最大时间计数
static TIMEVAL last_time_set = TIMEVAL_MAX;//上一次的时间计数
setTimer和getElapsedTime函数实现如下:
void setTimer(TIMEVAL value)
{
NextTime=(TimeCNT+value)%TIMER_MAX_COUNT;
}
TIMEVAL getElapsedTime(void)
{
int ret=0;
ret = TimeCNT> last_time_set ? TimeCNT - last_time_set : TimeCNT + TIMER_MAX_COUNT - last_time_set;
last_time_set = TimeCNT;
return ret;
}
另外还要开一个1毫秒的定时器,每1毫秒调用一下下面这个函数。
void timerForCan(void)
{
TimeCNT++;
if (TimeCNT>=TIMER_MAX_COUNT)
{
TimeCNT=0;
}
if (TimeCNT==NextTime)
{
TimeDispatch();
}
}
下面我贴上定时器的初始化代码
void TIM3_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
TIM_TimeBaseInitStructure.TIM_Period = 1000-1;
TIM_TimeBaseInitStructure.TIM_Prescaler= 84-1;
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
TIM_Cmd(TIM3,ENABLE);
NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
定时器3中断服务函数
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //òç3öÖD¶Ï
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
// TimerForCan();
TimeCNT++;
if (TimeCNT>=TIMER_MAX_COUNT)
{
TimeCNT=0;
}
if (TimeCNT==NextTime)
TimeDispatch();
}
}
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;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_CAN1);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_CAN1);
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= mode;
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);
CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
return 0;
}
void CAN1_RX0_IRQHandler(void)
{
u32 i;
Message m;
CanRxMsg RxMessage;
CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
m.cob_id=RxMessage.StdId;
if(RxMessage.RTR == CAN_RTR_REMOTE)
m.rtr=1;
else if(RxMessage.RTR == CAN_RTR_DATA)
m.rtr=0;
m.len=RxMessage.DLC;
for(i = 0; i < RxMessage.DLC; i++)
m.data[i] = RxMessage.Data[i];
canDispatch(&TestSlave_Data, &m);
}
unsigned char canSend(CAN_PORT notused, Message *m)
{
uint32_t i;
CanTxMsg TxMessage;
CanTxMsg *ptx_msg=&TxMessage;
ptx_msg->StdId = m->cob_id;
if(m->rtr)
ptx_msg->RTR = CAN_RTR_REMOTE;
else
ptx_msg->RTR = CAN_RTR_DATA;
ptx_msg->IDE = CAN_ID_STD;
ptx_msg->DLC = m->len;
for(i = 0; i < m->len; i++)
ptx_msg->Data[i] = m->data[i];
if( CAN_Transmit( CAN1, ptx_msg )==CAN_NO_MB)
{
return 0xff;
}
else
{
return 0x00;
}
}
一周热门 更多>