STM32HAL库写CAN通信程序最近遇到了难题,有谁有具体例子不

STM32HAL库写CAN通信程序最近遇到了难题,有谁有具体例子不,第1张

别人写的你参考一下:半年前接触STM32,刚开始MCU用的32F1,库用的标准外设库3.5,写过一些简单的东西。再后来发现ST还有一个软件叫做STM32CUBEMX,可以自动的生成初始化程序,对于我这个32新手来说无疑是天降福音!终于不用为繁琐的配置而苦恼了(其实就是自己对各项配置不熟,而且没有自己积累的程序可以CtrlC+CtrlV)。虽然CUBE用的是ST新出的HAL库,与以前的标准外设库完全不兼容,甚至基本的I/O *** 作都变了,会让习惯了标准外设库的人很苦恼。但是我对标准外设库也不是很熟,而且CUBE的界面化设计真的让配置工程变得很方便,再加上它还有一个类似于FPGA的引脚分配界面,让资源分配,PCB布局布线也方便了不少,于是我选择了用CUBE,用HAL库。很早就开始的写32的朋友有不少,他们也试过HAL库,可最后无一例外都选择了继续使用标准外设库。他们表示完全不习惯HAL库,另外HAL库不太好,毕竟是自动生成的配置,没有自己手动配置的来得熟悉来得透彻,谁知道软件是怎么给你配置的工程。另外CUBE就是给那些不会写32的人用的(ST的官方的说法似乎也是HAL是为了方便做嵌入式相关且对底层不熟的人设计的,但想不通他为何要把两个库做得不兼容)。前面一直在画PCB,调PCB,做机械之类的,没有写程序。最近又开始写32,现在用的MCU是32F4,库是HAL/F4库1.6.0。可是我发现我连GPIO的上拉输出都实现不了,无论如何I/O始终默认输出低电平( *** 作I/O可以实现电平跳变),这个问题我昨天查了一天,从库到最底层的寄存器都看了,可没发现什么问题。周围用HAL库的就我一个。。。有些无奈了,难道HAL库真有什么问题吗?如果真有这么明显的问题,ST官方肯定早就发现了。已经下好了标准外设库,打算换标准外设库,工程从头到尾都自己配置,这样出了问题也更方便找。可是我始终有一点想不明白,既然ST官方在推HAL库,那肯定也有他的道理,我们也应该勇于接受新事物,为何身边的朋友却都不愿意接纳HAL库。

这里有两个晶振,一个是单片机的你选择12M,一个是sja1000的推荐选择16M。

给你程序你不一定能用啊,还要和硬件对应啊,比如你的地址确定问题。

这就是网络的程序为什么大多不能直接使用的原因啊。

给你提供一些思路

1、sja1000初始化

2、发送子程序

3、中断方式接收

下面是一些程序段

你参考下(已用于产品)

/**********SJA1000初始化***********//

void Init_SJA1000(void)

{

uchar state

uchar ACRR[4]={0XAA,0XFF,0X22,0X11}// 接收代码寄存器

uchar AMRR[4]={0xff,0xff,0xff,0xff}// 接收屏蔽寄存器

//uchar AMRR[4]={0x00,0x00,0xff,0xff}// 接收屏蔽寄存器

do// 使用do--while语句确保进入复位模式

{

MODR = 0x09// 设置MOD.0=1--进入复位模式,以便设置相应的寄存器

state = MODR

}

while( !(state &0x01) )

// 对SJA1000部分寄存器进行初始化设置

CDR = 0x88// CDR为时钟分频器,CDR.3=1--时钟关闭, CDR.7=0---basic CAN, CDR.7=1---Peli CAN

BTR0 = 0x04//0x31// 总线定时寄存器0 ;总线波特率设定

BTR1 = 0x1c//0x1c// 总线定时寄存器1 ;总线波特率设定

IER = 0x01// IER.0=1--接收中断使能; IER.1=0--关闭发送中断使能

OCR = 0xaa// 配置输出控制寄存器

CMR = 0x04// 释放接收缓冲器

ACR0 = ACRR[0]// 初始化接收代码寄存器

ACR1 = ACRR[1]

ACR2 = ACRR[2]

ACR3 = ACRR[3]

AMR0 = AMRR[0]// 初始化接收屏蔽寄存器

AMR1 = AMRR[1]

AMR2 = AMRR[2]

AMR3 = AMRR[3]

do// 使用do--while语句确保退出复位模式

{

MODR = 0x08//MOD.3=0--双滤波器模式

state = MODR

}

while( state &0x01 )

}//////////////////////////////////////

