AD7908使用模拟SPI读取模拟量值

根据电路板的连线图和手册中的寄存器定义,可以先写一波SPI_AD7908相关的宏。
使用模拟S

#define AD7908_CS PAout(8)  //AD7908片选信号,低电平有效
#define AD7908_MISO PBin(14)
#define AD7908_MOSI PBout(15)
#define AD7908_CLK PBout(13)

#define SPI_AD7908_WRITE(n)         (n<<11) //0=read 1=write
#define SPI_AD7908_ADD(n)           (n<<6) //n:0~7 读取通道
#define SPI_AD7908_PM(n)            (n<<4) //n:0~3 0:无效,1:自动关断,2:完全关断,3:正常工作
#define SPI_AD7908_SEQ(n)           (n<<10)// 配合SHADOW使用  
#define SPI_AD7908_SHADOW(n)        (n<<3) // 配合SEQ使用 00:序列未使用 11:连续通道序列连续转换
#define SPI_AD7908_RANGE(n)         (n<<1)//  输入范围 0:0~2*Ref , 1:0~Ref
#define SPI_AD7908_CODING(n)        (n<<0)//  0:二进制补码输出, 1:二进制输出

void AD7908_Init(void);
uint16_t SPI_AD7908_Write_Control(uint8_t writeread, uint8_t Channel);
uint16_t SPI_ReadWrite(uint16_t TxData);

AD7908_Init初始化成普通IO输入输出,SPI_AD7908_Write_Control则根据定义生成相应的写入参数,SPI_ReadWrite则根据时序对参数进行写入,和对数据进行读取。
此处可以参考AD7908时序图:
在这里插入图片描述

void AD7908_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //PORTA时钟使能    片选引脚
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);  //PORTA时钟使能    片选引脚

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;  // PA8 推挽
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_SetBits(GPIOA, GPIO_Pin_8);


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15; // PA8 推挽
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_SetBits(GPIOB, GPIO_Pin_13 | GPIO_Pin_15);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;  // PA8 推挽
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;  //推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    AD7908_CS = 1;              //SPI AD7908不选中
    AD7908_CLK = 1;

}




uint16_t SPI_AD7908_Write_Control(uint8_t writeread, uint8_t Channel)//控制寄存器中写值
{
    u16 dat_16 = 0;
    if (writeread == 1) //write

        dat_16 = SPI_AD7908_WRITE(writeread) | \
                 SPI_AD7908_ADD(Channel) | \
                 SPI_AD7908_PM(3) | \
                 SPI_AD7908_SEQ(0) | \
                 SPI_AD7908_SHADOW(0) | \
                 SPI_AD7908_RANGE(0) | \
                 SPI_AD7908_CODING(1);

    else  //read
        dat_16 = SPI_AD7908_WRITE(writeread) | \
                 SPI_AD7908_ADD(Channel) | \
                 SPI_AD7908_PM(3) | \
                 SPI_AD7908_SEQ(0) | \
                 SPI_AD7908_SHADOW(0) | \
                 SPI_AD7908_RANGE(0) | \
                 SPI_AD7908_CODING(1);
    dat_16 <<= 4;
    return dat_16;

}

uint16_t SPI_ReadWrite(uint16_t TxData)
{
    uint16_t RxData = 0;
    int i = 0;
    AD7908_CS = 0;
    delay_us(1);
    for (i = 0; i < 16; i++)
    {
        AD7908_MOSI = (TxData & 0x8000) ? 1 : 0;
        delay_us(1);
        AD7908_CLK = 0;
        delay_us(1);
        RxData <<= 1;
        TxData <<= 1;
        AD7908_CLK = 1;
        delay_us(1);
        RxData |= AD7908_MISO;
    }
    delay_us(1);
    AD7908_CLK = 1;
    AD7908_CS = 1;
    return RxData >> 1;
}

循环体:

 	       addr++;
           if (addr > 7)  addr = 0;
           AD7908_Recive = SPI_ReadWrite(SPI_AD7908_Write_Control(1, addr));
           printf("%d:%x %d\r\n", addr, AD7908_Recive, (AD7908_Recive >> 4) & 0xFF);
           delay_ms(1000);

看一下输出结果,IN4连接的3.3V,量程为5V,5/255*168=3.294V完美。

1:22a0 42
2:12d0 45
3:2370 55
4:34a0 74
5:4a80 168
6:56c0 108
7:6530 83
0:7480 72
1:380 56
2:1350 53
3:2360 54
4:34c0 76
5:4a80 168
6:5700 112
7:6550 85
0:7490 73

注意,每次返回的结果都是上次写入参数时读取的结果!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值