求助,使用stm32f107 can通信,用pc向开发板发数据,控制小灯的亮灭

2019-03-23 19:12发布

求大神帮助,刚接触stm32 can总线,自己改的程序,想实现用usb转can接口向开发板CAN1接口发数据,实现发01LED1亮,02LED2亮,03LED3亮,04LED4亮,附上主程序和CAN.c里的程序,开发板有两个CAN接口,只用CAN1,程序编译上没问题,用usb转can的通信软件发数据也可以进入中断,但不知道CAN_DATA[8]中数据如何,而且不能实现控制等的亮灭,不知道怎么去改,感觉是CAN1接收中断函数的问题,求助各位高手帮忙
main.c主程序如下
#include "main.h"
#include "LED.h"
#define SYSTEMTICK_PERIOD_MS  10

__IO uint32_t LocalTime = 0; /* this variable is used to create a time reference incremented by 10ms */
uint32_t timingdelay;
unsigned int can_flag=0;
unsigned int led_flag=0;

/* Private function prototypes -----------------------------------------------*/

void Usart2_Send(unsigned char ch);
void System_Setup(void);
void CAN_Configuration(void);
void Delay(uint32_t nCount);
int main(void)
{
        
        /* Setup STM32 system (clocks, GPIO, NVIC) */        
        SystemInit();
        GPIO_Configuration();
        CAN_Configuration();
        NVIC_Configuration();
        USART_Configuration();
           System_Setup();                        //设置系统时钟72MHZ
        LED_Configuration();        //LED配置   
         
        /* Infinite loop */
        while (1)
        {
        LED_Blink();
        }

        
         }

}

void Delay(uint32_t nCount)
{
  while(nCount > 0)
  {
            nCount --;   
  }
}


#ifdef  USE_FULL_ASSERT

void assert_failed(uint8_t* file, uint32_t line)
{
  while (1)
  {}
}
#endif

CAN.c子程序如下:



#include "stm32f10x.h"
#include "CAN_DATA.h"
#include "LED.h"
#define CAN1_FILTER_START                        0
#define CAN2_FILTER_START                                                14//过滤器
#define        FILTER_MESSAGE_NUM                                        2                  //要过滤的报文总个数,不能超过14个
#define        FILTER_MESSAGE_NUM_SHAWOD                        2                  //一般与FILTER_MESSAGE_NUM相等,但如果为0则不过滤任何报文
const unsigned int can1_filter_list_id[FILTER_MESSAGE_NUM] =
                                                                                                                {
                                                                                                                        0x18400001,        //?
                                                                                                                };
const unsigned int can2_filter_list_id[FILTER_MESSAGE_NUM] =
                                                                                                                {
                                                                                                                        0x18400002,                //?
                                                                                                                };

extern unsigned int can_flag;
extern unsigned int led_flag;
volatile unsigned int  CAN_ID;                //unsigned int为32位的 unsigned short int为16位的
unsigned char CAN_DATA[8] = 0;
unsigned char CAN2_DATA[8] = 0;
unsigned char can_send_data[8] = 0;
unsigned char meter_flag = 0;

volatile unsigned char CanRec_flag = 0;
volatile unsigned char enable_meter_flag = 0;
volatile unsigned char disable_meter_flag = 0;


void NVIC_Configuration(void);
void GPIO_Configuration(void);
void  Filter_List(const unsigned int *CAN1_filte_list_id,unsigned char CAN1_num,const unsigned int *CAN2_filte_list_id,unsigned char CAN2_num);

void CAN_Configuration(void)
{
        
        u32 id = 0;
        unsigned char i = 0;
        CAN_InitTypeDef        CAN_InitStructure;
        CAN_FilterInitTypeDef  CAN_FilterInitStructure;
        
        CAN_DeInit(CAN1);

        CAN_StructInit(&CAN_InitStructure);

        /* 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_InitStructure.CAN_BS1=CAN_BS1_8tq;
        CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;
        CAN_InitStructure.CAN_Prescaler=9;        //我的时钟是PLL 72M,那么CAN应该是36M了吧?这样就是36/((1+8+7)*9)=250K        

        if (CAN_Init(CAN1,&CAN_InitStructure) == CANINITFAILED)                 
        {
               
                /* 初始化时先设置CAN_MCR的初始化位 */                                                                                                                  
                /* 然后查看硬件是否真的设置了CAN_MSR的初始化位来确认是否进入了初始化模式  */                                                                                                                                          
        }
        
        if (CAN_Init(CAN2,&CAN_InitStructure) == CANINITFAILED)                 
        {
               
                /* 初始化时先设置CAN_MCR的初始化位 */                                                                                                
                /* 然后查看硬件是否真的设置了CAN_MSR的初始化位来确认是否进入了初始化模式  */                                                                                                                                          
        }        

        Filter_List(can1_filter_list_id,FILTER_MESSAGE_NUM_SHAWOD,can2_filter_list_id,FILTER_MESSAGE_NUM_SHAWOD);//为0时不过滤任何ID
        
        CAN_ITConfig(CAN1,CAN_IT_FMP0, ENABLE);   /* 挂号中断, 进入中断后读fifo的报文函数释放报文清中断标志 */
        CAN_ITConfig(CAN2,CAN_IT_FMP0, ENABLE);   /* 挂号中断, 进入中断后读fifo的报文函数释放报文清中断标志 */
        
}

