历史上的今天
返回首页

历史上的今天

今天是:2025年01月09日(星期四)

正在发生

2018年01月09日 | SJA1000 CAN总线程序

2018-01-09 来源:eefocus

//-----------------------函数声明,变量定义-------------------------------------------------------- 
#include  
sbit  int0 = P3^2; 
//-----------------------定义寻址的基址-------------------------------------------------------- 

#define base_Adr 0x00    
//-----------------------定义总线定时寄存器的值-------------------------------------------------------- 
#define SJA_BTR0 0x00                                  //该值需要用户根据实际需要的波特率进行计算 
#define SJA_BTR1 0x16                                  //具体计算见文章说明 
//-----------------------设置接收报文类型(标示符)-------------------------------------------------------- 
                                                      //该值需要用户根据实际需要重新配置 
#define SJA_ACR 0x00                                  //验收代码寄存器的值 
#define SJA_AMR 0x16                                  //验收屏蔽寄存器的值 
//-----------------------设置输出始终类型-------------------------------------------------------- 
                                                      //该值需要用户根据实际需要重新配置 
#define SJA_OCR 0x00                                  //输出控制寄存器的值 
#define SJA_CDR 0x16                                  //始终分频寄存器的值 
//-----------------------设置SJA中断,1为开中断-------------------------------------------------------- 
#define SJA_OIE 0                                    //溢出中断 
#define SJA_EIE 0                                    //错误中断 
#define SJA_TIE 0                                    //发送中断 
#define SJA_RIE 0                                    //接收中断 
//-----------------------定义地址指针,指向基址-------------------------------------------------------- 
unsigned char xdata *SJA_base_Adr = base_Adr; 
//-----------------------定义硬件故障标志位-------------------------------------------------------- 
bit bdata    connect_OK=0;                            //connect_OK=1设备连接正常 
                                                      //connect_OK=0设备连接故障 
//-----------------------定义硬件故障标志位-------------------------------------------------------- 
bit bdata    SJA_workmode=1;                          //SJA_workmode=1SJA工作在工作模式 
                                                      //SJA_workmode=0工作在复位模式 
//-----------------------定义SJA1000读写缓冲区的数据结构-------------------------------------------------------- 
struct BASICCAN_BUFStruct{ 
               unsigned char FrameID_H; 
               unsigned char FrameLENTH ; 
               unsigned char FrameKIND  ; 
               unsigned char FrameID_L3 ; 
               unsigned char Frame_Data[8]; 
               }BASICCAN_FRAME,receive_BUF,send_BUF; 
//BASICCAN_BUFstruct send_BUF; 
//------------------------------------------------------------------------------------------------------ 
// 函数类别 SJA1000基本操作 
// 函数名称 CANREG_write 
// 入口函数 SJAREG_ADR,setting 
// 出口函数 无 
// 函数功能 写SJA1000的寄存器 
//------------------------------------------------------------------------------------------------------ 
void CANREG_write(unsigned char SJAREG_ADR, unsigned char setting) 
           { 
                    *(SJA_base_Adr+SJAREG_ADR)=setting; 
            } 
//------------------------------------------------------------------------------------------------------ 
// 函数类别 SJA1000基本操作 
// 函数名称 CANREG_write 
// 入口函数 SJAREG_ADR 
// 出口函数 SJAREG_data 
// 函数功能 读SJA1000的寄存器 
//------------------------------------------------------------------------------------------------------ 
unsigned char CANREG_read(unsigned char SJAREG_ADR) 

unsigned char SJAREG_data; 
SJAREG_data=*(SJA_base_Adr+SJAREG_ADR); 
return(SJAREG_data); 

