打印
[STM8]

stm8调试硬件i2c RDA5807读总出错

[复制链接]
2551|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
machao070|  楼主 | 2015-3-10 23:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include "include.h"

static unsigned int CurrFrequency;
static unsigned int Currchan;

/***************************************************
RDA5807P相关寄存器镜像
****************************************************/
static unsigned char RDA5807P_reg[]={
0xd0, 0x01, //02H;
0x00, 0x00, //03H;
0x84, 0x04, //04H;
0x88, 0xA1, //05H;
};

static void delayms(uint16_t nCount)
{
  while (nCount != 0)
  {   
    nCount--;
  }  
}
/**************************实现函数********************************************
*函数原型: void InitIIC(void)
*功  能: 初始化外设IIC
*******************************************************************************/
void InitIIC(void)
{
  //I2C_DeInit();
  //I2C_Init(IICSPEED, Radio_Address, I2C_DUTYCYCLE_2, I2C_ACK_CURR, I2C_ADDMODE_7BIT,2);
  //I2C_Cmd(ENABLE);
  
   /* 使能I2C */
  I2C_Cmd(ENABLE);
   /*
        设置I2C时钟速度为400K
        I2C1_SLAVE_ADDRESS7  自身7位从地址(对10位地址不响应)
        I2C_DUTYCYCLE_2  时钟占空比 1:2
        I2C_ACK_CURR 收到一个字节后(匹配的地址字节或者数据字节)后返回应答。
        I2C_ADDMODE_7BIT  从机地址为7位
        16  当前系统时钟速度,单位MHz
        */
  I2C_Init(IICSPEED, 0xa0, I2C_DUTYCYCLE_2, I2C_ACK_CURR, I2C_ADDMODE_7BIT, 2);
        //RDA5807P_Intialization();
}

/**************************实现函数********************************************
*函数原型: unsigned char OperationRDAFM_2w(unsigned char operation, unsigned char *data, unsigned char numBytes)
*功  能: 读或者写数据到RDA5807P
operation 功能选择 读READ 或者写
data 读或者写的数据指针
numBytes 需要读或者写numBytes个字节
*******************************************************************************/
unsigned char OperationRDAFM_2w(unsigned char operation, unsigned char *data, unsigned char numBytes)
{
        unsigned char j;
  /* Send STRAT condition */
  I2C_GenerateSTART(ENABLE);

  /* Test on EV5 and clear it */
  while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));  

    if(operation == READ)
             I2C_Send7bitAddress(Radio_Address, I2C_DIRECTION_RX);
    else
             I2C_Send7bitAddress(Radio_Address, I2C_DIRECTION_TX);
  
  /* Test on EV6 and clear it */
  while(!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
        I2C_ClearFlag(I2C_FLAG_ADDRESSSENTMATCHED);

for(j = 0; j < numBytes; j++, data++)
{
        if(operation == READ)
        {

    /* Test on EV7 and clear it */
    //if(I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_RECEIVED))  
    while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_RECEIVED));
      /* Read a byte */
      *data = I2C_ReceiveData();  
                       
                if(j == (numBytes -1))
    {
      /* Disable Acknowledgement */
      I2C_AcknowledgeConfig(I2C_ACK_NONE);
      
      /* Send STOP Condition */
      I2C_GenerateSTOP(ENABLE);
    }

        }
        else {
                I2C_SendData(*data);
   /* Send the byte to be written */
  /* Test on EV8 and clear it */
  while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));
        }
       
}
  /* Send STOP condition */
  I2C_GenerateSTOP(ENABLE);
      return 1;
}








/**************************实现函数********************************************
*函数原型: void RDA5807P_Init(void)
*功  能: 初始化RDA5807P
*******************************************************************************/
void  RDA5807P_Init(void)
{
  
/* OperationRDAFM_2w(WRITE, RDA5807P_reg, 8);  //上电
  RDA5807P_reg[1] |= 0x02;
  delayms(50);
  
  OperationRDAFM_2w(WRITE, RDA5807P_reg, 8); //软件复位
  RDA5807P_reg[1] &= ~(0x02);
  delayms(50);
  
  OperationRDAFM_2w(WRITE, RDA5807P_reg, 8); //上电*/
  RDA5807P_reg[1] = 0x02;//软复位
  OperationRDAFM_2w(WRITE, RDA5807P_reg, 2);
  delayms(5);
  
  RDA5807P_reg[1] = 0x01;
  OperationRDAFM_2w(WRITE, RDA5807P_reg, 8);//上电
  
}
/**************************实现函数********************************************
*函数原型: void RDA5807P_PowerOffProc(void)
*功  能: 开机,关机RDA5807
*******************************************************************************/
void  RDA5807P_Power_Off_ON(void)
{
  static unsigned char flag = 0;
  flag ++;
  if(flag == 1)
  {
   RDA5807P_reg[1] &= (~1);
  }
  else if(flag == 2)
       {
          RDA5807P_reg[1] |= 1;
          RDA5807P_SetFreq(9210);
          flag = 0;   
       }
  
  OperationRDAFM_2w(WRITE, RDA5807P_reg, 2);
}

