完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
#include "led.h" #include "delay.h" #include "sys.h" #include "usart.h" #include "spi.h" // 0321 注意1:SPI 空闲时为低电平,第二跳边沿生效 //注意2:SDN直接接DGND算了 // 注意3:SI4432和STM32要用同一个VCC3.3否则的话收到全为0 #define SI4432_NSEL PAout(4) //SI4432_NSEL 使能 #define SI4432_SDN PCout(4) //SI4432_SDN 使能 #define SI4432_NIRQ PCin(5) //SI4432_NIRQ 中断状态 void SI4432_Init(void) ; u8 SI4432_ReadReg(u8 addr) ; void SI4432_WriteReg(u8 addr, u8 value) ; unsigned char i; u8 ItStatus1,ItStatus2,res; int main(void) { delay_init(); //延时函数初始化 NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 uart_init(9600); //串口初始化为9600 LED_Init(); //LED端口初始化 SPI1_Init(); GPIOSet(); SI4432_NSEL=0; delay_ms(600); res = SI4432_ReadReg(0x00); delay_ms(20); printf("res =%02x n",(unsigned short)res ); res = SI4432_ReadReg(0x01); delay_ms(20); printf("res =%02x n",(unsigned short)res ); res = SI4432_ReadReg(0x02); delay_ms(20); printf("res =%02x n",(unsigned short)res ); delay_ms(1000); //读取中断状态 清除中断 释放 SI4432_NIRQ ItStatus1 = SI4432_ReadReg(0x03); ItStatus2 = SI4432_ReadReg(0x04); //软件复位 SI4432_WriteReg(0x07, 0x80); //向0X07地址 写入0X80 软件复位 while ( SI4432_NIRQ == 1); //读取中断状态 清除中断 释放 SI4432_NIRQ ItStatus1 = SI4432_ReadReg(0x03); ItStatus2 = SI4432_ReadReg(0x04); /开始设置 // 频率设置 434 SI4432_WriteReg(0x75, 0x53); SI4432_WriteReg(0x76, 0x64); // SI4432_WriteReg(0x77, 0x00); // 1.2K bps 发射速率 SI4432_WriteReg(0x2a, 0x14); SI4432_WriteReg(0x6e, 0x09); SI4432_WriteReg(0x6f, 0xd5); SI4432_WriteReg(0x70, 0x2c);// //SpiWriteRegister(0x72, 0x48); //(9.6kbps) SI4432_WriteReg(0x72, 0x38); //频率偏差(1.2kbps) // 下面的设置根据Silabs 的Excel (9.6 kbps, deviation: 45 kHz, channel filter BW: 102.2 kHz SI4432_WriteReg(0x1C, 0x1b); //write 0x1E to the IF Filter Bandwidth register SI4432_WriteReg(0x20, 0x83); //write 0xD0 to the Clock Recovery Oversampling Ratio register SI4432_WriteReg(0x21, 0xc0); //write 0x00 to the Clock Recovery Offset 2 register SI4432_WriteReg(0x22, 0x13); //write 0x9D to the Clock Recovery Offset 1 register SI4432_WriteReg(0x23, 0xa9); //write 0x49 to the Clock Recovery Offset 0 register SI4432_WriteReg(0x24, 0x00); //write 0x00 to the Clock Recovery Timing Loop Gain 1 register SI4432_WriteReg(0x25, 0x03); //write 0x24 to the Clock Recovery Timing Loop Gain 0 register SI4432_WriteReg(0x1D, 0x40); //write 0x40 to the AFC Loop Gearshift Override register SI4432_WriteReg(0x1E, 0x0A); //write 0x0A to the AFC Timing Control register SI4432_WriteReg(0x2A, 0x14); //write 0x20 to the AFC Limiter register //前导码 同步字 SI4432_WriteReg(0x34, 0X0A); // 发射5字节的Preamble SI4432_WriteReg(0x35, 0x2A); // 需要检测 Preamble SI4432_WriteReg(0x33, 0x02);// 同步字3,2 是同步字 SI4432_WriteReg(0x36, 0x2d); // 同步字为 0x2dd4 SI4432_WriteReg(0x37, 0xd4); SI4432_WriteReg(0x30, 0x8D); // 使能PH+ FIFO模式,高位在前面,使能CRC校验 CCITTT SI4432_WriteReg(0x32, 0x00 );// 禁止帧头 SI4432_WriteReg(0x71, 0x63); // 发射不需要 CLK,FiFo , FSK模式 //GPIO SI4432_WriteReg(0x0b, 0x12); // SI4432_WriteReg(0x0c, 0x15); // //其他设置 SI4432_WriteReg(0x09, 0xD7); // 负载电容 SI4432_WriteReg(0x69, 0x60); //AGC过载 //发射功率 SI4432_WriteReg(0x6d, 0x1e); //手动打开接收 SI4432_WriteReg(0x07, 0x05); //打开 接收中断 SI4432_WriteReg(0x05, 0x03); SI4432_WriteReg(0x06, 0x00); //清中断 ItStatus1 = SI4432_ReadReg(0x03); //read the Interrupt Status1 register ItStatus2 = SI4432_ReadReg(0x04); //read the Interrupt Status2 register SI4432_WriteReg(0x07, 0x05);//打开接收 SI4432_WriteReg(0x0d, 0xf4);//GPIO2接收数据 while(1) { GPIO_SetBits(GPIOB , GPIO_Pin_10);//信号灯 res = SI4432_ReadReg(0x02); delay_ms(20);printf("res =%02x n",(unsigned short)res ); SI4432_WriteReg(0x07, 0x01); // rf 模块进入Ready 模式 delay_ms(20); // 延时 5ms, 让系统稳定 SI4432_WriteReg(0x3e, 0x08); // 总共发射8个字节的数据 SI4432_WriteReg(0x7F, 0x42); SI4432_WriteReg(0x7F, 0x42); SI4432_WriteReg(0x7F, 0x42); SI4432_WriteReg(0x7F, 0x42); SI4432_WriteReg(0x7F, 0x42); SI4432_WriteReg(0x7F, 0x42); SI4432_WriteReg(0x7F, 0x42); SI4432_WriteReg(0x7F, 0x42); SI4432_WriteReg(0x05, 0x04); // 整包数据发射完后,产生中断 SI4432_WriteReg(0x06, 0x00); ItStatus1 = SI4432_ReadReg(0x03);//清除中断 ItStatus2 = SI4432_ReadReg(0x04); SI4432_WriteReg(0x07, 0x09);//打开发射 while ( SI4432_NIRQ == 1); GPIO_ResetBits(GPIOB , GPIO_Pin_10); //read interrupt status registers to release the interrupt flags ItStatus1 = SI4432_ReadReg(0x03); printf("ItStatus1 =%02x n",(unsigned short)ItStatus1 ); ItStatus2 = SI4432_ReadReg(0x04); printf("ItStatus2 =%02x n",(unsigned short)ItStatus2 ); delay_ms(1000); } } // 读取寄存器 u8 SI4432_ReadReg(u8 addr) //读取寄存器的值 { uint8_t temp=0; SI4432_NSEL=0; SPI1_ReadWriteByte(addr); //发送读取寄存器地址 temp=SPI1_ReadWriteByte(0Xff); SI4432_NSEL=1; return temp; } //写寄存器 void SI4432_WriteReg(u8 addr, u8 value) //写寄存器 { SI4432_NSEL=0; SPI1_ReadWriteByte(addr|0x80); SPI1_ReadWriteByte(value); SI4432_NSEL=1; } 一、无线模块选型。 根据无线通讯的频段,平常用的无线模块主要有315MHZ,433MHZ,2.4GHZ。2.4G最近貌似比较火,像24L01,好多开发板上都配这一款芯片。433MHZ频段的模块常用的有NRF905、CC1101、SI4432。在315MHZ频段好像做普通的遥控器比较多,像超外差模块。 本人想做无线通信,选择在2.4GHZ和433MHZ之间。说下区别,2.4G无线通信频率高、波长短、传输速率高、绕射能力差、通信距离短。网上卖的模块不加功率放大也就是一百米以内。433MHZ无线通信频率低、波长较长、传输速率低、绕射能力强、通信距离远。价格和2.4GHZ模块相当,但是距离一般在几百米甚至更远,据说加上功率放大可达一两千米。本人想用来遥控智能车,通信数据量不大,但是想让距离远一点。所以选择433MHZ模块,具体型号是SI4432。 二、初次接触SI4432 该芯片价格低、传输距离远,网上用的人挺多的。曾经找过一些资料发现很多商业上的无线通信也是用这一款。于是在网上买了一对,加运费一共四十多。没有广告嫌疑,感兴趣自己搜。买回来之后开始看相关的手册和例程。我嘞个去,需要配置的寄存器真多,而且通讯速率、频段、前导码、同步字等等都是自己定义的,大家写的都不一样。加上没有专业的知识,更是加大难度。 卖家配的资料室51的版本,说实话程序写的有点乱,主要是因为他们的程序是配套他们的开发板的,有很多都看不懂。而对于我们初学者而言,最需要的却是最简单的:简单收发就行。我使用的控制器型号:STM32F103RB。分析了很久慢慢移植到STM32里面,失败。多次修改,失败。在网上搜索,网上虽然用的人多,但是资料甚少。而且一般都是51单片机驱动的,而且是虚拟SPI!然后是几天的调试,不多说。 经过几天的调试,终于成功,下面说下使用这款芯片的要点。 三、SPI 我用的控制芯片是STM32F103RB。SPI可以软件模拟,也可以用硬件的。再次,建议大家用硬件的SPI,稳定,减少CPU负担。 配置硬件SPI要点: 1、速率不要太高,SI4432手册上说不要大于10MHZ。 2、MOSI、MOSO、SCK三个引脚配置为复用功能推挽输出。 3、SPI的时钟极性配置为:同步时钟的空闲状态为 低电平 4、SPI的时钟的第2个跳变沿数据被采样。(SPI_CPHA) 5、片选信号软件控制,自己定义一个IO空控制片选吧,方便。 四、硬件连接 STM32和SI4432硬件连接,具体看模块吧。我简单说几个比较重要的 1、SI4432的SDN引脚,为高时:芯片停止工作。为低时:芯片允许工作。我买的模块里,这个引脚是被引出来的,别费劲了,直接接地,不要用IO口控制高低。高手略过。 2、模块的引脚有些是2.54mm间距,有些是1.27mm。想DIY的朋友注意了,我当时就忘了结果买了个1.27mm的后来转接,麻烦了。 3、尽量不要用杜邦线。我开始一直用杜邦线连起来,但是经常在发送和接收的时候出错,初始化正常。后来用洞洞板连起来,正常。 4、SI4432是3.3V供电,电源线和地线尽量和STM32的3.3V和地线连在一起。不然的话容易出错,水平有限,不解释,等高人。 五、软件调试 1、SPI配置好以后,向SI4432写数据注意地址最高位置1。 如:SPI1_ReadWriteByte(addr|0x80) 2、 配置好以后,向0X00、0X01、0X02地址读取,应该有返回值,具体看手册,如果和手册上的差不多就证明SPI通讯成功了。 3、 前导码个数。SI4432_WriteReg(0x34, 0X0A); 0x34是向SI4432写入前导码的地址,0X0A是个数,但是表示其一半,也就是5个字节。 4、刚开始,不要配置帧头。直接禁止 SI4432_WriteReg(0x32, 0x00 );// 禁止帧头 5、SI4432有3个GPIO,一般自己是不用的,但是依然要配置,因为这个和模块相关。具体问卖家。 6、SI4432主要三个状态:接收状态、发送状态、挂起状态。发送和接收之间可以相互转换、但是转换之前需要先进入挂起状态然后至少15ms之后再进入发送或者接收状态。程序while(1)之前最好开始就配置为挂起状态:SI4432_WriteReg(0x07, 0x01); |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1804 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1629 浏览 1 评论
1097 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
736 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1686 浏览 2 评论
1944浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
748浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
582浏览 3评论
604浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
565浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-28 21:30 , Processed in 0.875480 second(s), Total 77, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (威廉希尔官方网站 图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号