最近进度有点慢。现在把我spi这部分分享下吧。这次我使用spi0和i2c2这两个模块,i2c2负责采集mpu6050的数据,然后用oled刷新数据。
spi是串行外设接口(serial peripheral interface)的缩写。spi,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为pcb的布局上节省空间,提供方便,正是出于这种简单易用的特性,如今越来越多的芯片集成了这种通信协议,在lpc5410中有两个spi的模块,分别是spi0和spi1。
spi根据spi时钟极性的极性和spi时钟相位,spi时钟极性cpol, =0表示在没有数据传输时为低电平,= 1表示没有数据传输时为高电平。spi时钟相位cpha,= 0表示时钟的第一个沿更新数据、第二个沿锁存数据,= 1表示时钟的第一个沿锁存数据、第二个沿更新数据。如下面的几个时序图:
我这次用了lpc54102的spi0刷了小oled。首先lpc54102套件上有个spi / i2c brdge header,如下套件的原理图:
具体位置如下图:
板子的背面有对应的丝印文字,很容易找到。
这次没用到中断和dma。首先我们要配置好管脚。
voidinit_spi_pinmux(void)
{
/* 1.3 = spi0_sck, 0.14 = spi0_sseln0,0.12 = spi0_mosi, 1.4 = spi0_miso */
chip_iocon_pinmuxset(lpc_iocon, 1,3, (iocon_func5 | iocon_digital_en |iocon_mode_pullup));
chip_iocon_pinmuxset(lpc_iocon, 0, 14,(iocon_func1 | iocon_digital_en | iocon_mode_pullup));
chip_iocon_pinmuxset(lpc_iocon, 0, 12,(iocon_func1 | iocon_digital_en | iocon_mode_pullup));
chip_iocon_pinmuxset(lpc_iocon, 1,4, (iocon_func5 | iocon_digital_en |iocon_mode_pullup));
}
然后进行spi的初始化。如下函数:
根据oled上的ssd1306提供的手册和别人的写的模拟spi驱动,我们要选用cpol = 0,和cpa = 0这种模式。
ssd1306的4线spi的时序图:
voidspi_init()
{
uint32_t memsize, *devmem;
rom_spim_init_t spiminit;
rom_spim_xfer_config_t spimconfig;
int i;
init_spi_pinmux();
chip_clock_enableperiphclock(lpc_spim_clock);
chip_syscon_periphreset(lpc_spim_reset);
/* get needed size for drivercontext memory */
memsize = rom_spim_getmemsize();
if (memsize 》 sizeof(drvdata)) {
debugout(“can‘t allocatememory for driver context
”);
}
devmem = drvdata; /* or just use malloc(memsize) */
/* initialize driver */
spiminit.puserdata = null;
spiminit.base = (uint32_t) lpc_spim_port;
spiminit.baseclockrate =chip_clock_getasyncsyscon_clockrate();
spiminit.spipol[0] = 0; /* active low select for ssel0 */
spiminit.spipol[1] = 1;
spiminit.spipol[2] = 1;
spiminit.spipol[3] = 1;
spimhandle = rom_spim_init(devmem,&spiminit);
if (spimhandle == null) {
/* error initializing spi */
debugout(“error initializingrom
”);
}
/* set spi transfer configuration */
spimconfig.dxferbitrate = spi_bitrate;
spimconfig.mode =rom_spi_clock_cpha0_cpol0;
spimconfig.lsbfirst = 0;
spimconfig.databits = 8;
spimconfig.predelay = 3;
spimconfig.postdelay = 1;
spimconfig.framedelay = 2;
spimconfig.transferdelay = 1;
if (rom_spim_setuptransfer(spimhandle,&spimconfig) != lpc_ok) {
debugout(“spi configurationis invalid
”);
}
/* show desired and actual spi rates */
debugout(“spi rate = %d (actual%d)
”, spimconfig.dxferbitrate, spimconfig.rxferbitrate);
/* callback registration for assertionand de-assertion events */
rom_spim_registercallback(spimhandle,rom_spim_assertssel_cb, (void *) cbspimasterxfercsassertcb);
rom_spim_registercallback(spimhandle,rom_spim_deassertssel_cb, (void *) cbspimmasterxfercsdeassertcb);
}
我对这里面几个关键的参数作下说明吧:
spiminit.spipol[0] = 0; /* active low select for ssel0 */
spiminit.spipol[1] = 1;
spiminit.spipol[2] = 1;
spiminit.spipol[3] = 1;
spiminit.spipol[x]是对应的4个片选ssel0~ ssel3引脚。
spimconfig.dxferbitrate= spi_bitrate;这个是时钟频率的参数,单位是hz。
spimconfig.mode= rom_spi_clock_cpha0_cpol0;这是设定spi时钟极性的极性和spi时钟相位的参数。如在spi的底层中可以看到这4个参数代表了4中模式。
spimconfig.lsbfirst= 0;这个是设置开始传输的数据是最高位还是最低位。9代表开始传输的是最高位,1代表开始传输的最低位。
spimconfig.databits= 8;这个参数是每次传输的数据多少位,可以1到16bit数据之间。
spimconfig.predelay = 3;
spimconfig.postdelay = 1;
spimconfig.framedelay = 2;
spimconfig.transferdelay = 1;
上面这几个参数是传输时的几个延时,我这里就不作过多说明了,我也在了解中。
附上测试图:
线接的有些乱;
现在共享我的源代码:
里面集成adxl345和mpu6050的驱动,看过时序,没问题。
欧盟为防止滥用面部识别 考虑禁时五年限用面部识别
RFID系统中耦合器定向性的提高方法
等夏天,等秋天,等了这么久iPhone8你什么时候才能到来?
新能源客车的去库存和专用车的加库存
瑞声科技2018年光学分部营收同比增长240%至5.5亿元
教你LPC54102双核套件固件库SPI的用法
嵌入式ARM处理具备怎样的优势
传TDK拟收购陀螺仪供应商应美盛
图文详解天线模式与性能及参数知识
采用数字示波器进行多域测量
外媒:中国集成电路设计产业营收的年复合增长率为22%
PicoScope OEM应用分享—电源时序测试
华大半导体旗下积塔半导体汽车芯片生产线项目银团正式签约
全新的WEBENCH®电源设计器将更加易于使用
AT&T和Orange等四家运营商在联网设备中成功激活了LTE-M漫游功能
DC/DC转换器的电感和电容器的选定-输入电容器的选定
代尔夫特数据集(VOD),4D雷达、激光雷达和相机数据
机器视觉检测设备上市企业
莱迪思半导体超低功耗FPGA解决方案助力机器学习面向大众市场
打造具有一定规模和国际竞争力的制造业,是经济能否稳定增长的核心