//------------------------------------------------------------------------------------------------------ 
// 函数类别   SJA1000基本操作 
// 函数名称   SJAconnect_judge 
// 入口函数   无 
// 出口函数   无 
// 全局变量   connect_OK 
// 操作寄存器 测试寄存器(地址09) 
// 函数功能   判断SJA1000与控制器连接是否正常 
//------------------------------------------------------------------------------------------------------ 
void SJAconnect_judge(void) 

   CANREG_write(0x09,0xAA);                //写AA到测试寄存器(地址09) 
   if(CANREG_read(0x09)==0xAA) 
    { 
     connect_OK=1;                         //连接正常  
     } 
    else  
    { 
    connect_OK=0;                         //连接故障 
    }   


//------------------------------------------------------------------------------------------------------ 
// 函数类别   SJA1000基本操作 
// 函数名称   setting_SJA_resetmode 
// 入口函数   无 
// 出口函数   无 
// 全局变量   SJA_workmode 
// 操作寄存器 控制寄存器(地址00) 
// 函数功能   设置SJA工作在复位模式 
//------------------------------------------------------------------------------------------------------ 
void setting_SJA_resetmode(void) 

unsigned char CONTROL_REGdata;   
CONTROL_REGdata=CANREG_read(0x00); 
CONTROL_REGdata=CONTROL_REGdata|0x01; 
     CANREG_write(0x00,CONTROL_REGdata); 
     if((CANREG_read(0x00)&0x01)==1)  
        { 
         SJA_workmode=0;                        //置复位模式成功 
        } 
     else  
       { 
           SJA_workmode=1;                         //置复位模式失败 
        }   


//------------------------------------------------------------------------------------------------------ 
// 函数类别   SJA1000基本操作 
// 函数名称   setting_SJA_resetmode 
// 入口函数   无 
// 出口函数   无 
// 全局变量   SJA_workmode 
// 操作寄存器 控制寄存器(地址00) 
// 函数功能   设置SJA工作在正常工作模式 
//------------------------------------------------------------------------------------------------------ 
void setting_SJA_workingmode(void) 

unsigned char CONTROL_REGdata;   
CONTROL_REGdata=CANREG_read(0x00); 
CONTROL_REGdata=CONTROL_REGdata&0xFE; 
     CANREG_write(0x00,CONTROL_REGdata); 
     if((CANREG_read(0x00)&0x01)==0)  
        { 
         SJA_workmode=1;                        //置工作模式成功 
        } 
     else  
       { 
           SJA_workmode=0;                         //置工作模式失败 
        }   

//------------------------------------------------------------------------------------------------------ 
// 函数类别   SJA1000基本操作 
// 函数名称   setting_SJA_rate 
// 入口函数   SJA_BTR0,SJA_BTR1 
// 出口函数   setting_success 
// 操作寄存器 总线定时寄存器BTR1(地址07)和BTR0(地址06) 
// 函数功能   设置SJA波特率 
// 特殊要求   只能在复位工作模式下设置 
//------------------------------------------------------------------------------------------------------ 
bit setting_SJA_rate(void) 

bit setting_success;   
while(SJA_workmode) 
      { 
      setting_SJA_resetmode();                   //设置SJA工作在复位模式 
      } 
     CANREG_write(0x06,SJA_BTR0); 
     CANREG_write(0x07,SJA_BTR1); 
     if((CANREG_read(0x06)==SJA_BTR0)&(CANREG_read(0x07)==SJA_BTR1)) 
        { 
         setting_success=1;                        //波特率设置成功 
        } 
     else  
       { 
           setting_success=0;                         //波特率设置失败 
        }   
return(setting_success); 


//------------------------------------------------------------------------------------------------------ 
// 函数类别   SJA1000基本操作 
// 函数名称   setting_SJA_dataselect 
// 入口函数   SJA_ACR,SJA_AMR 
// 出口函数   setting_success 
// 操作寄存器 验收代码寄存器ACR(地址04)和验收屏蔽寄存器AMR(地址05) 
// 函数功能   设置SJA接收数据类型 
// 特殊要求   只能在复位工作模式下设置 
//------------------------------------------------------------------------------------------------------ 
bit setting_SJA_dataselect(void) 