/**************************实现函数********************************************
*函数原型: void RDA5807P_Mute(unsigned char mute)
*功  能: 静音RDA5807
*******************************************************************************/
void RDA5807P_Mute(unsigned char vol_mute)
{
  if(vol_mute == mute)
          RDA5807P_reg[0] &= ~(1<<6);
  else if(vol_mute == NO_mute)
          RDA5807P_reg[0] |= 1<<6;

  OperationRDAFM_2w(WRITE, RDA5807P_reg, 2);
  delayms(50);    //delayms 50 ms
}

/**************************实现函数********************************************
*函数原型: unsigned int RDA5807P_FreqToChan(unsigned int frequency)  
*功  能: 通过频率设置信道chan
*******************************************************************************/
unsigned int RDA5807P_FreqToChan(unsigned int frequency)
{
  unsigned char channelSpacing;
  unsigned int bottomOfBand;
  unsigned int channel;

  if ((RDA5807P_reg[3] & 0x0c) == 0x00)
          bottomOfBand = 8700;
  else if ((RDA5807P_reg[3] & 0x0c) == 0x04)       
          bottomOfBand = 7600;
  else if ((RDA5807P_reg[3] & 0x0c) == 0x08)       
          bottomOfBand = 7600;       
  if ((RDA5807P_reg[3] & 0x03) == 0x00)
          channelSpacing = 10;
  else if ((RDA5807P_reg[3] & 0x03) == 0x01)
          channelSpacing = 20;
  else if ((RDA5807P_reg[3] & 0x03) == 0x02)
          channelSpacing = 5;
  channel = (frequency - bottomOfBand) / channelSpacing;
  return (channel);//10位的2进制数
}
/**************************实现函数********************************************
*函数原型: unsigned int RDA5807P_ChanToFreq(unsigned int chan)
*功  能: 通过信道chan设置频率
*******************************************************************************/
unsigned int RDA5807P_ChanToFreq(unsigned int chan)
{
  unsigned char channelSpacing;
  unsigned int bottomOfBand;
  unsigned int freq;

  if ((RDA5807P_reg[3] & 0x0c) == 0x00)
          bottomOfBand = 8700;
  else if ((RDA5807P_reg[3] & 0x0c) == 0x04)       
          bottomOfBand = 7600;
  else if ((RDA5807P_reg[3] & 0x0c) == 0x08)       
          bottomOfBand = 7600;       
  if ((RDA5807P_reg[3] & 0x03) == 0x00)
          channelSpacing = 10;
  else if ((RDA5807P_reg[3] & 0x03) == 0x01)
          channelSpacing = 20;
  else if ((RDA5807P_reg[3] & 0x03) == 0x02)
          channelSpacing = 5;
  freq = bottomOfBand + chan * channelSpacing;

  return (freq);
}

/**************************实现函数********************************************
*函数原型: void RDA5807P_SetFreq( unsigned int curFreq )
*功  能: 频率设置 调用RDA5807P_FreqToChan函数
*******************************************************************************/
void RDA5807P_SetFreq( unsigned int curFreq )
{   
  unsigned int curChan;
  
  curChan=RDA5807P_FreqToChan(curFreq);
  
  //SetNoMute
  RDA5807P_reg[0] |=        1<<7;
  RDA5807P_reg[2]=curChan>>2;
  RDA5807P_reg[3]=(((curChan&0x0003)<<6)|TUNE) | (RDA5807P_reg[3]&0x0f);        //set tune bit
  OperationRDAFM_2w(WRITE, RDA5807P_reg, 4);
  delayms(50);     //Delay five ms
  RDA5807P_reg[3] = RDA5807P_reg[3] & 0xef;
  curr_fre_chan();
}
/**************************实现函数********************************************
*函数原型: static void curr_fre_chan(void)
*功  能: 保存当前频点及chan值
*******************************************************************************/
static void curr_fre_chan(void)
{
  Currchan = ((((unsigned int)( RDA5807P_reg[2])<<8) | (RDA5807P_reg[3]&0xc0))>>6);//保存当前频点
  CurrFrequency = Currchan * 10 + 8700;
}

