1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > SI4702 驱动 基于STC单片机

SI4702 驱动 基于STC单片机

时间:2021-07-24 07:29:53

相关推荐

SI4702 驱动 基于STC单片机

基于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 -05-21** @copyright Copyright (c) ** @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.0592Mhzvoid si4702_delay_100ms() {unsigned char i, j, k;i = 6;j = 157;k = 59;do {do {while (--k);} while (--j);} while (--i);}// 200us @ //@11.0592MHzvoid 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

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。