OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 10642|回复: 8

STM32 CAN收发 PA11&PA12回环OK ,正常模式在调试的时候,出现TERR0(邮箱0发送错误),通信不成功。

[复制链接]

1

主题

5

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2015-2-7
在线时间
0 小时
发表于 2015-2-7 15:36:43 | 显示全部楼层 |阅读模式
5金钱

主函数如下:

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h" 
#include "can.h"


        

 
 int main(void)
 { 
 u8 key;
 u8 i=0,t=0;
 u8 cnt=0;
 u8 canbuf[8];
 u8 res;
 u8 mode=0;//CAN_Mode_LoopBack;//CAN工作模式;CAN_Mode_Normal(0):普通模式,CAN_Mode_LoopBack(1):环回模式

 delay_init();       //延时函数初始化  
 NVIC_Configuration();   //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
 uart_init(9600);   //串口初始化为9600
 LED_Init();      //初始化与LED连接的硬件接口
 LCD_Init();       //初始化LCD 
// KEY_Init();    //按键初始化    
  
 cnt = CAN_Mode_Init(1,8,7,5,mode);//CAN初始化环回模式,波特率450Kbps   

  OINT_COLOR=RED;//设置字体为红色
 LCD_ShowString(60,50,200,16,16,"WarShip STM32"); 
 LCD_ShowString(60,70,200,16,16,"CAN TEST"); 
 LCD_ShowString(60,90,200,16,16,"ATOM@ALIENTEK");
 LCD_ShowString(60,110,200,16,16,"2012/9/11");
 LCD_ShowString(60,130,200,16,16,"LoopBack Mode"); 
 LCD_ShowString(60,150,200,16,16,"KEY0:Send WK_UP:Mode");//显示提示信息  
   OINT_COLOR=BLUE;//设置字体为蓝色  
 LCD_ShowString(60,170,200,16,16,"Count:");   //显示当前计数值 
 LCD_ShowString(60,190,200,16,16,"Send Data:");  //提示发送的数据 
 LCD_ShowString(60,250,200,16,16,"Receive Data:"); //提示接收到的数据  
  while(1)
 {
//  key++;
//  key=2;  //KEY_RIGHT;//KEY_Scan(0);
//  if(key==3)key=0;
  if(1)//KEY0按下,发送一次数据
  {
   for(i=0;i<8;i++)
   {
    canbuf=cnt+i+2;//填充发送缓冲区
    if(i<4)LCD_ShowxNum(60+i*32,210,canbuf,3,16,0X80); //显示数据
    else LCD_ShowxNum(60+(i-4)*32,230,canbuf,3,16,0X80); //显示数据
    }
   res=Can_Send_Msg(canbuf,8);//发送8个字节
   if(res)LCD_ShowString(60+80,190,200,16,16,"Failed");  //提示发送失败
   else LCD_ShowString(60+80,190,200,16,16,"OK    ");    //提示发送成功          
  }
   if(1)//WK_UP按下,改变CAN的工作模式
  {   
//   mode=!mode;
//     CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_7tq,CAN_BS1_8tq,5,mode);//CAN普通模式初始化, 波特率450Kbps
   OINT_COLOR=RED;//设置字体为红色
   if(mode==0)//普通模式,需要2个开发板
   {
    LCD_ShowString(60,130,200,16,16,"Nnormal Mode ");    
   }else //回环模式,一个开发板就可以测试了.
   {
     LCD_ShowString(60,130,200,16,16,"LoopBack Mode");
   }
    OINT_COLOR=BLUE;//设置字体为蓝色
  }  
  key=Can_Receive_Msg(canbuf);
  if(key)//接收到有数据
  {   
   LCD_Fill(60,270,130,310,WHITE);//清除之前的显示
    for(i=0;i<key;i++)
   {            
    if(i<4)LCD_ShowxNum(60+i*32,270,canbuf,3,16,0X80); //显示数据
    else LCD_ShowxNum(60+(i-4)*32,290,canbuf,3,16,0X80); //显示数据
    }
  }

  t++;
  delay_ms(10);
  if(t==2)
  {
   RUNLED=!RUNLED;//提示系统正在运行 
   t=0;
   cnt++;
   LCD_ShowxNum(60+48,170,cnt,3,16,0X80); //显示数据
  }    
 }
}




