CC2530移植TSL2591过程(模拟IIC信号)

        最近用到TSL2591,并需要将检测数据完成点对点无线传输,其核心是基于Zstack协议栈利用CC2430模拟IIC信号,与传感器通信,由于之前有CC2530的开发经验,对ZSTACK协议栈也相对熟悉,觉得应该不是一件难事,开始做的时候才发现一步一坑。

        首先就是开发环境的问题,由于CC2430这个工程文件用的是低版本的环境创建的,之前开发CC2530时用的IAR版本与此不兼容。

 

        不得以在网上找到了IAR7.20H,按照步骤安装,破解,然后打开CC2430带有Zstack协议栈的工程,将开发板通过SmartRF与PC相连,准备测试代码,点击debugger,一直显示没有发现设备,反复确认驱动已安装的情况下,开始怀疑是不是其他问题。

         也是网上搜有没有相同的情况,然后找到一个说明文档发现可能是系统的问题,其实可以安装一个XP的虚拟机,但到这一步,花在配置环境上的时间就已经折磨我够久的了,心态爆炸,准备更改方案,换CC2530。

         ​​​换到CC2530这个芯片,移植的过程还是挺舒服的,参照正点原子IIC例程,写了基于CC2530的模拟IIC程序,具体程序如下:

/*******************************************************************************
* File         : IIC.h
* Description  : IIC
* Version      : v0.1
* Author       : Newbit_Msming
* Date         : 2018/6/13
* Change Logs  :
*******************************************************************************/
#ifndef _IIC_H_
#define _IIC_H_
/*******************************************************************************
 * INCLUDES
 */
/*******************************************************************************
 * MACROS
 */
 
/*******************************************************************************
 * CONSTANTS
 */
 
/*******************************************************************************
 * TYPEDEFS
 */

/*******************************************************************************
 * GLOBAL VARIABLES
 */
/*******************************************************************************
 * EXTERNAL VARIABLES
 */
/*******************************************************************************
 * EXTERNAL FUNCTIONS
 */
/*******************************************************************************
 * LOCAL VARIABLES
 */

#include "ioCC2530.h"
#include "HalHardwareApi_CC2530.h"
#include "HalHardwareDefine_CC2530.h"
#include "stdio.h"
#include "hal_types.h"
#include "DEV_Config.h"



#define SDA_PIN            P1_2
#define SDA_GEN()          HAL_GEN_P12()
#define SDA_INPUT()        HAL_INPUT_P12()
#define SDA_OUTPUT()       HAL_OUTPUT_P12()
#define SDA_PULL_UP()      HAL_PULL_UP_P12()
#define SDA_HIGH()         HAL_SET_P12()
#define SDA_LOW()          HAL_CLR_P12()
   
#define SCL_PIN            P1_1
#define SCL_GEN()          HAL_GEN_P11()
#define SCL_INPUT()        HAL_INPUT_P11()
#define SCL_OUTPUT()       HAL_OUTPUT_P11()
#define SCL_HIGH()         HAL_SET_P11()
#define SCL_LOW()          HAL_CLR_P11()
/*******************************************************************************
*为了代码的高效性建议你使用以下的宏进行配置中断,不建议使用 vHAL_DioWakeEnable()
********************************************************************************/
#define SCL_INT_ENABLE()    st( P1IEN |= BV(1); \
                                P1IFG &= ~BV(1);\
                                IEN2 |= BV(4);  \
                                EA = TRUE;)
#define SCL_INT_RISINGEDGE()      st( PICTL &= ~BV(1);)  
#define SCL_INT_DISABLE()   st( P1IEN &= ~BV(1); P1IFG &= ~BV(1);)   
#define SCL_INT_FLAG        BV(1) 

#define SDA_INT_ENABLE()    st( P1IEN |= BV(2); \
                                P1IFG &= ~BV(2);\
                                IEN2 |= BV(4);  \
                                EA = TRUE;)
#define SDA_INT_FALLINGEDGE()      st( PICTL |= BV(1);)  
#define SDA_INT_DISABLE()          st( P1IEN &= ~BV(2); P1IFG &= ~BV(2);)   
#define SDA_INT_FLAG               BV(2) 

extern void vDelay_us(uint16 u16us);
extern void vDelay_ms(uint16 u16ms);
extern void IIC_Start (void);
extern void IIC_Stop (void);



extern uint8 IIC_Wait_Ack(void);

