汽车芯片应用 ---L9826
1 芯片简介
ST公司的L9826芯片,8通道低边驱动,SPI通信方式,带诊断功能,同时两个端口可以并行控制,驱动能力450ma。
1.1 硬件设计
1.1.1 封装:
SO20
图1.1.1
1.1.2 引脚定义:
引脚 |
名称 |
描述 |
1 |
Out6 |
输出端口6 |
2 |
Out1 |
输出端口1 |
3 |
NRes |
复位口 |
4 |
NCS |
SPI片选口 |
5 |
GND |
地 |
6 |
GND |
地 |
7 |
NON1 |
输出端口1的并行控制口 |
8 |
SDO |
SPI控制线 |
9 |
Out8 |
输出端口8 |
10 |
Out3 |
输出端口3 |
11 |
Out5 |
输出端口5 |
12 |
Out2 |
输出端口2 |
13 |
SDI |
SPI控制线 |
14 |
CLK |
SPI控制线 |
15 |
GND |
地 |
16 |
GND |
地 |
17 |
NON2 |
输出端口2的并行控制口 |
18 |
Vcc |
电源 |
19 |
Out7 |
输出端口7 |
20 |
Out4 |
输出端口4 |
2 软件设计
软件设计主要包括,器件的初始化,IO控制,诊断数据读取。
2.1 SPI通信
2.1.1 SPI时序分析:
Spi的通信速率可达到3Mhz,下降沿移位数据,上升沿锁存数据到输出寄存器。具体时序图如下
具体实现函数如下,详细代码参考附录中百度网盘下载地址。
/******************************************************************************
* spi 读写函数
*
* 说明: spi 时序操作函数,第一个时钟的上升沿输出数据。
*
* 参数: cmd 通过 MOSI 写入的数据
*
* 返回: MISO 读出的数据
******************************************************************************/
INT8U L9826SpiRdWr (INT8U cmd)
{
INT8U i;
INT8U tmp;
CPU_ENTER_CRITICAL()
L9826_CLK_L()
tmp = 0;
Delay(2);
L9826_SPI_EN() //芯片要求在时钟的低电平才能操作芯片使能脚
for (i = 0;i < 8;i++)
{
L9826_CLK_H() //时钟的上升沿 MOSI 移位数据
if (cmd & 0x80)
{
L9826_SDI_H()
}
else
{
L9826_SDI_L()
}
cmd <<= 1;
// Delay(2);
tmp <<= 1;
if (GET_L9826_SDO()) //上升沿读数据
{
tmp++;
}
L9826_CLK_L() //下降沿数据写入从机
//Delay(2);
}
CPU_EXIT_CRITICAL()
L9826_SPI_DIS()
return tmp;
}
注:1. 函数中的Delay()函数可根据实际情况调试选择合适的参数,其影响器件的spi通信速率。
2.由于SPI对时序要求不是很严格,CPU_EXIT_CRITICAL()和CPU_ENTER_CRITICAL()可以(临界代码保护)屏蔽。
2.1.2 SPI 操作说明:
Spi通过给器件发送相应的控制字节,控制对应的通道开关,同时获取器件返回的数据(诊断相关)。
如上图所示,8个通道对应一个字节,每一个bit对应一个通道。如发送0x01,则Q7输出有效低电平。同时收到各个通道的诊断数据,如下图:
对于上述这个数据格式,软件里使用了位域操作方式,使用该方式的局限性是不同的MCU大小端模式不同对于的定义不同,为提高程序的通用性建议使用宏操作。本文使用的是HCS12内核,codewarrior开发环境,数据类型如下:
typedef union
{
uchar bytes;
struct
{
uchar chn7 :1;
uchar chn5 :1;
uchar chn3 :1;
uchar chn1 :1;
uchar chn8 :1;
uchar chn6 :1;
uchar chn4 :1;
uchar chn2 :1; //2 channel
} Bits;
} CTRL_BYTE_TYPE;
如果大小端和作者使用的开发平台一致可直接复用,如不同可修改如下:
typedef union
{
uchar bytes;
struct
{
uchar chn2 :1;
uchar chn4 :1;
uchar chn6 :1;
uchar chn8 :1;
uchar chn1 :1;
uchar chn7 :1;
uchar chn5 :1;
uchar chn7 :1; //2 channel
} Bits;
} CTRL_BYTE_TYPE;
有了数据结构,我们操作起来就方便,如,通道1为LED控制,可如下定义操作宏:
#define LED_CTRL chnData.Bits.chn1 // chnData为通道控制数据
#define LED_ON() LED_CTRL = 1; //开灯
#define LED_OFF() LED_CTRL = 0; //关灯
有了上述这种接口我们操作相应的宏非常方便,只需要在软件中周期性的把chnData通过SPI发送给器件。
2.2 诊断
我们周期性的把chnData发送给器件,同时会收到一个字节的数据,此数据中包含诊断信息。这里我们只关注SPI命令操作的诊断,只能检测两种情况1:输出短路到电源,2:输出开路或输出短路到地。
从图中可看到,如果通道输出1,得到的相应通道诊断数据也是1,此为1故障状态,类似的,如果输出通道0,得到的相应通道诊断数据也是0,此为2故障状态。其他情况为正常。
假设我们得到的诊断数据为chnSta,则软件中可以如下处理:
CTRL_BYTE_TYPE orTmp.bytes,andTmp.bytes;
//把控制数据和诊断数据进行位或,位与操作
orTmp.bytes = chnSta.bytes | chnData.bytes;
andTmp.bytes = chnSta.bytes & chnData.bytes;
if (orTmp.Bits.chn1 == 0)
{
//输出开路或输出短路到地
}
else if (andTmp.Bits.chn1 == 1)
{
//输出短路到电源
}
else
{
//正常
}
2.3 软件简介
整个软件的构架L9826_spi.c, L9826_app.c其中L9826_spi.c为L9826器件spi通信的驱动,L9826app.c则在spi的基础上封装了L9826的相关操作。
2.3.1移植接口
#define L9826_NCS XXX
#define L9826_CLK XXX
#define L9826_SDI XXX
#define L9826_SDO XXX
#define L9826_RST XXX
用户只需要在代码中定义其用于接口即可。
2.3.2 使用说明
在移植好相关接口后,需要在初始化中调用InitL9826()函数,然后周期性调用L9826Monitor(),具体的调用周期看项目的实时性要求,本人使用的调用周期为10ms。
用户只需要在L9826_app.h文件中定义形如
//8 路输出通道控制 -- 写 1 输出低电平,
#define XXX chnData.Bits.chn1
#define XXX chnData.Bits.chn2
#define XXX chnData.Bits.chn3
#define XXX chnData.Bits.chn4
#define XXX chnData.Bits.chn5
#define XXX chnData.Bits.chn6
#define XXX chnData.Bits.chn7
#define XXX chnData.Bits.chn8
欢迎关注微信号,获取更多资讯和代码下载地址: