智能车制作

 找回密码
 注册

扫一扫,访问微社区

查看: 3671|回复: 2
打印 上一主题 下一主题

c8051f020 ADS1248

[复制链接]

1

主题

12

帖子

0

精华

注册会员

Rank: 2

积分
122
QQ
威望
63
贡献
39
兑换币
39
注册时间
2013-7-4
在线时间
10 小时
毕业学校
兰州理工
跳转到指定楼层
1#
发表于 2013-8-20 17:05:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/********************************************************************************************
第一次编写SPI接口的芯片,编写了三天,最后还是在淘宝上要的资料才编出的,哎,
该代码是用c8051f020的I/Om模拟的SPI ,自己没有变出来的原因(1)文档没仔细看,
对读写寄存器那块的操作没看懂,没注意到 读写寄存器那块上面的指令
编写者:漠北的孤狼
编写地点;本部飞思卡尔实验室
编写时间 2013 8 20
代码首次完成时间 2013 8 20 9点24分
********************************************************************************************/
#include<c8051f020.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char              
unsigned long  results=0;
unsigned char  AD_reg[6];
unsigned char char_results[3];
unsigned int DELAY_10ms = 10000;
unsigned char red_Adc = 0;
//*********************************指令集****************************************************
#define   ADS1248_CMD_WAKEUP    0x00   // Exit sleep mode
#define   ADS1248_CMD_SLEEP     0x02   // Enter sleep mode
#define   ADS1248_CMD_SYNC      0x04   // Synchronize the A/D conversion
#define   ADS1248_CMD_RESET     0x06   //  Reset to power-up values
#define   ADS1248_CMD_NOP       0xff   //  No operation
#define   ADS1248_CMD_RDATA     0x12   //  Read data once
#define   ADS1248_CMD_RDATAC    0x14   //  Read data continuously
#define   ADS1248_CMD_SDATAC    0x16   //  Stop reading data continuously
#define   ADS1248_CMD_RREG      0x20   //  Read from register rrrr
#define   ADS1248_CMD_WREG      0x40      //  Write to register rrrr
#define   ADS1248_CMD_SYSOCAL 0x60      //  System offset calibration
#define   ADS1248_CMD_SYSGCAL 0x61   //  System gain calibration
#define   ADS1248_CMD_SELFOCAL 0x62    // Self offset calibration  
//*********************************寄存器集*****************************************************
#define   ADS1248_REG_MUX0    0x00
#define   ADS1248_REG_VBIAS   0x01
#define   ADS1248_REG_MUX1    0x02
#define   ADS1248_REG_SYS0    0x03
#define   ADS1248_REG_CFC0    0x04
#define   ADS1248_REG_CFC1    0x05
#define   ADS1248_REG_CFC2    0x06
#define   ADS1248_REG_FSC0    0x07
#define   ADS1248_REG_FSC1    0x08
#define   ADS1248_REG_FSC2    0x09
#define   ADS1248_REG_IDAC0   0x0a
#define   ADS1248_REG_IDAC1   0x0b
#define   ADS1248_REG_GPIOCFG  0x0c
#define   ADS1248_REG_GPIODIR  0x0d
#define   ADS1248_REG_GPIODAT  0x0e
////***********************SPI引脚 ********************************   
sbit TX0 = P0^0;      //C8051F0200中串口引脚
sbit RT0 = P0^1;     //C8051F0200中窜口引脚
sbit ADS_SCLK= P0^4; //结C8051f020的SCK   时钟
sbit ADS_Din = P0^5; //结C8051f020的MISO    数据输入
sbit ADS_Dout = P0^6; //结C8051f020的MOSI, 数据输出端
sbit ADS_CS =  P3^0;     //结C8051f020的NSS,片选,此程序中未用,直接接低电平了
sbit ADS_DRDY = P0^2;  //程序中此端口接P3.2,用于外部中断  =P0^6;
sbit ADS_Start =P0^7;    //转换启动            
sbit ADS_RESET = P0^3;   //复位
///************************************************************************************/
//=====================================SPI的接口定义=========================================
/***********************************************************************************
* 函数名称:Delay;
*
* 函数功能描述:延时n微秒子函数;
*              
* 输入参数:延时时间(单位微秒);
*
* 返回数据:none;
*
* 注意:    none;
************************************************************************************/
void Delay(unsigned char Times)
{
    unsigned char i;
for (i=0; i<Times; i++)
{
  _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
  _nop_();_nop_();_nop_();_nop_();
  _nop_();
}
}  
//*************************c8051f020模块中的函数 开始***********************************************
//======================================================================================
//外部晶振初始化函数
void Oscillator_init(void)      
{
    int i = 0;
    OSCXCN    = 0x67;
    for (i = 0; i < 3000; i++);  // Wait 1ms for initialization
    while ((OSCXCN & 0x80) == 0);
    OSCICN    = 0x0C;
}
//======================================================================================
//关看门狗函数
void Reset_sources_init(void)     
{
    WDTCN     = 0xDE;
    WDTCN     = 0xAD;
}
//======================================================================================
//IO初始化函数
void Port_iO_init(void)  
{        
XBR0      = 0x04;     //串口TX0是P0^0,RT0是P0^1,SCK是P0^4,MISO是P0^5,MOSI是P0^6
    XBR1      = 0x04;
    XBR2      = 0xC0;
    P0MDOUT   |= 0xff;        //把P0^0到P0^5设置为推挽输出
}
void Interrupts_Init(void)
{
    IE        |= 0x81;
IE        |= 0x10;           //串口中断

}
//======================================================================================
//串口初始化函数
void UART0_init(void)  //串口0初始化
{
SCON0=0x50;            //串口方式1
TMOD=0X20;             //选用定时器1作为波特率发生器
TH1=(65536-600)/256;              
TL1=(65536-600)%256;
PCON=0x80;    //波特率为9600
TR1=1;                //定时器启动
}
//======================================================================================
//c8051f020的SPI模式设置函数
void SPI_init(void)     
{
// SPI0CN    |= 0x01;     //启动SPI
// SPI0CN    |= 0x03;     //SPI工作方式为主机模式,系统默认的是从机模式
// SPI0CFG   |= 0x80;        //SPI时钟相位在第二个SCK周期采样,系统默认的是在第一个SCK周期采样
// SPI0CFG   |= 0x40;        //SPI时钟极性为空闲高电平,系统默认的是空闲为低电平
}