//////////////////////////////////////////////////////////////////////////////////
//CAN初始化
//tsjw:重新同步跳跃时间单元.范围:1~3; CAN_SJW_1tq  CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq
//tbs2:时间段2的时间单元.范围:1~8;
//tbs1:时间段1的时间单元.范围:1~16;   CAN_BS1_1tq ~CAN_BS1_16tq
//brp :波特率分频器.范围:1~1024;(实际要加1,也就是1~1024) tq=(brp)*tpclk1
//注意以上参数任何一个都不能设为0,否则会乱.
//波特率=Fpclk1/((tsjw+tbs1+tbs2)*brp);
//mode:0,普通模式;1,回环模式;
//Fpclk1的时钟在初始化的时候设置为36M,如果设置CAN_Normal_Init(1,8,7,5,1);
//则波特率为:36M/((1+8+7)*5)=450Kbps
//返回值:0,初始化OK;
//    其他,初始化失败;


u8 CAN_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 CAN_RX0_INT_ENABLE
    NVIC_InitTypeDef  NVIC_InitStructure;
#endif

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能PORTA时钟                               

   RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//使能CAN1时钟 
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; //复用推挽
    GPIO_Init(GPIOA, &GPIO_InitStructure);  //初始化IO
  
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING ;//上拉输入
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化IO
  /* CAN register init */
  CAN_DeInit(CAN1);
  CAN_StructInit(&CAN_InitStructure); 
  //CAN单元设置
  CAN_InitStructure.CAN_TTCM=DISABLE;       //非时间触发通信模式  //
  CAN_InitStructure.CAN_ABOM=DISABLE;       //软件自动离线管理  //
   CAN_InitStructure.CAN_AWUM=DISABLE;       //睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)//
   CAN_InitStructure.CAN_NART=DISABLE;        //禁止报文自动传送 //
   CAN_InitStructure.CAN_RFLM=DISABLE;       //报文不锁定,新的覆盖旧的 //
   CAN_InitStructure.CAN_TXFP=ENABLE;       //优先级由报文标识符决定 //
   CAN_InitStructure.CAN_Mode= mode;          //模式设置: mode:0,普通模式;1,回环模式; //
   //设置波特率
   CAN_InitStructure.CAN_SJW=tsjw;    //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位  CAN_SJW_1tq  CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq
   CAN_InitStructure.CAN_BS1=tbs1; //Tbs1=tbs1+1个时间单位CAN_BS1_1tq ~CAN_BS1_16tq
   CAN_InitStructure.CAN_BS2=tbs2;//Tbs2=tbs2+1个时间单位CAN_BS2_1tq ~ CAN_BS2_8tq
   CAN_InitStructure.CAN_Prescaler=brp;            //分频系数(Fdiv)为brp+1 //
   CAN_Init(CAN1, &CAN_InitStructure);            // 初始化CAN1

  CAN_FilterInitStructure.CAN_FilterNumber=1;   //过滤器0
  CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
   CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位
   CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;////32位ID
   CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
   CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32位MASK
   CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
   CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器0关联到FIFO0
  CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活过滤器0

   CAN_FilterInit(&CAN_FilterInitStructure);//滤波器初始化
#if CAN_RX0_INT_ENABLE
 
 CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);//FIFO0消息挂号中断允许.     
 
   NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;     // 主优先级为1
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;            // 次优先级为0
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
   NVIC_Init(&NVIC_InitStructure);
#endif
 return 0;
}  
 
#if CAN_RX0_INT_ENABLE //使能RX0中断
//中断服务函数      
void USB_LP_CAN1_RX0_IRQHandler(void)
{
   CanRxMsg RxMessage;
 int i=0;
    CAN_Receive(CAN1, 0, &RxMessage);
// for(i=0;i<8;i++)
// 
//   {            
//    if(i<4)LCD_ShowxNum(60+i*32,270,RxMessage.Data,3,16,0X80); //显示数据
//    else LCD_ShowxNum(60+(i-4)*32,290,RxMessage.Data,3,16,0X80); //显示数据
//    }
 printf("rxbuf[%d]:%d\r\n",i,RxMessage.Data);
}
#endif

