TI中文支持网
TI专业的中文技术问题搜集分享网站

TDA4VM-Q1: TDA4VM-Q1上用SPI连接ADS8684采集数据问题

Part Number:TDA4VM-Q1Other Parts Discussed in Thread: ADS8684

HI:

我的项目上使用TDA4VM-Q1,然后通过SPI1连接到ADS8684,SPI1的设备树配置如下:

&main_spi1 {
pinctrl-names = "default"; pinctrl-0 = <&spi1_pins_default>;
status="okay";
spidev@0 {
spi-max-frequency = <24000000>;
reg = <0>;
compatible = "linux,spidev";
};
};

spi1_pins_default: spi1_pins_default {
pinctrl-single,pins = <
J721E_IOPAD(0x1dc, PIN_INPUT, 0) /* (Y1) SPI1_CLK */
J721E_IOPAD(0x1d4, PIN_INPUT, 0) /* (Y3) SPI1_CS0 */
J721E_IOPAD(0x1e0, PIN_INPUT, 0) /* (Y5) SPI1_D0 */
J721E_IOPAD(0x1e4, PIN_INPUT, 0) /* (Y2) SPI1_D1 */

>;
};

目前跑到LInux下已经可以识别到SPIDEV1.0,可以通过spidev_test读写

然后,我写了ADS8684的驱动,代码如下:

typedef unsigned char		u8;
typedef unsigned short		u16;
typedef unsigned int		u32;
typedef unsigned long long	u64;
typedef signed char		s8;
typedef short			s16;
typedef int			s32;
typedef long long		s64;

u16 My_Ad[8]={0,0,};
float ad_real[2]={0.0,0.0};
#define NO_OP 0X0000 
#define STDBY 0X8200 
#define PWR_DN 0X8300 
#define SPIRST 0X8500 
#define AUTO_RST 0XA000 
#define MAN_Ch_1 0XC000 
#define MAN_Ch_2 0XC400 
#define MAN_Ch_3 0XC800 
#define MAN_Ch_4 0XCC00 
#define MAN_Ch_5 0XD000 
#define MAN_Ch_6 0XD400 
#define MAN_Ch_7 0XD800 
#define MAN_Ch_8 0XDC00 
#define MAN_AUX 0XE000 
#define CH1 0x05 
#define CH2 0x06 
#define CH3 0x07 
#define CH4 0x08 
#define CH5 0x09 
#define CH6 0x0a 
#define CH7 0x0b 
#define CH8 0x0c 

