珩源电子
加入收藏 联系我们 繁體中文
公 告:    2019-5月新品上市  本公司所有产品的相关说明书下载位置!  本站承担过项目简介,欢迎合作交流!
珩源首页

资料下载

电子中心

新闻资讯 客户服务 游客留言 联系我们

技术论坛

登录
最新下载
Stm32F103vctb数控原...
简易并口ISSP编程器
Cypress CY21434 ...
PSoC_ISSP编程器(USB...
中文资料列表
AD7705程序以及开发参考资料...
AD7705程序以及开发参考资料...
步进电机控制器
 雕刻机控制器卡
 专用步进电机控制器
 通用步进电机控制器
步进电机驱动器
 板式步进电机驱动器
 盒式步进电机驱动器
步进电机
 二相42步进电机
 三相110步进电机
 二相86步进电机
 二相57步进电机
专用领域产品
动力锂电池保护板
开发板
 STM32开发板
 can通信模块
 ATMEGA 8功能板
开关电源
    你希望了解的是什么?
STM32开发板
单片机资料
锂电池保护
动力蓄电池检测系统
电子元器件价格
单片机新闻咨询
汽车参数检测与语音报警
单片机开发板

  
下载中心
AVR单片机 >> AD7705程序以及开发参考资料1

AD7705程序以及开发参考资料1

 资料分类:AVR单片机 |
AD7705程序以及开发参考资料1
 文件大小:
 运行环境:WIN98, WIN2000, WIN XP
 整理日期:2009-7-21
 下载次数:6011
::下载地址::
 ┊下载地址┊ ┊备用下载地址一┊ ┊备用下载地址二
::下载说明::
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include "1KF01.h"
#include "ad7705.h"
#include "HC595.h"
#include "main.h"
#include "crc16.h"
#include "usart.h"

volatile  uint16_t  eep_cali_data_addr;//计算校准系数存放地址的变量
extern  volatile 	uint8_t timer0out;//主函数定义的超时标志
extern  volatile 	MODULE_INFO module_info;//主函数定义的模块信息结构体
extern  volatile 	ALL_CALI_DATA all_cali_data;//主函数定义的读取EEPROM校准数据的结构体
extern  volatile 	CHN_CALI_DATA module_cali_data[CALI_VALUE_NUM];//主函数定义的全局校准系数数组
//----------------------------------------------------------------------------
//函数:reset_AD7705
//功能:AD7705串行接口失步后将其复位。复位后要延时500us再访问
//----------------------------------------------------------------------------
void reset_AD7705(void)
{
	uint8_t i;
	
	SBI_AD_SDI;
	for( i=0; i<36; i++ )
	{
		CBI_AD_SCK;
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");		
		SBI_AD_SCK;
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");		
	}	
	for( i = 0; i<10; i++)
	  _delay_us(50);
}

//------------------------------------------------------------------------------------------
//函数:read_AD7705_word
//功能:从AD7705读一个字的数据,共16bit
//------------------------------------------------------------------------------------------
uint16_t read_AD7705_word(void)
{
	uint16_t data = 0;
	for( uint8_t i = 0; i<16; i++)
	{
		CBI_AD_SCK;
		asm("nop");
		asm("nop");		
		data <<= 1;
		if(!AD7705_DO)
			data++;
		SBI_AD_SCK;
		asm("nop");
		asm("nop");
		asm("nop");		
	}		
	return data;	
}

//------------------------------------------------------------------------------------------
//函数:read_AD7705_dword
//功能:从AD7705读一个24的数据
//------------------------------------------------------------------------------------------
uint32_t read_AD7705_dword(void)
{
	uint32_t data = 0;	
	for( uint8_t i = 0; i<24; i++)
	{
		CBI_AD_SCK;
		asm("nop");
		asm("nop");		
		data <<= 1;
		if(!AD7705_DO)
			data++;
		SBI_AD_SCK;
		asm("nop");
		asm("nop");
		asm("nop");		
	}		
	return data;	
}

//------------------------------------------------------------------------------------------
//函数:write_AD7705_byte
//功能:往AD7705写8位数据
//参数:IN - uint8_t  data,要写入AD7705的数据
//------------------------------------------------------------------------------------------
void write_AD7705_byte( uint8_t data )
{
	for( uint8_t i = 0; i<8; i++)
	{
		CBI_AD_SCK;
		if(data&0x80)
			SBI_AD_SDI;
		else
			CBI_AD_SDI;
		data <<= 1;
		asm("nop");
		asm("nop");		
		SBI_AD_SCK;
		asm("nop");
		asm("nop");
		asm("nop");		
	}
	SBI_AD_SDI;//在空闲器件保持输入数据线为高
}

//------------------------------------------------------------------------------------------
//函数:write_AD7705_dword
//功能:往AD7705写24位数据,因为AD7705是24位的器件
//------------------------------------------------------------------------------------------
void write_AD7705_dword( uint32_t data )
{
	for( uint8_t i = 0; i<24; i++)
	{
		CBI_AD_SCK;
		if(data&0x800000)
			SBI_AD_SDI;
		else
			CBI_AD_SDI;
		data <<= 1;
		asm("nop");
		asm("nop");		
		SBI_AD_SCK;
		asm("nop");
		asm("nop");
		asm("nop");		
	}
	SBI_AD_SDI;//在空闲器件保持输入数据线为高
}

//------------------------------------------------------------------------------------------
//函数:AD7705_calibration
//
//      EEPROM数据块格式为:
// 		系统0校正值(4byte), 系统满量程校正值(4byte), 系统0校正标志(1byte),系统满量程校正标志
//      (1byte),CRC16校验值(2byte),共12byte。
//
//参数:IN - uint8_t board, 0 - 对主板进行校正,1-对副板进行校正
//		IN - uint8_t range, 需要校正的量程
//      IN - uint8_t cali_type, 校正类型,ZERO_CALIBRATION- 0校正;
//           FULL_CALIBRATION - 满量程校正
//
//返回:返回-1表示校准失败,非0表示校正成功,并返回相应的索引值
//------------------------------------------------------------------------------------------
int8_t AD7705_calibration( uint8_t const board, uint8_t const range, uint8_t const cali_type )
{
	uint8_t setup_reg;//AD7705设置寄存器内容变量
	int8_t  index;//校准系数偏移位置
	
	if(board > 1)//主副板标志,0-主板,1-副板
		return -1;//返回错误指示
	
	if(cali_type > 1)//校准类型,0-零校准,1-满量程校准
		return -1;//返回错误指示
	
	SBI_AD_CS;//操作595的时候要重新将7705的CS置无效
	_delay_ms(1);//光耦延时,至少要等待30us左右
	
	switch( range )
	{
		case B5V:
		case S1VTo5V:
		case S0VTo10V:
		case B10V:
		case S0TO20MA:
		case S4TO20MA:
		case B20MA:
			if(board == 0)
			{  //主板校准控制字设置,选择第5通道
				send_byte_to_595(0,0x30);//副板无效
		        send_byte_to_595(0,0x00);//主板第一通道
		        send_byte_to_595(1,0x89);//模拟开关设置
			}
			else
			{  //副板校准控制字设置,选择第1通道			
				send_byte_to_595(0,0x0a);//副板第一通道
		      	send_byte_to_595(0,0x30);//主板无效
		        send_byte_to_595(1,0x89);//模拟开关设置
			}
			setup_reg = PGA_2|_BV(BUF);//大电压校准7705的设置,增益为2
			index = 0;//校准系数偏移为0
			break;
		
		case B1V:
		case B500MV:
			if(board == 0)
			{  // 第5通道
	         	send_byte_to_595(0,0x30);
		        send_byte_to_595(0,0x20);
	    	    send_byte_to_595(1,0x83);//模拟开关设置
			}
			else
			{  // 第1通道
	         	send_byte_to_595(0,0x2a);
		        send_byte_to_595(0,0x30);
	    	   	send_byte_to_595(1,0x83);//模拟开关设置
			}
			setup_reg = PGA_2|_BV(BUF);//中电压校准7705的设置,增益为2
			index = 1;//校准系数偏移为1
			break;
        
		case B50MV:
			if(board == 0)
			{  // 第5通道
          	  	send_byte_to_595(0,0x30);
	          	send_byte_to_595(0,0x20);
	          	send_byte_to_595(1,0x83);//模拟开关设置
			}
			else
			{  // 第1通道
	         	send_byte_to_595(0,0x2a);
		        send_byte_to_595(0,0x30);
	    	    send_byte_to_595(1,0x83);//模拟开关设置
			}
			setup_reg = PGA_32|_BV(BUF);//小电压校准7705的设置,增益为32
			index = 2;//校准系数偏移为2
			break;
        
		case R600:  // 0.255ma
			if(board == 0)
			{  // 第5通道
              	send_byte_to_595(0,0x30);
	          	send_byte_to_595(0,0x00);
	          	send_byte_to_595(1,0x36);//第一次测量模拟开关设置
			}
			else
			{  // 第1通道
				send_byte_to_595(0,0x0a);
		        send_byte_to_595(0,0x30);
	        	send_byte_to_595(1,0x36);//第一次模拟开关设置
			}
			setup_reg = PGA_4|_BV(BUF);  
			index = 3;//校准系数偏移为3,index=4为第二次校准存放位置
			break;
        
		case R6000: // 0.255ma
			if(board == 0)
			{  // 第5通道
              	send_byte_to_595(0,0x30);
	          	send_byte_to_595(0,0x00);
	          	send_byte_to_595(1,0x36);//第一次模拟开关设置
			}
			else
			{  // 第1通道
				send_byte_to_595(0,0x0a);
		        send_byte_to_595(0,0x30);
	        	send_byte_to_595(1,0x36);//第一次模拟开关设置
			}
			setup_reg = PGA_1|_BV(BUF);  
			index = 5;//校准系数偏移为5,index=6为第二次校准存放位置
			break;
		
		default:            
			return -1;//量程不存在则返回错误指示
	}
	
	//计算校准系数在EEPROM中的存放地址,副板要跨越12*14=168个字节
	eep_cali_data_addr = 168*board+index*CALI_DATA_LEN;
	
	for( uint8_t resistor = 0; resistor<2; resistor++ )//电阻要进行两次校准
	{
		CBI_AD_CS;//使能7705的数字接口
		_delay_ms(1);//光耦延时,至少要等待30us左右
		reset_AD7705();//7705复位
     
		for( uint8_t freq = 0; freq < 2; freq++ )//AD7705两次不同频率的校准,0-50HZ校准,1-60HZ校准
		{
			//写7705的CLOCK寄存器
			write_AD7705_byte( SEL_WR_CLOCK_REG );
			if( 0 == freq )
				write_AD7705_byte( F_50HZ|_BV(CLK) );//select 50HZ
			else	
				write_AD7705_byte( F_60HZ|_BV(CLK) );//select 60HZ
			
			_delay_ms(10);//延时
			
			eep_cali_data_addr += 84*freq;//60HZ频率校准系数存放的位置还要偏移12*7=84个字节
            
			if( ZERO_CALIBRATION == cali_type )
			{
				//AD7705系统零校准
				write_AD7705_byte( SEL_WR_SETUP_REG );  
				write_AD7705_byte( setup_reg|SYS_ZERO_CALI );//把设置内容写入7705的设置寄存器
				
				start_timer0(50);
				_delay_ms(2);
				while(!AD7705_RDY)
				{
					if( 1 == timer0out)
					{  // 内部0校正出错
						SBI_AD_CS;//将7705片选置为无效,由于光耦延时,至少要延时30us
						_delay_us(66);
						STOP_TIMER0;//超时返回前先关闭定时器中断
						return -1;//超时返回
					}
				}
				STOP_TIMER0;
				
				// 如果系统0校正正确,读OFFSET寄存器
				write_AD7705_byte(SEL_RD_OFFSET_REG);
				all_cali_data.data_frame.ZS.dword_data = read_AD7705_dword();//保存到校准系数结构体变量的ZS变量
				
                /*
                put_c( 0x80 );//监控零校正数据
				put_c( resistor );
				put_c( freq );
				put_c( all_cali_data.data_frame.ZS.byte_data[0]);
				put_c( all_cali_data.data_frame.ZS.byte_data[1]);
				put_c( all_cali_data.data_frame.ZS.byte_data[2]);
				put_c( all_cali_data.data_frame.ZS.byte_data[3]);
				*/
				
				all_cali_data.data_frame.flag[0] = 0x55;//设置零校准正确标志
				//计算校验和
		       	all_cali_data.data_frame.crc_val = checksum( (unsigned char*)(&all_cali_data.data[0]), CALI_DATA_LEN-2 );
				//保存校正值到EEPROM
				eeprom_busy_wait();
		        eeprom_write_block( (unsigned char*)(&all_cali_data.data[0]), (void*)eep_cali_data_addr, CALI_DATA_LEN );
			}
			else//满量程校正,零校准在满量程校准之前进行
			{
		    	eeprom_busy_wait();//读取EEPROM的零校准系数
        		eeprom_read_block( (unsigned char*)(&all_cali_data.data[0]), (void*)eep_cali_data_addr,CALI_DATA_LEN);
				//计算校验和,并验证是否可用:零校准标志和校验和两个条件中任何一个不正确都将认为是错误
		        if( checksum( (unsigned char*)(&all_cali_data.data[0]), CALI_DATA_LEN-2 ) != all_cali_data.data_frame.crc_val
				    || 0x55 != all_cali_data.data_frame.flag[0] )
        		{
					SBI_AD_CS;//AD7705的数字接口置为无效
					_delay_us(66);//由于光耦延时,至少要延时30us左右
					return -1;//如果零校准系数不可用则返回错误只是-1
        		}
				
				//将ZS写入offset寄存器
				write_AD7705_byte(SEL_WR_OFFSET_REG);
				write_AD7705_dword(all_cali_data.data_frame.ZS.dword_data);
              
				write_AD7705_byte(SEL_WR_SETUP_REG);//设置7705的设置寄存器
				write_AD7705_byte(setup_reg|SYS_FULL_CALI);
              
				start_timer0(50);
				_delay_ms(2);	
				while(!AD7705_RDY)
				{
					if( 1 == timer0out)
					{  // 系统满量程校正出错
						SBI_AD_CS;//AD7705的数字接口置为无效
						_delay_us(66);//由于光耦延时,至少要延时30us左右
						STOP_TIMER0;
						return -1;
					}
				}
				STOP_TIMER0;
                
				// 如果内部满量程校正正确,读FULL SCALE寄存器
				write_AD7705_byte(SEL_RD_FULL_REG);
				all_cali_data.data_frame.GS.dword_data  = read_AD7705_dword();//保存到校准系数结构体变量的GS变量
                
				/*
                put_c( 0x81 );//监控满量程校正数据
				put_c( resistor );
				put_c( freq );
				put_c( all_cali_data.data_frame.GS.byte_data[0]);
				put_c( all_cali_data.data_frame.GS.byte_data[1]);
				put_c( all_cali_data.data_frame.GS.byte_data[2]);
				put_c( all_cali_data.data_frame.GS.byte_data[3]);
				*/
				
				all_cali_data.data_frame.flag[1] = 0xaa;//设置满量程校准正确标志
		        all_cali_data.data_frame.crc_val = checksum( (unsigned char*)(&all_cali_data.data[0]),CALI_DATA_LEN-2 );
	            
				// 保存校正值到EEPROM第一个地址
				eeprom_busy_wait();
        		eeprom_write_block( (unsigned char*)(&all_cali_data.data[0]), (void*)eep_cali_data_addr, CALI_DATA_LEN );
			}
		}
		
		if( 0==resistor && (R600==range || R6000==range) )//如果是电阻校准则要进行两次校准
		{
			SBI_AD_CS;//操作595的时候要重新将7705的CS置无效
	        _delay_ms(1);//由于光耦延时,至少要延时30us左右
			
			if(0==board)
			{  // 第5通道
        	   	send_byte_to_595(0,0x30);
          		send_byte_to_595(0,0x20);
	          	send_byte_to_595(1,0x32);//第二次电阻校准模拟开关设置
			}
			else
			{//第1通道
        	    send_byte_to_595(0,0x2a);
          		send_byte_to_595(0,0x30);
	          	send_byte_to_595(1,0x32);//第二次电阻校准模拟开关设置
			}
			eep_cali_data_addr -= 72; //第二次电阻校准时,校准系数存放地址从60HZ第一次测量的地址跳转到50HZ第二次测量的地址
		}
		else
		{
		    break;//非电阻量程只校准一次便退出。
		}
	}
	
	SBI_AD_CS;//将AD7705的CS置无效
	_delay_us(66);//因为光耦延时,至少要延时30us左右
	
    return index;//返回校准系数偏移位置
}

//------------------------------------------------------------------------------------------
//函数:start_AD7705
//功能:先写offset寄存器,再写full scale寄存器,然后启动7705进行单次转换
//第二次电阻测量的校准系数存放位置要加1,由cali标识
//------------------------------------------------------------------------------------------
void start_AD7705(uint8_t const channel, uint8_t const cali)
{        
	//cli();//设置7705的过程中关闭中断,防止被干扰导致设置错误
	
	//写OFFSET寄存器
	write_AD7705_byte(SEL_WR_OFFSET_REG);
	write_AD7705_dword( module_cali_data[ module_info.channel_info[channel].cali_index+cali ].cali_data_sys0.dword_data);
    //write_AD7705_dword( module_cali_data[ module_info.channel_info[channel].cali_index-cali ].cali_data_sys0.dword_data);
	/*
    put_c(cali);
    put_c(0x00);//监控量程的的零校正系数
	put_c(module_cali_data[ module_info.channel_info[channel].cali_index+cali ].cali_data_sys0.byte_data[0]);
	put_c(module_cali_data[ module_info.channel_info[channel].cali_index+cali ].cali_data_sys0.byte_data[1]);
	put_c(module_cali_data[ module_info.channel_info[channel].cali_index+cali ].cali_data_sys0.byte_data[2]);
	put_c(module_cali_data[ module_info.channel_info[channel].cali_index+cali ].cali_data_sys0.byte_data[3]);
	*/
	
	//写满量程校准寄存器
	write_AD7705_byte(SEL_WR_FULL_REG);
	write_AD7705_dword( module_cali_data[ module_info.channel_info[channel].cali_index+cali ].cali_data_sysf.dword_data);
    //write_AD7705_dword( module_cali_data[ module_info.channel_info[channel].cali_index-cali ].cali_data_sysf.dword_data);
	/*
	put_c(0x11);//监控量程的的满校正系数
	put_c(module_cali_data[ module_info.channel_info[channel].cali_index+cali ].cali_data_sysf.byte_data[0]);
	put_c(module_cali_data[ module_info.channel_info[channel].cali_index+cali ].cali_data_sysf.byte_data[1]);
	put_c(module_cali_data[ module_info.channel_info[channel].cali_index+cali ].cali_data_sysf.byte_data[2]);
	put_c(module_cali_data[ module_info.channel_info[channel].cali_index+cali ].cali_data_sysf.byte_data[3]);
	*/
	
	write_AD7705_byte(SEL_WR_SETUP_REG);//写配置信息
	write_AD7705_byte(module_info.channel_info[channel].setup_reg);
	
	write_AD7705_byte(SEL_WR_CLOCK_REG);//写时钟信息
	write_AD7705_byte(module_info.clock_reg);
	
	//sei();//设置7705结束后重新打开中断
}

//------------------------------------------------------------------------------------------
//函数:start_and_wait_AD7705
//功能:启动7705进行单次转换,并等待AD转换结束
//------------------------------------------------------------------------------------------
uint8_t start_and_wait_AD7705(uint8_t const channel, uint8_t const cali)
{
	start_AD7705(channel, cali);//设置AD7705
	
	start_timer0(6);
	_delay_ms(2);
	while(!AD7705_RDY)
	{
		if( 1 == timer0out)
		{
			STOP_TIMER0;
			return 0;
		}
	}
	STOP_TIMER0;	
	
	return 1;
}

 

(1)本站如需解压密码的资源,解压密码为:www.hymcu.com
(2)本站内所有资料仅限学习、交流,禁止用于任何商业用途!
(3)如果发现该资料不能下载或链接错误,请点击报告错误,谢谢!
(4)站内提供的资料部分来自网络以及注册用户自行上传,若侵犯了您的权益,敬请来信通知我们!
(5)若您的资料希望能与大家分享,我们愿意和您一起宣传!投稿请点击这里。
(6)本站不支持多线程下载。

返回

sitemap | 联系我们 | 广告服务 | 关于我们 | 版权信息 | 友情链接 | 网站地图 | 电话:15307733338 | 点击发消息给站长
CopyRight © 2007-2014 珩源科技all right Reserved Best view 1024*768 桂ICP备19004328号
地址:广西桂林市叠彩区站前路2号27栋 ┋总访问量  百度