extern void IIC_Ack (void);
extern void IIC_NAck (void);
void IIC_Write_Byte(uint8 txd);
unsigned  char IIC_Read_Byte(void);
uint8 Write_Device_Addr(uint8 addr);
uint8 Device_Read_One_Byte(uint8 IC_Addr,uint8 Addr);
void Device_Write_One_Byte(uint8 IC_Addr,uint8 Addr,uint8 data);
void Device_Read_Bytes(uint8 IC_Addr,uint8 Addr,uint8 *buf,uint8 len);
void Device_Write_Bytes(uint8 IC_Addr,uint8 Addr,uint8 *buf,uint8 len);





void vIIC_WriteData(uint8 u8Data);

extern bool bIIC_GetAck (void);
extern void vIIC_Init (void);
extern void vIIC_WriteOneByte (uint8 u8Data);
extern uint8 u8IIC_ReadOneByte (void);
void IIC_Init(void);
void vIIC_SendAck (void);
void vIIC_SendNAck (void);
uint8 u8IIC_ReadData(void);

uint8 u8IIC_ReadData(void);
void vIIC_Reset (void);
void Device_Write_Bytes(uint8 IC_Addr,uint8 Addr,uint8 *buf,uint8 len);
#endif

/*******************************************************************************
   Copyright 2018 Newbit Studio. All rights reserved.
*******************************************************************************/


void I2C_Init(void);
/*******************************************************************************
* File         : IIC.c
* Description  : IIC Drivers
* Version      : v0.1
* Author       : Newbit_Msming
* Date         : 2018/3/29
* Change Logs  :
*******************************************************************************/
/*******************************************************************************
 * INCLUDES
 */
#include "IIC.h"
#include "OnBoard.h"

/*******************************************************************************
 * MACROS
 */
 
/*******************************************************************************
 * CONSTANTS
 */
 
/*******************************************************************************
 * TYPEDEFS
 */
 
/*******************************************************************************
 * GLOBAL VARIABLES
 */
/*******************************************************************************
 * EXTERNAL VARIABLES
 */
/*******************************************************************************
 * EXTERNAL FUNCTIONS
 */
/*******************************************************************************
 * LOCAL VARIABLES
 */
/*  xus延迟  */
void vDelay_us(uint16 u16us)    
{      
  while(u16us--)
  {
    MicroWait (1);
  }
}


/*  xms延时  */
void vDelay_ms(uint16 u16ms)	
{						
   while(u16ms--)
   {
      vDelay_us(1000);
   }					
}
  
/*******************************************************************************  
 * Function:   vIIC_Start
 * Description:   IIC启动时序
 * Input parameter:   
 * Return parameter:   
 * Author: Newbit_Msming      
 * Date@@2018/5/11    
 * Other:  
*******************************************************************************/  
void IIC_Start (void)
{
  SDA_GEN();
  SCL_GEN();
  SDA_OUTPUT();
  SCL_OUTPUT();
  SDA_PULL_UP();
    
  SDA_HIGH(); 
  SCL_HIGH(); //拉高时钟线和数据线

  vDelay_us(1);                      //延时
  SDA_LOW();  		//产生下降沿
  vDelay_us(1);                 		//延时
  SCL_LOW();        //拉低时钟线
  vDelay_us(1);
}

  
/*******************************************************************************  
 * Function:   vIIC_Stop
 * Description:   IIC停止时序
 * Input parameter:   
 * Return parameter:   
 * Author: Newbit_Msming      
 * Date@@2018/5/11    
 * Other:  
*******************************************************************************/   
void IIC_Stop (void)
{
  SDA_OUTPUT();
  SCL_LOW();        //拉低时钟线
  SDA_LOW();

  vDelay_us(1);                 //延时

  SCL_HIGH();                   //拉高时钟线
  vDelay_us(1);                 //延时
  SDA_HIGH();                      //产生上升沿
  vDelay_us(1);                 //延时
}
  


uint8 IIC_Wait_Ack(void)
{
    unsigned char ack = 0;

    SDA_INPUT(); 
    SDA_HIGH(); vDelay_us(1);  
    SCL_HIGH(); vDelay_us(1);
    while(SDA_PIN)
    {
    ack++;
    if(ack>250)
      {
        IIC_Stop();
        return 1;
      }
    }
    SCL_LOW();   
    return 0;
}