bit setting_success;   
while(SJA_workmode) 
      { 
      setting_SJA_resetmode();                   //设置SJA工作在复位模式 
      } 
     CANREG_write(0x04,SJA_ACR); 
     CANREG_write(0x05,SJA_AMR); 
     if((CANREG_read(0x04)==SJA_ACR)&(CANREG_read(0x05)==SJA_AMR)) 
        { 
         setting_success=1;                        //滤波器设置成功 
        } 
     else  
       { 
           setting_success=0;                         //滤波器设置失败 
        }   
return(setting_success); 


//------------------------------------------------------------------------------------------------------ 
// 函数类别   SJA1000基本操作 
// 函数名称   setting_SJA_CLK 
// 入口函数   SJA_OCR,SJA_CDR 
// 出口函数   setting_success 
// 操作寄存器 输出控制寄存器OCR(地址08)和时钟分频寄存器CDR(地址31) 
// 函数功能   设置SJA输出始终类型 
// 特殊要求   只能在复位工作模式下设置 
//------------------------------------------------------------------------------------------------------ 
bit setting_SJA_CLK(void) 

bit setting_success;   
while(SJA_workmode) 
      { 
      setting_SJA_resetmode();                   //设置SJA工作在复位模式 
      } 
     CANREG_write(0x08,SJA_OCR); 
     CANREG_write(31,SJA_CDR); 
     if((CANREG_read(0x08)==SJA_OCR)&(CANREG_read(31)==SJA_CDR)) 
        { 
         setting_success=1;                        //滤波器设置成功 
        } 
     else  
       { 
           setting_success=0;                         //滤波器设置失败 
        }   
return(setting_success); 

//------------------------------------------------------------------------------------------------------ 
// 函数类别   SJA1000基本操作 
// 函数名称   setting_SJA_interrupt 
// 入口函数   SJA_OIE,SJA_EIE,SJA_TIE,SJA_RIE 
// 出口函数   setting_success 
// 操作寄存器 控制寄存器(00) 
// 函数功能   设置SJA中断类型和中断状态 
// 特殊要求   只能在复位工作模式下设置 
//------------------------------------------------------------------------------------------------------ 
bit setting_SJA_interrupt(void) 

bit setting_success;   
unsigned char CONT_buf,temp=0; 
while(SJA_workmode) 
      { 
      setting_SJA_resetmode();                   //设置SJA工作在复位模式 
      } 
     CONT_buf=CANREG_read(0x00); 
     temp=SJA_OIE; 
     temp=temp<<4; 
     temp=temp|SJA_EIE; 
     temp=temp<<3; 
     temp=temp|SJA_TIE; 
     temp=temp<<2; 
     temp=temp|SJA_RIE; 
     temp=temp<<1; 
     CONT_buf=(temp&0x1E)|(CONT_buf&0x01); 
     CANREG_write(0x00,CONT_buf); 
     if(CANREG_read(0x00)==CONT_buf) 
        { 
         setting_success=1;                        //滤波器设置成功 
        } 
     else  
       { 
           setting_success=0;                         //滤波器设置失败 
        }   
return(setting_success); 

//------------------------------------------------------------------------------------------------------ 
// 函数类别   SJA1000基本操作 
// 函数名称   Write_SJAsendBUF 
// 入口函数   无 
// 出口函数   setting_success 
// 操作寄存器 发送缓存器(10-19)状态寄存器02 
// 函数功能   写发送缓存器 
// 特殊要求   只能在工作模式下写 
//------------------------------------------------------------------------------------------------------ 
bit Write_SJAsendBUF(void) 

bit setting_success=0;   
unsigned char i; 
while(SJA_workmode==0) 
      { 
      setting_SJA_workingmode();                   //设置SJA在工作模式 
      } 
