当前位置: 首页 > news >正文

开网站建设公司好高端网站制作多少钱

开网站建设公司好,高端网站制作多少钱,文章网建站,哈尔滨大型网站建设Author#xff1a;杨正 Data#xff1a;2016.1.1 Mail#xff1a;yz2012wwgmail.com一、 概述 SPI是英文SerialPeripheral Interface的缩写#xff0c;顾名思义就是串行外围设备接口。SPI是一种高速、全双工、同步通信总线#xff0c;标准的SPI有4个引脚#xff…Author杨正  Data2016.1.1  Mailyz2012wwgmail.com一、       概述 SPI是英文SerialPeripheral Interface的缩写顾名思义就是串行外围设备接口。SPI是一种高速、全双工、同步通信总线标准的SPI有4个引脚常用于单片机和EEPROM、FLASH、实时时钟、数字信号处理等器件的通信。SPI通信原理要比I2C简单它主要是主从方式通信这种通信方式通常只有一个主机和一个或多个从机标准的SPI是4根线分别是SSEL片选、SCLK时钟也写作SCK、MOSI主机输入从机输出和MISO主机输入从机输出。 SSEL从设备片选使能信号。譬如从设备是低电平使能的话当拉低这个引脚从设备就会被选中主机和这个被选中的从设备通信。 SCLK时钟信号即主机产生。 MOSI主机给从机发送指令或者数据的通道。 MISO主机读取从机的状态或者数据的通道。   在某些情况下也可以用3根或者2根线的SPI进行通信。譬如主机只给从机发送指令从机不需要回复数据的时候MISO就可以不要而主机只读从机的数据不需要给从机发送数据的时候MOSI就可以不要当一个主机与一个从机通信时从机的片选有时可以固定为有效电平而一直处于使能状态那么SSEL可以不要此时如果主机只给从机发数据那么SSEL和MISO都可以不要如果主机只读取从机发送来的数据那么SSEL和MOSI都可以不要。当然一般情况下说的SPI都指的是标准的SPI有4根线进行通信。     二、  时序分析 众所周知SPI时序有4种模式在讲解4种模式之前先学习两个单词即Polarity和Phase这两个单词分别是SPI的时钟极性Polarity和相位Phase最常见的写法CPOL和CPHA也有其它的一些写法如 (1) CKPOL (Clock Polarity) CPOL POL Polarity 时钟极性 (2) CKPHA (Clock Phase)    CPHA PHA Phase 时钟相位   那么时钟极性是什么概念呢SPI通信过程分为空闲状态和通信状态空闲状态是指SCLK在数据发送之前和发送完之后的状态通信状态当然就是指发送数据的状态。CPOL1那么空闲状态SCLK为高电平反之CPOL0则空闲状态SCLK为低电平。   SPI是一个环形的总线结构主要是在SCLK的控制下两个双向移位寄存器进行数据交换。那么主机和从机在进行交换数据的时候就设计到一个问题即主机在什么时刻输出到MOSI上而从机在什么时刻采样这个数据或者从机什么时刻输出到MISO上而主机什么时刻采样这个数据。同步通信的一个特点就是所有数据的变化和采样都是伴随着时钟沿进行的也就是说数据总是在时钟的边沿附近变化或被采样而一个完整的时钟周期必定包含了一个上升沿和一个下降沿这是周期的定义所决定的只是这两个沿的先后并无规定。又因为数据从产生到它稳定是需要一定的时间那么如果主机在上升沿输出数据到MOSI从机就只能在下降沿去采样这个数据了。反之如果一方在下降沿输出数据那么另一方就必须在上升沿采样这个数据。那么由谁来决定上升沿采样还是下降沿采样上升沿输出还是下降沿输出呢   当CPHA1时表示数据的输出在一个时钟周期的第一个沿上至于这个沿是上升沿还是下降沿就得由CPOL来决定。CPOL1那就是下降沿反之就是上升沿。那么数据采样自然就是第二个沿上了。 当CPHA0时表示数据采样在一个时钟周期的第一个沿上至于这个沿是上升沿还是下降沿就得由CPOL来决定。CPOL1那就是下降沿反之就是上升沿。那么数据输出自然就是第二个沿上了。   通过以上的学习SPI的4中模式其实已经浮现出来了下面对此做一总结 Mode0 CPOL0CPHA0 Mode1 CPOL0CPHA1 Mode2 CPOL1CPHA0 Mode3 CPOL1CPHA1   图形比文字更容易看懂所以SPI4种模式的时序图如下 再进一步说明模式1。当SPI处于使能状态而且发送FIFO内有有效数据时设置SSEL信号为低表示开始传输数据。来自Slave的数据立刻发送到Master的接收数据线MISO。半个SCLK时钟周期之后有效的Master数据传输到MOSI。此时Master和Slave数据都已经有效SCLK管脚在接下来的半个SCLK时钟周期之后变为高电平。数据在SCLK时钟的上升沿被捕获(采样)在时钟的下降沿被传送输出传输完成后SSEL恢复为高电平。   再进一步说明模式2。当SPI为使能状态而且发送FIFO内有有效数据时设置SSEL信号为低表示开始传输数据。半个SCLK时钟周期之后Master和Slave的有效数据分别在各自的传输线上有效。同时SCLK从第一个上升沿开始有效。数据在SCLK时钟的下降沿被捕获在时钟的上升沿被传送传输完成后SSEL恢复为高电平。   再进一步的说明模式3。当SPI为使能状态而且发送FIFO内有有效数据时设置SSEL信号为低表示开始传输数据。此时Slave的数据立刻发送到Master的接收数据线MISO。半个SCLK周期之后Master的有效数据传送到MOSI。再过半个SCLK时钟周期之后SCLK管脚设置为低。这表示数据在SCLK时钟的下降沿被捕获在SCLK时钟的上升沿被传送传输完成后SSEL恢复为高电平。   再进一步的说明模式4。当SPI为使能状态而且发送FIFO内有有效数据时设置SSEL信号为低表示开始传输数据。半个SCLK时钟周期后Master和Slave数据在各自的传输线上有效。同时时钟SCLK从1个下降沿开始有效。数据在SCLK时钟的上升沿被捕获在时钟的下降沿被传送传输完成后SSEL恢复为高电平。       三、  SPI访问寄存器模式   常见的SPI访问寄存器模式有3种分别是SingleAccess单次访问、Burst Access突发访问、FIFO AccessFIFO访问。   SingleAccess通过写访问发送一个地址字节后跟一个数据字节或者发送一个地址字节再通过读访问接收一个数据字节。发送帧时SSEL为低发送完最后一个字节后SSEL变为高。如下图将0x0A写到寄存器0x02上再从该寄存器上读其值。 W addr. 0x02 Data: 0x0A                      R addr. 0x02 Data: 注意SSEL第一次为低电平使能时MISO变为高电平然后立即变为低电平这表示从设备芯片已经装备好Thefirst time CSn goes low, MISO goes high and then low again immediately,indicating that the chip is ready.。 Single Byte Access (Write and Read)     BurstAccess一个地址字节后跟多个数据字节。在每个数据字节之间地址字节会在内部自动增加并且片选信号SSEL在发送帧时为低电平在每个数据字节之间也保持低电平当发送完最后一个字节后变为高电平。如 BYTE xdata regValues[] {1,2,3}; halSpiWriteBurstReg(0x00, regValues,sizeof(regValues)); halSpiReadReg(0x00); halSpiReadReg(0x01); halSpiReadReg(0x02) BurstWrite Followed by Single Read     FIFO Access如果地址字节对应的是FIFO地址那么随后的数据字节将针对FIFO。该地址字节没有自动递增而被存储并且不需要在每个数据字节之间发送该地址。片选信号SSEL在发送帧时为低电平在每个数据字节之间也保持低电平当发送完最后一个字节后变为高电平。   特别说明不同的SPI从设备地址字节的内容不一定相同需要查看相关手册才能知道地址字节的构成是什么样的。例如RFM69H这个模块SPI的地址字节的组成如下 The first byteis the address byte. It is made of: u  wnr bit, whichis 1 for write access and 0 for read access u 7 bits of address, MSB first   又如CCXX00的地址字节组成如下 The R/W bit in the address header controlsif the register should be written or read, and the burst bit controls if it is a single access or a burst access. R/W Burst A5 A4 A3 A2 A1 A0 注其实地址位只有5位最高位为读写位1为读0为写后面一位是burstAccess的使能位当为1时使能。     四、  例程解析 特别注意在主设备这边配置SPI接口时钟的时候一定要弄清楚从设备的时钟要求因为主设备这边的时钟极性和相位都是以从设备为基准的。因此在时钟极性的配置上一定要搞清楚从设备是在时钟的上升沿还是下降沿接收数据是在时钟的下降沿还是上升沿输出数据。但要注意的是由于主设备的SDO连接从设备的SDI从设备的SDO连接主设备的SDI从设备SDI接收的数据是主设备的SDO发送过来的主设备SDI接收的数据是从设备SDO发送过来的所以主设备这边SPI时钟极性的配置即SDO的配置跟从设备的SDI接收数据的极性是相反的跟从设备SDO发送数据的极性是相同的。   通过手册得知MOSI is generated by the master on the falling edge ofSCK and is sampled by the slave (i.e. this SPI interface) on the rising edge ofSCK. MISO is generated by the slave on the falling edge of SCK.A transferalways starts by the NSS pin going low. MISO is high impedance when NSS ishigh.本例程使用的从设备的SPI工作在Mode1即CPOL 0 and CPHA 0且SSEL低电平使能当SSEL为高电平时MISO为高。故主机的MOSI在空闲状态时为高。 /********************************************************************************* * Copyright: (C) 2015 YangZhengyz2012wwgmail.com * All rights reserved. * * Filename: dev_rfm69h.c * Description: This file * * Version: 1.0.0(12/28/2015~) * Author: Yang Zhengyz2012wwgmail.com * ChangeLog: 1, Release initialversion on 12/28/2015 07:46:07 PM * ********************************************************************************/ #includelinux/kernel.h #includelinux/version.h #includelinux/module.h #includelinux/types.h #includelinux/errno.h #includelinux/fcntl.h #includelinux/mm.h #includelinux/proc_fs.h #includelinux/fs.h #includelinux/slab.h #includelinux/init.h #includeasm/uaccess.h #includeasm/io.h #include asm/system.h #includelinux/miscdevice.h #includelinux/delay.h #includelinux/sched.h #includelinux/proc_fs.h #includelinux/poll.h #includeasm/bitops.h #includeasm/uaccess.h #includeasm/irq.h #includelinux/moduleparam.h #include linux/ioport.h #includelinux/interrupt.h #includelinux/cdev.h #includelinux/semaphore.h #includelinux/wait.h #define IOCONFIG4_4 IO_ADDRESS(0x200f0000 0x054) //复用管脚gpio4_4 #define IOCONFIG4_5 IO_ADDRESS(0x200f0000 0x050) //复用管脚gpio4_5 #define IOCONFIG4_6 IO_ADDRESS(0x200f0000 0x04c) //复用管脚gpio4_6 #define IOCONFIG4_7 IO_ADDRESS(0x200f0000 0x048) //复用管脚gpio4_7 #define GPIO4_BASE 0x20180000 //gpio基地址 #define GPIO4_SIZE 0x10000 // 64KB #define GPIO4_DIR IO_ADDRESS(GPIO4_BASE 0x400) //gpio4方向寄存器 #defineGPIO_SPI_CS_REG IO_ADDRESS(GPIO4_BASE 0x40) //gpio4_4数据寄存器 #defineGPIO4_SPI_SCK_REG IO_ADDRESS(GPIO4_BASE 0x80) //gpio4_5数据寄存器 #defineGPIO4_SPI_MOSI_REG IO_ADDRESS(GPIO4_BASE 0x100) //gpio4_6数据寄存器 #defineGPIO4_SPI_MISO_REG IO_ADDRESS(GPIO4_BASE 0x200) //gpio4_7数据寄存器 #define GPIO4_4 (1 4) //gpio4_4 #define GPIO4_5 (1 5) //gpio4_5 #define GPIO4_6 (1 6) //gpio4_6 #define GPIO4_7 (1 7) //gpio4_7 #define DATA_LENGTH 21 #define DRV_AUTHOR Yang Zhengyz2012wwgmail.com #define DRV_DESC spi driver #define DRV_VERSION v0.0.1 #if 0 #defineDBG(x...) printk(x) #define DBG_PRINT #else #defineDBG(x...) do {} while (0) #endif staticDECLARE_WAIT_QUEUE_HEAD(spi_waitq); unsigned char read_tmp_data[DATA_LENGTH] {0}; void __iomem *reg_ssp_base_va; typedef unsignedchar byte; typedef unsignedshort word; static int read_flag 0; /****************************************************************************** **函数名称Set_nCS **函数功能禁用片选 **输入参数无 **输出参数无 **注意 高电平为禁用片选低电平为使能片选 ******************************************************************************/ void Set_nCS(void) { unsigned char regvalue; writel(0, IOCONFIG4_4); //gpio模式 regvalue readl(GPIO4_DIR); //设置gpio输出 regvalue | GPIO4_4; writel(regvalue, GPIO4_DIR); regvalue readl(GPIO_SPI_CS_REG); regvalue | GPIO4_4; writel(regvalue, GPIO_SPI_CS_REG); //禁用片选 } /****************************************************************************** **函数名称Clr_nCS **函数功能使能片选 **输入参数无 **输出参数无 **注意 高电平为禁用片选低电平为使能片选 ******************************************************************************/ void Clr_nCS(void) { unsigned char regvalue; writel(0, IOCONFIG4_4); //gpio模式 regvalue readl(GPIO4_DIR); //设置gpio输出 regvalue | GPIO4_4; writel(regvalue, GPIO4_DIR); regvalue readl(GPIO_SPI_CS_REG); regvalue ~GPIO4_4; writel(0, GPIO_SPI_CS_REG); //使能片选 } /****************************************************************************** **函数名称Set_SCK **函数功能SCK为高电平 **输入参数无 **输出参数无 **注意 ******************************************************************************/ void Set_SCK(void) { unsigned char regvalue; writel(0, IOCONFIG4_5); //gpio模式 regvalue readl(GPIO4_DIR); //设置gpio输出 regvalue | GPIO4_5; writel(regvalue, GPIO4_DIR); regvalue readl(GPIO4_SPI_SCK_REG); //设置gpio输出高电平 regvalue | GPIO4_5; writel(regvalue, GPIO4_SPI_SCK_REG); } /****************************************************************************** **函数名称Set_SCK **函数功能SCK为高电平 **输入参数无 **输出参数无 **注意 ******************************************************************************/ void Clr_SCK(void) { unsigned char regvalue; writel(0, IOCONFIG4_5); //gpio模式 regvalue readl(GPIO4_DIR); //设置gpio输出 regvalue | GPIO4_5; writel(regvalue, GPIO4_DIR); regvalue readl(GPIO4_SPI_SCK_REG); //设置gpio输出低电平 regvalue ~GPIO4_5; writel(regvalue,GPIO4_SPI_SCK_REG); } /****************************************************************************** **函数名称Set_MOSI **函数功能MOSI为高电平 **输入参数无 **输出参数无 **注意 ******************************************************************************/ void Set_MOSI(void) { unsigned char regvalue; writel(0, IOCONFIG4_6); //gpio模式 regvalue readl(GPIO4_DIR); //设置gpio输出 regvalue | GPIO4_6; writel(regvalue, GPIO4_DIR); regvalue readl(GPIO4_DIR); //设置gpio输出高电平 regvalue | GPIO4_6; writel(regvalue, GPIO4_SPI_MOSI_REG); } /****************************************************************************** **函数名称Set_MOSI **函数功能MOSI为低电平 **输入参数无 **输出参数无 **注意 ******************************************************************************/ void Clr_MOSI(void) { unsigned char regvalue; writel(0, IOCONFIG4_6); //gpio模式 regvalue readl(GPIO4_DIR); //设置gpio输出 regvalue | GPIO4_6; writel(regvalue, GPIO4_DIR); regvalue readl(GPIO4_DIR); //设置gpio输出低电平 regvalue ~GPIO4_6; writel(regvalue, GPIO4_SPI_MOSI_REG); } /****************************************************************************** **函数名称MISO_H **函数功能读取MISO_H的值 **输入参数无 **输出参数无 **注意 ******************************************************************************/ unsigned charMISO_H(void) { unsigned char regvalue; writel(0, IOCONFIG4_7); //gpio模式 regvalue readl(GPIO4_DIR); //设置gpio输入 regvalue ~GPIO4_7; writel(regvalue, GPIO4_DIR); regvalue readl(GPIO4_SPI_MISO_REG); //读取输入值 //DBG(regvalue %x\n,regvalue); return regvalue; } /****************************************************************************** **函数名称SPICmd8bit **函数功能SPI写入参数8bit **输入参数WrPara **输出参数无 **注意 保留nCS输出Low ******************************************************************************/ voidSPICmd8bit(byte WrPara) { byte bitcnt; Clr_nCS(); Clr_SCK(); for(bitcnt 8; bitcnt ! 0; bitcnt--) { Clr_SCK(); if(WrPara0x80) { Set_MOSI(); } else { Clr_MOSI(); } Set_SCK(); WrPara 1; } Clr_SCK(); Set_MOSI(); //Set_nCS(); //*此处不关闭nCS使用连续模式* } /****************************************************************************** **函数名称SPIRead8bitt **函数功能SPI读取参数8bit **输入参数读取8bit数据——RdPara **输出参数无 **注意 保留nCS输出Low ******************************************************************************/ byte SPIRead8bit(void) { byte RdPara 0; byte bitcnt; Clr_nCS(); Set_MOSI(); //读FIFO维持SDI为H for(bitcnt8; bitcnt!0; bitcnt--) { Clr_SCK(); RdPara 1; Set_SCK(); if(MISO_H()) { RdPara | 0x01; } else { ; } } Clr_SCK(); //Set_nCS(); //*此处不关闭nCS使用连续模式* //DBG(RdPara %x\n,RdPara); return(RdPara); } /****************************************************************************** **函数名称SPIRead **函数功能SPI读取一个地址数据 **输入参数adr **输出参数无 ******************************************************************************/ byte SPIRead(byteadr) { byte tmp; SPICmd8bit(adr); //发送要读取的地址 tmp SPIRead8bit(); //读取数据 Set_nCS(); return(tmp); } /****************************************************************************** **函数名称SPIWrite **函数功能SPI写入一个16数据高8位地址低8位数据 **输入参数WrPara **输出参数无 ******************************************************************************/ void SPIWrite(wordWrPara) { byte bitcnt; Clr_SCK(); //注意SCK先清0保持低 Clr_nCS(); WrPara | 0x8000; //写数据高位置1 for(bitcnt16; bitcnt!0; bitcnt--) { Clr_SCK(); if(WrPara0x8000) { Set_MOSI(); } else { Clr_MOSI(); } Set_SCK(); WrPara 1; } Clr_SCK(); Set_MOSI(); Set_nCS(); } /****************************************************************************** **函数名称SPIBurstRead **函数功能SPI连续读取模式 **输入参数adr——读取地址 ** ptr——存储数据指针 ** length 读取长度 **输出参数无数据存在ptr中 ******************************************************************************/ voidSPIBurstRead(byte adr, byte *ptr, byte length) { byte i; if(length1) //读取长度必须大于1 { return; } else { Clr_SCK(); //注意SCK先清0保持低 Clr_nCS(); SPICmd8bit(adr); //读取地址 for(i0;ilength;i) { ptr[i] SPIRead8bit(); } Set_nCS(); } } /****************************************************************************** **函数名称SPIBurstWrite **函数功能SPI连续写入模式 **输入参数adr——写入地址 ** ptr——存储数据指针 ** length 写入长度 **输出参数无 ******************************************************************************/ voidBurstWrite(byte adr, byte *ptr, byte length) { byte i; if(length1) //读取长度不为0或1 { return; } else { Clr_SCK(); //注意SCK先清0保持低 Clr_nCS(); SPICmd8bit(adr|0x80); //连续写 for(i0;ilength;i) { SPICmd8bit(ptr[i]); } Set_nCS(); } } longspi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { …… switch(cmd) { case SSP_READ_ALT: …... val *(unsigned int*)arg; addr (unsignedchar)(val0xff); data SPIRead(addr); …… *(unsigned int *)arg (unsigned int)(data0x0000ff); break; case SSP_READ_BURST: { unsignedchar addr 0x00; …… /*读取数据 */ SPIBurstRead(addr,read_tmp_data, DATA_LENGTH); …... break; } case SSP_WRITE_ALT: data 0; val *(unsigned int *)arg; tmp (unsignedshort)((val0xff0000)8); tmp | (unsignedshort)((val0x0000ff)0); …… SPIWrite(tmp); break; case SSP_WRITE_BURST: res copy_from_user(tmp_str, (unsigned char *)arg, sizeof(tmp_str)); if (res ! 0) { printk(copydata from the user space error\n); } …… BurstWrite(addr,data, DATA_LENGTH); break; default: { printk(Nosuch spi command %#x!\n, cmd); return -1; } } return 0; } int spi_open(structinode * inode, struct file * file) { …… return 0; } intspi_close(struct inode * inode, struct file * file) { return 0; } static structfile_operations spi_fops { .owner THIS_MODULE, .unlocked_ioctl spi_ioctl, .open spi_open, .release spi_close }; static structmiscdevice spi_dev { .minor MISC_DYNAMIC_MINOR, .name DEV_NAME, .fops spi_fops, }; static int __initspi_gpio_init(void) { int ret; ret misc_register(spi_dev); if (ret 0) { printk(registerspi_gpio device failed!\n); return -1; } printk(SPI driver initializesuccessful! .\n); return 0; } static void __exitspi_gpio_exit(void) { misc_deregister(spi_dev); printk(SPI driver exit!\n); } module_init(spi_gpio_init); module_exit(spi_gpio_exit); MODULE_LICENSE(GPL); MODULE_AUTHOR(DRV_AUTHOR); MODULE_DESCRIPTION(DRV_DESC);
http://www.pierceye.com/news/109688/

