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

模拟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;
} 


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,219评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,363评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,933评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,020评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,400评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,640评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,896评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,597评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,327评论 1 244
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,581评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,072评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,399评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,054评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,849评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,672评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,585评论 2 270

推荐阅读更多精彩内容