小白分享-SI4702在STM32上的调试过程分享

初学小白,说得不对的地方欢迎大家指教,谢谢!
题外话:最近突然来了兴趣想学stm32,在某宝搞了块核心版,学习过程中又在某宝闲逛的时候看了了一个小模块,si4702收音模块,哦豁,兴奋了。可能跟工作有关吧,总想弄个收音机,以前弄过基于51的rda5820,tea5767,这回换stm32+si4702,芯片到手后照例找店家要例程,店家告诉我没有,只有一张引脚图,突然懵逼了,怎么办,硬上吧,不就是看数据手册吗,我有谷歌翻译。
正题开始了。开始了我的表演。
从店家告诉我没有例程后,我就开始了自己编写,模块引脚图如下:
引脚图
参照官方数据手册对比在这里插入图片描述
模块2脚是SDIO,10脚是SCLK,9脚这个置位使能端应该是RST,模块分析完毕,连上stm32核心版,接下来开始写程序了,怎么写?只有看数据手册了,手册上4.9 Reset, Powerup, and Powerdown介绍了怎么上电并选择2线或者3线操作模式,这模块一看就只能2线操作啊,那就先写复位,在RST上升沿时保持SDIO为低,且SCLK为高。如下:
总线模式选择

static void si4702_reset(void)  //4702复位,选择2线模式
{
	SI_SDIO_L;
	SI_RST_L;
	SI_SCL_H;  //手册上有句话:复位期间必须保持SCLK为高,且至少持续到第一个开始信号
	delay_ms(300);
	SI_RST_H;
	delay_ms(150);
	SI_SDIO_H;
	delay_ms(10);
}

上电了,就准备写入或者读取数据了,看时序图
时序图
时序图
有开始,ACK,结束,这不是IIC吗?不知道IIC兼容不,手册上也没有明确表示支持IIC,我也没试,就参照官方的例程写的,关于写和读,器件地址是0010000b+R/W,最后一位是读写标志位,1为读,0为写,芯片总共有16个16位的寄存器,从00H到0FH,写入是从寄存器02H开始,每次1个字节,高位在前,低位在后,直到0F低8位写完后,绕回到00H。读取顺序是从0A开始,每次1个字节,高位在前,低位在后,到0FH,再到00H。
关于写入,芯片收到开始信号后就可以连续写入,每个字节后芯片给个ACK(SDIO=0),直到收到停止信号结束。代码如下:

开始信号,u8 addr:芯片地址,u8 rw:读写标志1或0

static void si4702_start(u8 addr, u8 rw) //开始,rw读写标志,0写,1读
{
	signed char i;
	SI_SCL_H;
	si4702_sdio_out();
	SI_SDIO_H;
	delay_us(2);
	SI_SDIO_L;
	delay_us(2);
	SI_SCL_L;
	
	addr = (addr & 0xfe) | (rw & 0x01);
	for(i=7;i>=0;i--)
	{
		SI_SCL_L;
		delay_us(2);
		if(((addr >> i) & 0x01) > 0) SI_SDIO_H;
		else SI_SDIO_L;
		delay_us(2);
		SI_SCL_H;
		delay_us(2);		
	}
	//wait ack
	SI_SCL_L;
	si4702_sdio_in();  //这里因为配置SDIO为上拉输入模式,所以SDIO=1
	delay_us(2);
	SI_SCL_H;
	delay_us(2);
	if(SI_SDIO_IN != RESET) printf("ack error!\r\n"); //判断是否收到4702应答,自行优化
}

停止传输

static void si4702_stop(void)  //数据传输停止
{
	SI_SCL_L;
	delay_us(2);
	si4702_sdio_out();
	SI_SDIO_L;
	delay_us(2);
	SI_SCL_H;
	SI_SDIO_H;	
}

写入一个字节, u8 wdata:需要写入的内容
ps:这里有个坑,stm32 char 默认是从0-255,signed char -127~128。说多了都是泪。

static void si4702_write_byte(u8 wdata)  //发送一个字节
{
	signed char i;
	si4702_sdio_out();
	for(i=7;i>=0;i--)
	{
		SI_SCL_L;
		delay_us(2);
		if(((wdata >> i) & 0x01) > 0) SI_SDIO_H;
		else SI_SDIO_L;
		delay_us(2);
		SI_SCL_H;
		delay_us(2);		
	}
	//wait ack
	SI_SCL_L;
	si4702_sdio_in();
	delay_us(2);
	SI_SCL_H;
	delay_us(2);
	if(SI_SDIO_IN != RESET) printf("ack error\r\n"); //判断是否收到4702应答,自行优化
}

连续写入多个字节,u8 *data_out:8位的数组存放需要写入的内容,u8 num:写入的次数,16个16位的寄存器,一次8位,全部写完需要写入32次

static void si4702_write(u8 num, u8 *data_out) //向4702写入数组里的数据
{
	si4702_start(SI_SIADDR,SI_WRITE);
	
	while(num--)
	{
			si4702_write_byte(*data_out++);
	}
	
	si4702_stop();
}

写入有了,接下来就是读取了,每读完一个字节需要mcu给芯片一个ACK(SDIO=0)是否继续读。代码如下:
读取一个字节,u8 num_bytes:是否给出ACK信号,为0是表示不发送

static u8 si4702_read_byte(u8 num_bytes)  //读取一个字节
{
	signed char i;
	u8 rdata=0;
	
	si4702_sdio_in();
	for(i=7;i>=0;i--)
	{
		SI_SCL_L;
		delay_us(1);
		delay_us(2);
		SI_SCL_H;
		delay_us(2);
		rdata = ((rdata<<1) | SI_SDIO_IN);			
	}
	//send ack
	si4702_sdio_out();
	SI_SCL_L;
	delay_us(2);
	if(num_bytes != 0) SI_SDIO_L;  //连续读取需要mcu给出应答,参照数据手册
	else SI_SDIO_H;
	delay_us(2);
	SI_SCL_H;
	delay_us(2);
	SI_SCL_L;
	
	return rdata;
}

连续读取,u8 *data_in:存放数据的数组,u8 num:读取的次数,16个16位的寄存器,一次8位,全部读完需要读取32次

static void si4702_read(u8 num, u8 *data_in) //读取4702寄存器数据并存入数组中
{
	si4702_start(SI_SIADDR,SI_READ);
	
		while(num--)
		{
			*data_in++ = si4702_read_byte(num);
		}

	si4702_stop();
}

写入和读取都有了,剩下的就是寄存器配置了,参照手册自行配置了,以上所有配置都已调试好,暂未发现问题,有不对的地方欢迎大家指正,谢谢!
完整程序:https://download.csdn.net/download/u014040765/19731407?spm=1001.2014.3001.5503
资源包里除了驱动程序,还包含了si4702/02-c19数据手册,AN332官方编程指导和AN332官方源码。
最后放一张垃圾图
调试过程

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值