RDA5807.c
#include <reg2051.h>
#include <intrins.h>
#include "IIC.h"
#include "delay.h"
#define uchar unsigned char
#define uint unsigned int
sbit K1 = P1^4;
sbit K2 = P1^5;
sbit K3 = P1^6;
sbit K4 = P1^7;
unsigned long frequency;
// RDA5807 寄存器
unsigned char RDA_reg_data[8] =
{
0xd0,0x00, // 02H
0x00,0x00, // 03H
0x00,0x40, // 04H
0x90,0x88, // 05H
};
char code reserve[3]_at_ 0x3b; //保留0x3b开始的3个字节
/**********************************************************
连续写寄存器子函数
**********************************************************/
void RDA5807_write_reg(void)
{
uchar i;
I2C_start();
// 收音模块写入操作
I2C_write_byte(0x20);
// 寄存器连续写操作
for(i=0; i<8; i++)
{
I2C_write_byte(RDA_reg_data);
}
I2C_stop();
}
/**********************************************************
连续读寄存器子函数
**********************************************************/
void RDA5807_read_reg(uchar *reg_buf)
{
I2C_start();
// 收音模块读取操作
I2C_write_byte(0x21);
// 寄存器连续读操作
reg_buf[0] = I2C_read_byte(I2C_ACK);
reg_buf[1] = I2C_read_byte(I2C_ACK);
reg_buf[2] = I2C_read_byte(I2C_ACK);
reg_buf[3] = I2C_read_byte(I2C_NACK);
I2C_stop();
}
/**********************************************************
模块上电初始化子函数
**********************************************************/
void RDA5807_power(void)
{
delayms(50);
// 发送软件复位指令
RDA_reg_data[0] = 0x00;
RDA_reg_data[1] = 0x02;
RDA5807_write_reg();
delayms(10);
// 收音模块默认参数
RDA_reg_data[0] = 0xd0;
RDA_reg_data[1] = 0x01;
RDA5807_write_reg();
}
/**********************************************************
功能描述:收音模块自动寻台模式
**********************************************************/
void RDA5807_FM_seek(void)
{
uint chan;
uchar reg_data[4] = {0x00, 0x00, 0x00, 0x00};
RDA_reg_data[3] &= ~(1 << 4); //调谐禁用
// 内部自动寻台使能
RDA_reg_data[0] |= (1 << 0); //SEEK位置1
RDA5807_write_reg();
// 等待STC 标志置位
while(0 == (reg_data[0] & 0x40))
{
delayms(20);
// 读取内部状态
RDA5807_read_reg(reg_data);
}
// 获取当前工作频点
chan = reg_data[0] & 0x03;
chan = reg_data[1] | (chan << 8);
chan = chan << 6;
// 保存当前工作频点
RDA_reg_data[2] = (chan >> 8) & 0xff;
RDA_reg_data[3] = (chan & 0xff);
}
/**********************************************************
主函数
**********************************************************/
void main(void)
{
P1 = 0xff;
RDA5807_power();
while(1)
{
if(K1 == 0)
{
delayms(20);
if(K1 == 0)
{
RDA_reg_data[0] |= (1 << 1); //SEEK UP
RDA5807_FM_seek();
while(K1 == 0);
}
}
if(K2 == 0)
{
delayms(20);
if(K2 == 0)
{
RDA_reg_data[0] &= ~(1 << 1); //SEEK DOWN
RDA5807_FM_seek();
while(K2 == 0);
}
}
if(K3 == 0)
{
delayms(20);
if(K3 == 0)
{
if((RDA_reg_data[7] & 0x0f) < 0x0f)
{
RDA_reg_data[0] = 0xd0;
RDA_reg_data[1] = 0x01;
RDA_reg_data[3] &= ~(1 << 4);
RDA_reg_data[7]++; // 音量递增
RDA5807_write_reg();
while(K3 == 0);
}
}
}
if(K4 == 0)
{
delayms(20);
if(K4 == 0)
{
if((RDA_reg_data[7] & 0x0f) > 0x00)
{
RDA_reg_data[0] = 0xd0;
RDA_reg_data[1] = 0x01;
RDA_reg_data[3] &= ~(1 << 4);
RDA_reg_data[7]--; // 音量递减
RDA5807_write_reg();
while(K4 == 0);
}
}
}
}
}
IIC.c
#include <reg2051.h>
#include "delay.h"
#include "IIC.h"
sbit SDA = P3^4;
sbit SCL = P3^5;
/**********************************************************
启动子程序
在 SCL 高电平期间 SDA 发生负跳变
**********************************************************/
void I2C_start()
{
SDA = 1;
SCL = 1;
delayNOP();
SDA = 0;
delayNOP();
SCL = 0;
}
/**********************************************************
停止子函数
在 SCL 高电平期间 SDA 发生正跳变
**********************************************************/
void I2C_stop()
{
SDA = 0;
SCL = 1;
delayNOP();
SDA = 1;
delayNOP();
}
void iic_ack()
{
SDA = 0;
SCL = 1;
delayNOP();
SCL = 0;
NOP;
SDA = 1;
}
void iic_noack()
{
SDA = 1;
SCL = 1;
delayNOP();
SCL = 0;
delayNOP();
SDA = 0;
}
bit iic_testack()
{
bit ack_bit;
SDA = 1; //置SDA为输入方式
SCL = 1;
delayNOP();
ack_bit = SDA;
SCL = 0;
NOP;
return ack_bit; //返回应答位
}
/**********************************************************
发送一个字节子程序
**********************************************************/
unsigned char I2C_write_byte(unsigned char indata)
{
unsigned char i, ack;
// I2C 发送8 位数据
for (i=0; i<8; i++)
{
// 高在前低在后
if (indata & 0x80)
SDA = 1;
else
SDA = 0;
// 发送左移一位
indata <<= 1;
delayNOP();
SCL = 1;
delayNOP();
SCL = 0;
}
// 设置SDA为输入
SDA =1;;
delayNOP();
// 读取从机应答状态
SCL = 1;
delayNOP();
if(SDA)
{
ack = I2C_NACK;
}
else
{
ack = I2C_ACK;
}
SCL = 0;
return ack;
}
/**********************************************************
读一个字节子程序
**********************************************************/
unsigned char I2C_read_byte(unsigned char ack)
{
unsigned char i, data1 = 0;
// SDA 设置输入方向
SDA = 1;
// I2C 接收8位数据
for(i = 8; i > 0; i--)
{
data1 <<= 1;
SCL = 1;
delayNOP();
// 高在前低在后
if (SDA)
{
data1++;
}
SCL = 0;
delayNOP();
}
// 主机发送应答状态
if(ack == I2C_ACK)
SDA = 0;
else
SDA = 1;
delayNOP();
SCL = 1;
delayNOP();
SCL = 0;
return data1;
}
delay.c
#include "delay.h"
/**********************************************************
us延时子程序
**********************************************************/
void delayNOP()
{
_nop_();_nop_();_nop_();_nop_();
}
/**********************************************************
ms延时子程序
**********************************************************/
void delayms( unsigned int ms)
{
unsigned char k;
while(ms--)
{
for(k = 0; k < 120; k++);
}
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
#include "IIC.h"
#include "delay.h"
下载了学习。谢谢分享
一周热门 更多>