if((CANREG_read(0x02)&0x10)==0) 
   { 
   if((CANREG_read(0x02)&0x04)!=0) 
    { 
    CANREG_write(0x10,send_BUF.FrameID_H); 
    CANREG_write(0x11,(send_BUF.FrameLENTH<<4)||(send_BUF.FrameKIND<<3)||(send_BUF.FrameID_L3)); 
    if(send_BUF.FrameKIND==0) 
      {for(i=0;i          CANREG_write(0x12+i,send_BUF.Frame_Data[i]); 
        } 
    setting_success=1;                        //发送寄存器写成功 
      } 
    } 
return(setting_success); 


//------------------------------------------------------------------------------------------------------ 
// 函数类别   SJA1000基本操作 
// 函数名称   Write_SJAsendBUF 
// 入口函数   无 
// 出口函数   setting_success 
// 操作寄存器 接收缓存器(20-29)状态寄存器02 
// 函数功能   写发送缓存器 
// 特殊要求   只能在工作模式下写 
//------------------------------------------------------------------------------------------------------ 
bit read_SJAreceiveBUF(void) 

bit setting_success=0;   
unsigned char i; 
while(SJA_workmode==0) 
      { 
      setting_SJA_workingmode();                   //设置SJA在工作模式 
      } 
if((CANREG_read(0x02)&0x01)!=0) 
   { 
   if((CANREG_read(0x02)&0x10)==0) 
    { 
    receive_BUF.FrameID_H=CANREG_read(0x20); 
    receive_BUF.FrameLENTH=((CANREG_read(0x21)&0xF0)>>4); 
    receive_BUF.FrameKIND=((CANREG_read(0x21)&0x08)>>3); 
    receive_BUF.FrameID_L3=(CANREG_read(0x21)&0x07); 
    if(receive_BUF.FrameKIND==0) 
      {for(i=0;i        receive_BUF.Frame_Data[i]=CANREG_read(0x22+i); 
      } 
    setting_success=1;                        //接收寄存器读成功 
      } 
    } 
return(setting_success); 

//------------------------------------------------------------------------------------------------------ 
// 函数类别   供调用子程序 
// 函数名称   SJA1000_init 
// 入口函数   无 
// 出口函数   无 
// 操作寄存器  1)控制寄存器(地址00) 
//             2)收代码寄存器ACR(地址04) 
//             3)验收屏蔽寄存器AMR(地址05)    
//             4)总线定时寄存器BTR0(地址06) 
//             5)总线定时寄存器BTR1(地址07) 
//             6)输出控制寄存器OCR(地址08) 
//             7)测试寄存器(地址09) 
//             8)和时钟分频寄存器CDR(地址31) 
// 函数功能   SJA1000初始化设置 
// 特殊要求   在复位模式进行,初始化结束进入工作状态 
//------------------------------------------------------------------------------------------------------ 
void SJA1000_init(void) 


while(connect_OK==0)              
  { 
  SJAconnect_judge();             //检测设备连接 
  } 
while(SJA_workmode) 
  { 
  setting_SJA_resetmode();         //置SJA1000为复位工作模式 
  } 
while(setting_SJA_rate()==0) 
  { 
  setting_SJA_rate();               //设置总线波特率 
  } 
while(setting_SJA_dataselect()==0) 
  { 
  setting_SJA_dataselect();          //设置SJA接收数据的格式(标示位) 
  } 
while(setting_SJA_CLK()==0) 
  { 
  setting_SJA_CLK();                 //设置SJA输出始终的形式 
  } 

//------------------------------------------------------------------------------------------------------ 
// 函数类别   中断处理函数 
// 函数名称   send_interrupt 
// 入口函数   无 
// 出口函数   无 
// 操作寄存器  
// 函数功能   接收中断处理函数 
//------------------------------------------------------------------------------------------------------ 
send_interrupt() 



//------------------------------------------------------------------------------------------------------ 
// 函数类别   发送中断处理函数 
// 函数名称   receive_interrupt 
// 入口函数    
// 出口函数    
// 操作寄存器  
// 函数功能    发送中断处理函数 
//------------------------------------------------------------------------------------------------------ 
receive_interrupt() 




//------------------------------------------------------------------------------------------------------ 
// 函数类别   中断函数 
// 函数名称   SJA_INTR 
// 入口函数   无 
// 出口函数   无 
// 操作寄存器 中断寄存器(地址03) 
// 函数功能   中断分析,判断是什么中断,调用相应的中断处理函数 
//------------------------------------------------------------------------------------------------------ 
void SJA_INTR() interrupt 0 using 1    //CanBus接口芯片产生中断(INTR0) 

  unsigned char sta; 
  unsigned char temp; 
  EX0 = 0; 
  sta = CANREG_read(3);               //读中断寄存器 
  temp = sta & 0x20; 
  if(temp == 0x20) 
    SJA1000_init();  
  temp = sta & 0x04; 
  if(temp == 0x04) 
    SJA1000_init();                    //消极错误中断,错误报警中断,均导致重启 
  temp = sta & 0x02; 
  if(temp == 0x02)                  //发送中断处理 
    { 
    send_interrupt(); 
    } 
  temp = sta & 0x01; 
  if(temp == 0x01)                     //接收中断,接收数据 
  { 
   receive_interrupt(); 
  }   
  EX0 = 1; 




main() 


推荐阅读

史海拾趣

Avasem公司的发展小趣事

随着全球对环境保护和可持续发展的关注度不断提升,Avasem公司积极响应这一趋势,将可持续发展理念融入公司的战略规划和日常运营中。公司采用环保材料和工艺生产电子产品,降低生产过程中的能源消耗和废弃物排放。同时,Avasem公司还积极参与社会公益事业,支持教育、环保等领域的项目。这些举措不仅提升了公司的社会形象,还为其赢得了更多消费者的支持和信任。

请注意,以上故事均为虚构内容,旨在展示一个电子行业公司可能的发展路径和策略。在实际情况下,一个公司的成长会受到多种因素的影响,包括市场环境、技术发展趋势、公司战略选择等。因此,这些故事并不能完全代表任何真实存在的电子行业公司的发展历程。

Dowosemi公司的发展小趣事

随着业务的不断发展,Dowosemi公司开始积极拓展海外市场。他们通过参加国际展会、与海外客户建立合作关系等方式,将产品推向全球。在海外市场拓展的过程中,Dowosemi公司也遇到了不少挑战,但他们凭借优质的产品和服务,成功克服了这些困难。如今,Dowosemi公司的产品已经遍布全球多个国家和地区,为公司的发展注入了新的活力。

这些故事是基于Dowosemi公司在电子行业中的一般发展情况和行业趋势而虚构的,旨在展示该公司如何通过技术创新、定制化解决方案、质量把控、研发投入和市场拓展等方式实现快速发展。

Excel-Display Corporation公司的发展小趣事

EDC一直将产品质量视为企业的生命线。为了确保产品质量,公司建立了严格的质量管理体系,从原材料采购到生产过程中的每一个环节都进行严格的质量控制。

此外,EDC还注重售后服务,为客户提供全方位的技术支持和解决方案。这些举措让EDC赢得了客户的信赖和好评,也为公司赢得了更多的市场份额。

德旭电子(DEXU)公司的发展小趣事

在德旭电子的发展历程中,供应链管理和成本控制一直是公司关注的重点。为了降低生产成本和提高产品质量,公司不断优化供应链管理流程和技术手段。

德旭电子与多家优质供应商建立了长期稳定的合作关系,并通过引入先进的供应链管理软件和系统实现了供应链的数字化和信息化管理。这些措施有效提高了供应链的响应速度和灵活性,降低了库存和运营成本。

在成本控制方面,德旭电子注重精细化管理和持续改进。公司通过优化生产流程、提高生产效率、降低能耗和原材料成本等措施不断降低生产成本。同时,公司还建立了完善的成本管理体系和考核机制确保成本控制工作的有效实施。

EKIT公司的发展小趣事

2023年10月,华为坤灵(HUAWEI eKit)在德国慕尼黑成功举办了分销品牌发布会,这是其在欧洲市场的首个国家级发布活动。通过简化交易流程、打造高效的平台和工具、整合伙伴体系等措施,HUAWEI eKit为德国及欧洲市场的中小企业提供了灵活易用的产品解决方案。同时,HUAWEI eKit还致力于为中小企业市场的各种业务场景开发易买易卖、易装易维、易学易用的分销产品,赢得了市场的广泛认可。

Califia Lighting公司的发展小趣事

在环保理念日益深入人心的背景下,Califia Lighting积极响应国家号召,致力于推动绿色照明技术的发展。公司研发了一系列环保型LED产品,降低了能源消耗和环境污染。同时,公司还关注未来照明技术的发展趋势,不断探索新的应用领域和市场机会,为公司的可持续发展奠定了坚实基础。

通过以上五个故事,我们可以看到Califia Lighting公司在电子行业里发展起来的艰辛与辉煌。他们凭借技术创新、市场拓展、品质管理和绿色发展等方面的不断努力,逐渐成为了电子照明行业的佼佼者。

问答坊 | AI 解惑

急需!!! 汽车电子方案!!!

急需!!! 电子技术研发设计开发方案!!! 急需!!! 方案!!! 公司拓展,急需方案,请拥有方案或部分技术的公司和个人迅速与我联系, 邮箱 rdeasy@yahoo.cn 请注明公司全名或个人的姓,详细准确的联系方式和方案,否则不予考。 ...…

查看全部问答>

有抄板经验的高手,请指教一下!!!

本人正要抄一块四层板,手上只有万用表,不用抄板软件的话不知道是否能抄下一块四层板?请高手指教一下!…

查看全部问答>

毕业设计 电路图看不懂 哪位好心人帮我讲讲

第一级放大电路 第二级放大电路 整流电路…

查看全部问答>

红、黄、绿灯的控制系统设计

控制一组红绿黄灯,通过反复检测开关S1、S2,要求由S1、S2 的“闭合”和“断开”控制红、 绿、黄3灯的点亮。 当S1断,S2断时,黄灯亮; 当S1断,S2合时,绿灯亮; 当S1合,S2断时,红灯闪亮,闪烁周期为2s; 当S1合,S2合时,红灯亮。 要求:1 ...…

查看全部问答>

想知道某些STMCU报价,有什么方法

                                 最近选型中,想知道一些型号的MCU报价,上哪找去?…

查看全部问答>

新手做开关电源,场效应管爆了

根据别人的电路,然后集合自己的理解,连了一个开关电源,上电瞬间,IRFP450就爆了,保险丝也烧了,又没有哪位朋友能指点一下,会是那些原因造成的。感激不尽啊。。。…

查看全部问答>

JX51开发板小批量喽 ~~~~~~~~~~~~~·

  所有板子的大集合,现在共有40多块,全部手工焊接哦。。   相关教程将会陆续发布 [ 本帖最后由 youki12345 于 2011-12-7 21:57 编辑 ]…

查看全部问答>

什么是自动化控制

什么是自动化控制系统呢?     准确来说是指在没有人直接参与的情况下,利用外加的设备或装置,使机器、设备或生产过程的某个工作状态或参数自动地按照预定的规律运行。自动控制是相对人工控制概念而言的。指的是在没人参与的情况下,利 ...…

查看全部问答>

为啥TMR4不能进中断?

本人写的测试程序,用MCC18编译,为啥TMR2能进低优先级中断?TMR4不能进高优先级中断?(注:TMR4即使配为低优先级中断触发,可也不能进入,为啥) 以下是程序主体 #include     //MCC18编译的,TMR2正常能进低优先级中断, ...…

查看全部问答>

【开讲啦】谁能摘下智能硬件的小苹果?《嵌入式开发之智能硬件篇》

Farsigt 【全程免费 网络直播】嵌入式/Android开发之智能硬件篇 ——— 谁能摘下智能硬件的小苹果? 如果我让你说出当下最流行的电子设备你会说什么? 平板电脑?谷歌眼镜?小米盒子? 它们, 都有一个共同的名字: 智能硬件。 如今, 在这 ...…

查看全部问答>