/**************************实现函数********************************************
*函数原型: unsigned char RDA5807P_GetSigLvl( unsigned int curf )
*功  能: 返回当前频率下的RSSI
*******************************************************************************/
unsigned char RDA5807P_GetSigLvl( void )
{   
  unsigned char RDA5807P_reg_data[4]={0};       
  
  OperationRDAFM_2w(READ,RDA5807P_reg_data, 4);
      delayms(50);    //Dealy 50 ms
  return  (RDA5807P_reg_data[2]>>1);  /*返回rssi*/
}

/**************************实现函数********************************************
*函数原型: void RDA5807P_SetVolumeLevel(unsigned char level)
*功  能: 声音大小调节
*******************************************************************************/
void RDA5807P_SetVolumeLevel(unsigned char level)
{
  unsigned char RDA5807P_reg_data[8];
  unsigned char i = 0;
  unsigned char vol;//当前声音大小
  for (i=0;i<8;i++)
      RDA5807P_reg_data[i] = RDA5807P_reg[i];
  
  vol = (RDA5807P_reg_data[7] & 0x0f);
  
  if(vol_add == level)//声音增加
    if(vol == vol_max)
      RDA5807P_reg_data[7] = ( RDA5807P_reg_data[7] & 0xf0 )|vol;
    else
      RDA5807P_reg_data[7] = ( RDA5807P_reg_data[7] & 0xf0 )|(++vol);
        
  else if(vol_dec == level)//声音减小
          if(vol == vol_min)
            RDA5807P_reg_data[7] = ( RDA5807P_reg_data[7] & 0xf0 )|vol;
          else
            RDA5807P_reg_data[7] = ( RDA5807P_reg_data[7] & 0xf0 )|(--vol);

/* for (i=0;i<8;i++)
      RDA5807P_reg[i] = RDA5807P_reg_data[i];*/
  RDA5807P_reg[7] = RDA5807P_reg_data[7];//保存当前VOL
  
  RDA5807P_reg_data[3] &= (~(TUNE));

  OperationRDAFM_2w(WRITE, RDA5807P_reg_data, 8);
  delayms(50);    //Dealy 50 ms
}



i2c写正常,读的时候,第一次正常,第二次就不正常了,找不到错误呀,帮忙找下吧,谢谢大虾们了!
沙发
machao070|  楼主 | 2015-3-10 23:09 | 只看该作者
自己先顶一个。还有就是用的是复位后的hsi  2M

使用特权

评论回复
板凳
machao070|  楼主 | 2015-3-10 23:10 | 只看该作者
本帖最后由 machao070 于 2015-3-10 23:54 编辑

#ifndef _radio_h_
#define _radio_h_


//typedef unsigned char           uint8;
//typedef unsigned short int      uint16;
//typedef short int               int16;


//RA5807
#define Radio_WAddress 0x20
#define Radio_RAddress 0x21
#define Radio_Address 0x20

#define READ 1
#define WRITE 0

#define I2C_ACK  1
#define I2C_NACK 0

#define vol_add 1
#define vol_dec 0
#define vol_max 15
#define vol_min 0
#define mute 1
#define NO_mute 0

#define seek_up 1
#define seek_down 0
#define SEEKUP 0x02
#define SEEKDOWN (~SEEKUP)
#define SEEKON 0x01
#define TUNE 0x10
#define STC 0x40

#define READ_num 4
#define WRITE_num 8

//#define I2CRaido_Speed 400000
//#define I2CRaido_SLAVE_ADDRESS7 0xA0

static unsigned int CurrFrequency;

static void delayms(uint16_t nCount);

/***************************************************
RDA5807P interfaces
****************************************************/
extern void RDA5807P_Init(void);//初始化RDA5807
extern void  RDA5807P_Power_Off_ON(void);//开机关机RDA5807

extern void RDA5807P_Mute(unsigned char vol_mute);//静音RDA5807
unsigned int RDA5807P_FreqToChan(unsigned int frequency);//通过频率设置信道chan
unsigned int RDA5807P_ChanToFreq(unsigned int chan);//通过信道chan设置频率
extern void RDA5807P_SetFreq( unsigned int curFreq );//频率设置 调用RDA5807P_FreqToChan函数
static void curr_fre_chan(void);
extern unsigned char RDA5807P_GetSigLvl( void );//返回当前频率下的RSSI
extern void RDA5807P_SetVolumeLevel(unsigned char level);//声音大小调节level==vol_add增加;level==vol_dec减小

static unsigned char RDA5807P_reg[];



/*I2C interface*/
#define IICSPEED 400000       //100K速度,时钟速度至少1M,400K速度,时钟速度至少4M

extern void InitIIC(void);
unsigned char OperationRDAFM_2w(unsigned char operation, unsigned char *data, unsigned char numBytes);


#endif
/******************* (C) COPYRIGHT 2014 LENCHIMCU.TAOBAO.COM ******************/

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

6

帖子

0

粉丝