/*******************************************************************************  
 * Function:   vIIC_Reset
 * Description:   释放IIC总线
 * Input parameter:   
 * Return parameter:   
 * Author: Newbit_Msming      
 * Date@@2018/5/11    
 * Other:  
*******************************************************************************/  
void vIIC_Reset (void)
{
  SDA_GEN();
  SCL_GEN();
  SDA_OUTPUT();
  SCL_OUTPUT();
  SDA_HIGH();    
  SCL_HIGH();    
}
  
void IIC_Ack(void)
{
    SCL_LOW();
    SDA_OUTPUT();
    SDA_LOW();
    vDelay_us(2);
    SCL_HIGH();
    vDelay_us(2);
    SCL_LOW();
}

void IIC_NAck(void)
{
    SCL_LOW();
    SDA_OUTPUT();
    SDA_HIGH();
    vDelay_us(2);
    SCL_HIGH();
    vDelay_us(2);
    SCL_LOW();
}


void IIC_Write_Byte(uint8 u8Data)
{
   SDA_OUTPUT();
   SCL_LOW();  
   for(uint8 i=0; i<8; i++)
   {
      if(u8Data & 0x80)
         SDA_HIGH(); 
      else
         SDA_LOW(); 
      
      vDelay_us(1);
      SCL_HIGH();
      vDelay_us(1);
      SCL_LOW();  
      vDelay_us(1);
      u8Data <<= 1;
   }
   
  SDA_HIGH(); 
  SCL_HIGH(); //
}
  

uint8 IIC_Read_Byte(void)
{
  uint8 u8Data =0;
  uint8 i =0;
  
  SCL_LOW();
  vDelay_us(1);
  SDA_INPUT();
  for(i=0;i<8;i++)
  {
    u8Data <<= 1;
    SCL_HIGH();
    if(SDA_PIN)
      u8Data |= 0x01;
	
    vDelay_us(1);
    SCL_LOW();  
    vDelay_us(1);
  }
  return u8Data;
}

  
uint8 Device_Read_One_Byte(uint8 IC_Addr,uint8 Addr)
{
	uint8 dat;

	IIC_Start();
	IIC_Write_Byte(IC_Addr);
	IIC_Wait_Ack();
	printf("1");
	IIC_Write_Byte(Addr);
	IIC_Wait_Ack();

	IIC_Start();
	IIC_Write_Byte((IC_Addr) | 0x01);
	IIC_Wait_Ack();

	dat = IIC_Read_Byte();
	IIC_NAck();
	IIC_Stop();
	return dat;
}

void Device_Write_One_Byte(uint8 IC_Addr,uint8 Addr,uint8 data)//
{
	
	IIC_Start();
	IIC_Write_Byte(IC_Addr);
	IIC_Wait_Ack();

	IIC_Write_Byte(Addr);
	IIC_Wait_Ack();

	IIC_Write_Byte(data);
	IIC_Wait_Ack();

	IIC_Stop();
}


void Device_Read_Bytes(uint8 IC_Addr,uint8 Addr,uint8 *buf,uint8 len)
{
	IIC_Start();
	IIC_Write_Byte(IC_Addr);
	IIC_Wait_Ack();

	IIC_Write_Byte(Addr);
	IIC_Wait_Ack();

	IIC_Start();
	IIC_Write_Byte((IC_Addr) | 0x01);
	IIC_Wait_Ack();

	while(len > 1)
	{
		*buf++ = IIC_Read_Byte();
		IIC_Ack();
		len--;
	}
	*buf = IIC_Read_Byte();
	IIC_NAck();
	IIC_Stop();	
}

void Device_Write_Bytes(uint8 IC_Addr,uint8 Addr,uint8 *buf,uint8 len)
{
	while(len > 0)
	{
		IIC_Start();
		IIC_Write_Byte(IC_Addr);
		IIC_Wait_Ack();

		IIC_Write_Byte(Addr++);
		IIC_Wait_Ack();

		IIC_Write_Byte(*buf++);
		IIC_Wait_Ack();

		IIC_Stop();
		vDelay_us(10000);
		len--;
	}
}


void I2C_Init(void)
{
	
        SCL_OUTPUT();
	SDA_OUTPUT();

	SCL_HIGH();
	SCL_LOW();

	SDA_HIGH();
	SDA_LOW();
	
	vDelay_ms(1);
	
	//SHT30_Periodic_Measure(SHT30_PERIODOC_H_MEASURE_1S);
  
}