相关文章:

  • 个人网站备案名称填写货运网站建设公司
  • 有网页源码 怎么做网站外链发布软件
  • 医疗网站建设基本流程wordpress速度加快
  • 网站建设优化开发公司哪家好泰州东方医院男科
  • 怎么自己做歌曲网站大连网站制作公司费用多少
  • 网站专题设计稿用vue做商城网站常用的js
  • 怎么在免费空间里面做网站深圳英文站seo
  • 学风建设网站版块如何用visual studio做网站
  • 山东响应式网站设置字体颜色的网站
  • 美容院网站建设西安有关做网站的公司有哪些
  • 湛江做网站设计公司网络推广网站培训班
  • 大型网站建立萝岗微信网站建设
  • 门户网站建设发展趋势官网网站怎么创建
  • 企业网站如何做自然搜索phpcms 网站转移
  • 站内优化怎么做建设设计网站
  • 如何建设机器人教育网站上海有名的网络公司
  • 网站二级目录做网站淄博网站建设 很乱
  • 常州做网站企业海口网站开发建设
  • 做php网站用什么软件开发wordpress页面图片轮播图
  • 做网站页面大小多大8上的信息课做网站作业
  • 自己做微网站创欧科技 网站建设
  • 网站设计师大学学什么专业北京燕华工程建设有限公司网站
  • 广州专业网站建设企业wordpress 数据库修改
  • 淮南装饰公司网站建设seo 网站树
  • 设计素材下载网站网络营销课程设计报告
  • 安庆公司做网站搜索引擎收录提交入口
  • 城固网站建设wordpress主题谁的最好
  • 国外建站企业北京鑫创网站建设
  • 网站做视频wordpress插件手动升级
  • wordpress收不到网站没有收款接口网站怎么做收款