CAAS 发表于 2010-10-12 14:40:33

为什么TLV2544很快就不能用了?

MCU=M128, TLV2544 5V供电、选内部基准
在相对正确转换结果时: 信号输入=0V   转换结果=0x015
                     信号输入=0.4V   转换结果=0x45E左右( 理论值应0x333 )
                     信号输入=1.99V转换结果=0xFFF
问题 1:   转换结果值偏高!!!!
问题 2:   内部基准无论选2V还是4V对转换结果无影响
问题 3:   新的芯片换上去,开始有相对正确的转换结果,但次日再试,在信号输入=0V时 转换结果=0xFFF(已换3片了)
急!!请用过TLV2544的高手指点,感谢!!
http://cache.amobbs.com/bbs_upload782111/files_34/ourdev_589256Q533AN.jpg
(原文件名:tlv2544.jpg)
主程序中:

data = SingeShotMode(0x0E84, TLV2544_CH_0 );


头文件
#ifndef _TLV2544_H
#define _TLV2544_H

#define _BV(bit) (1 << (bit))
#define TLV_SPI_ON      SPCR = 0x50   //50
#define TLV_SPI_OFF       SPCR = 0x00
#define TLV_PORT          PORTB                  // 2544引脚占用口
#define TLV_CSTART_PORT   PORTD                // 采样控制,PD7
#define TLV_EOC_INT_PORTPORTE                             // 中断,PE7
#define TLV_CSTART      PD7                    // 采样控制引脚
#define TLV_SDO                          PINB&_BV(PB3)          // MISO PB3
#define TLV_SDI                          PB2                             // MOSI
#define TLV_SCK                          PB1                             // SCK
#define TLV_CS            PB0                    // 片选引脚
#define TLV_EOC_INT       PINE&_BV(PE7)   // 中断引脚

#define TLV_SELECT      TLV_PORT &= ~_BV(TLV_CS)
#define TLV_DESELECT      TLV_PORT |=_BV(TLV_CS)
#define TLV_CSTART_ON   TLV_CSTART_PORT &= ~_BV(TLV_CSTART)
#define TLV_CSTART_OFF    TLV_CSTART_PORT |=_BV(TLV_CSTART)
#define TLV_SDI_L                  TLV_PORT &= ~_BV(TLV_SDI)
#define TLV_SDI_H                  TLV_PORT |=_BV(TLV_SDI)
#define TLV_SCK_L                  TLV_PORT &= ~_BV(TLV_SCK)                  
#define TLV_SCK_H                  TLV_PORT |=_BV(TLV_SCK)

#define TLV2544_CH_0      0x0000
#define TLV2544_CH_1      0x2000
#define TLV2544_CH_2      0x4000
#define TLV2544_CH_3      0x6000
#define SW_PWR_DWN      0x8000    // SW电源跌落(模拟+参考)
#define READ_CFR          0x9000    // 读配置寄存器
#define WRITE_CFR         0xA000    // 写配置寄存器
#define TEST_HALF         0xB000    // 选择测试电压=(REFP+REFM)/2
#define TEST_MINUS      0xC000    // 选择测试电压=REFM
#define TEST_PLUS         0xD000    // 选择测试电压=REFP
#define FIFO_Read         0xE000    // FIFO读,将FIFO内容送SDO D(15~4),D(3~0)=0000

/* NOTE: The status of the CFR can be read with a read CFR command
   when the device is programmed for one-shot conversion mode (CFR D = 00)*/
   
   
/****************************************************/
/* 配置寄存器(CFR)位定义 */
/****************************************************/
#define REF_SEL             11    //
                                  //
#define INTER_REF_VOL_SEL   10   
                                 
#define SAMPLE_PERIOD_SEL   9   
                                 
#define CCSS_H      8
#define CCSS_L      7      
#define CMS_H         6
#define CMS_L         5
#define SASS_H      4
#define SASS_L      3
#define EOC_INT       2
#define FTL_H         1
#define FTL_L         0

/****************************************************/
/* 配置寄存器(CFR)位命令定义 */
/****************************************************/
/* 基准选择 D11 */
#define EXTER_REF            0x0000          // 0: External
#define INTER_REF         _BV(REF_SEL)   // 1: Internal

/* 内部基准电压选择 D10 */
#define INTER_REF_4V         0x0000                  // 0: Internal ref = 4 V
#define INTER_REF_2V      _BV(INTER_REF_VOL_SEL)   // 1: internal ref = 2 V

/* 采样周期选择 D9 */
#define SHORT_SAMPLING       0x0000                  // 0: Short sampling 12 SCLKs
                                                   //    (1x sampling time)
#define LONG_SAMPLING       _BV(SAMPLE_PERIOD_SEL)   // 1: Long sampling 24 SCLKs
                                                   //    (2x sampling time)   
/* 转换时钟源选择 D8-D7 */
#define INTERNAL_OSC         0x0000                  // 转换时间=内OSC   00
#define SCLK_1            _BV(CCSS_L)            // 转换时钟=SCLK    01
#define SCLK_4            _BV(CCSS_H)            // 转换时钟=SCLK/410
#define SCLK_2            _BV(CCSS_H)|_BV(CCSS_L)// 转换时钟=SCLK/211
                                                                                                   
