我的毕业设计要用到ADC0832芯片,下面是我自己写的程序,是只参考ADC0832的DataSheet文件的时序图而写出来的。在Proteus 6 Professional中通过调试,但没有进行实际的硬件调试,但我也可以确定没有问题,有也是很容易解决的小问题,我记下来,以防自己的硬盘数据丢失,我以前就有过,在大三时装Linux(Fedora7),弄的整个硬盘都没有了。如果大家觉得对自己有些用处,转载请注明出处,谢谢!
编程环境:Keil uVision2
ADC0832_BiYeSheJi.h头文件如下:
/*────────────────────────────────*/
/*修改日期: 2008-05-22 -16:55*/
/*修改主要变化:将引脚ADC0832_DI和ADC0832_DO复用为ADC0832_DIOO*/
/*状态:在proteus中未通过调试,不知为什么?现在又改回来了*/
/*修改人:heshanxingzhe*/
/*────────────────────────────────*/
/*────────────────────────────────*/
/*修改日期: 2008-05-03 -11:32*/
/*修改主要变化:调试*/
/*状态:通过调试*/
/*修改人:heshanxingzhe*/
/*────────────────────────────────*/
/*────────────────────────────────*/
/*修改日期: 2008-05-03 -00:22*/
/*修改主要变化:.将原来的ADC0832_BiYeSheJi.txt变为ADC0832_BiYeSheJi.h和
ADC0832_BiYeSheJi.c
2.读数据语句改为:if(ADC0832_DIO)data_out++;
data_out=date_out<<1;
3.变化中的语句该位于CLK从1到0;还是从0到1;根据CLK从1到
0时,DO输出下一位,CLK在0时,DO不一定是一个不变的状态,
而在1时,DO则一定是一个不变的状态,故应在1时,读出DO,
此次修改把中的语句从0和1之间挪到1和0之间
*/
/*状态:未通过调试*/
/*修改人:heshanxingzhe*/
/*────────────────────────────────*/
#include <REGX52.H>
#include <intrins.h>
#define uchar unsigned char
#define uint unsinged int
sbit ADC0832_CS =P2^0; /*ADC0832的片选信号,低电平有效*/
sbit ADC0832_DI =P2^2;
sbit ADC0832_DO =P2^3; /*端口复用*/
sbit ADC0832_CLK=P2^1;
/*函数定义*/
/*ADC0832读数据函数*/
uchar ADC0832_Read(uchar chan_sel);
/*功能:uchar类型变量,高位依次变为低位*/
/*例: input=10010010 output=01001001*/
/*uchar dat_inverse(uchar inv_data); */
ADC0832_BiYeSheJi.c程序文件如下:
/*────────────────────────────────*/
/*修改日期: 2008-05-22 -16:55*/
/*修改主要变化:将引脚ADC0832_DI和ADC0832_DO复用为ADC0832_DIO*/
/*状态:在proteus中未通过调试,不知为什么?现在又改回来了*/
/*修改人:heshanxingzhe*/
/*────────────────────────────────*/
/*────────────────────────────────*/
/*修改日期: 2008-05-03 -11:32*/
/*修改主要变化:调试*/
/*状态:通过调试*/
/*修改人:heshanxingzhe*/
/*────────────────────────────────*/
/*────────────────────────────────*/
/*修改日期: 2008-05-03 -00:22*/
/*修改主要变化:1.将原来的ADC0832_BiYeSheJi.txt变为ADC0832_BiYeSheJi.h和
ADC0832_BiYeSheJi.c
2.读数据语句改为:if(ADC0832_DIO)data_out++;
data_out=date_out<<1;
3.变化中的语句该位于CLK从1到0;还是从0到1;根据CLK从1到
0时,DO输出下一位,CLK在0时,DO不一定是一个不变的状态,
而在1时,DO则一定是一个不变的状态,故应在1时,读出DO,
此次修改把中的语句从0和1之间挪到1和0之间
*/
/*状态:未通过调试*/
/*修改人:heshanxingzhe*/
/*────────────────────────────────*/
/*────────────────────────────────*/
/*修改日期: 2008-05-02 -19:37*/
/*修改主要变化:写原程序*/
/*状态:未通过调试*/
/*修改人:heshanxingzhe*/
/*────────────────────────────────*/
/*----------------------------------------------------------------------*/
/********************ADC0832模数转换程序*********************************/
/**********************************参照ADC0832芯片资料,写于2008-05-02***/
/*****************************************************注:还没通过调试***/
/*****************************************16:30-19:25****heshanxingzhe***/
/*----------------------------------------------------------------------*/
/*CS,片选信号,转换过程低电平有效,*/
/*DI(DATA IN),输入数据线,CLK上升沿锁住信号,过程:在CS置低后的第*/
/*一个CLK上升沿,DI为一个START BIT,一般为高电平;然后是两位信号*/
/*为SGL/DIF和ODD/SIGN,此两信号为通道选择信号,通道选择表如下: */
/* ───────────────────────────────*/
/* SGL/DIF | ODD/SIGN | CHANNEL #0 | CHANNEL #1 | MUX MODE */
/* 1 | 0 | + | | Single-Ended */
/* 1 | 1 | | + | Single-Ended */
/* 0 | 0 | + | - | Differential */
/* 0 | 1 | - | + | Differential */
/* ───────────────────────────────*/
/*DO(DATA OUT),输出数据线,CLK下降沿输出信号*/
/*CLK,时钟信号,一般上升沿锁住输入信号,下降沿输出信号*/
/*chan_sel:通道选择位*/
/*────────────────────────────────────*/
/*包含头文件*/
#include "ADC0832_BiYeSheJi.h"
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*功能:模数转换ADC0832读数据*/
/*输入:chan_sel,为1,2,3,4
1,选单通道;
2,选单通道;
3,channel#0为+,channel#1为-;
4,channel#0为-,channel#1为+;
输出:返回读到的为数据,为uchar型
修改日期:080505-heshanxingzhe
080502-heshanxignzhe
注:*/
uchar ADC0832_Read(uchar chan_sel)
{ uchar data_out=0; /*读到的数据,MSB FIRST DATA*/
//uchar re_data_out=0; /*读到的数据,LSB FIRST DATA*/
uchar i;
bit SGL_DIF; /*通道选择信号*/
bit ODD_SIGN;
switch(chan_sel)
{ case 1:SGL_DIF=1;ODD_SIGN=0;break; /*选单通道*/
case 2:SGL_DIF=1;ODD_SIGN=1;break; /*选单通道*/
case 3:SGL_DIF=0;ODD_SIGN=0;break; /*channel#0为+,channel#1为-*/
case 4:SGL_DIF=0;ODD_SIGN=1;break; /*channel#0为-,channel#1为+*/
default:break; /*通道选择错误提示*/
}/*switch*/
ADC0832_CS=1; /*片选无效*/
/*一个无效时钟周期*/
ADC0832_CLK=1;
_nop_();
ADC0832_CLK=0;
_nop_();
ADC0832_CS=0; /*片选有效,开始AD转换*/
/*传START BIT 信号*/
ADC0832_CLK=0;
_nop_();
ADC0832_DI=1; /*START BIT*/
ADC0832_CLK=1; /*上升沿锁住START BIT信号*/
_nop_();
/*传通道选择信号*/
ADC0832_CLK=0;
_nop_();
ADC0832_DI=SGL_DIF;
ADC0832_CLK=1; /*上升沿锁住SGL/DIF信号*/
_nop_();
ADC0832_CLK=0;
_nop_();
ADC0832_DI=ODD_SIGN;
//for(i=0;i<125;i++);
ADC0832_CLK=1; /*上升沿锁住ODD_SIGN信号*/
_nop_();
ADC0832_CLK=0; /*此下降沿开始转换,开始读取DATA OUT*/
_nop_();
/*此脉冲是多余的,否则在2.5V是输出0*/
/*调试于 2008-05-05 -13:07,heshanxingzhe*/
/*ADC0832_CLK=1;
_nop_();*/
/*ADC0832_CLK=0;*/ /*此下降沿输出MSB,一直保持到下一个下降沿*/
/*_nop_();*/
/*读取DATA OUT数据*/
for(i=0;i<8;i++)
{ ADC0832_CLK=1; /*CLK为时,DO肯定保持在稳定态*/
_nop_(); /*故此时可读出数据*/
if(ADC0832_DO)data_out++;
data_out=data_out<<1;
ADC0832_CLK=0;
_nop_();
}//for
/*这一段code为严格按照ADC0832的TIMING DIAGRAMS输出而加入*/
/*此处取data_out的LSB,因为时序图的原因,此处委婉用这个*/
/*re_data_out=data_out&1;*/
/*for(i=0;i<7;i++)
{ ADC0832_CLK=1;
_nop_();
if(ADC0832_DIO)re_data_out++;
re_data_out=re_data_out<<1;
ADC0832_CLK=0;
_nop_();
}//for
*/
/*此时钟信号没什么作用*/
ADC0832_CLK=1;
_nop_();
ADC0832_CLK=0;
_nop_();
/*读取完毕*/
ADC0832_CS=1; /*片选无效*/
return data_out;
/*重复读数据的code,是严格按照ADC0832的TIMING DIAGRAMS加入的*/
/*if(data_out==dat_inverse(re_data_out))
retrun data_out;
else
return 0;
*/
}//ADC0832_Read()
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*功能:反转位uchar型数据
输入:待反转的数,例如:0x 0C
输出:返回已反转的数,为uchar型,则:0x30
修改日期:080505-heshanxingzhe
080502-heshanxignzhe
注:
*/
/*this function is to inverse one unchar data*/
/*example: input=10010010*/
/*and the output=01001001*/
/*uchar dat_inverse(uchar inv_data)
{ uchar temp1,temp2,i;
temp1=1;
temp2=0;*/
/* for(i=0;i<7;i++)*/ /*注意这里i<7,换成8会多左移一位*/
/* { if((temp1&inv_data)!=0)temp2++; */ /*调试后修改的,调试成功,08-05-05修改*/
/*这条语句是错的*/
/*temp2=(temp2++)|(temp1&inv_data);*/
/* temp1<<=1;
temp2<<=1;
}
return temp2;
}*/