美文网首页
捌:模拟SPI总线,实现CS1180AD转换

捌:模拟SPI总线,实现CS1180AD转换

作者: 恰冯同学年少 | 来源:发表于2016-07-12 01:02 被阅读295次

    模拟spi总线操作ad转换芯片cs1180,实现电压、电流表,以下为CODE

    cs1180.c-模式转换芯片驱动

    /******************************************
    *MCU:stc15wk32s4
    *AUTHOR:Golf
    ******************************************/
    #include <stdio.h>
    #include "CS1180.h"
    #include "Usart_Init.h"
    
    //寄存器地址定义
    #define SETUP 0X00//PGA 及BO//cs 控制
    #define MUX   0X01//输入通道选择
    #define ACR   0X02//模拟电路控制
    #define ODAC  0X03//Offset DAC 设置
    #define DIO   0X04//数字I/O 引脚设置
    #define DIR   0X05//输入输出的方向选择
    #define IOCON 0X06//I/O 配置寄存器
    #define OCC0  0X07//失调误差正系数
    #define OCC1  0X08//失调误差正系数
    #define OCC2  0X09//失调误差正系数
    #define GCC0  0X0A//增益误差校正系数
    #define GCC1  0X0B//增益误差校正系数
    #define GCC2  0X0C//增益误差校正系数
    #define DOR2  0X0D//模数转换数据高8位
    #define DOR1  0X0E//模数转换数据中8位
    #define DOR0  0X0F//模数转换数据低8位 
    
    //命令定义
    #define RDATA    0X01//从DOR 寄存器中读取数据
    #define RDATAC   0X03//从DOR 寄存器中连续读取数据
    #define STOPC    0X0F//停止从DOR 寄存器中连续读取数据
    #define RREG     0X10//低4位为寄存器地址
    #define WREG     0X50//低4位为寄存器地址
    #define CALSELF  0XF0//对芯片的失调误差和增益误差进行纠正
    #define OCALSELF 0XF1//对芯片的失调误差进行纠正
    #define GCALSELF 0XF2//对芯片的增益误差进行纠正
    #define OCALSYS  0XF3//对系统的失调误差进行纠正
    #define GCALSYS  0XF4//对系统的增益误差进行纠正
    #define WAKEUP   0XFB//将系统从睡眠模式模式中唤醒
    #define SYNC     0XFC//对DRDY 进行同步
    #define SLEEP    0XFD//使芯片进入睡眠模式
    #define RESET    0XFE//将芯片复位到上电后的状态
    #define P_ADD    0XA3//将芯片复位到上电后的状态
    
    //IO口定义
    #define DRDY2 P32
    #define DRDY1 P33
    #define SCK P34
    #define SDO P35
    #define SDI P36
    #define CS1_A P37
    #define CS2_V P20
    
    xdata adi ad_d[2];
    bit ad_a_ok,ad_v_ok;//ADC转换完标志
        
    /*写一个字节的数据到CS1180的SDI引脚*/
    void Write_One_Byte(unsigned char Byte)    
    {
        char i=0;
        for(;i<8;i++)
        {
            SDI = (bit)(Byte&(0x80>>i));           //先传高位  
            SCK = 0;                               //写数据的时候,数据在上升沿被写入   
            SCK = 1;
        }
    }
    
    /*从SDO引脚读取一个字节的数据*/
    unsigned char Read_One_Byte(void)       
    {
        char i=0;
        unsigned char Data = 0;
        for(;i<8;i++)
        {
            SCK = 1;                               //读数据的时候,数据在下降沿被输出
            SCK = 0;
            Data = (Data << 1) | SDO;
        }
        SCK = 1;
        return Data;
    }
    
    /*1:读取ADC数据 命令编码:0x01*/
    unsigned long Read_Adc_Data(void)
    {
        char datah;
        unsigned char datam,datal;
        signed long c=0;
        datal=datam=datah=0;
        Write_One_Byte(0x01);         //写入命令:0x01 写完后SCK=1 
        datah=Read_One_Byte();
        datam=Read_One_Byte();
        datal=Read_One_Byte();
        c=datah<<16|datam<<8|datal;
        return(c);
    }
    
    /*2:读取寄存器的值 命令编码:0001 rrrr xxxx nnnn*/
    void Read_Reg_Data(char start_reg_addr,char num,char *ptr)
    {
        Write_One_Byte(0x10|start_reg_addr);  //命令的第一个字节    
        Write_One_Byte(num-1);
        for(;num!=0;num--)
        {
            *(ptr++) = Read_One_Byte();           //将读取的寄存器的值顺序保存在数组中 
        }
    }
    
    /*3:写数据到控制寄存器中 命令编码:0101 rrrr xxxx nnnn*/
    unsigned char Write_Reg_Data(char start_reg_addr,char reg_data)
    {
        char err_num = 0;
        Write_One_Byte(0x50|start_reg_addr);  //命令的第一个字节,第一个寄存器为0x00   
        Write_One_Byte(0x00);                 //命令的第二个字节,总共写1个寄存器   
        Write_One_Byte(reg_data);             //写入第一个寄存器值  
        return 0;
    }
    
    //4:CS1180初始化函数 
    void CS1180_ADC_Init(void)
    {
        //全部为准双向口
        P3M0=0;
        P3M1=0;
        P2M0&=~0x01;
        P2M1&=~0x01;
        
        //初始化电流ADC 
        CS1_A = 0;             
        Write_One_Byte(RESET);    
        Write_Reg_Data(SETUP,0x02);
        Write_Reg_Data(ACR,0x62);
        Write_Reg_Data(ODAC,0x30);
        CS1_A = 1; 
    
        //初始化电压ADC 
        CS2_V = 0;              
        Write_One_Byte(RESET);   
        Write_Reg_Data(ACR,0x62);
        Write_Reg_Data(ODAC,0x30); 
        CS2_V = 1; 
        
        //外部中断初始化
        IT0=1;//下降沿触发
        EX0=1;//开中断
        IT1=1;//下降沿触发
        EX1=1;//开中断
    }
    
    /*外部中断0响应函数 读取电压*/
    void Int0_func() interrupt 0
    {
        EX1 = 0;    //关掉电流表中断  
        if(DRDY2==0)
        {
            LED1 = 0;
            CS2_V = 0;
            ad_d[1].ad_re = Read_Adc_Data();
            CS2_V = 1;
            IE0 = 0;       //外部中断标志位清0
            ad_a_ok = 1;
            LED1 = 1;
        }
        EX1=1;
    } 
    
    /*外部中断1响应函数 读取电流*/
    void Int1_func() interrupt 2
    {
        EX0 = 0;    //关掉电压表中断  
        if(DRDY1==0)
        {
            LED2 = 0;
            CS1_A = 0;
            ad_d[0].ad_re = Read_Adc_Data();
            CS1_A = 1;
            IE1 = 0;        //外部中断标志位清0
            ad_v_ok = 1;
            LED2 = 1;
        }
        EX0 = 1;
    } 
    
    
    

    相关文章

      网友评论

          本文标题:捌:模拟SPI总线,实现CS1180AD转换

          本文链接:https://www.haomeiwen.com/subject/evvjjttx.html