基于STC8单片机的Si4702驱动

简介

某宝随便买的,以为开发起来会很顺利没想到还是掉坑了,主要是因为没有详细阅读其数据手册导致。

没有示例代码也只有这么一张图,通过比对数据手册猜测这是一个2线通信的模块,而9脚的置位使能端其实就是芯片RST#引脚。

按上图的引脚定义连接到单片机就行了,注意每个引脚都需要串一个电阻,作用有两个:

第一下面的STC评估板在断电重启时不会断开上层扩展板电源,这导致有可能发生IO间的电流灌入导致无法成功烧录。STC烧录时需要冷重启,且所有IO不能灌入太大的电流,否则将失败。

第二个作用主要是因为模块是3.3V供电,而STC这边是5V,数据线电平不一致我又懒得上电平转换电路,所以串连1K电阻限制一下电流。

复位时序及2线模式选择

模式选择直接看表9就可以了,因为是模块那些IO已经给设置好了。
千万不要被这里SEN#带坑里,这里不是模块的置位使能端

然后这附近的说明要仔细看

复位时序总结下来就是:
SCL拉高
SDA拉高
RST拉低
延时等一下
RST拉高
SDA拉高
接着启用振荡器器,07H寄存器里的XOSCEN位使能,重点bit13:0=0x0100,这里的说明一定要仔细看
把寄存器数据更新一下等待振荡器稳定,经过我的测试大约需要500ms,建议不低于此时长。
启动后进行上电操作,即:
02H[bit 0]ENABLE=1
07H[bits13:0]=0x3C04
其他设置看代码吧。