/*******************************************************************************  
 * Function:   vIIC_SendAck
 * Description:   IIC 发送ack
 * Input parameter:   
 * Return parameter:   
 * Author: Newbit_Msming      
 * Date@@2018/5/11    
 * Other:  
*******************************************************************************/  
void vIIC_SendAck (void)
{
  SDA_OUTPUT();
 
  SDA_LOW(); //ACK
  SCL_HIGH();     
  vDelay_us(1);
  SCL_LOW();    
  vDelay_us(1);
  SDA_HIGH(); 
  vDelay_us(1);
}

/*******************************************************************************  
 * Function:   vIIC_SendNAck
 * Description:   IIC 发送 no ack
 * Input parameter:   
 * Return parameter:   
 * Author: Newbit_Msming      
 * Date@@2018/5/11    
 * Other:  
*******************************************************************************/  
void vIIC_SendNAck (void)
{
  SDA_OUTPUT();

  SDA_HIGH(); //NACK
  SCL_HIGH();     
  vDelay_us(1);
  SCL_LOW();    
  vDelay_us(1);
  SDA_HIGH(); 
  vDelay_us(1);
}
/*******************************************************************************  
 * Function:   bIIC_GetAck
 * Description:   检查是否有应答
 * Input parameter:   
 * Return parameter:   bool, 1 is ack, 0 is no ack
 * Author: Newbit_Msming      
 * Date@@2018/5/11    
 * Other:  
*******************************************************************************/    
bool bIIC_GetAck (void)
{ 
  SDA_INPUT();
  vDelay_us(1);
  if(!SDA_PIN)//有应答
  {
      vDelay_us(1);
      SCL_LOW(); 
      return 1;
  }
  else
  {
      SCL_LOW(); 
      printf(" no ack!\n");
      return 0;
  }
}
  
/*******************************************************************************  
 * Function:   IIC_Init
 * Description:   初始化IIC
 * Input parameter:   
 * Return parameter:   
 * Author: Newbit_Msming      
 * Date@@2018/5/11    
 * Other:  
*******************************************************************************/  
void IIC_Init(void)
{
  SDA_GEN();
  SCL_GEN();
  SDA_OUTPUT();
  SCL_OUTPUT();
  SDA_HIGH();    
  SCL_HIGH();    
}
  
/*******************************************************************************  
 * Function:   vIIC_WriteData
 * Description:   写数据
 * Input parameter:   uint8 u8Data
 * Return parameter:   
 * Author: Newbit_Msming      
 * Date@@2018/5/11    
 * Other:  
*******************************************************************************/  
void vIIC_WriteData(uint8 u8Data)
{
   SDA_OUTPUT();
   SCL_LOW();  
   for(uint8 i=0; i<8; i++)
   {
      if(u8Data & 0x80)
         SDA_HIGH(); 
      else
         SDA_LOW(); 
      
      vDelay_us(1);
      SCL_HIGH();
      vDelay_us(1);
      SCL_LOW();  
      vDelay_us(1);
      u8Data <<= 1;
   }
   
  SDA_HIGH(); 
  SCL_HIGH(); //
}
  
/*******************************************************************************  
 * Function:   u8IIC_ReadData
 * Description:   读取数据
 * Input parameter:   
 * Return parameter:   uint8 读到的数据
 * Author: Newbit_Msming      
 * Date@@2018/5/11    
 * Other:  
*******************************************************************************/  
uint8 u8IIC_ReadData(void)
{
  uint8 u8Data =0;
  uint8 i =0;
  
  SCL_LOW();
  vDelay_us(1);
  SDA_INPUT();
  for(i=0;i<8;i++)
  {
    u8Data <<= 1;
    SCL_HIGH();
    if(SDA_PIN)
      u8Data |= 0x01;
	
    vDelay_us(1);
    SCL_LOW();  
    vDelay_us(1);
  }
  return u8Data;
}

        然后找商家要了传感器的驱动代码,这个代码是基于32位处理器的,首先用STM32跑了一下,得出以下结果:

        然后就是往工程里面加移植代码了,这个代码可移植性很强,改下相应的IIC接口函数,以及相应的引脚定义即可,然后得出以下结果:

         Lux和红外线数据好像没什么问题,能见度和光谱数据好像太小了,这就涉及到之前提到的,商家给的例程代码是基于32位处理器的,而CC2530是集成了一个增强型的8051单片机,是16位处理器,所以当要传输8位数字时,long变量就不够用了,所以将光谱和能见度的相关函数和变量改为long long再次运行程序,得到正确结果。

 

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值