//**********CAN发送数据到CAN-Bus***********//

void CAN_TXD(void)

{

uchar state

//初始化标示码头信息

TX_buffer[0] = 0x88//.7=0--扩展帧;.6=0--数据帧.0-.3=100--数据长度为8字节

// TX_buffer[1] = 0xFF//本帧信息的ID

//TX_buffer[2] = 0xFF

TX_buffer[3] = 0xFF

TX_buffer[4] = 0xFF

do //查询SJA1000是否处于接收状态,当SJA1000不处于接收状态时才可继续执行

{

state = SR //SR为SJA1000的状态寄存器

}

while( state &0x10 ) //SR.4=1 正在接收,等待

do //查询SJA1000是否处于发送完毕状态

{

state = SR

}

while(!(state &0x08))//SR.3=0,发送请求未处理完,等待直到SR.3=1

do //查询发送缓冲器状态

{

state = SR

}

while(!(state &0x04))//SR.2=0,发送缓冲器被锁。等待直到SR.2=1

//将待发送的一帧数据信息存入SJA1000的相应寄存器中

TBSR0 = TX_buffer[0]

TBSR1 = TX_buffer[1]

TBSR2 = TX_buffer[2]

TBSR3 = TX_buffer[3]

TBSR4 = TX_buffer[4]

TBSR5 = TX_buffer[5]

TBSR6 = TX_buffer[6]

TBSR7 = TX_buffer[7]

TBSR8 = TX_buffer[8]

TBSR9 = TX_buffer[9]

TBSR10 = TX_buffer[10]

TBSR11 = TX_buffer[11]

TBSR12 = TX_buffer[12]

CMR = 0x04//置位发送请求

}//////////////////////////////////////

//**********中断接收来自CAN-Bus数据***********//

void inter1_can_rxd( void ) interrupt 0

{

uchar state

EA = 0 //关CPU中断

IE0 = 0//由于是中断INT1是电平触发方式,所以需要软件将INT1的中断请求标志IE0清零

state = IR//IR为SJA1000的中断寄存器

if( state &0x01) //若IR.0=1--接收中断

{

RX_buffer[0] = RBSR0

RX_buffer[1] = RBSR1

RX_buffer[2] = RBSR2

RX_buffer[3] = RBSR3

RX_buffer[4] = RBSR4

RX_buffer[5] = RBSR5

RX_buffer[6] = RBSR6

RX_buffer[7] = RBSR7

RX_buffer[8] = RBSR8

RX_buffer[9] = RBSR9

RX_buffer[10] = RBSR10

RX_buffer[11] = RBSR11

RX_buffer[12] = RBSR12

RXD_flag = 1//接收标志置位,以便进入接收处理程序

CMR = 0x04 //CMR.2=1--接收完毕,释放接收缓冲器

state = ALC//释放仲裁随时捕捉寄存器(读该寄存器即可)

state = ECC//释放错误代码捕捉寄存器(读该寄存器即可)

}

IER = 0x01 // IER.0=1--接收中断使能

EA = 1 //重新开启CPU中断

}//////////////////////////////////////

//********** ***********//

希望对你能有帮助


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/8096567.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-13
下一篇 2023-04-13

发表评论

登录后才能评论

评论列表(0条)

保存