/** Send a char to MC **/
void sendChar(unsigned char ch)
{
SBUF0 = ch;
while(TI0 == 0);
TI0 = 0;
}
//*******************************串口模块化程序 结束********************************************************
//*******************************SPI构架的第一层 开始************************************************************
//*******************************SPI构架的第一层 开始************************************************************
//-----------------------------------------------------------------//
// 功    能:延时
// 入口参数: 延时时间 delay * us
// 出口参数: /
// 全局变量: /
// 备    注:
//-----------------------------------------------------------------//
//*************************************模拟 SPI程序**************************************************
//-----------------------------------------------------------------//
// 功    能:IO口模拟的SPI程序,ADS1248 SPI接口程序
// 入口参数: /
// 出口参数: /
// 全局变量: /
// 备    注: SPI速度最高2MHz,用于命令发送等操作
//-----------------------------------------------------------------//
unsigned char ADS1248SPI(unsigned char m)
{
    //SPI速度最高2MHz,用于命令发送等操作
    unsigned char i,r=0;
    for(i=0;i<8;i++)
    {
      ADS_SCLK = 1;
      r=r<<1;
      if(m & 0x80)       //
   {
     ADS_Din = 1;
   }   
   else
   {  
    ADS_Din = 0;
   }
   m = m<<1;
      ADS_SCLK = 0;
      if(ADS_Dout == 1)
   {
    r++;
   }
    }
    return r;
}
//-----------------------------------------------------------------//
// 功    能:ADS1248 读取
// 入口参数: /
// 出口参数: /
// 全局变量: /
// 备    注:
// SPI速度最高2MHz,用于读取AD的24位结果.在使用START引脚控制ADS1248时,可使用此函数
// 输出为有符号数。已经把ADS1248的输出格式转变为有符号数,0输入对应码值0,正最大对应7FFFFF,负最大对应-7FFFFF
// WriteOut是在发送24个SCLK以读取数据的同时写出去的24位指令,比如写入MUX0寄存器以改变通道。注意此次读取的为设置改变前的结果
// 如果WriteOut是操作控制寄存器,则START线应该保持高
//-----------------------------------------------------------------//
unsigned long ADS1248ReadData(unsigned long WriteOut)
{
    unsigned char i=0;
    unsigned long r=0;
    for(i=0;i<24;i++)
    {
      ADS_SCLK = 1;
      r=r<<1;
   Delay(10);

      if (WriteOut & 0x800000)
   {
    ADS_Din = 1;
   }
   else
   {
    ADS_Din = 0;
   }
   WriteOut=WriteOut<<1;
      ADS_SCLK = 0;
      if(ADS_Dout)
   {
    r++;
   }
    }   
    return r;
}
//*******************************SPI构架的第一层 结束************************************************************
//*******************************SPI构架的第一层 结束************************************************************
//===============================================================================================================
//*******************************SPI构架的第二层 开始************************************************************
//*******************************SPI构架的第二层 开始************************************************************
//-----------------------------------------------------------------//
// 功    能:ADS1248 写寄存器
// 入口参数: /
// 出口参数: /
// 全局变量: /
// 备    注: 向ADS1248中地址为regaddr的寄存器写入一个字节databyte
//-----------------------------------------------------------------//
void ADS1248WREG(unsigned char regaddr,unsigned char databyte)     //直接看文档53页写寄存器3个指令就可以了
{
                                                               
    ADS1248SPI(ADS1248_CMD_WREG+(regaddr & 0xF));    //向寄存器写入数据地址,为什么&0xf?因为是16位的寄存器
    ADS1248SPI(0);            //写入数据的个数n-1
    ADS1248SPI(databyte);          //向regaddr地址指向的寄存器写入数据databyte
}
//-----------------------------------------------------------------//
// 功    能:ADS1248 读寄存器
// 入口参数: /
// 出口参数: /
// 全局变量: /
// 备    注: 从ADS1248中地址为regaddr的寄存器读出一个字节databyte
//-----------------------------------------------------------------//
unsigned char ADS1248RREG(unsigned char regaddr)
{                  // 看文档53页读寄存器的指令
                                             
    unsigned char r=0;           //从ADS1248中地址为regaddr的寄存器读出一个字节
                   //在ADS1248_CMD_RREG的基础上加regaddr & 0xF)
    ADS1248SPI(ADS1248_CMD_RREG+(regaddr & 0xF));    //写入地址,为什么是&0xf,因为是16位的寄存器
    ADS1248SPI(0);            //写入读取数据的个数n-1
    r=ADS1248SPI(ADS1248_CMD_NOP);        //读出regaddr地址指向的寄存器的数据,这是明智的
    return r;//返回数据
}
//*******************************SPI构架的第二层 结束************************************************************
//*******************************SPI构架的第二层 结束************************************************************
//===============================================================================================================
//*******************************SPI构架的第三层 开始************************************************************
//*******************************SPI构架的第三层 开始************************************************************
//连续的读,连续的写
//*******************************SPI构架的第三层 结束************************************************************
//*******************************SPI构架的第三层 结束************************************************************