/* 转换模式 D6-D5 */
#define SINGLE_SHOT_MODE   0x0000                  //单次模式   00
#define REPEAT_MODE         _BV(CMS_L)               //重复模式   01         
#define SWEEP_MODE          _BV(CMS_H)               //扫描模式   10         
#define REPEAT_SWEEP_MODE _BV(CMS_H)|_BV(CMS_L)      //重复扫描模式 11         

/* 扫描自动序列选择 D4-D3 */
#define SWEEP_AUTO_SEQUENCE_SEL_0    0x0000               //00: N/A
#define SWEEP_AUTO_SEQUENCE_SEL_1   _BV(SASS_L)             //01: 0–1–2–3–0–1–2–3
#define SWEEP_AUTO_SEQUENCE_SEL_2   _BV(SASS_H)             //10: 0–0–1–1–2–2–3–3
#define SWEEP_AUTO_SEQUENCE_SEL_3   _BV(SASS_H)|_BV(SASS_L) //11: 0–1–0–1–0–1–0–1

/* EOC/INT引脚功能选择 D2*/
#define INT_PIN               0x0000         // 0: 引脚用作INT
#define EOC_PIN            _BV(EOC_INT)    // 1:引脚用作EOC   
                                          
/* FIFO触发器电平(扫描序列长度)D1-D0 */
#define FIFO_TRIGGER_LEVEL_FULL   0x0000                //00 全部(FIFO level 7填满后产生INT)
#define FIFO_TRIGGER_LEVEL_3_4   _BV(FTL_L)             //01:3/4(FIFO level 5填满后产生INT)
#define FIFO_TRIGGER_LEVEL_1_2   _BV(FTL_H)             //10:1/2(FIFO level 3填满后产生INT)
#define FIFO_TRIGGER_LEVEL_1_4   _BV(FTL_H)|_BV(FTL_L)//11:1/4(FIFO level 1填满后产生INT)

extern uint SPI_2544(unsigned char data);
extern uint SingeShotMode( uint config_command, uchar channel );
extern void InitRepeatSweepMode(void);
extern void InitSingleShotMode(void);
extern void InitSweepMode(void);


#endif /* _TLV2544_H*/

TLV2544.C程序代码
#include "include.h"

/***** 配置寄存器(CFR)的位定义 *******************
内部基准   D11=1 INTER_REF
   基准电压选择 D10=0 INTER_REF_4V
   采样周期选择 D9=0SHORT_SAMPLING 短期采样12SCLKs(1x采样时间)
   转换时钟源选择 D8-D7 SCLK_1 转换时钟=SCLK    01
   转换模式 D6-D5 SINGLE_SHOT_MODE 单次模式   00
   扫描自动序列选择 D4-D3
   EOC/INT引脚功能选择 D2=0 INT_PIN
***************************************/

//单次模式(模式00)不用FIFO,转换结束EOC/INT引脚拉低
/*
1.CS拉低,写A000h,再写AXXXh(配置命令),尽量使用内部OSC;
2.读CFR,验证spi的正常;
3.如果是扩展采样:拉高cs,然后拉低CSTART,延时一段时间,拉高CSTART,开始转换;
4.等待EOC有效
5.CS拉低再拉高,再拉低,即CS拉低两次,并保持低。当然这时CSTART保持高电平。
6.写0000h,即可读出结果。
*/

uint SingeShotMode( uint config_command, uchar channel )
{
uint select_channel;
volatile uint Conv_result;
volatile uchar result1,result2;

switch( channel ) {
   case 0: select_channel = TLV2544_CH_0;
               break;
   case 1: select_channel = TLV2544_CH_1;
               break;
   case 2: select_channel = TLV2544_CH_2;
               break;
   case 3: select_channel = TLV2544_CH_3;
               break;
}       
// return 0x08AF;   //为仿真
CLI();                                            
TLV_SPI_ON;
TLV_CSTART_OFF;                  
TLV_SELECT;                           //CS拉低
SPI_2544(0xA0);                  //初始化命令 A000H
SPI_2544(0x00);
TLV_DESELECT;
TLV_SELECT;
SPI_2544((uchar)(config_command>>8));                 //写配置字
SPI_2544((uchar)(config_command&0x00FF));
TLV_DESELECT;
TLV_SELECT;
// result1 = SPI_2544(0x90);   //读CFR数据以此检测2544是否工作
// result2 = SPI_2544(0x00);           //生成SCLK
// TLV_DESELECT;
// TLV_SELECT;

SPI_2544((uchar)(select_channel>>8));       //选通道
SPI_2544((uchar)(select_channel&0x00FF));   //生成SCLK
TLV_DESELECT;
TLV_CSTART_ON;
delay_us(2);
TLV_CSTART_OFF;
while(TLV_EOC_INT);
TLV_DESELECT;
TLV_SELECT;
TLV_DESELECT;
TLV_SELECT;
result1 = SPI_2544(0x00);    //写0000h,即可读出结果
result2 = SPI_2544(0x00);
SEI();
TLV_CSTART_OFF;
TLV_DESELECT;
TLV_SPI_OFF;
Conv_result = ((uint)(result1)<<4) | (uint)((result2>>4)&0x0f);
return (Conv_result-0x333);
}

uint SPI_2544(unsigned char data)
{
SPDR = data;
while (!(SPSR & (1<<SPIF)));   //等待完成       
return SPDR;
}

Taoj 发表于 2013-12-23 18:00:00

哥 有51驱动2554的程序吗
页: [1]
查看完整版本: 为什么TLV2544很快就不能用了?