51单片机驱动AD7799程序(keil c)

发布者:rocky96最新更新时间:2015-01-06 关键字:51单片机  AD7799  keil 手机看文章 扫描二维码
随时随地手机看文章

下面提供一个完整版本的ad7799程序,Keil C写的ADI的24位A/DAD7799使用SPI接口程序:(VRS51L3074单片机 是一颗基于8051内核集成了多种模块并可多 范围的在嵌入式设计中应用的芯片,完整的工程文件及hex下载地址:http://www.51hei.com/f/Keil_C_AD7799.rar )

ad7798,ad7799的详细中文资料请看: http://www.51hei.com/chip/4000.html
#pragma CODE DEBUG SYMBOLS OBJECTEXTEND     //SRC 当与汇编混合编译时需要

#include"VRS51L3074_keil.h"
#include
#define uchar   unsigned char
#define uint    unsigned int
#define ulong   unsigned long
typedef union{     //无符号字符型,整形,长整形数据联合体
              uchar uc[2];
              uint  ui;
             }UCI;
typedef union{     //无符号字符型,整形,长整形数据联合体
              uchar uc[4];
              uint  ui[2];
              ulong ul;
             }UCIL;
                            
 
#define DELAY5  delay()   //_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_()
sbit    P1_5    =   P1^5;      //1
sbit    P1_6    =   P1^6;      //2
sbit    P1_7    =   P1^7;      //3
sbit    P4_5    =   P4^5;     //6  pin
sbit    P5_0    =   P5^0;     //7
sbit    P5_1    =   P5^1;     //8
sbit    P5_2    =   P5^2;     //9
sbit    P5_3    =   P5^3;     //10
sbit    P5_4    =   P5^4;     //20
sbit    P5_5    =   P5^5;     //21
sbit    P5_6    =   P5^6;     //22
sbit    P5_7    =   P5^7;     //23
 
#define AD7799_CS    P4_5           //输出   6pin
#define AD7799_SCLK  P5_1           //输出   8pin
#define AD7799_DOUT  P5_2           //输入   9pin
#define AD7799_RDY   P5_2           //输入   9pin  同上是一个引脚
#define AD7799_DIN   P5_0           //输出   7pin
 
UCIL MainData,demoul;
ulong xdata XMainData,xdemoul;
void Ad7799_Ini();
 
#define DELAYS10    _nop_();_nop_();_nop_();_nop_()
void delay(char i)
{uchar j;
 for(;i>0;i--); for(j=0;j<10;j++)_nop_();
}
 
void CPUInit(void)
{
  /*I/O口配置:输入配置为1(配置为1后,内部自动上拉到2.5V,输出配置为0;空脚要配置为0*/  
  PERIPHEN1=0x18;  //BIT7:SPICSEN 6:SPIEN 5:I2CEN 4:U1EN 3:U0EN 2:T2EN 1;T1EN 0:T0EN  //TIMER2和TIMER0使能
  P0PINCFG=0x00;
  P1PINCFG=0x04;
  P2PINCFG=0x00;   //00100100
  P3PINCFG=0x01;
  P4PINCFG=0x00;
  P5PINCFG=0x04;  //00000100
  P6PINCFG=0x00;
  PORTINEN=0xff; //0xff全部I/O口均不使用
  P0=P1=P2=P3=P6=0x00;  P4=0x00;P5=0x04;
  PERIPHEN2=0x28;//BIN7:PWC1EN 6:PWC0EN 5:AUEN 4:XRAM2CODE 3:IOPORTEN 2:WDTEN 1:PWMSFREN 0:FPIEN  算术单元、IO口使能*/
  P0=P1=P2=P3=P6=0x00; P4=0x00; P5=0x04;
  AD7799_CS=1;
    UART0CFG=0x90;  // 0x09:38400 BRADJ=0x02(19200)/波特率发生器使用内部晶振/9th不使用/1位停止位
    UART0INT=0x00;  //使能接收中断,使能发送完成中断,允许接收 Enable RX AV + RXOVint + Enable Reception
    UART0EXT=0x00;  //Not using UART0 Extensions
    UART0BRL=0x1f;   //0040=19200  001f=38400
    UART0BRH=0x00;  //波特率19200
    U0IEN=1;
   GENINTEN = 0x01;      //Enable Global interrupt
   UART0BUF=0xff;
   while(!(UART0INT & 0x01));
   UART0BUF=0xff;
   while(!(UART0INT & 0x01));
   UART0BUF=0xff;
   while(!(UART0INT & 0x01));
   UART0BUF=0xff;
   while(!(UART0INT & 0x01));
   UART0BUF=0x0d;
   while(!(UART0INT & 0x01));
}
 
/*  AD7799写寄存器函数
    WriteData:要写的数据*/
void WriteByteToAd7799(unsigned char WriteData)
{
    unsigned char i ;
    AD7799_CS=0;
    for(i=0;i<8;i++)
    {
        DELAYS10;
        AD7799_SCLK=0 ;
        DELAYS10;
        if(WriteData&0x80)AD7799_DIN=1 ;
        else AD7799_DIN=0 ;
        WriteData=WriteData<<1 ;
        DELAYS10;
        AD7799_SCLK=1 ;
        DELAYS10;
    }
    AD7799_CS=1;
}
 
/*AD7799读寄存器函数*/
unsigned char ReadByteFromAd7799(void)
{
    unsigned char i ;
    unsigned char ReadData ;
    AD7799_CS=0;
    ReadData=0 ;
    for(i=0;i<8;i++)
    {
        DELAYS10;
        AD7799_SCLK=0 ;
        DELAYS10;
        ReadData=ReadData<<1 ;
        if(AD7799_DOUT)ReadData+=1 ;
        DELAYS10;
        AD7799_SCLK=1 ;
        DELAYS10;
    }
    AD7799_DOUT=1 ;
    AD7799_CS=1;
    return(ReadData);
}
void WaiteRDY(void)
{
    unsigned int iint ;
    iint=0 ;
    while(AD7799_RDY)
    {
        iint++;
        if(iint>65530)
        {
            //reset ad7799
            WriteByteToAd7799(0xff);
            WriteByteToAd7799(0xff);
            WriteByteToAd7799(0xff);
            WriteByteToAd7799(0xff);
            Ad7799_Ini();
            break ;
        }
    }
}
void Ad7799_Ini()
{
    WriteByteToAd7799(0x10);
    //b0001 0000
    /* Writes to Communications Register Setting Next Operation as Write to CONFIGURATION Register*/
    //写通讯寄存器为:下一操作写配置寄存器 WriteByteToAd7799(0x10)b0001 0000    0写通讯0下操作写010配置寄存器0关连续读00留用
    WriteByteToAd7799(0x37);//增益为128  B0011 0111   00留用1开电流源1单端  0留用111是128倍增益
    WriteByteToAd7799(0x00);  //通道号 0 B0011 0000   00留用1基准默认1开缓冲 0留用000通道0
    //1通道
    /*CONFIGURATION REGISTER[00,BO(0),U/B(0),0(0),G2(1),G1(1),G0(1),0,0,REF_DET(0),BUF(1),0(0),CH2(0),CH1(0),CH0(0)]*/
    //WriteByteToAd7799(0x08);
    //b0000 1000
    /* Writes to Communications Register Setting Next Operation as Write to Mode Register*/
    //WriteByteToAd7799(0x80);
    //WriteByteToAd7799(0x0a);
    /* Writes to Mode Register Initiating Internal Zero-Scale Calibration*/
    //WaiteRDY();
    /* Wait for RDY pin to go low to indicate end of calibration cycle*/
    //WriteByteToAd7799(0x08);
    /* Writes to Communications Register Setting Next Operation as Write to
        Mode Register*/
    //WriteByteToAd7799(0xa0);
    //WriteByteToAd7799(0x0a);
    /* Writes to Mode Register Initiating Internal Full-Scale Calibration*/
    //WaiteRDY();
    /* Wait for RDY pin to go low to indicate end of calibration cycle*/
    WriteByteToAd7799(0x08);//b0000 1000
    /* Writes to Communications Register Setting Next Operation as Write to Mode Register*/
    WriteByteToAd7799(0x00);   //000连续模式0断PSW0000留用
    WriteByteToAd7799(0x09);   //0000留用0011(123Hz)1010(16.7HZ65dB)
    /* Mode Register[MD2(0),MD1(0),MD0(0),PSW(0),0(0),0(0),0(0),0(0),(0),(0),0(0),0(0),FS3(1),FS2(0),FS1(1),FS0(0)]*/
    /*模式0 Continuous-Conversion Mode.,Fadc=16.7HZ;*/
 
}
ulong ReadAd7799ConversionData(void)
{
    ulong ConverData ;
    unsigned char ADSAT ;
    unsigned char ErrNUM=0;
    WaiteRDY();              //等待数据READY
    WriteByteToAd7799(0x40);  //0100 0000 配置下一操作为:读状态寄存器
    ADSAT=ReadByteFromAd7799();   //读出状态 8位
    while((ADSAT&0x40)||(!(ADSAT&0x08)))    //出错或者读写异常
    {
        WriteByteToAd7799(0xff);         //复位
        WriteByteToAd7799(0xff);
        WriteByteToAd7799(0xff);
        WriteByteToAd7799(0xff);
        Ad7799_Ini();                   //初始化
        WaiteRDY();                     //读状态
        WriteByteToAd7799(0x40);        //下一操作:读状态
        ADSAT=ReadByteFromAd7799();     //读状态
       
        ErrNUM++;
        if(ErrNUM>5)return(0xffffff);//if(ErrNUM>5)break;              //连续5次都读出错
    }
   
    WriteByteToAd7799(0x58);  //0101 1000 配置下一操作:读数据寄存器,000
    /* Writes to Communications Register Setting Next Operation as Continuous Read From Data Register*/
    WaiteRDY();
    /* Wait for RDY pin to go low to indicate end of calibration cycle*/
    if(!AD7799_RDY)
    {
        ConverData=0 ;
        ConverData=ReadByteFromAd7799();
        ConverData=ConverData<<8 ;
        ConverData=ReadByteFromAd7799()+ConverData;
        ConverData=ConverData<<8 ;
        ConverData=ReadByteFromAd7799()+ConverData;
    }
    /* Read Conversion Result from AD7799's Data Register*/
    return(ConverData);
}
UCIL temp;
void main(void)
{
   uint code *adtpoint;   //
   uchar    i=0,j=0;
 
 
 delay(100);
 CPUInit();
 //AD7799_CS=0;
 delay(10);
        WriteByteToAd7799(0xff);       //写入32个高电平,复位ADC
        WriteByteToAd7799(0xff);
        WriteByteToAd7799(0xff);
        WriteByteToAd7799(0xff);
        Ad7799_Ini();
 while(1)
 {
   temp.ul=ReadAd7799ConversionData();
   UART0BUF=temp.uc[0];
   while(!(UART0INT & 0x01));
   UART0BUF=temp.uc[1];
   while(!(UART0INT & 0x01));
   UART0BUF=temp.uc[2];
   while(!(UART0INT & 0x01));
   UART0BUF=temp.uc[3];
   while(!(UART0INT & 0x01));
 }
}
 

关键字:51单片机  AD7799  keil 引用地址:51单片机驱动AD7799程序(keil c)

上一篇:用1602液晶模块显示汉字和图形
下一篇:单片机keil C中的data、bdata、code解释

推荐阅读最新更新时间:2024-03-16 13:50

51单片机基础(5)
1、对程序员来讲,最基本的51单片机具有如下3个存储空间: (1)内部数据空间,地址范围0~255,使用MOV指令和8位地址进行直接和间接访问,当然也有更多的操作类指令如ANL、ADD等可以直接或间接地访问该空间; (2)外部数据空间,地址范围0~65535,(仅可)使用MOVX指令配合存于DPTR中的16位地址或存于R0、R1中的(低)8位地址进行寄存器间接方式的读写访问;使用8位地址访问外部数据空间实际是默认更高位的地址须由其它输出口线事先指定或实际配置的外部数据存储器不超过256字节而没有更高位的地址线需要给定; (3)程序存储空间,地址范围0~65535,(仅可)使用MOVC指令配合作为基地址的存于DPTR中的
[单片机]
51单片机 LCD1602调试工具
本章博客讲述的是关于LCD1602的调试,使用它是为了更加直观的表示出代码所要实现的功能 1.首先,需要添加两份驱动文件到新建的工程中来,再插入到新建的工程中来 将其复制到新建文件的同一目录下,在进行添加 2.写出以下代码进行编译查看效果 #include REGX52.H #include LCD1602.h void main() { LCD_Init(); LCD_ShowChar(1,1,'A'); LCD_ShowString(1,3, Hello ); LCD_ShowNum(1,9,123,3); //高位补零,如果最后一位是2则显示23 LCD_
[单片机]
<font color='red'>51单片机</font> LCD1602调试工具
基于51单片机的大屏幕LED显示屏高速控制方案
引言   LED显示屏的基本工作原理是动态扫描。显示控制的过程是先从数据存储器读得字模数据,再通过单片机的串行口或并行口将数据写给LED点阵片,然后再行扫描。   动态扫描方案和静态显示方案相比节省驱动元件,但要求刷新频率高于50 Hz,以避免显示的图像或文字出现闪烁。由于刷新频率的限制,一片单片机能控制显示元件的片数是较少的。   现在大屏幕LED显示屏的应用已越来越广泛。为了对成百、上千片的LED点阵片实现有序的、快速的显示控制,人们动了许多脑筋,双CPU、双RAM的方案,FPGA的方案等都获得了成功的应用;但是这些方案的显示控制过程还是先读后写。   本方案另开思路:用一条读指令,将读和写合在一步完成,可大大地提高显
[单片机]
基于<font color='red'>51单片机</font>的大屏幕LED显示屏高速控制方案
基于AT89S51单片机和LM35温度传感器的温度采集显示
随着电子和传感技术的快速发展,温度的测量和控制在民用、工业以及航空航天技术等领域,等到了广泛应用。小型的、低功耗的、廉价的、可靠性高的温度传感器引起了人们的广泛关注。在实际生产、生活等领域中,温度是环境因素不可或缺的一部分,对温度进行及时精确的控制和检测显得尤为重要。本文基于AT89S51单片机,采用LM35温度传感器,设计了一种灵敏度较高,抗干扰能力强,工作稳定可靠的温度采集显示系统。 1、系统结构及工作原理 温度采集显示系统电路由温度采集模块、A/D转换模块、单片机控制模块、数码管显示模块和下载模块组成。电路工作原理是:首先由LM35温度传感器采集外界环境的温度,经LM358放大10倍后以电压形式输入到A/D采样电路,由A
[单片机]
基于AT89S<font color='red'>51单片机</font>和LM35温度传感器的温度采集显示
AT89C51单片机游戏(俄罗斯方块)
一、电路设计 此电路由AT89C51最小系统、12864显示模块和独立按键组成。可实现类似俄罗斯方块的游戏 二、运行效果 三、部分代码 /*想要更多项目私wo!!!*/ #include REGX52.H #include pic.c #include intrins.h #define LCD_DATA P2 #define button_delay 150 //按键延时 #define button_acceleration 65 //按键加速度阈值 #define GAME_LOCATION 30 sbit button_a = P3^4; //变形 sbit button_b = P3^5; //开始 s
[单片机]
自制51单片机常用头文件(st7920串行方式)
/*-------------------------------------------------------------------------- ST7920.H The user function is C51. Copyright (c) 1988-2004 Keil Elektronik GmbH sum zhaojun All rights reserved. --------------------------------------------------------------------------*/ // 串行方式 #ifndef __ST7920_H__ #define __ST7920_H__ #
[单片机]
51单片机子程序调用与返回指令简介及举例
(1)主程序与子程序 在前面的灯的实验中,我们已用到过了子程序,只是我们并没有明确地介绍。子程序是干什么用的,为什么要用子程序技术呢?举个例程,我们数据老师布置了10道算术题,经过观察,每一道题中都包含一个(3*5+2)*3的运算,我们能有两种选择,第一种,每做一道题,都把这个算式算一遍,第二种选择,我们能先把这个结果算出来,也就是51,放在一边,然后要用到这个算式时就将51代进去。这两种办法哪种更好呢?不必多言。设计程序时也是这样,有时一个功能会在程序的不一样地方反复使用,我们就能把这个功能做成一段程序,每次需要用到这个功能时就“调用”一下。  (2)调用及回过程:主程序调用了子程序,子程序执行完之后必须再回到主程序继续执行,不
[单片机]
Matlab/RTW实时仿真与嵌入式系统开发
  引 言   在日益激烈的竞争中,系统的开发周期显得尤为重要,但开发时间与系统安全性、可靠性又有一定冲突,如果仍然使用传统的编写代码的模式,显然有些不妥。本文介绍一种基于Matlab/RTW实现实时仿真与嵌入式系统开发的方法。方法所涉及的开发环境如下: ◆Microsoft Windows XP SP3: ◆Matlab Version 7.5.0.342(R2007b); ◆Keil uVersion2V 2.30; ◆Proteus 7.1SP2。   先借助Matlab/RTW建立模型并生成RTW(Real-Time Workshop)代码(C语言),再使用Keil编译、调试Matlab生成的C语言代码,并且生
[嵌入式]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved