求助--我使用CS5532做AD转换SDO一直不会变低
求助--我使用CS5532做AD转换SDO一直不会变低调试很久都不行,不知道为什么
哪位高手有成功使用 的 代码, 先谢谢了!
我的代码如下:
#ifndef _cs5532_h_
#define _cs5532_h_ 1
/*
//================================
// CS5532驱动
// AVR_C代码M8
// knight
//=================================
*/
#include <avr/io.h>
#include "macros.h"
#include "define.h"
#include "func.h"
#include "spi.h"
#define SYNC1 0xff
#define SYNC0 0xfe
#define CMD0 0
#define ARA BIT(6) /*整列方式访问通道0、1的寄存器*/
#define CS0 4
#define CS1 5
#define CMD0_COMM0 (BIT(CS0))
#define CMD0_COMM1 (BIT(CS1))
#define CMD0_WRITE 0
#define CMD0_READ BIT(3)
#define CMD0_reg_offset 0x01
#define CMD0_reg_gain 0x02
#define CMD0_reg_config 0x03
#define CMD0_reg_data 0x04
#define CMD0_reg_cconfig 0x05
#define CMD1 0x80
#define CMD1_step 0
#define CMD1_continue BIT(6)
#define CMD1_cconfig(x) ((x)<<3)
#define CMD1_convert 0
#define CMD1_adj_offset 1
#define CMD1_adj_gain 2
#define CMD1_adj_sys_offset 5
#define CMD1_adj_sys_gain 6
////配置寄存器
#define PSS 7 /* 节电模式选择 */
#define PDW 6 /* 节电模式 */
#define RS 5 /* 系统复位 */
#define RV 4 /* 复位有效 */
#define IS 3 /* 输入短路 */
#define GB 2 /* 保护信号位 */
#define VRS 1 /* 参考电压选择 */
#define A1 0 /* 输出锁存位1 */
#define A0 7 /* 输出锁存位0 */
#define OLS 6 /* 输出锁存选择 */
////通道配置寄存器
#define cc_CS17
#define cc_CS06
#define cc_G2 5
#define cc_G1 4
#define cc_G0 3
#define GEN64 ( BIT(cc_G2)|BIT(cc_G1) )
#define GEN32 ( BIT(cc_G2)|BIT(cc_G0) )
#define cc_WR32
#define cc_WR21
#define cc_WR10
#define cc_WR07
#define cc_UB 6
#define cc_OL15
#define cc_OL04
#define cc_DT 3
#define cc_OCD2
#define isADCnotReady() ( PINB & BIT(SDO) )
//=======================================
// CS5532初始化程序
// 作用:cs5532 AD转换器
//=======================================
void
init_cs5532(void)
{
uint8_t i;
disable_spi();//SPI禁止
delay1us();
enable_spi();//SPI使能
delay1us();
clrbit(SPI_PORT,SDI);
setbit(SPI_PORT,SDO);
clrbit(SPI_PORT,SCK);
////进入命令模式
for (i=0;i<18;i++) SPI_RWBYTE(SYNC1);
SPI_RWBYTE(SYNC1);
delay1us();
////RS=1复位 (写配置寄存器)
SPI_RWBYTE( CMD0|CMD0_COMM0|CMD0_WRITE|CMD0_reg_config);
SPI_RWBYTE(BIT(RS));
SPI_RWBYTE(0x00);
SPI_RWBYTE(0x00);
SPI_RWBYTE(0x00);
delay1us();
i=0;
while ( !isbit(i,RV) ) //等待复位完毕
{
SPI_RWBYTE(CMD0|CMD0_COMM0|CMD0_READ|CMD0_reg_config); //读配置寄存
delay1us();
i=SPI_RWBYTE(0x00);
SPI_RWBYTE(0x00);
SPI_RWBYTE(0x00);
SPI_RWBYTE(0x00);
}
////配置寄存器
SPI_RWBYTE( CMD0|CMD0_COMM0|CMD0_WRITE|CMD0_reg_config);
SPI_RWBYTE(0x00);
SPI_RWBYTE(0x58);
SPI_RWBYTE(0x00);
SPI_RWBYTE(0x58);
//通道0设置寄存器
SPI_RWBYTE(CMD0|CMD0_COMM0|CMD0_WRITE|CMD0_reg_cconfig);
SPI_RWBYTE( 0x40 );//GEN64|BIT(cc_WR1) );
SPI_RWBYTE( 0x30 );
SPI_RWBYTE( 0x40 );//GEN64|BIT(cc_WR1) );
SPI_RWBYTE( 0x30 );
//偏移寄存器 0
SPI_RWBYTE(CMD0|CMD0_COMM0|CMD0_WRITE|CMD0_reg_offset);
SPI_RWBYTE(0x00);
SPI_RWBYTE(0x00);
SPI_RWBYTE(0x00);
SPI_RWBYTE(0x00);
//增益寄存器 增益64倍
SPI_RWBYTE(CMD0|CMD0_COMM0|CMD0_WRITE|CMD0_reg_gain);
SPI_RWBYTE( 0x3f );//BIT(5));
SPI_RWBYTE(0x00);
SPI_RWBYTE(0x00);
SPI_RWBYTE(0x00);
delay1us();
//执行校准
SPI_RWBYTE(CMD1|CMD1_adj_offset);//自偏移校准
_delay_us(100);
SPI_RWBYTE(CMD1|CMD1_adj_gain);//自增益校准
_delay_us(100);
////while(isADCnotReady());
}
//=======================================
// CS5532开始转换
// 作用:发送转换命令
// i=0,1 通道号
//=======================================
uint8_t adcstatu;
#define isADCOver 0
#define isoverflow1
void
start_adc(uint8_t n)
{
if ( isbit(adcstatu,isADCOver) )
{
clrbit(SPI_PORT,SCK);//时钟低
enable_spi();
delay1us();
SPI_RWBYTE( CMD1 | CMD1_step | CMD1_cconfig(n)| CMD1_convert );
clrbit(adcstatu,isADCOver); //清0 标记正在转换中,数据还未读取
delay1us();
disable_spi();
}
}
//=======================================
// 读CS5534转换数据
// 作用:当ADC转换完毕后
// 发送空字节,读取数据
// i=0,1,2,3 通道号
//=======================================
bool
cs5532_read(int32_t* value)
{
uint32_tval;
uint8_t c;
start_adc(0);
clrbit(SPI_PORT,SCK);
NOP();
clrbit(SPI_PORT,SDI);
clrbit(SPI_PORT,SDO);
enable_spi(); //SPI禁止
_delay_us(100);
delay1us();
if ( isbit(SPI_PIN,SDO) )
{
return false;
};
uart_send_byte(2);
clrbit(SPI_PORT,SCK); //时钟低
enable_spi(); //SPI使能
delay1us();
//SPI_RWBYTE(CMD0|CMD0_COMM0|CMD0_READ|CMD0_reg_data);
//SPI_RWBYTE(CMD0|CMD0_COMM0|CMD0_READ|CMD0_reg_gain);
//SPI_RWBYTE(CMD0|CMD0_COMM0|CMD0_READ|CMD0_reg_config);
delay1us();
val=SPI_RWBYTE(0x00);
val<<=8;
val|=SPI_RWBYTE(0x00);
val<<=8;
val|=SPI_RWBYTE(0x00);
val<<=8;
val|=SPI_RWBYTE(0x00);
setbit(adcstatu,isADCOver); //置1 标记这次转换完成,数据已经读取
disable_spi();//SPI禁止
delay1us();
c=val.arr;
if (val.arr&0x80)
{
*value=(((~val.val)+1)/0x100);
}
else
{
*value = (val.val/0x100);
}
if (c&0x04)
{
adcstatu|=BIT(isoverflow);
return false;
}
else
{
adcstatu&=~BIT(isoverflow);
}
return true;
}
#endif #ifndef _spi_h_
#define _spi_h_
#include <avr/io.h>
#include "macros.h"
#include "define.h"
//=================================
// SPI 硬件接口引脚定义
//=================================
#define SPI_PORT PORTB
#define SPI_DDR DDRB
#define SPI_PIN PINB
#define SCK PB5 /*数据传输脉冲*/
#define MISO PB4 /*主机--数据输入*/
#define MOSI PB3 /*主机--数据输出*/
#define SS PB2 /*片选 低电平有效*/
#define INT PD3 /*中断信号 低电平有效*/
#define SCLK SCK
#define SDO MISO
#define SDI MOSI
#define CS SS
#define enable_spi() clrbit( SPI_PORT,SS )
#define disable_spi() setbit( SPI_PORT,SS )
//================================
// SPI 初始化
//接收和发送:高位在前
//================================
void
init_spi(void)
{
clrbit(SPI_PORT,MOSI);
clrbit(SPI_PORT,SCK);
clrbit(SPI_PORT,MISO);
setbit(SPI_PORT,SS);
setbit(PORTD,INT);
setbit(SPI_DDR,SCK);
setbit(SPI_DDR,MOSI);
setbit(SPI_DDR,SS);
clrbit(SPI_DDR,MISO);
clrbit(DDRD,INT);
SPCR = BIT(SPE)|BIT(MSTR)|BIT(SPR1)|BIT(SPR0);////SPI使能主机模式fos/128频率
}
//================================
// spi 发送 1个字节
//================================
uint8_t
SPI_RWBYTE(uint8_t byte)
{
//enable_spi();
delay1us();
SPDR = byte;
while (!(SPSR & BIT(SPIF)));
delay1us();
//disable_spi();
return SPDR;
}
#endif 自己顶一下
在线等哦! N年前用过CS5532AS,用的也是M8,用SPI的查询模式做读取的,还可以,不过后来让人给模仿了,呵呵,后来就没再去捣鼓它了。
之所以没用中断读取,是因为项目时间紧迫,加上使用4.9M的晶振,M8的实际大多富裕到没事可干的地步,所以本着稳定压倒一切的原则用了查询模式,呵呵。
代码已经找不到了,不过SPI的初始化我依稀记得就是参考那帮蓝色封面的AVR的C语言编程书上修改过来的,好用。 能发出来吗? TO ilikemcu 我爱单片机 非常感谢!
SPI 初始化是肯定没有错的
SPI和其他一块芯片CS1180通讯是没有问题的,但是CS1180位数稍微少了点 只有20位 放大128倍的时候 只有17位是稳定的(经过实践,最好效果也只有这么多了)
所以改用 CS5532 但是M8对CS5532操作 采用查询SDO是否为低电平 来取数据的但是SDO总是为高 不知道为什么
本来想用ADS1246 但是申请样片的时候 说没有库存了 郁闷啊! to quray
你是要我发出来什么?
代码都在上面的俄 =啊
=啊
=个兄弟给我提供一代码哦
非常感谢!!!^-^ 估计你没做好CS5532的初始化了,呵呵,所以它没启动转换,当然SDO当然没有出来了。 嗯
应该是初始化没有成功!
我的初始化 是按照芯片手册上 一步步 写的,后来对照了很久,还是没有查出原因,
今天又是新的一天,继续等哦 ^-^ ////进入命令模式
for (i=0;i<18;i++) SPI_RWBYTE(SYNC1);
SPI_RWBYTE(SYNC1);
delay1us();
这里好像不太对吧,是先发送15个0xff,再发送一个0xfe! LS
你真好
我查了这么多可能出现问题 的地方 就是这个地方没有查 ,应该是
////进入命令模式
for (i=0;i<18;i++) SPI_RWBYTE(SYNC1);
SPI_RWBYTE(SYNC0);
delay1us();
呵呵
我改过来 明天去公司试试
太感谢了!! 不知道为什么当初都写成了 “SYNC1”粗心啊 会害死人的 呵呵试过了
还是不行
估计还有其他问题没有解决
如果不检测SDO电平的话,读出来都是0xFF 继续求助!
===========一直到天荒地老 knight_avr:
你可以试一下这个办法,SYNC1+SYNC0共计发送31个字节的FFH,一个字节FEH
天道酬勤,祝你好运。 谢谢!!
您是不是王工,看你的签名很像的哦,
太感谢您了,我去试试!看 搞定,能读出数据了
现在还有些参数没有调试好
1、输出速率我选择的是 30HZ 感觉数据变化好慢了
2、数据有点不稳定,24位我屏蔽了最后2位 感觉还是有点跳动太大,加上滤波之后,有感觉数据滞后太大了 正确代码如下:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef _cs5532_h_
#define _cs5532_h_
#include <util/delay.h>
#include "macros.h"
#include "define.h"
#include "spi.h"
/*
//================================
// CS5532驱动
// AVR_C代码M8
// 谭志平 2009-4-21
//=================================
*/
#include <avr/io.h>
#include "macros.h"
#include "define.h"
#include "func.h"
#include "spi.h"
#define SYNC1 0xff
#define SYNC0 0xfe
#define CMD0 0
#define ARA BIT(6) /*整列方式访问通道0、1的寄存器*/
#define _CS0 4
#define _CS1 5
#define CMD0_COMM0 0
#define CMD0_COMM1 BIT(_CS0)
#define CMD0_WRITE 0
#define CMD0_READ BIT(3)
#define CMD0_reg_offset 0x01
#define CMD0_reg_gain 0x02
#define CMD0_reg_config 0x03
#define CMD0_reg_data 0x04
#define CMD0_reg_cconfig 0x05
#define CMD1 0x80
#define CMD1_step 0
#define CMD1_continue BIT(6)
#define CMD1_cconfig(x) ((x)<<3)
#define CMD1_convert 0
#define CMD1_adj_offset 1
#define CMD1_adj_gain 2
#define CMD1_adj_sys_offset 5
#define CMD1_adj_sys_gain 6
////配置寄存器
#define PSS 7 /* 节电模式选择 */
#define PDW 6 /* 节电模式 */
#define RS 5 /* 系统复位 */
#define RV 4 /* 复位有效 */
#define IS 3 /* 输入短路 */
#define GB 2 /* 保护信号位 */
#define VRS 1 /* 参考电压选择 */
#define A1 0 /* 输出锁存位1 */
#define A0 7 /* 输出锁存位0 */
#define OLS 6 /* 输出锁存选择 */
////通道配置寄存器
#define cc_CS17
#define cc_CS06
#define cc_G2 5
#define cc_G1 4
#define cc_G0 3
#define GEN64 ( BIT(cc_G2)|BIT(cc_G1) )
#define GEN32 ( BIT(cc_G2)|BIT(cc_G0) )
#define cc_WR32
#define cc_WR21
#define cc_WR10
#define cc_WR07
#define cc_UB 6
#define cc_OL15
#define cc_OL04
#define cc_DT 3
#define cc_OCD2
#define isADCnotReady() ( isbit(SPI_PIN,SDO) )
boolisADCOver;
//=======================================
// CS5532初始化程序
// 作用:cs5532 AD转换器
//=======================================
void
init_cs5532(void)
{
uint8_t i;
isADCOver=true;
enable_spi_0();//SPI使能
delay1us();
clrbit(SPI_PORT,SDI);
clrbit(SPI_PORT,SCK);
////进入命令模式
for (i=0;i<31;i++) SPI_RWBYTE(SYNC1);
SPI_RWBYTE(SYNC0);
delay1us();
////RS=1复位 (写配置寄存器)
SPI_RWBYTE( CMD0|CMD0_COMM0|CMD0_WRITE|CMD0_reg_config);
SPI_RWBYTE(BIT(RS));
SPI_RWBYTE(0x00);
SPI_RWBYTE(0x00);
SPI_RWBYTE(0x00);
_delay_ms(5);
delay1us();
////等待复位完毕
i=0;
while ( isbit(i,RV) )
{
SPI_RWBYTE(CMD0|CMD0_COMM0|CMD0_READ|CMD0_reg_config);
delay1us();
i=SPI_RWBYTE(0x00);
SPI_RWBYTE(0x00);
SPI_RWBYTE(0x00);
SPI_RWBYTE(0x00);
}
////配置寄存器
SPI_RWBYTE( CMD0|CMD0_COMM0|CMD0_WRITE|CMD0_reg_config);
SPI_RWBYTE(0x00);
SPI_RWBYTE(0x00);
SPI_RWBYTE(0x00);
SPI_RWBYTE(0x00);
//通道0设置寄存器
SPI_RWBYTE(CMD0|CMD0_COMM0|CMD0_WRITE|CMD0_reg_cconfig);
SPI_RWBYTE( GEN64 | 0x01);
SPI_RWBYTE( 0x00 );
SPI_RWBYTE( 00);
SPI_RWBYTE( 00);
//偏移寄存器 0
SPI_RWBYTE(CMD0|CMD0_COMM0|CMD0_WRITE|CMD0_reg_offset);
SPI_RWBYTE(0x00);
SPI_RWBYTE(0x00);
SPI_RWBYTE(0x00);
SPI_RWBYTE(0x00);
//增益寄存器 增益64倍
SPI_RWBYTE(CMD0|CMD0_COMM0|CMD0_WRITE|CMD0_reg_gain);
SPI_RWBYTE( 0b00100000 );
SPI_RWBYTE( 0x00 );
SPI_RWBYTE( 0x00 );
SPI_RWBYTE( 0x00 );
delay1us();
//执行校准
SPI_RWBYTE(CMD1|CMD1_adj_offset);//自偏移校准
_delay_us(100);
SPI_RWBYTE(CMD1|CMD1_adj_gain);//自增益校准
while(isADCnotReady());
}
//=======================================
// CS5532开始转换
// 作用:发送转换命令
// i=0,1 通道号
//=======================================
void
start_adc(void)
{
if ( isADCOver )
{
clrbit(SPI_PORT,SDI);
clrbit(SPI_PORT,SCK);//时钟低
enable_spi_0();
delay1us();
SPI_RWBYTE( CMD1 | CMD1_step | CMD1_cconfig(0)| CMD1_convert );
isADCOver=false; // 标记正在转换中,数据还未读取
delay1us();
disable_spi_0();
}
}
//=======================================
// 读CS5534转换数据
// 作用:当ADC转换完毕后
// 发送空字节,读取数据
// i=0,1,2,3 通道号
//=======================================
bool
cs5532_read(int32_t* value)
{
Tint32val;
start_adc();
enable_spi_0();
clrbit(SPI_PORT,SCK);
clrbit(SPI_PORT,SDI);
if ( isADCnotReady() )
{
return false;
};
delay1us();
SPI_RWBYTE(00); //清SDO标志
delay1us();
//uart_send_byte( SPI_RWBYTE(0x00) );
//uart_send_byte( SPI_RWBYTE(0x00) );
//uart_send_byte( SPI_RWBYTE(0x00) );
//uart_send_byte( SPI_RWBYTE(0x00) );
val.arr=SPI_RWBYTE(0x00);
val.arr=SPI_RWBYTE(0x00);
val.arr=SPI_RWBYTE(0x00);
val.arr=SPI_RWBYTE(0x00);
*value=( val.val / (256 * 4) ); ///去掉无效低8位 和跳动2位
disable_spi_0();//SPI禁止
delay1us();
isADCOver=true;
return true;
}
#endif 搞定,能读出数据了
现在还有些参数没有调试好
1、输出速率我选择的是 30HZ 感觉数据变化好慢了
2、数据有点不稳定,24位我屏蔽了最后2位 感觉还是有点跳动太大,加上滤波之后,有感觉数据滞后太大了 呵呵,大家好,我也在做CS5532,数据是读出来了,但是不知道如何校准什么的,希望和大家一起交流学习 求助,请问自偏移校准、自增益校准及其滤波那些如何操作 我也是数据很不稳定,怎么处理一下呀 大家交流一下吧,qq 113630402 我现在用vhdl来写这个程序,从示波器上看到RV位已经置1,说明ad复位成功了,但是sdo始终不能变低,为什么啊?
有哪位用vhdl写过这个啊? 问一下:
我读写cs5532的设置寄存器和通道寄存器时,均没问题。
但是读采集值时,老是0001ff00其中的01是最后的通道数,修改通道会变,但总能读对。
还有 0001ff 00老是循环被读出。 CS5532 MARK一下 你好LZ我现在搞CS5532也是遇到你的问题SDO一直都是高电平 您当时是哪里出问题啦呢???
页:
[1]