/*******************************************************************************
* Function Name  : CanWriteData
* Description    : Can Write Date to CAN-BUS
* Input          : None
* Output         : None
* Return         : None
* Attention                 : None
*******************************************************************************/
void  Filter_List(const unsigned int *CAN1_filte_list_id,unsigned char CAN1_num,const unsigned int *CAN2_filte_list_id,unsigned char CAN2_num)
{
        unsigned int temp_id = 0;
        unsigned char temp = 0;
        unsigned char i = 0;
        CAN_FilterInitTypeDef  CAN_FilterInitStructure;
        /*******************以下是num为0不过滤任何ID***************************************/

        if(CAN1_num > 0 && CAN2_num > 0)//can1和can2都要过滤
        {
                temp = CAN1_num <= CAN2_num ? CAN1_num : CAN2_num;//取出较小的数
                for(i = 0;i < temp;i ++)
                {
                        temp_id = CAN1_filte_list_id;
                        CAN_FilterInitStructure.CAN_FilterNumber = i;     ///* 过滤器组 */
                        CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;//CAN_FilterMode_IdList;//CAN_FilterMode_IdMask;  /* 屏敝模式 */
                        CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; ///* 32位 */
                        CAN_FilterInitStructure.CAN_FilterIdHigh = (temp_id<<3)>>16;//(id<<3)>>16;  
                        CAN_FilterInitStructure.CAN_FilterIdLow = (temp_id<<3)|CAN_ID_EXT|CAN_RTR_DATA;//扩展帧
                        CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xffff;
                        CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xffff;
                        CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;  ///* 能够通过该过滤器的报文存到fifo0中 */
                        CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
                        CAN_FilterInit(&CAN_FilterInitStructure);

                        temp_id = CAN2_filte_list_id;
                        CAN_FilterInitStructure.CAN_FilterNumber = i + 14;     ///* 过滤器组 */
                        CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;//CAN_FilterMode_IdList;//CAN_FilterMode_IdMask;  /* 屏敝模式 */
                        CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; ///* 32位 */
                        CAN_FilterInitStructure.CAN_FilterIdHigh = (temp_id<<3)>>16;//(id<<3)>>16;  
                        CAN_FilterInitStructure.CAN_FilterIdLow = (temp_id<<3)|CAN_ID_EXT|CAN_RTR_DATA;//扩展帧
                        CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xffff;
                        CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xffff;
                        CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;  ///* 能够通过该过滤器的报文存到fifo0中 */
                        CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
                        CAN_FilterInit(&CAN_FilterInitStructure);               
                }        
        }
        else if(CAN1_num == 0 && CAN2_num == 0)
        {
                CAN_FilterInitStructure.CAN_FilterNumber = 0;     /* 过滤器组 */
                CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;//CAN_FilterMode_IdList;//CAN_FilterMode_IdMask;  /* 屏敝模式 */
                CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; /* 32位 */
                CAN_FilterInitStructure.CAN_FilterIdHigh = 0;
                CAN_FilterInitStructure.CAN_FilterIdLow = 0;
                CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
                CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
                CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;  /* 能够通过该过滤器的报文存到fifo0中 */
                CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
                CAN_FilterInit(&CAN_FilterInitStructure);
                CAN_FilterInitStructure.CAN_FilterNumber = 14;        //CAN2过滤器从14开始
                CAN_FilterInit(&CAN_FilterInitStructure);
        }

}

//CAN1中断程序
void CAN1_RX0_IRQHandler(void)
{
        CanRxMsg RxMessage;
        unsigned char i;
        can_flag=1;
        CAN_Receive(CAN1,CAN_FIFO0, &RxMessage);  /* 此函数包含释放提出报文了的,在非必要时,不需要自己释放 */
        //CAN_ID = RxMessage.ExtId;
        for(i = 0;i < 8; i ++)
        {

                CAN_DATA[8]= RxMessage.Data;
        }
            One_LED_ON(2);Delay(0x1ffffff);
            if(CAN_DATA[0]==0x01)
                { One_LED_ON(1);Delay(0x1ffffff);}
                if(CAN_DATA[0]==0x02)
                { One_LED_ON(2);Delay(0x1ffffff);}
                if(CAN_DATA[0]==0x03)
                { One_LED_ON(3);Delay(0x1ffffff);}
                if(CAN_DATA[0]==0x04)
                { One_LED_ON(4);Delay(0x1ffffff);}
        

        CAN_ClearITPendingBit(CAN1,CAN_IT_FMP0);  /* 清除挂起中断 */
   
}


[ 本帖最后由 cheng_long 于 2013-6-22 21:31 编辑 ] 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。