/*** @brief 初始化* */
void si4702_init() {si4702_delay_100ms();SI_RST_PIN_INIT;soft_i2c_init();SOFT_I2C_SCL = 1;SOFT_I2C_SDA = 0;SI_RST = 0;si4702_delay_200us();SI_RST = 1;si4702_delay_200us();SOFT_I2C_SDA = 1;si4702_delay_200us();//启用晶振siRegData[SI_REG_07H] = SI_XOSCEN | SI_07H_13_0_EN0; //当0x02H bit0 ENABLE = 0 时 bits 13:0 要设置为 0x0100si4702_update();//等待振荡器稳定si4702_delay_100ms();si4702_delay_100ms();si4702_delay_100ms();si4702_delay_100ms();si4702_delay_100ms();//初始化配置siRegData[SI_REG_02H] |= SI_DSMUTE | SI_DMUTE | SI_ENABLE; //禁用软静音,禁用静音,启用电源; 软静音可减弱没有信号时的白噪声siRegData[SI_REG_03H] = 0x0000;siRegData[SI_REG_04H] |= SI_DE;                      // 50us预加重 与增益有关,预加重电路siRegData[SI_REG_05H] |= SI_BAND | SI_SPACE | 8;   // 波段 信道间隔 音量 默认为8 范围0-15siRegData[SI_REG_07H] = SI_XOSCEN | SI_07H_13_0_EN1; //当0x02H bit0 ENABLE = 0 时 bits 13:0 要设置为 0x3C04si4702_update();//等待上电si4702_delay_100ms();si4702_delay_100ms();}

完整的代码

main.c

/*** @file main.c* @author WangBo* @brief STC8G2K64S2-48PIN @ 11.0592Mhz 使用Keil 5编译* @version 0.1* @date 2022-05-21** @copyright Copyright (c) 2022** @note 随便写的测试代码**/#include "STC8G.H"
#include "INTRINS.H"
#include "io.h"
#include "uart.h"#include "si4702.h"unsigned char uartBuf[16];
unsigned char uartBufIdx = 0;
bit uartRecvFlag = 0;unsigned char vol = 8;
unsigned int freq = 917;void main() {si4702_init();si4702_set_vol(vol);si4702_set_freq(freq);while (1) {}
}

si4702.h

#ifndef __SI4702_H__
#define __SI4702_H__#include "STC8G.H"
#include "INTRINS.H"
#include "software_i2c.h"#define SI_ADDR_WRITE (0x10 << 1)
#define SI_ADDR_READ ((0x10 << 1) | 0x01)#define SI_REG_02H 0
#define SI_REG_03H 1
#define SI_REG_04H 2
#define SI_REG_05H 3
#define SI_REG_06H 4
#define SI_REG_07H 5// Register 02h POWERCFG
#define SI_DSMUTE (0x0001 << 15)
#define SI_DMUTE (0x0001 << 14)
#define SI_MONO (0x0001 << 13)
#define SI_SKMODE (0x0001 << 10)
#define SI_SEEKUP (0x0001 << 9)
#define SI_SEEK (0x0001 << 8)
#define SI_DISABLE (0x0001 << 6)
#define SI_ENABLE 0x0001// Register 03h CHANNEL
#define SI_TUNE (0x0001 << 15)// Register 04h SYSCONFIG1
#define SI_DE (0x0001 << 11)// Register 05h SYSCONFIG2
#define SI_SEEKTH 0xFF00 // MASK
#define SI_BAND_875_1080 // 87.5~108MHz
//#define SI_BAND_760_108  // 76-108
//#define SI_BAND_760_900  // 76-90//#define SI_SPACE_200K 0x0000 //200k
#define SI_SPACE_100K  // 100k
//#define SI_SPACE_50K 0x0020 //50k#ifdef SI_BAND_875_1080
#define SI_BAND 0x0000
#define SI_BAND_FREQ 875U
#endif#ifdef SI_BAND_760_1080
#define SI_BAND 0x0040
#define SI_BAND_FREQ 760U
#endif#ifdef SI_BAND_760_900
#define SI_BAND 0x0080
#define SI_BAND_FREQ 760U
#endif#ifdef SI_SPACE_200K
#define SI_CHANNEL(f)(f - SI_BAND_FREQ) / 2
#define SI_SPACE 0x0000
#endif#ifdef SI_SPACE_100K
#define SI_SPACE 0x0010
#define SI_CHANNEL(f)(f - SI_BAND_FREQ)
#endif#ifdef SI_SPACE_50K
#define SI_CHANNEL(f)(f - SI_BAND_FREQ) * 2
#define SI_SPACE 0x0020
#endif// Register 07h TEST1
#define SI_XOSCEN 0x8000
#define SI_07H_13_0_EN0 0x0100
#define SI_07H_13_0_EN1 0x3C04void si4702_delay_100ms();
void si4702_update();
void si4702_init();
void si4702_set_freq(unsigned int _freq);
void si4702_set_vol(unsigned char _vol);
void si4702_seek(unsigned char _seekup);
#endif

si4702.c

#include "si4702.h"#define SI_RST P07
#define SI_RST_PIN_INIT \P0M1 &= ~(1 << 7);  \P0M0 |= (1 << 7);unsigned int siRegData[6] = {0};// 100ms @ 11.0592Mhz
void si4702_delay_100ms() {unsigned char i, j, k;i = 6;j = 157;k = 59;do {do {while (--k);} while (--j);} while (--i);
}
// 200us @ //@11.0592MHz
void si4702_delay_200us() {unsigned char i, j;i = 3;j = 221;do {while (--j);} while (--i);
}/*** @brief 更新寄存器* */
void si4702_update() {unsigned char i;soft_i2c_start();soft_i2c_send_byte(SI_ADDR_WRITE);soft_i2c_recv_ack();for (i = 0; i < 6; i++) {soft_i2c_send_byte(siRegData[i] >> 8);soft_i2c_recv_ack();soft_i2c_send_byte(siRegData[i] & 0xFF);soft_i2c_recv_ack();}soft_i2c_stop();
}/*** @brief 初始化* */
void si4702_init() {si4702_delay_100ms();SI_RST_PIN_INIT;soft_i2c_init();SOFT_I2C_SCL = 1;SOFT_I2C_SDA = 0;SI_RST = 0;si4702_delay_200us();SI_RST = 1;si4702_delay_200us();SOFT_I2C_SDA = 1;si4702_delay_200us();//启用晶振siRegData[SI_REG_07H] = SI_XOSCEN | SI_07H_13_0_EN0; //当0x02H bit0 ENABLE = 0 时 bits 13:0 要设置为 0x0100si4702_update();//等待振荡器稳定si4702_delay_100ms();si4702_delay_100ms();si4702_delay_100ms();si4702_delay_100ms();si4702_delay_100ms();//初始化配置siRegData[SI_REG_02H] |= SI_DSMUTE | SI_DMUTE | SI_ENABLE; //禁用软静音,禁用静音,启用电源; 软静音可减弱没有信号时的白噪声siRegData[SI_REG_03H] = 0x0000;siRegData[SI_REG_04H] |= SI_DE;                      // 50us预加重 与增益有关,预加重电路siRegData[SI_REG_05H] |= SI_BAND | SI_SPACE | 8;   // 波段 信道间隔 音量 默认为8 范围0-15siRegData[SI_REG_07H] = SI_XOSCEN | SI_07H_13_0_EN1; //当0x02H bit0 ENABLE = 0 时 bits 13:0 要设置为 0x3C04si4702_update();//等待上电si4702_delay_100ms();si4702_delay_100ms();}/*** @brief 频率设置** @param freq 频率 Khz,91.7Mhz =>917 Khz** @note TUNE由0变1时才会调谐,TUNE在调谐完成后不会自动置0,需手动清除*/
void si4702_set_freq(unsigned int _freq) {siRegData[SI_REG_03H] = 0x0000; // TUNE不会自动置0si4702_update();si4702_delay_200us();siRegData[SI_REG_03H] = SI_TUNE | SI_CHANNEL(_freq);si4702_update();
}/*** @brief 音量设置* * @param _vol */
void si4702_set_vol(unsigned char _vol) {siRegData[SI_REG_05H] &= ~0x000F;siRegData[SI_REG_05H] |= _vol;si4702_update();
}/*** @brief 搜索* * @param _seekup 0=向下搜索 1=向上搜索*/
void si4702_seek(unsigned char _seekup) {siRegData[SI_REG_02H] &= ~(SI_SEEKUP | SI_SEEK);siRegData[SI_REG_03H] &= ~SI_TUNE;si4702_update();if (!_seekup) {siRegData[SI_REG_02H] |= SI_SEEK;} else {siRegData[SI_REG_02H] |= SI_SEEKUP | SI_SEEK;}si4702_update();
}

software_i2c.h

#include "software_i2c.h"#define I2C_DELAY_COUNT 10void soft_i2c_delay() {unsigned char i;i = I2C_DELAY_COUNT;while (--i);
}void soft_i2c_init() {SOFT_I2C_PIN_INIT;
}void soft_i2c_start() {SOFT_I2C_SCL = 1;SOFT_I2C_SDA = 1;soft_i2c_delay();SOFT_I2C_SDA = 0;soft_i2c_delay();SOFT_I2C_SCL = 0;
}void soft_i2c_stop() {SOFT_I2C_SDA = 0;soft_i2c_delay();SOFT_I2C_SCL = 1;soft_i2c_delay();SOFT_I2C_SDA = 1;
}void soft_i2c_send_byte(unsigned char dat) {unsigned char i;for (i = 0; i < 8; i++) {//改变SDA状态if ((dat << i) & 0x80) {SOFT_I2C_SDA = 1;} else {SOFT_I2C_SDA = 0;}soft_i2c_delay();//拉高SCL,等待从机读取SDASOFT_I2C_SCL = 1;soft_i2c_delay();//拉低SCL,准备改变SDA状态SOFT_I2C_SCL = 0;}
}unsigned char soft_i2c_recv_ack() {unsigned char t = 0;unsigned char ack;SOFT_I2C_SDA = 1; //释放SDA等待从机ACK信号while (SOFT_I2C_SDA) {if (++t > 200) {break;}}SOFT_I2C_SCL = 1;soft_i2c_delay();if (SOFT_I2C_SDA) {ack = 0;} else {ack = 1;}SOFT_I2C_SCL = 0;return ack;
}

software_i2c.h

#ifndef __SOFTWARE_I2C_H__
#define __SOFTWARE_I2C_H__#include "STC8G.H"#define SOFT_I2C_SCL P00
#define SOFT_I2C_SDA P01
#define SOFT_I2C_PIN_INIT            \P0M1 &= ~((0x01 << 1) | 0x01); \P0M0 &= ~((0x01 << 1) | 0x01);void soft_i2c_delay();
void soft_i2c_init();
void soft_i2c_start();
void soft_i2c_stop();
void soft_i2c_send_byte(unsigned char dat);
unsigned char soft_i2c_recv_ack();#endif

SI4702 驱动 基于STC单片机相关推荐

  1. 基于STC单片机的两轮平衡车设计

    给大家传福利了..后续继续共享基于Arduino/安卓Android/树莓派raspberry等平台的两轮车设计 这是我前年暑假做的一个小项目,今年拿出来整理了下当毕设了(当然毕设里添加了许多其他元素 ...

  2. 基于STC单片机的排队管理系统的设计

    摘要:为改善营业窗口的服务质量和工作效率,解决枯燥无序的排队问题,采用STC89C52单片机控制语音芯片.打印机.LCD显示屏来模拟人工叫号过程,完成号码的打印.存储.显示及播报工作:采用MAX485 ...

  3. 基于STC单片机和AHT10温湿度传感器的温湿度计的设计

    大家好,我是『芯知识学堂』的SingleYork,今天笔者要跟大家分享一款"温湿度计"的制作,这是笔者曾经发表过的原文地址:https://www.icxbk.com/articl ...

  4. 基于STC单片机的无线充电系统

    先放一张实物图: 使用的是STC12C4052AD单片机,可以用拆机的就可. 项目内容 输入电压 12V~5V 输出电压 5V   工作电流 1A~2A 功率 5~10w 实现功能 无线充电.充电计时 ...

  5. MT25QL128/MTQL256_FLASH驱动——基于华大单片机

    MT25QL256的数据手册: https://download.csdn.net/download/weixin_47041339/85933399?spm=1001.2014.3001.5501 ...

  6. STC单片机驱动1.8‘TFT SPI屏幕示例模板(含资料包)

    STC单片机驱动1.8'TFT SPI屏幕示例模板(含资料包) 驱动演示 STC单片机采用的是: STC12C5A60S2,采用的自制开发板:<[开源]STC12C5A60S2开发板> 1 ...

  7. 步进电机驱动器设计c语言软件,最新基于单片机系统的步进电机驱动STC单片机步进电机驱动器的设计及C语言程序.doc...

    最新基于单片机系统的步进电机驱动STC单片机步进电机驱动器的设计及C语言程序 基于单片机系统的步进电机驱动 摘 要 本文介绍了基于80C52单片机的步进电机控制系统的设计.分别概括的介绍了单片机和步进 ...

  8. 74hc164驱动数码管c语言程序,基于51单片机的74HC164驱动数码管显示程序与仿真

    基于51单片机的74HC164驱动数码管显示程序与仿真 基于51单片机的74HC164驱动一位数码管显示程序与仿真 #include #include #define uchar unsigned c ...

  9. STC单片机驱动BLDC无刷直流电机(无HALL)官方示例

    STC单片机驱动BLDC无刷直流电机(无HALL)官方示例 示例代码在STC8系列文档第20章里面:http://www.stcmcudata.com/STC8F-DATASHEET/STC8H.pd ...

最新文章

  1. js MD5加密处理
  2. go 通道 返回_GCTT 出品 | Go 语言的缓冲通道:提示和技巧
  3. Json工具类 - JsonUtils.java
  4. 改变背景色为苹果绿--保护眼睛
  5. maven常用的命令(window控制台和linux命令是一致的)
  6. 阿里巴巴制定了这 16 条
  7. thymeleaf 使用javascript定义数组报错
  8. 整理一些完全免费开放的API接口
  9. L2TP连接result_code_avp: avp is incorrect size. 错误
  10. 深入浅出Zookeeper(一) Zookeeper架构及FastLeaderElection机制
  11. 高薪的 10 倍工程师不能带来 10 倍的产出?
  12. Unity3D开发环境的搭建
  13. k9s加速k8s集群管理
  14. 图像处理的空间频率(波数)、角波数与空间波长
  15. Oracle中的函数(详细!!!)
  16. 二极管计算机原理,二极管逻辑电路
  17. 睡眠障碍,正在“杀死”3亿中国人
  18. python如何更改背景颜色_python背景颜色,python改背景色
  19. Ubuntu17.0版本 安装firefox浏览器flash插件
  20. wampserver常见问题

热门文章

  1. SAP MTS/ATO/MTO/ETO专题之三:MTS后台配置,对应10策略
  2. 模拟IC设计学习笔记(1)---恒流源负载的共源极放大器极点的观察与计算
  3. redis集群节点宕机 fail状态 redis的投票机制实测
  4. assa_【脚本教程】ASSA指令解析与案例
  5. 浏览器判断是否全屏, 设置浏览器全屏,设置浏览器退出全屏
  6. feralhosting饭盒通过deluge+flexget实现全自动刷PT
  7. (AS笔记)Android全透明沉浸式主题样式——代码篇
  8. 介绍一款HCIA、HCIP、HCIE的刷题软件
  9. 微信备份聊天记录,显示网络复杂(PC)
  10. 将一个图片切割成多个图片