精华内容
下载资源
问答
  • 软核EPCS配置芯片的存储操作 EPCS4配置芯片除了存储FPGA配置信息和NIOS II程序外,还有很多存储空间剩余未使用,可以用来做用户配置信息存储。 ALTERA提供的HAL函数来调用EPCS相关的函数,在“altera_avalon_...

                                                     NIOS II 软核中EPCS配置芯片的存储操作

    EPCS4配置芯片除了存储FPGA配置信息和NIOS II程序外,还有很多存储空间剩余未使用,可以用来做用户配置信息存储。

    ALTERA提供的HAL函数来调用EPCS相关的函数,在“altera_avalon_epcs_flash_controller.c”函数(路径为:\\altera\72\ip\sopc_builder_ip\altera_avalon_epcs_flash_controller\HAL\src)中。

    一个老外写的关于NIOS IICPCS器件操作的帖子,他是花了一个多月才摸索到怎么操作,然后给出了一个简单的例子。

    先看一下这个简单程序

    #include <stdio.h>

    #include <unistd.h>

    #include "system.h"

    #include "alt_types.h"

    #include "sys/alt_flash.h"

    #include "sys/alt_flash_dev.h"

    alt_u8 epcsbuf[32];

    int ret_code;

    flash_region *regions;
    int number_of_regions;

    alt_flash_fd* my_epcs;//定义句柄

    main()

    {

    my_epcs = alt_flash_open_dev("/dev/epcs_controller");//打开FLASH器件,获取句柄

        ret_code = alt_epcs_flash_get_info (my_epcs, &regions, &number_of_regions);//获取配置芯片信息

        if(my_epcs) //信息获取成功

        {

        //example application, read general data from epcs address 0x70000

           ret_code = alt_epcs_flash_erase_block(my_epcs, regions->offset+0x70000);//擦除第8

    ret_code = alt_epcs_flash_write(my_epcs, regions->offset+0x70000, epcsbuf, 32); //32字节

            ret_code = alt_epcs_flash_read(my_epcs, regions->offset+0x70000, epcsbuf, 32); //32字节

        }

        while(1)

        {

        }

    }

    上面的程序就是对EPCS配置芯片操作的流程和方式。首先打开器件获取句柄my_epcs,然后的读写及擦除操作都是通过句柄my_epcs来操作的。“/dev/epcs_controller”中的“epcs_controller”是用户在配置NIOS核时自命名的,可以在system.h中查到,即“EPCS_CONTROLLER_NAME”。通过IDE调试的话可以查看my_epcs指向的FLASH相关参数。EPCS器件只有一个区(regions),EPCS4区内有8个块(block),每个块是65536字节。(注:只有EPCS1每个块32768字节,其余配置芯片是每块65536字节。

    alt_epcs_flash_erase_block(my_epcs, regions->offset+0x70000);//擦除第8

    这个函数是擦除整块的函数,第一个参数是刚才获得的句柄,用于指示是对刚刚打开的FLASH进行擦除,第二个regions->offset的值其实是0,是由EPCS控制模块自己管理的。FPGA配置文件和NIOS核中的程序是从前边存储的,即从regions->offset+0x00000开始的地址。我的用掉不到4个块,还剩4个块可以用于自定义的存储。为便于将来进行功能扩展,尽量空余低块以备将来使用,优先使用高地址空间(第8块,起始地址为regions->offset+0x70000)进行用户配置信息存储。

    alt_epcs_flash_write(my_epcs, regions->offset+0x70000, epcsbuf, 32); //32字节

    epcsbuf数组中的连续32字节写入regions->offset+0x70000开始的EPCS4芯片内。如果是写入第6块的第0x100开始的地址,那么可用regions->offset+0x60100代替regions->offset+0x70000

    alt_epcs_flash_read(my_epcs, regions->offset+0x70000, epcsbuf, 32); //32字节

    EPCS4中的第8段起点regions->offset+0x70000读取连续32字节存到epcsbuf数组内。

    调试过程中可以在执行alt_epcs_flash_write前手动修改epcsbuf数组内的值,在执行alt_epcs_flash_read前再更改epcsbuf数组内的值为其他值,如果执行alt_epcs_flash_readepcsbuf数组内的值恢复到执行alt_epcs_flash_write前的值,那么对EPCS芯片的读写操作已经成功了

     注意:EPCS的擦写是针对整个块的,也可以不用擦写,直接写数据,因为重新写入时会发生覆盖。

     

    EPCS操作相关的头文件有以下:

    #include "system.h"

    #include "alt_types.h"

    #include "sys/alt_flash.h"

    #include "sys/alt_flash_dev.h"

    当然系统还需要一些相关的标准头文件,执行一些操作。

     

    其他参考程序:

    1First of all init the flash device and possibly get extra info about the flash device, like block size:

    flash_region *regions;
    int numRegions;
    int error = 0;
    pFlashDevice = alt_flash_open_dev(FLASH_CONTROLLER_NAME);
    if (pFlashDevice <= 0)
    error = -1;
    if (!error)
    error = alt_epcs_flash_get_info(pFlashDevice, &regions, &numRegions);
    if (!error)

     {flash_block_size = regions->block_size;
    flash_max_addr = regions->region_size;
    This is for erasing a single block:
    alt_epcs_flash_erase_block(pFlashDevice, block_address);
    This is for writing any data to a previously erased area:
    int buf[10] = { 1, 2,3,4,5,6,7,8,9,10 };
    rv = alt_epcs_flash_write_block(pFlashDevice, block_address,
    data_offset_inside_block , buf, 10);
    Then, read back data with:
    alt_epcs_flash_read(pFlashDevice, addr, buf, len);

     

    问题:

    First of all init the flash device and possibly get extra info about the flash device, like block size:

    flash_region *regions;
    int numRegions;
    int error = 0;
    pFlashDevice = alt_flash_open_dev(FLASH_CONTROLLER_NAME);
    if (pFlashDevice <= 0)
    error = -1;
    if (!error)
    error = alt_epcs_flash_get_info(pFlashDevice, &regions, &numRegions);
    if (!error) {
    flash_block_size = regions->block_size;
    flash_max_addr = regions->region_size;

    i am using cfi, is it the same? besides, my pFlashDevice is <= 0. i dunno why. is it sth to do with reset vector as my reset vector is sdram.

    This is for writing any data to a previously erased area:
    int buf[10] = { 1, 2,3,4,5,6,7,8,9,10 };
    rv = alt_epcs_flash_write_block(pFlashDevice, block_address,
    data_offset_inside_block , buf, 10);

    why need rv when write data?

    Then, read back data with:
    alt_epcs_flash_read(pFlashDevice, addr, buf, len);

    where is the data when we read it from the flash? like i want to print out the data.
    please help me with the ques in bold. thanks!

     

     

    回答:

    why need rv when write data?
    This is not mandatory, but recommended to check if data has been written correctlywhere is the data when we read it from the flash? like i want to print out the data.
    ???
    What's the problem? The buf array contains your data.
    Maybe this way is clearer:
    int buf[10];
    alt_flash_read(pFlashDevice, addr, buf, 10);Remark:
    remove epcs_ from the previous post. I copied and pasted from a project using epcs instead of parallel flash and forgot to change function names.

     

    注:此程序为altera论坛问答帖子,如何在DE2上使用flash的问题,具体链接地址为,http://www.alteraforum.com/forum/archive/index.php/t-27526.html

    展开全文
  • W25Q64Flash芯片STM32操作

    万次阅读 多人点赞 2018-07-31 16:25:27
    1、W25Q64Flash芯片介绍 通讯方式:SPI通讯 大小:8M(Byte) (128块(Block),每块64K字节,每块16个扇区(Sector),每个扇区4K字节,每个扇区16页,每页256个 字节) 特点:Flash芯片内的数据只能由1变0,...

    1、W25Q64Flash芯片介绍

    通讯方式:SPI通讯

    大小:8M(Byte)   (128块(Block),每块64K字节,每块16个扇区(Sector),每个扇区4K字节,每个扇区16页,每页256个              字节)

    特点:Flash芯片内的数据只能由1变0,不能由0变1。

    引脚: 

                   

                  CS:CS为片选管脚,低电平有效。上电之后,在执行一条新的指令之前,必须让/CS管脚先有一个下降沿。 

                  DO(MISO:DO为串行数据输出引脚,在CLK(串行时钟)管脚的下降沿输出数据。

                  WP:WP为写保护管脚,有效电平为低电平。高电平可读可写,低电平仅仅可读。

                  DI(MOSI):DI为串行数据输入引脚,数据、地址和命令从DI引脚输入到芯片内部,在CLK(串行时钟)管脚的上升沿捕获捕获数据。

                  CLK(SLCK):CLK为串行时钟引脚。SPI时钟引脚,为输入输出提供时钟脉冲。

                  HOLD:HOLD为保持管脚,低电平有效。当CS为低电平,并且把HOLD拉低时,数据输出管脚将保持高阻态,并且会忽略数据输入管脚和时钟管脚上的信号。把HOLD管脚拉高,器件恢复正常工作。

                   VCC:电源2.7V~3.6V。

                   GND:地。

    W25Q64内部框架图:

    2、W25Q64Flash工作方式

           2.1 W25Q64 SPI数据传输时序

    W25Q64支持SPI数据传输时序模式0(CPOL = 0、CPHA = 0)和模式3(CPOL = 1、CPHA = 1),模式0和模式3主要区别是当SPI主机硬件接口处于空闲状态时,SCLK的电平状态是高电平或者是低电平。对于模式0来说,SCLK处于低电平;对于模式3来说,SCLK处于高电平。不过,在这两种模式下,芯片都是在SCLK的上升沿采集输入数据,下降沿输出数据。

           2.2 W25Q64数据格式

    W25Q64数据格式为数据长度8位大小,先发高位,再发低位。

           2.3 W25Q64传输速度

    W25Q64在标准模式下支持80M bit/s速度,快速模式下支持160M bit/s速度,高速模式下支持320M bit/s速度。

    3、W25Q64控制和状态寄存器

    通过对“读状态寄存器”指令读出的状态数据可以知道芯片存储器阵列是否可以写入或不可写,或是否处于写保护状态。通过“写状态寄存器”指令可以配置芯片写保护特征。

    总线忙标志位(BUSY)

    BUSY位是一个只读位,在状态寄存器中的S0位。当W25Q64在执行“页编程”、“扇区擦除”、“块区擦除”、“芯片擦除”以及“写状态寄存器”指令时,该位被硬件自动置1。这时候,除了“读状态寄存器”指令外的所有操作指令讲会被芯片忽略。当芯片执行完这些指令后,硬件会自动将该位清零,表示芯片器件可以接收其他的指令。

    写保护位(WEL

    WEL位是一个只读位,在状态寄存器的S1位。在执行完“写使能”指令后,该位会被硬件自动置1。当芯片掉电后和执行“写禁能”、“页编程”、“扇区擦除”、“块区擦除”以及“芯片擦除”指令都会进入“写保护状态”。

    块区保护位(BP2、BP1、BP0

    BP2、BP1、BP0这3位为可读可写位,分别在状态寄存器的S4、S3以及S2位。这3个位默认状态为0,即块区处于未保护状态。可以利用“写状态寄存器”指令对这几个位进行置1来达到块区保护的目的。块区保护状态为:没有保护、部分保护和全部保护状态。

    注:当状态寄存器的SRP位为1或读写保护管脚(/WP)为低电平时,这3个位不可被更改。

    底部和顶部块保护位(TB

    TB位是一个可读可写位,在状态寄存器的S5位,默认值为0。可以利用“写状态寄存器”指令对这个位进行置1或清零。当TB = 0时,表示保护位从顶部开始,当TB = 1时,表示保护位从底部开始。

    注:当状态寄存器的SRP位为1或读写保护管脚(/WP)为低电平时,这个位不可被更改。

    扇区/块保护(SEC

    SEC位为一个可读可写位,在状态寄存器的S6位,默认值为0。可以利用“写状态寄存器”指令对这个位进行置1或清零。当SEC = 0时,表示每次保护的区域大小为4K;当SEC = 1时,表示每次保护的区域大小为8K。

    状态寄存器保护位(SRP0、SRP1

    SRP0和SRP1这2位为可读可写位,分别在状态寄存器的S7和S8(状态寄存器2)位。这两个位的默认值为0,可以利用“写状态寄存器”指令对这个位进行置1或清零。这2个位和读写保护管脚(/WP)决定了状态寄存器写保护的方式。状态寄存器写保护的方式有:软件保护,硬件保护、电源锁定或一次性可编程(OTP)保护。

    快速SPI通讯使能(QE

    QE位为一个可读可写位,在状态寄存器的S9(状态寄存器2)位,默认值为0。以利用“写状态寄存器”指令对这个位进行置1或清零。当QE = 0时,W25Q54设置为标准速度模式或快速模式,保持管脚(/HOLE)和读写保护管脚(/WP)启用;当QE = 1时,W25Q54设置为高速模式,保存管脚(/HOLE)和读写保护管脚(/WP)被设置位IO2和IO3功能使用。

    4、W25Q64器件标识

    5、W25Q64工作原理

               W25Q64操作原理

    通过SPI接口,用标准的SPI协议发送相应指令给flash,然后flash根据命令进行各种相关操作。

                W25Q64常用操作命令

    指令名称

    字节1(CODE)

    字节2

    字节3

    字节4

    字节5

    字节6

    写使能

    06h

     

    写禁能

    04h

     

    读状态寄存器1

    05h

    (S7~S0)

     

    读状态寄存器2

    35h

    (S15~S8)

     

    读数据

    03h

    A23~A16

    A15~A8

    A7~A0

    D7~D0

    直至读完所有

    写状态寄存器

    01h

    (S7~S0)

    (S15~S8)

     

    页编程

    02h

    A23~A16

    A15~A8

    A7~A0

    D7~D0

    直至255个字节

    块擦除(64K)

    D8h

    A23~A16

    A15~A8

    A7~A0

     

    半块擦除(32K)

    52h

    A23~A16

    A15~A8

    A7~A0

     

    扇区擦除(4K)

    20h

    A23~A16

    A15~A8

    A7~A0

     

    芯片擦除

    C7/60h

     

    芯片掉电

    B9h

     

    释放掉电/器件ID

    ABh

    伪字节

    伪字节

    伪字节

    ID7~ID0

     

    制造/器件ID

    90h

    伪字节

    伪字节

    00h

    MF7~MF0

    ID7~ID0

    JEDEC ID

    9Fh

    MF7~MF0

    ID15~ID8

    ID7~ID0

     

    6、W25Q64常用指令工作时序

    写使能(06H

    写禁止(04H

    读状态寄存器指令(05H

    写状态寄存器指令(01H

     

    读数据(03H

    页写(02H

    扇区擦除指令(20H

    块擦除指令(D8H

    芯片擦除指令(07H

    掉电指令(B9H

    读ID指令(90H

    写使能(06H

    写禁止(04H

    读状态寄存器指令(05H

    写状态寄存器指令(01H

     

    读数据(03H

    页写(02H

    扇区擦除指令(20H

    块擦除指令(D8H

    芯片擦除指令(07H

    掉电指令(B9H

    读ID指令(90H

    7、STM32模块编程思路

    1. 配置SPI模块功能管脚相应的GPIO管脚。
    2. 配置SPI模块工作方式。
    3. 使能SPI模块时钟。
    4. 根据SPI SPI主模式设置步骤设置SPI工作方式。
    5. 编写SPI读写字节函数。
    6. 根据目前器件的指令操作器件。

    8、硬件原理图

    代码资源下载:https://download.csdn.net/download/lalala098/10576508

    展开全文
  • AD7327 AD芯片使用记录

    千次阅读 2019-12-02 16:27:34
    最近项目调试使用到了AD7327芯片,为了防止后续忘记又得各种查资料,将自己这次调试的心得记录于此,如果错误请指正。谢谢。 开发环境:STM32F407VET6+AD7327 keil mdk 5.23 这款芯片有官方例程,代码开发起来省...

    最近项目调试使用到了AD7327芯片,为了防止后续忘记又得各种查资料,将自己这次调试的心得记录于此,如果错误请指正。谢谢。

    开发环境:STM32F407VET6+AD7327     keil mdk 5.23

    这款芯片有官方例程,代码开发起来省事儿好多。

     

    1.芯片简介

      -12位精度

     - 支持软件选择量程:±10V、±5V、±2.5V,0-10V

      -500ksps传输速率

      -8个模拟量输入通道,既可配置为单个输入,也可配置为双路输入(传感器信号包含V+、V-两根信号线情况下)

      -内置2.5V参考电压

    注意!!!设计硬件时请先参考芯片手册Table 6,注意根据你要使用的量程选择相应的电压。如果采集电压含有正负,则电源也需要接正负电源;如果只有正电压,则可以只接电源正和地。

    此处可能导致后期程序配置好了寄存器,确定了量程,结果发现输入电压没到最大量程还差好远,结果已经到了fff最大值了,莫名其妙的一脸懵...

     

     

    2.引脚简介

     

     

         硬件接线按照上图所示即可,注意以下几点:

     -1.  1脚CS  片选。接mcu一个IO口即可;初始化芯片及数据转换读取时需要对该引脚输出高低电平

     -2.  2脚DIN  SPI通讯数据引脚,我使用STM32做主机控制AD7327芯片,因此,DIN脚接mcu的SPI_MOSI

     -3.  18脚.DOUT  SPI通讯数据引脚,DOUT脚接mcu的SPI_MISO

     -4.  20脚SCLK  SPI时钟,接SPI_SCK

     -5. 17脚VDRIVE 接mcu的IO口,初始化后拉高即可。注意该引脚必须和VCC电压相同,最大也不能超过VCC+0.3V。我是用的   stm32f4芯片,因此VCC就是用的3.3V,所以该引脚直接接到stm32的一个IO口即可。

      PS.注意硬件电路上的电容方向,我的板子上有个电容方向画反了,结果上电一个劲儿的发热。建议画板时一定要仔细,参考官方模板电路,焊好后通电没有发现什么问题也要摸一摸芯片和各个元器件看是不是有短路或者接错导致的发热现象出现

     

    3.硬件电路

        注意vin0-vin7,引脚号并不是按照顺序来的,我之前引脚号弄错了,还花了一番功夫,结果发现原理图上引脚号跟芯片文档对不上,还好电源引脚没有错误,不至于烧掉元器件。

        未连接的输入端可以不接或者通过一个电阻下拉到地,不要直接接地!!!请特别注意!!!!否则会导致输入采样电压莫名被拉低...

     

    4.寄存器简介

     

    AD7327包含4个寄存器,通过SPI发送一个16位的值来读写AD7237.

    16位命令中,最高位第15位为写入命令,1有效

                          第14位与第13位用来选择对相应寄存器进行写入操作

     

    4.1 控制寄存器

      控制寄存器注意以下几点:

      1)coding  即为AD值的类型,0则输出补码,1则输出二进制原码

      2)ref   电压参考。0则开启外部参考,不使用内部参考;1则使用内部参考作为AD输出值的参考

      3)2-10位,ADD2-ADD0地址选择,如下图所示。我需要8个独立输入通道,因此我配置ADD2-ADD0:111   mode1 = 0,mode0 = 0

      4)Table11中电源模式选择中两个参数所示,00即为正常模式

    5)sequence选择  

    全为0或全为1,不使用sequence,需要每次进行读取前进行寄存器配置。

    seq1=0,seq2=1,例如我使用VIN0,VIN2两个通道,且使用自动获取模式,则按此设置后,AD7327会自动只获取VIN0 VIN2通道的数值。大多数情况使用此设置。

    seq1=1,seq2=0,如下图,会从VIN0开始到我们设定的通道地址。即设置通道地址为VIN5,按此设置后,AD7327会获取VIN0~VIN5的数值

     

     

    4.2  序列寄存器

      选择相应输入采集通道值,输出到总线。我使用了8个通道,因此全选即可,VIN0-VN7全为1即可。

     

    4.3  量程寄存器

     

      通过设置VinxA与VinxB,来配置相应通道的输入量程,我使用的8个通道均为±10V,因此配置为00即可。

     

    5.数据输出

      通过向SPI总线写入0x00来读取AD值,返回的16位数据中,第15-13位为当前12位采集值的地址值,第12位为正负标志,若采用补码方式,采集到负电压,则该位为1.

      具体ADD2-ADD0对应哪个通道,可以在上述4.1控制寄存器中table10中找到

     

    6.代码

    官方例程中已经配置好各个寄存器地址,在ad7327.h文件中,此处我就不放那些代码了,自己去官网下就好。

    H文件增加内容如下:

    /*edit by hyarcher25 用于读取数据地址判断*/
    #define CH0Add 0x00
    #define CH1Add 0x01
    #define CH2Add 0x02
    #define CH3Add 0x03
    #define CH4Add 0x04
    #define CH5Add 0x05
    #define CH6Add 0x06
    #define CH7Add 0x07
    

      6.1 sequence模式,自动读取指定通道

      初始化

    #define AD_AUTO 1 //默认使用sequence模式,若想单独读取,改成0即可
    
    uint8_t AD7327Init(void)
    {
      GPIO_InitTypeDef GPIO_InitStructure;
    	
      SPI1_Init();//SPI1初始化
      SPI1_SetSpeed(SPI_BaudRatePrescaler_2);//spi速率选择
    		
      //PA4 Vdrive/PC4 CS 引脚初始化
      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOC, ENABLE);
    
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
      GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
      GPIO_Init(GPIOA, &GPIO_InitStructure);
    	
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
      GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
      GPIO_Init(GPIOC, &GPIO_InitStructure);
    		
      AD_Vdrive_1;//Vdrive拉高
      AD_CS_HIGH;//片选拉高,禁止AD读取,带配置完寄存器后拉低
      delayms(20);
    			
      //量程选择
      WriteToRangeRegister1 (IN10vCH0, IN10vCH1, IN10vCH2, IN10vCH3);
      delayms(20);
      WriteToRangeRegister2 (IN10vCH4, IN10vCH5, IN10vCH6, IN10vCH7);
      delayms(20);
    	
      #if AD_AUTO //使用自动sequence模式,则初始化以下代码,否则无需执行
                  //我使用了8个通道,因此VIN0-VIN7全部要初始化
      WriteToSequenceRegister (VIN0|VIN1|VIN2|VIN3|VIN4|VIN5|VIN6|VIN7);
      delayms(20);
      WriteToControlRegister(CH0|CH1|CH2|CH3|CH4|CH5|CH6|CH7, Mode0, Normal,                  
                             StraightBinary, Ref_En, SequencerPrev);
      delayms(20);
      #endif 
    	
      return 0;
    }
    
    
    void SPI1_Init(void)
    {
        GPIO_InitTypeDef  GPIO_InitStructure;
        SPI_InitTypeDef  SPI_InitStructure;
    
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
    
        GPIO_PinAFConfig(GPIOA , GPIO_PinSource5, GPIO_AF_SPI1);
        GPIO_PinAFConfig(GPIOA , GPIO_PinSource6, GPIO_AF_SPI1);
        GPIO_PinAFConfig(GPIOA , GPIO_PinSource7, GPIO_AF_SPI1);
    	
        //GPIOA 5 6 7
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
    
        RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1,ENABLE);
        RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1,DISABLE);
    	
        //SPI_I2S_DeInit(SPI1);
        SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
        SPI_InitStructure.SPI_Mode = SPI_Mode_Master;		
        SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
        SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;		//空闲状态高电平
        SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;	//时钟第一个跳边沿数据被采样
        SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;	
        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;	
        SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
        SPI_InitStructure.SPI_CRCPolynomial = 7;	
        SPI_Init(SPI1, &SPI_InitStructure); 
        SPI_Cmd(SPI1, ENABLE);
    
    }

     使用sequence模式,配置完成后,系统则会按照VIN0-VIN7的顺序采集转换并送出

    假如只需要读取某几个通道的数据,则初始化后选择相应通道即可。

    SPI读写

    uint16_t SPI1_ReadWriteByte(uint16_t TxData)
    {
            uint16_t returnData;
    
    	    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){}
    	    AD_CS_LOW;//拉低cs
    	    SPI_I2S_SendData(SPI1, TxData); //发送命令
    		
            while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET){}  
            returnData = SPI_I2S_ReceiveData(SPI1);//读取SPI数据
            AD_CS_HIGH;//拉高cs
    	    
            return returnData;//返回SPI读取到的值
    }

    读取AD值函数

    uint16_t ReadSequence (void)
    {
    	    uint16_t DataToWrite = 0x00;
    	    uint16_t ReturnData = 0x00;
    		
    	    DataToWrite = 0x0000;
    	
    	    ReturnData = SPI1_ReadWriteByte (DataToWrite);
    	
    	    return ReturnData;	
    }

    写入00,芯片便会按照之前的设置返回采集值

    注意返回值第15-13位为通道值,第12位为正负标志

     

    其他功能函数

    求绝对值,便于数据处理

    //求绝对值
    static uint16_t Absolute(uint16_t val)
    {
        uint16_t temp;
    
    		//判断第13位正负标志位
    		switch((val >> 12) & 0x0001)
    		{
    			case 0://负值
    				temp = (0x0fff - (val&0x0fff));//先去掉高4位,再求其绝对值
    				break;
    			
    			case 1://正值
    				temp = (val&0x0fff);//去掉高4位留下数据位后直接返回
    				break;
    			
    			default:
    				temp = val;
    				break;
    		}
    
    	return temp;
    }

    自动读取,个人项目使用,三个通道的。请手动修改其中内容

    void AutoReadAD(void)
    {
    		uint16_t value_temp;
    		uint8_t i, j;
    		
    		for(i = 0; i < 10; i ++)//采10组
    		{		
    				for(j = 0; j < 3; j ++)//3个通道,保证每个通道一个初值
    				{
    						value_temp = ReadSequence();
    			            delayus(1);//没有此延时可能会导致接收的数据莫名其妙异常,有时又没问   
                                       //题,至今没找到原因
    
    						//右移13位,判断地址
    						switch(value_temp >> 13)
    						{
    								case CH2Add://CH2
    										adOriginal[0][i] = Absolute(value_temp);
    										break;
    
    								case CH3Add://CH3
    										adOriginal[1][i] = Absolute(value_temp);
    										break;
    						
    								case CH7Add://CH7接的参考2.5V
    										adOriginal[2][i] = Absolute(value_temp);
    										break;
    						
    								default:
    										break;
    						}//end of switch
    				}//end of for
    		}//end of for
    
    		//求均值
    		ValueAverageCal();
    }

    6.2  不使用sequence,每次需要配置后再读取指定通道

    static uint16_t ReadCHx(uint16_t VINx, uint16_t CHx)
    {
    	uint16_t value;
    	uint8_t i;
    	double sum = 0;
    	
    	WriteToSequenceRegister (VINx);//读取VINx通道的值
    	delayms(10);
    	WriteToControlRegister(CHx, Mode0, Normal, StraightBinary, Ref_En, Sequencer);
    	delayms(10);
    	for(i = 0; i < N; i ++)//采集N次
    	{
    		ADValue_Original[i] = (ReadSequence() & 0X0FFF);//读取值后12位放入数组
    		sum += ADValue_Original[i];//N次值相加求和
    	}
    	value = (uint16_t) (sum / N);//取平均值
    	
    	return value;
    }

    VINx与CHx为相同通道值。就是你想读通道1,就把x写1,读通道2,就把x改成2

    这个貌似还有一点bug,我基本没使用过这个模式,都是使用sequence模式自动读取,无需每次配置,更为方便,sequence模式也可以读取指定通道值。

     

    PS.近来发现一些问题,SPI速率与AD速率匹配不太对,例如我开通全部通道,要求每个通道在10ms内采集100个 共800个数据,按照AD7327 5000ksps的速率应该是小菜一碟,但实际采集到的数据就不是很正确,把SPI各个速率设定都试过了,效果不明显。

    但是如果单个通道好像又效果好一些。把数据采集速度降低比如采集20个数据,数据又正常了。 头疼,真是奇怪。。。望大神解惑!

    展开全文
  • 为Bitlocker建立启动分区 要在Windows Vista实施BitLocker,除标准的操作系统分区(存放Windows 操作系统及其支持文件)外,还需一个启动分区,存放 BIOS引导后加载 Windows Vista 计算机时所需的特定硬件文件及...

    为Bitlocker建立启动分区

      要在Windows Vista中实施BitLocker,除标准的操作系统分区(存放Windows 操作系统及其支持文件)外,还需一个启动分区,存放 BIOS引导后加载 Windows Vista 计算机时所需的特定硬件文件及调用密钥的相关程序。

      需要指出的是,无论操作系统分区还是启动分区,均需使用NTFS格式,同时,BitLocker保护的只是操作系统分区中的数据,对启动分区而言,此上的数据则不受BitLocker 保护。

      此外,根据微软的建议,启动分区应不小于1.5GB,老实说,为什么需要这么大的空间有点让人迷惑,也许是对多用户环境下情况的考虑吧(部分用户数据也会存放在该分区中),不过,如果硬盘空间足够大,这倒不是一个大问题。在下面的示例中,为简便起见,我们使用50MB的分区,在您的实际使用中,当然最好还是按照微软的建议,特别是希望对此分区也启用系统还原时。

      要创建用于Bitlocker的启动分区,有两种方式:在安装Windows Vista时创建及在安装后创建。——当然,从数据安全的角度考虑,肯定是安装时创建最佳,事实上,微软甚至建议用户最好不要在安装Windows Vista后再考虑创建BitLocker分区,而是建议重新备份数据后重新对硬盘分区并重新安装Windows Vista。

      下面我们分别介绍这两种情况下的创建方法。

    在安装Windows Vista时创建BitLocker启动分区

      在Windows Vista的安装过程中,出现选择安装目标盘时,按下“CTRL+Shift+F10”,调出命令窗口,然后,依次输入如下命令:

      (注 : 在下面的示例中,除BitLocker启动分区外,我们仅建立一个分区“C:”,如果您的系统需建立多个分区,需要注意将BitLocker启动分区的盘符放到最后,即将例中的“D:”改为相应值,或者为稳妥起见直接将其设为最后一个可用盘符“Z:”)

    1. Diskpart
    2. Select Disk 0
    3. Clean
    4. Create Partition Primary Size=50 (创建BitLocker启动分区)
    5. Create Partition Primary
    6. Select Partition 1
    7. Assign Letter D (将BitLocker启动分区盘符设为“D:”)
    8. Active (激活BitLocker启动分区)
    9. Select Partition 2
    10. Assign Letter C
    11. Exit
    12. Format D: /Y /FS:NTFS /Q /V:BDE
    13. Format C: /Y /FS:NTFS /Q /V:5270
    14. Exit

      设置完毕后,在安装目标盘选择界面点击一下“刷新 (Refresh)” ,然后选择将Windows Vista安装在“C:”。之后的安装与正常的Windows Vista安装过程相同,不再赘述。BitLocker的其他设置在Windows Vista安装完成后才会进行。

    在已安装Windows Vista的系统中创建BitLocker启动分区

      再次强调一下,这样的方式是微软不推荐的,在设置前最好备份系统中的重要数据,以免造成损失。

      首先,打开Windows Vista中的磁盘管理控制台,从“C:”中分割出50MB的自由空间,然后,使用这50MB磁盘空间创建一个新的主分区,盘符设为“D:”,同时,将该分区激活。(操作方法请参考使用磁盘管理器调整硬盘分区)

      然后,重启系统,进入恢复控制台,依次输入如下命令:

    1. MKDIR D:/BOOT (创建引导目录)
    2. XCOPY C:/BOOTMGR D:/ /H (将引导文件从C盘拷贝到D盘)
    3. XCOPY C:/BOOT Z:/BOOT /CHERKY
      (将 “C:/BOOT”目录下的所有文件包括子目录中的文件拷贝到 “D:/BOOT”下)
    4. ATTRIB +R+H+S Z:/BOOT
      (将该目录赋予只读、隐藏及系统属性)

      最后,重新启动系统,进行BitLocker设置

    设置BitLocker驱动器加密的步骤

      对于不含TPM安全芯片的系统,如果要启用BitLocker驱动器加密,必须提供一个USB盘以保存密钥。当然,这个密钥除了保存在USB盘上以外,您还要考虑将其在其他地方——如其他计算机、本计算机上未被加密的分区上等——将其做个备份,以防USB盘损坏或遗失造成BitLocker加密将自己也拒之门外的可能。

      如果您使用上页中我们介绍的在安装Windows Vista时创建BitLocker启动分区的方法,那么,在Windows Vista安装完成后即会启动“BitLocker驱动器加密 (BitLocker Drive Encryption)”向导;如果您是采用上页介绍的第二种方法,即安装Windows Vista后才创建BitLocker启动分区,那么,在重启系统后,依次点击“控制面板” => “安全” => “BitLocker Drive Encryption”,均会出现类似下图的画面:

      (注意:必须以管理员身份登录,同时,如果Windows Vista 中UAC未被关闭的话,将会弹出相应的对话框,需要确认操作。)

    启动BitLocker设置向导

      插入USB盘,点击 “Turn on Secure Startup”,开始BitLocker驱动器加密设置。

      随后向导即会进行相应的设置,生成BitLocker密钥。

    BitLocker提示信息

      在BitLocker密钥生成后,您可以将其打印出来,这是一个48位的恢复密码,在USB盘万一损坏时,可以用此进入系统,不然,BitLocker将会让您也无法看到自己的数据。

    记录BitLocker密钥

      在出现 “将密钥保存在USB设备 (Save the Recovery Password on a USB device)”提示时,选择插入的USB盘,点击保存。

    将BitLocker密钥保存于USB盘

      然后还将会出现“将密钥保存在文件夹 (Save recovery key to a folder)”的对话框,如果您的系统中存在其他硬盘时,建议将其保存于其上,当然,隐藏在一个不易被发现的地方,或者DVD RW上,不然,如果别人也可找到这个密钥,BitLocker将形同虚设。

    保存BitLocker密钥

      这样,BitLocker驱动器加密设置步骤即告完成,点击“EnCrypt”,Windows Vista即进行相应的加密运算。

    BitLocker设置完毕

    查看BitLocker加密过程

      上页介绍的BitLocker驱动器加密设置步骤完成后,Windows Vista即自动进行对示例中的操作系统分区,C盘,进行加密。

      这时,如果打开“电脑”,您将会看到操作系统分区此时以红条高亮显示,同时,可用硬盘空间变得很小。——注意,这是因为BitLocker加密过程需使用大量的临时空间,而非对硬盘分区实施Bitlocker加密将导致可用空间变小。

    BitLocker加密的驱动器

      在任务栏中也可以看到BitLocker运行图标,及BitLocker进程状态。根据加密分区大小的不同,整个BitLocker加密过程需耗时几小时不等,不过,在BitLocker进行驱动器加密时,您仍可以使用您的系统。

    BitLocker加密进程

      当整个BitLocker加密过程完成后,您将可以看到如下图的显示状态。此外,也可从中进行密钥的管理如在另一块USB盘上生成密钥或禁用BitLocker驱动器加密等管理。

    BitLocker加密的驱动器状态

    展开全文
  • 转载:在路上 » 【整理】手机的RF射频芯片和基带芯片的区别和联系 请教一下【射频芯片,wifi/蓝牙芯片,基带是什么关系?】我看到,射频、wifi、蓝牙是三种并列关系的通信协议。所以我理解射频芯片就是打电话用的...
  • 限于SX1268芯片的高频设计方法,本人并不能很好掌握,所以硬件设计使用现有模块,可参考日志:常用元器件使用方法25:LoRa模块E22-400M22S的使用方法。本文以E22-400M22S为硬件平台,对该模块的硬件连接做详细阐述。...
  • 使用UART串口下调试CH376芯片

    千次阅读 2016-11-06 22:10:19
    CH376是文件管理控制芯片,用于单片机系统读写U 盘或者SD 卡的文件。CH376支持USB设备方式和USB主机方式,并且内置了USB通讯协议的基本固件,内置了处理Mass-Storage海量存储设备的专用通讯协议的固件,内置了SD卡...
  • STM32操作24位AD芯片ADS1246

    千次阅读 2019-07-09 09:30:56
    在实际使用中发现,START脚做为ADC的启动脚,还必须得接出来,因我还找到有通过软件能启动ADS1246转换的方法,但其DS有提到START信号和SLEEP/WAKEUP相类似的功能,暂深研究。顺便 提一下,TI关于ADS1246的...
  • 国产芯片与国外芯片公司的差距

    千次阅读 2020-10-09 15:24:08
    今天给大侠带来国产芯片与国外芯片公司的差距,话不多说,上货。 从2010年到2018年,设计公司数量从582家增加到1698家,数量增长近3倍。国内芯片设计公司数量世界第一,总营收却只占全球芯片营收的13%...
  • affy芯片质量控制 前言 大家手头的芯片数据一般有两个来源,一个是自己做的芯片的数据,一个是从数据库下载的芯片数据。 如果是自己做的芯片的数据,是一定要进行芯片质量控制的。虽然厂家会提供芯片质量分析的...
  • 语音编解码芯片AMBE2000中文手册

    千次阅读 2014-03-03 10:18:33
    【数字对讲技术】语音编解码芯片AMBE2000中文手册 2012-05-16 18:13  加入收藏  转发分享  人人网  开心网  新浪微博  搜狐博客  百度收藏  谷歌收藏  qq书签  豆瓣  ...
  • 贴brcm4330芯片的情况下,invensense的sensor失效问题分析 结论: 启动顺序问题。 sensor的上层应用会在启动过程试图打开invensense的sys文件接口。 invensense驱动目前以ko方式通过init.rc进行加载,并在...
  • 幸运转盘芯片——CD4017和NE555

    千次阅读 2020-11-01 22:15:51
    幸运转盘原理图,用到了NE55和CD4017两种芯片。... 原理图CLK-----CP RST-----CR ENA-----INH INH为低电平时,计数器在时钟上升沿计数;反之,计数功能无效。CR为高电平时,计数器清零。John.
  • Flash存储芯片M25P16中文资料

    万次阅读 2014-04-14 11:24:21
    对于某个单字节空间的操作,在使用PP指令之前需要对其擦除(FFh)。擦除操作可通过单块擦除指令(SE)和整块擦除(BE)来完成。擦除之前需要先执行WREN指令。当片选S信号为低电平,则选中该器件,此时处于有效电源模式;当...
  • 自动驾驶芯片之——FPGA和ASIC介绍

    千次阅读 2019-01-10 08:08:25
    当前阶段,GPU 配合 CPU 仍然是 AI 芯片的主流,而后随着视觉、语音、深度学习的算法在 FPGA以及 ASIC芯片上的不断优化,此两者也将逐步占有更多的市场份额,从而与GPU达成长期共存的局面。从长远看,人工智能类脑...
  • FPGA芯片行业科普

    千次阅读 2020-12-30 15:18:59
    ​ 文章大纲 中国FPGA芯片行业综述 ... •FPGA芯片特点及分类 ... •FPGA芯片行业产业链 ... •FPGA芯片关键技术 ... 中国FPGA芯片行业驱动因素 ... •5G通信体系建设提高FPGA芯片需求 ... 中国FPGA芯片行业制约...FPGA芯片...
  • m1芯片有多强!MacBook Pro M1芯片评测

    千次阅读 2020-12-01 15:47:40
    搭载M1芯片的13寸MacBook Pro已到手,初代M1芯片的MacBook Pro性能有多强大,为了对比有参照物,这一次搭载M1芯片的13寸MacBook Pro对比的笔记本是 2020 款英特尔 i5 处理器 16GB 内存的 MacBook Pro 13,和 2019 款...
  • xlinx芯片JTAG烧录

    千次阅读 2017-01-04 16:46:33
    在刚拿到xlinx芯片时,需要对其进行烧录,相对较麻烦,故在有linux系统时,用flashcp命令进行擦写。 下面介绍JTAG烧录操作的步骤(解决的大致步骤是,先将制作的BOOT.bin保存在DDR的一个位置,然后烧录u-boot系统...
  • AI芯片发展的前世今生

    千次阅读 2020-02-24 11:13:23
    2020-02-16 19:38:48 作者 | 任 源、潘 俊、刘京京、何燕冬、何 进 来源 | 《微纳电子与智能制造》期刊...在过去几十年 ,摩尔定 律一直是通过不断缩小芯片上的器件特征尺寸来提高计算能力 ,带来了电子产品诸...
  • wifi芯片研究

    千次阅读 2018-07-26 15:27:13
    Author: Crystal 2018/1/5 ...由于对电源的考虑导致设备设计人员选择应用 FullMAC WiFi 实现方式,这样 WiFi 芯片是自行负责处理 PHY,MAC 和 MLME ,并自行传输准备好的内核驱动程序数据包,这也就是...
  • SSD1306 OLED驱动芯片 详细介绍

    万次阅读 多人点赞 2020-03-23 11:30:35
    概述   SSD1306是一款泛用的OLED驱动芯片 简介    GDDRAM内部结构    三种内存地址模式   
  • 芯片数据分析步骤6 探针注释

    万次阅读 多人点赞 2018-05-22 18:46:36
    因此,芯片厂商不会使用基因名作为探针的名称,而是使用自己定义的探针名称。要合并重复探针,我们必须先对探针进行注释,确定每个探针对应检测哪个基因的表达,然后再合并重复探针。而后续分析如GSEA,只能对基因...
  • 在不少测试,我们看到了令人期待的结果:M1 芯片跑分比肩高端 X86 处理器,对标的 CPU 是 Ryzen 4900HS 和英特尔 Core i9,还能跟英伟达的 GPU GTX 1050Ti 打得有来有回。5 纳米的芯片,真就如此神奇? 自...
  • 主控芯片:STM32L051C8T6 采用内部1.2V参考电压,解决了测量电池电量小于3.0V以下检测不准的问题。篇幅有点长,还需要各位看官慢慢阅读。 基本上可以做到1.8V~5V之间的精准检测电池电量。 1、原理图 2、在...
  • 芯片的原理应用与分类

    万次阅读 2018-01-17 11:49:56
    芯片(chip)或称微电路(microcircuit)、微芯片(microchip)、集成电路(英语:integrated circuit, IC),在电子学是一种把电路(主要包括半导体设备,也包括被动组件等)小型化的方式,并通常制造在半导体晶圆表面上。...
  • 芯片加密解密

    千次阅读 2014-05-13 16:45:16
    基本概述编辑 单片机(MCU)一般都有内部EEPROM/FLASH供用户存放程序和工作数据。为了防止未经授权访问或拷贝...单片机攻击者借助专用设备或者自制设备,利用单片机芯片设计上的漏洞或软件缺陷,通过多种技术手段
  • 合泰触控芯片开发

    千次阅读 2018-03-07 18:41:15
    本次公司项目,需要用到合泰的触控芯片BS82D20A-3,是一款8位,有20个触控引脚的国产芯片芯片提供商给了相关的触控程序软件包。软件包版本V101。开发过程 1.硬件 本身只是一个简单的墙板触控PCB,所以硬件及其...
  • 清华出品:最易懂的AI芯片报告!人才技术趋势都在这里   https://mp.weixin.qq.com/s/kDZFtvYYLLqJSED_0V1RZA   2010 年以来, 由于大数据产业的发展, 数据量呈现爆炸性增长态势,而传统的计算架构又无法支撑...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 51,974
精华内容 20,789
关键字:

芯片中如何使用未操作