ADS7841接线:1、7、9脚接VCC=5V
3、6、10、11脚接GND
4、5脚悬空
12----16脚接PD4----PD0
2脚加外部输入电压,8脚接2.5V外部参考电压
以下是main.c
/******************************************************************************
ADS7841驱动程序
* * 主控芯片:ATmega64
* * 编译环境:ICCAVR6.31A
******************************************************************************/
#include <iom64v.h>
#include <macros.h>
#include "delay.h"
#include "ads7841.h"
#include "LCD1602.h"
//----------------------ADS7841控制字节----------------------------------------
#define control_byte 0b10011000
//bit val description
//bit7 1 start,恒为1
//bit6,5,4 001 选择CH0为+IN
//bit4 1 选择为单端输入
//bit2 X 外部MODE接GND,该位无作用,恒为12位
//bit1,0 00 转换期间ADC为掉电模式
void port_init(void)
{
PORTA = 0xFF;//将所有端口初始化为输入,打开上拉
DDRA = 0x00;
PORTB = 0xFF;
DDRB = 0x00;
PORTC = 0xFF;
DDRC = 0x00;
PORTD = 0xFF;
DDRD = 0x00;
PORTE = 0xFF;
DDRE = 0x00;
PORTF = 0xFF;
DDRF = 0x00;
PORTG = 0xFF;
DDRG = 0x00;
}
void main()
{
unsigned int result;
unsigned char i,array[4],table[]="0123456789";
port_init(); //端口初始化
LCD1602_init(); //1602液晶初始化
ads7841_init(); //ADS7841初始化
LCD_write_string(0x80,"result:");
while(1)
{
ads7841_start(); //启动ADS7841,即拉低CS
delay_nus(10);
result=ads7841_W_R(control_byte); //发送控制字,并得到转换数据
result&=0b0000111111111111; //屏蔽掉高四位
delay_nus(10);
ads7841_finish(); //停止ADS7841,即拉高CS
for(i=0;i<4;i++) //以下均为显示部分
{
array[i]=result%10;//
result/=10;
}
for(i=0;i<4;i++)
{
LCD_write_onechar(0x87+i,table[array[3-i]]);
}
delay_nms(300);
}
}
以下是ads7841.h
#ifndef _ads7841_h
#define _ads7841_h
#define DCLK PD0
#define DCLK_ddr DDRD
#define DCLK_port PORTD
#define DCLK_pin PIND
#define CS PD1
#define CS_ddr DDRD
#define CS_port PORTD
#define CS_pin PIND
#define DIN PD2
#define DIN_ddr DDRD
#define DIN_port PORTD
#define DIN_pin PIND
#define BUSY PD3
#define BUSY_ddr DDRD
#define BUSY_port PORTD
#define BUSY_pin PIND
#define DOUT PD4
#define DOUT_ddr DDRD
#define DOUT_port PORTD
#define DOUT_pin PIND
#define ads7841_start() CS_port&=~(1<<CS) //启运ADS7841
#define ads7841_finish() CS_port|=(1<<CS) //停止ADS7841
void ads7841_init(void);
unsigned int ads7841_W_R(unsigned char byte);
#endif
以下是ads7841.c
#include <iom64v.h>
#include <macros.h>
#include "delay.h"
#include "ads7841.h"
/*******************************************************************************
* * 函数名称:ads7841_init()
* * 函数功能:初始化ADS7841端口
* * 备 注:无
*******************************************************************************/
void ads7841_init(void)
{
DCLK_port&=~(1<<DCLK); //时钟端初始化为输出低电平
DCLK_ddr|=(1<<DCLK);
CS_port|=(1<<CS); //片选端初始化为输出高电平
CS_ddr|=(1<<CS); //即不选中ADS7841
DIN_port&=~(1<<DIN); //数据输入端初始化为输出低电平
DIN_ddr|=(1<<DIN);
BUSY_port|=(1<<BUSY); //忙信号初始化为输入,打开上拉
BUSY_ddr&=~(1<<BUSY);
DOUT_port|=(1<<DOUT); //数据输出初始化为输入,打开上拉
DOUT_ddr&=~(1<<DOUT);
}
/*******************************************************************************
* * 函数名称:ads7841_W_R
* * 函数功能:向ADS7841写入控制字节,读出转换好的数
* * 输入参数:unsigned char byte : 控制字节
unsigned int result: AD转换好的数
* * 备 注:数据从高位到低位写入,从高位到低位读出
*******************************************************************************/
unsigned int ads7841_W_R(unsigned char byte)
{
unsigned char i,temp;
unsigned int result=0;
for(i=0;i<8;i++) //8位数据计数
{
DCLK_port&=~(1<<DCLK); //拉低时钟端
if(byte&0x80) //当前位是否是1
{
DIN_port|=(1<<DIN); //当前位是1,拉高数据端
}
else
{
DIN_port&=~(1<<DIN); //当前位是0,拉低数据端
}
delay_nus(10); //调整时钟和脉冲宽度
DCLK_port|=(1<<DCLK); //时钟上升沿
delay_nus(10);
byte<<=1; //数据左移1位,为送出新数据位做准备
}
delay_nus(10);
DCLK_port&=~(1<<DCLK); //拉低时钟端
delay_nus(10);
i=BUSY_pin; //读BUSY的状态
delay_nus(10);
if(i&(1<<BUSY)) //如果为高则说明转换完成,应将其读出
{
//------------------------以下先读出高八位-------------------------------------
for(i=1;i<=8;i++)
{
result<<=1; //保存读入的数据位
DCLK_port|=(1<<DCLK); //时钟上升沿
delay_nus(10);
DCLK_port&=~(1<<DCLK); //拉低时钟端
delay_nus(10);
if(DOUT_pin&(1<<DOUT))
{
result|=0x01;
}
else
{
result&=0xfe;
}
}
//-----------------------以下读出低四位----------------------------------------
for(i=1;i<=4;i++)
{
temp<<=1; //保存读入的数据位
DCLK_port|=(1<<DCLK); //时钟上升沿
delay_nus(10);
DCLK_port&=~(1<<DCLK); //拉低时钟端
delay_nus(10);
if(DOUT_pin&(1<<DOUT))
{
temp|=0x01;
}
else
{
temp&=0xfe;
}
}
for(i=1;i<=4;i++) //再给ADS7841四个时钟
{
DCLK_port|=(1<<DCLK); //时钟上升沿
delay_nus(10); //调整时钟和脉冲宽度
DCLK_port&=~(1<<DCLK); //拉低时钟端
delay_nus(10); //调整时钟和脉冲宽度
}
}
result=(result<<4)+temp; //将结果合成,返回
return result;
}
|