static int spidev_fd = 0;
static void transfer(int fd, uint8_t const *tx, uint8_t const *rx, size_t len)
{
	int ret;
	int out_fd;
	struct spi_ioc_transfer tr = {
		.tx_buf = (unsigned long)tx,
		.rx_buf = (unsigned long)rx,
		.len = len,
		.delay_usecs = delay,
		.speed_hz = speed,
		.bits_per_word = bits,
	};

	if (mode & SPI_TX_OCTAL)
		tr.tx_nbits = 8;
	else if (mode & SPI_TX_QUAD)
		tr.tx_nbits = 4;
	else if (mode & SPI_TX_DUAL)
		tr.tx_nbits = 2;
	if (mode & SPI_RX_OCTAL)
		tr.rx_nbits = 8;
	else if (mode & SPI_RX_QUAD)
		tr.rx_nbits = 4;
	else if (mode & SPI_RX_DUAL)
		tr.rx_nbits = 2;
	if (!(mode & SPI_LOOP)) {
		if (mode & (SPI_TX_OCTAL | SPI_TX_QUAD | SPI_TX_DUAL))
			tr.rx_buf = 0;
		else if (mode & (SPI_RX_OCTAL | SPI_RX_QUAD | SPI_RX_DUAL))
			tr.tx_buf = 0;
	}

	ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
	if (ret < 1)
		pabort("can't send spi message");

	if (verbose)
		hex_dump(tx, len, 32, "TX");

	if (output_file) {
		out_fd = open(output_file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
		if (out_fd < 0)
			pabort("could not open output file");

		ret = write(out_fd, rx, len);
		if (ret != len)
			pabort("not all bytes written to output file");

		close(out_fd);
	}

	if (verbose)
		hex_dump(rx, len, 32, "RX");
}

void ADS8688_SPI_WB(uint8_t com) 
{
	int ret = 0;
	transfer(spidev_fd,&com,0,1);
	return;
	ret = ioctl(spidev_fd, SPI_IOC_WR_BITS_PER_WORD, &com);
	if (ret == -1)
		printf("can't set bits per word\n");
	else
		printf("set bits per word \n");
}


uint8_t ADS8688_SPI_RB(void) 
{ 
	int ret = 0;
	
	uint8_t bits=0;
	transfer(spidev_fd,0,&bits,1);
	
	return bits;
	ret = ioctl(spidev_fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
	if (ret == -1)
		printf("can't get bits per word");
	else
		printf(" bits per word");
	return  bits;
}


void ADS8688_WriteCommandReg(uint16_t command)//写ADS8688命令寄存器 
{ 
	ADS8688_SPI_WB(command>>8 & 0XFF);
	ADS8688_SPI_WB(command & 0XFF);
}


void ADS8688_Write_Program_Register(uint8_t Addr,uint8_t data)
{ 
	ADS8688_SPI_WB(Addr<<1| 0X01);
	ADS8688_SPI_WB(data);
}


u8 ADS8688_READ_Program_Register(uint8_t Addr)
{ 
	u8 data = 0;
	ADS8688_SPI_WB(Addr<<1); 
	data = ADS8688_SPI_RB();
	data = ADS8688_SPI_RB(); 
	return data;
}void Enter_RESET_MODE(void)//软件复位模式,复位 program registers
{ADS8688_WriteCommandReg(SPIRST);
}

void AUTO_RST_Mode(void)//进入自动扫描模式 
{ 
	ADS8688_WriteCommandReg(AUTO_RST);
}

void MAN_Ch_n_Mode(uint16_t ch)//自动模式 
{ 
	ADS8688_WriteCommandReg(ch);
}

void Set_CH_Range_Select(uint8_t ch,uint8_t range) //设置各个通道的范围 
{ 
	ADS8688_Write_Program_Register(ch,range);
}

void Get_AUTO_RST_Mode_Data(uint16_t* outputdata, uint8_t chnum) 
{ 
	//读取扫描通道序列的AD转换数据code到变量数组中 
	u8 i=0,datal=0,datah=0;
	u16 data=0; 
	for (i=0; i<chnum; i++) 
	{ 
		ADS8688_SPI_WB(0X00); 
		ADS8688_SPI_WB(0X00); 
		datah = ADS8688_SPI_RB();
		datal = ADS8688_SPI_RB();
		data = datah<<8 | datal; //低位在前,低位在后 
		*(outputdata+i) = data; 
	} 
}

//初始化通道1,默认正负10V范围 
void ADS8688_Init_Single() 
{ 
	//ADS_8688_RST_PD_L;
	//delay_us(2);
	//ADS_8688_RST_PD_H;
	//ADS_8688_DAISY_IN_L;
	Enter_RESET_MODE();
	ADS8688_Write_Program_Register(0X01,0Xff);
	ADS8688_READ_Program_Register(0X01);
	usleep(2);
	ADS8688_Write_Program_Register(0x02,0x00);//所有通道退出低功耗状态 
	ADS8688_Write_Program_Register(0x01,0xff);//使能所有通道 
	Set_CH_Range_Select(CH1,0x00);//设置通道1的输?范围:+-2.5*Vref 
	// //0x00 -> +-2.5*ref 
	// //0x01 -> +-1.25*ref 
	// //0x02 -> +-0.625*ref
	// //0x03 -> +2.5*ref 
	// //0x04 -> +1.25*ref 
	MAN_Ch_n_Mode(MAN_Ch_1); 
	//HAL_Delay(300);
 }void ADS8688_Init_Mult(void)
{
	//ADS_8688_RST_PD_H; 
	//ADS_8688_DAISY_IN_L; 
	//delay_us(10);
	Enter_RESET_MODE();
	//进入配置
	ADS8688_Write_Program_Register(0X00,0X00);
	usleep(10);
	//开启通道
	ADS8688_Write_Program_Register(0X01,0X07);
	usleep(10);
	//下拉
	ADS8688_Write_Program_Register(0x02,0xf8);//所有通道退出低功耗状态 
	usleep(10);
	//设置功能
	ADS8688_Write_Program_Register(0x03,0x03);
	usleep(10);
	//ADS8688_Write_Program_Register(0x01,0xff);//使能所有通道 
	Set_CH_Range_Select(CH1,0x00);//设置通道1的输入范围:+-2.5*Vref 
	usleep(10);
	
	Set_CH_Range_Select(CH2,0x00); 
	usleep(10);
	
	Set_CH_Range_Select(CH3,0x00);
	usleep(10);
	Set_CH_Range_Select(CH4,0x00);
	usleep(10);
	/*
	Set_CH_Range_Select(CH2,0x00);
	Set_CH_Range_Select(CH3,0x00);
	Set_CH_Range_Select(CH4,0x00); 
	Set_CH_Range_Select(CH5,0x00); 
	Set_CH_Range_Select(CH6,0x00); 
	Set_CH_Range_Select(CH7,0x00); 
	
	*/
	// //0x00 -> +-2. 5*ref 
	// //0x01 -> +-1.25*ref 
	// //0x02 -> +-0.625*ref 
	// //0x03 -> +2.5*ref 
	// //0x04 -> +1.25*ref 
	//AUTO_RST_Mode();//进入自动扫描模式 
	ADS8688_Write_Program_Register(0xa0,0x03);
	usleep(10);AUTO_RST_Mode();
	
}
uint16_t Get_MAN_Ch_n_Mode_Data(void) 
{ 
	u8 datah=0,datal=0;
	//ADS_8688_nCS_L; 
	ADS8688_SPI_WB(0X00);
	ADS8688_SPI_WB(0X00);
	datah = ADS8688_SPI_RB();
	datal = ADS8688_SPI_RB();
	//ADS_8688_nCS_H; 
	return (datah<<8 | datal);
}
u16 get_ADS_ch1(void) 
{ 
	return Get_MAN_Ch_n_Mode_Data();//读取通道1数据,具体通道数由函数 MAN_Ch_n_Mode()所决定的 
}

static u16 ADS_Results[4]={0,};
void get_ADS_allch(float*result) 
{
	Get_AUTO_RST_Mode_Data(ADS_Results,4);//?动扫描模式,?动扫描并转换8通 道。转换数据存与Results数组中
}


double get_realdata(u16 x,u8 t)//mv
{
	double y;
	
	if(!t)
	{
		y = (s16)(((double)(x-32762) *20.48/(double)65535)*1000);
	}else
	{
		y = (s16)(((double)(x-32725) *20.48/(double)65535)*1000);
	}
	return y;
}

//初始化多通道,默认全开、正负10V范围 

void gat_real_ad(float *real_ad)
{
	real_ad[0]= (float)get_realdata(My_Ad[0],0);
	real_ad[1]= (float)get_realdata(My_Ad[1],1);
}


void get_ADS_1and2(u16 *My_Ad,float *real_ad)
{
	Get_AUTO_RST_Mode_Data(My_Ad,2);
	gat_real_ad(real_ad);
}

double get_realdata1(u16 x)
{
	double y;
	y=x-32768;
	if(y<0) y = y * 0.0001907+0.02;
	else y = y * 0.0001907+0.02;
	return y;
}




int main(int argc, char *argv[])
{
	int ret = 0;
	int fd;

	parse_opts(argc, argv);

	if (input_tx && input_file)
		pabort("only one of -p and --input may be selected");

	spidev_fd = open(device, O_RDWR);
	if (fd < 0)
		pabort("can't open device");

	printf("open device %s ok...",device);
	
	/** spi mode*/
	ret = ioctl(spidev_fd, SPI_IOC_WR_MODE32, &mode);
	if (ret == -1)
		pabort("can't set spi mode");

	ret = ioctl(spidev_fd, SPI_IOC_RD_MODE32, &mode);
	if (ret == -1)
		pabort("can't get spi mode");
	/** bits per word*/
	ret = ioctl(spidev_fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
	if (ret == -1)
		pabort("can't set bits per word");

	ret = ioctl(spidev_fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
	if (ret == -1)
		pabort("can't get bits per word");

	/** max speed hz*/
	ret = ioctl(spidev_fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
	if (ret == -1)
		pabort("can't set max speed hz");

	ret = ioctl(spidev_fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
	if (ret == -1)
		pabort("can't get max speed hz");

	printf("spi mode: 0x%x\n", mode);
	printf("bits per word: %u\n", bits);
	printf("max speed: %u Hz (%u kHz)\n", speed, speed/1000);

	ADS8688_Init_Mult();
	while(1)
	{
		Get_AUTO_RST_Mode_Data(ADS_Results,4);//?动扫描模式,?动扫描并转换8通 道。转换数据存与Results数组中
		
		printf("get data:{%d,%d,%d,%d}---%f,%f,%f,%f\n",ADS_Results[0],ADS_Results[1],ADS_Results[2],ADS_Results[3], get_realdata1(ADS_Results[0]),get_realdata1(ADS_Results[1]),get_realdata1(ADS_Results[2]),get_realdata1(ADS_Results[3]));
		usleep(500*1000);
	}
}

但是我给通道输入数据后,通过spi读出来的数据却一直是65535,没有获取到实际的ADC通道数据,请帮忙看看这个过程中哪里有问题?

Cherry Zhou:

您好,

我先和您确认下,以下帖子和这个问题是有关联的吗?之前的这个问题是否已解决?

https://e2echina.ti.com/support/processors/f/processors-forum/756152/tda4vm-kernel-adc

,

wei dong:

没有关联,这是另外一个问题了跟上个帖子里的问题不是同一个问题,之前的问题也没有解决,上个帖子问题是连续读取的问题,这个是读取数据异常或者说可能是读取不到的问题。

,

Cherry Zhou:

了解了,升级到英文论坛了,请查看以下链接:

e2e.ti.com/…/tda4vm-q1-using-spi-to-connect-the-ads8684-to-capture-data

,

wei dong:

还没有看到回复,帮忙看看是否端午前能回复到?

,

Cherry Zhou:

您可以关注下工程师的答复。非常抱歉,这条线人手比较短缺,回复会相对较慢,给您带来的不便敬请谅解。

,

Cherry Zhou:

您好,

您的两个问题我们的工程师在跟进中,但还需要您提供更多信息来帮助debug。

https://e2e.ti.com/support/processors-group/processors/f/791/t/1235583

赞(0)
未经允许不得转载:TI中文支持网 » TDA4VM-Q1: TDA4VM-Q1上用SPI连接ADS8684采集数据问题
分享到: 更多 (0)

© 2025 TI中文支持网   网站地图 鲁ICP备2022002796号-1