//*******************************ADS1248的AD模块的函数 ************************************************************
void Ads1248(void)
{                                      
    ADS1248SPI(ADS1248_CMD_RDATA);   //发送单次读数据命令
    results=ADS1248ReadData(0xFFFFFF);  //读取ADC转换完成的数据,24位数故6个F,当然了还可以是7FFFFFF,000000,
                                         //等不同地点模式,差别是单端输入的值得范围不同,见文档35页详解
    ADS1248SPI(ADS1248_CMD_NOP);   //发送空操作指令,强迫D_OUT变高
}
//*******************************SPI构架的第四层 开始************************************************************
//*******************************SPI构架的第四层 开始************************************************************
//-----------------------------------------------------------------//
// 功    能:ADS1248初始化子程序
// 入口参数: /
// 出口参数: /
// 全局变量: /
// 备    注: /
//-----------------------------------------------------------------//
void InitADS1248(void)
{
    Delay(10);
   
    ADS_Start = 0;
ADS_CS = 0;
//发送复位命令
    ADS_RESET = 0;
    Delay(DELAY_10ms);
    ADS_RESET = 1;
                                                                         //在写寄存器的函数中给寄存器的地址以及它的指令
    //ADS1248SPI(ADS1248_CMD_RESET);
    //初始化MUX0多路复用控制寄存器
    ADS1248WREG(ADS1248_REG_MUX0,0x07); //00100101,Bit7-6:传感器电流源检测不使用,Bit5-3:正输入为AIN0,Bit2-0:负输入为AIN1 ,通道的选择 (0x00)是单通道0
    //初始化MUX1多路复用控制寄存器
    ADS1248WREG(ADS1248_REG_MUX1,0x33); //00110000,Bit7:启用内部晶振,Bit6-5:内部基准一直打开,Bit4-3:输入基准为片上基准,Bit2-0:普通模式
    //延时等待10ms,等待内部基准稳定,可以打内部传感器  ADS1248WREG(ADS1248_REG_MUX1,0x03)打开内部温度传感器
    Delay(6*DELAY_10ms);
    //初始化VBIAS偏压寄存器
    ADS1248WREG(ADS1248_REG_VBIAS,0); //00000000,Bit7-0:偏置电压选择关闭(默认)
    //初始化IDAC1控制寄存器
    ADS1248WREG(ADS1248_REG_IDAC1,0xFF);//11111111,Bit7-4:断开内部第一恒流源的连接,Bit3-0:断开内部第二恒流源的连接  0X8F打开第一内部恒流源
    //初始化IDAC0控制寄存器
    ADS1248WREG(ADS1248_REG_IDAC0,0x00); //00001000,Bit7-4:只读,Bit3RDY/DOUT功能复用Dout线 ,Bit2-0:关闭内部恒流源
    //初始化SYS0系统控制寄存器
    ADS1248WREG(ADS1248_REG_SYS0,0x09); //00000000,Bit7:必须设置为0,Bit6-41:选择1倍增益,Bit3-0:选择2000SPS测量速度
}
//************************************主函数模块开始****************************************************
void main(void)
{   
    unsigned long fVoltage;
unsigned char buf[10],i;
   
unsigned long Result_sum=0;
Result_sum = 0;
  ADS_CS = 0;
    Oscillator_init();
Reset_sources_init();
Port_iO_init();
UART0_init();
Interrupts_Init()
InitADS1248();
       EA=1;                   //打开中断  void SYSCLK_Init(void)
    IT0=1;                   //打开外部中断0边沿触发。IT0=0时是低电平触发。
    EX0=1;                   //初始化外部中断标志位
    ADS_Start = 0;
while(1)
{
  ADS_Start = 1;               //测试单独触发模式 Start为高至少3mS
  Delay(10);         //测试结果:每触发一次,发送一次数据。
  ADS_Start = 0;
  Result_sum =  results >> 8;
  if(Result_sum<0x8000)        //测得电压值为正的情况
  {
     fVoltage=Result_sum*625;  //625=2.048/32768*10000000   6.144位基准电压 32768为2的15次方 10000000为为了计算的准确性转换为整形计算
     buf[0]=(unsigned char)(fVoltage/10000000);
     buf[0]=buf[0]+0x30;
     buf[1]='.';
     buf[2]=(unsigned char)((fVoltage%10000000)/1000000);
     buf[2]=buf[2]+0x30;
     buf[3]=(unsigned char)((fVoltage%1000000)/100000);
     buf[3]=buf[3]+0x30;
     buf[4]=(unsigned char)(fVoltage%100000/10000);
     buf[4]=buf[4]+0x30;
     buf[5]=(unsigned char)(fVoltage%10000/1000);
     buf[5]=buf[5]+0x30;
     buf[6]=(unsigned char)(fVoltage%1000/100);
     buf[6]=buf[6]+0x30;        
     buf[7]='V';        //V
     buf[8]=0x20;
     buf[9]=0x20;
   }
   else          //测得电压值为负的情况
   {
     //buf[0]='-';            //取‘-’号
     Result_sum=0xffff-Result_sum;    //取反运算
     fVoltage=Result_sum*625;  //625=2.048/32768*10000000   6.144位基准电压 32768为2的15次方 10000000为为了计算的准确性转换为整形计算
     buf[0]=(unsigned char)(fVoltage/10000000);
     buf[0]=buf[0]+0x30;
     buf[1]='.';
     buf[2]=(unsigned char)((fVoltage%10000000)/1000000);
     buf[2]=buf[2]+0x30;
     buf[3]=(unsigned char)((fVoltage%1000000)/100000);
     buf[3]=buf[3]+0x30;
     buf[4]=(unsigned char)(fVoltage%100000/10000);
     buf[4]=buf[4]+0x30;
     buf[5]=(unsigned char)(fVoltage%10000/1000);
     buf[5]=buf[5]+0x30;
     buf[6]=(unsigned char)(fVoltage%1000/100);
     buf[6]=buf[6]+0x30;        
     buf[7]='V';   //V         
     buf[8]=0x20;   //空格
     buf[9]='-';
   }
  
     i=0;
     while(i<10)
     {
    sendChar(buf[i]);
    i++;
     }
  
    Delay(5*DELAY_10ms);     //延时
/***************************************************************/
   }
}
//*******************************SPI构架的第四层 结束************************************************************
//*******************************SPI构架的第四层 结束************************************************************
/** COM receive message interrupt function**/
void inteReceive (void) interrupt 4
{
if(RI0 == 1)
{
  RI0 = 0;
}
}
void ISR_ADC_DRDY(void) interrupt 0
{
EX0=0;         //外部中断0关   
Ads1248();    //读取AD值,读取的数值存储在全局变量中。
sendChar((unsigned long)(results >> 16) & 0x0000ff); //发送最高位
sendChar((unsigned long)(results >> 8) & 0x0000ff);  //发送中间位
    sendChar((unsigned long)results & 0x0000ff);   //发送低位
    EX0 = 1;         
}


4

主题

41

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1201
威望
634
贡献
359
兑换币
296
注册时间
2012-2-8
在线时间
104 小时
2#
发表于 2013-8-20 17:20:12 | 只看该作者
sf~~
回复 支持 反对

使用道具 举报

1

主题

12

帖子

0

精华

注册会员

Rank: 2

积分
122
QQ
威望
63
贡献
39
兑换币
39
注册时间
2013-7-4
在线时间
10 小时
毕业学校
兰州理工
3#
 楼主| 发表于 2013-8-25 15:13:41 | 只看该作者
?????????????????
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关于我们|联系我们|小黑屋|智能车制作 ( 黑ICP备2022002344号

GMT+8, 2024-9-27 22:38 , Processed in 0.040207 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表