//can发送一组数据(固定格式:ID为0X12,标准帧,数据帧) 
//len:数据长度(最大为8)        
//msg:数据指针,最大为8个字节.
//返回值:0,成功;
//   其他,失败;
u8 Can_Send_Msg(u8* msg,u8 len)

  u8 mbox;
  u16 i=0;
  CanTxMsg TxMessage;
  TxMessage.StdId=0;//0x12;      // 标准标识符为0
  TxMessage.ExtId=0;//0x12;     // 设置扩展标示符(29位)
  TxMessage.IDE=0;    // 使用扩展标识符
  TxMessage.RTR=0;   // 消息类型为数据帧,一帧8位
  TxMessage.DLC=len;        // 发送两帧信息
  for(i=0;i<8;i++)
  TxMessage.Data=msg;     // 第一帧信息         
  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;  

}
//can口接收数据查询
//buf:数据缓存区; 
//返回值:0,无数据被收到;
//   其他,接收的数据长度;
u8 Can_Receive_Msg(u8 *buf)
{         
  u32 i;
 CanRxMsg RxMessage;
    if( CAN_MessagePending(CAN1,CAN_FIFO0)==0)return 0;  //没有接收到数据,直接退出
    CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);//读取数据 
    for(i=0;i<8;i++)
    buf=RxMessage.Data
 return RxMessage.DLC; 
}


我做了两个实验板,我将第一块的PA11接第二块的PA12,第一块的PA12接第二块的PA11. 上拉4k7电阻到5v




最佳答案

查看完整内容[请看2#楼]

因为你没用电平转接芯片,所以不行的。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-2-7 15:36:44 | 显示全部楼层
因为你没用电平转接芯片,所以不行的。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

39

主题

2026

帖子

1

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2020
金钱
2020
注册时间
2013-5-1
在线时间
87 小时
发表于 2015-2-7 18:02:39 | 显示全部楼层
没做过,但CAN不需要交叉接线吧?
博观而约取,厚积而薄发。
回复

使用道具 举报

0

主题

43

帖子

0

精华

初级会员

Rank: 2

积分
163
金钱
163
注册时间
2014-11-13
在线时间
28 小时
发表于 2015-2-7 18:27:01 | 显示全部楼层
楼主你用CAN没有加CAN收发芯片,这能行?
回复

使用道具 举报

1

主题

5

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2015-2-7
在线时间
0 小时
 楼主| 发表于 2015-2-8 13:26:42 | 显示全部楼层
回复【4楼】正点原子:
---------------------------------
我做好准备用光线收发。但是在调试的时候,发送数据的时候,调试发现TERR0  为1, 表示发送错误。有需要再电平转换吗?
51单片机RS232串口通信,两个单片机不是互相交叉就能收数据了?CAN就不能吗?
回复

使用道具 举报

1

主题

5

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2015-2-7
在线时间
0 小时
 楼主| 发表于 2015-2-8 13:29:14 | 显示全部楼层
回环模式,不需要电平转换,都能发送成功啊。 那么我自己讲PA11和PA12接线,能在正常模式下实现回环的功能吗? 我试了好像也不行。
回复

使用道具 举报

1

主题

5

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2015-2-7
在线时间
0 小时
 楼主| 发表于 2015-2-8 13:38:36 | 显示全部楼层
回复【3楼】youhm:
---------------------------------
RS232不是可以这么做?不接RS232电平转换不是可以收发成功吗?
另,回环模式下能收发成功,现我执行在正常模式下,将PA11与PA12对接,是不是等效为回环模式呢? 我也收发不成功。
我做好准备用光线收发。但是在调试的时候,发送数据的时候,调试发现TERR0  为1(邮箱0发送错误。需要再电平转换吗? 
51单片机RS232串口通信,两个单片机不是互相交叉就能收数据了?CAN就不能吗?
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-2-8 22:52:36 | 显示全部楼层
回复【5楼】j367926:
---------------------------------
CAN不行的。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

1

主题

5

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2015-2-7
在线时间
0 小时
 楼主| 发表于 2015-2-9 09:07:30 | 显示全部楼层
回复【8楼】正点原子:
---------------------------------

哦,那我只能改别的通信了。谢谢原子兄弟。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-26 03:09

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表