加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

cc2530下载程序

发布时间:2020-12-15 06:29:38 所属栏目:百科 来源:网络整理
导读:? ?外部mcu通过调试接口对CC2530进行编程,基本的功能函数如下: p //--cc2530 Debug commands--- #define CMD_CHIP_ERASE?? 0x10 #define CMD_WR_CONFIG??? 0x18 #define CMD_RD_CONFIG??? 0x20 #define CMD_READ_STATUS? 0x30 #define CMD_RESUME?????? 0x
?

?外部mcu通过调试接口对CC2530进行编程,基本的功能函数如下:
<p>
//--cc2530 Debug commands---
#define CMD_CHIP_ERASE?? 0x10
#define CMD_WR_CONFIG??? 0x18
#define CMD_RD_CONFIG??? 0x20
#define CMD_READ_STATUS? 0x30
#define CMD_RESUME?????? 0x48
#define CMD_DEBUG_INSTR? 0x50
#define CMD_BURST_WRITE? 0x80
#define CMD_GET_CHIP_ID? 0x68
//---------------------------

#define LOBYTE(w) ((unsigned char)(w))
#define HIBYTE(w) ((unsigned char)(((unsigned short)(w) >> 8) & 0xFF))

#define FCTL??????? 0x6270
#define FADDRL????? 0x6271
#define FADDRH????? 0x6272
#define FWDATA????? 0x6273

#define DBGDATA???? 0x6260?//DMA register
#define X_DMAARM??? 0x70D6?? //? DMA Channel Arm???
#define X_DMAREQ??? 0x70D7
#define X_DMA1CFGL? 0x70D2?? //? DMA Channel 1-4 Configuration Address Low Byte
#define X_DMA1CFGH? 0x70D3?? //? DMA Channel 1-4 Configuration Address High Byte??

// Buffers
#define ADDR_BUF0??????? 0x0000 // 1K,存放来自调试接口的数据,长度为1K,0x0000--0x03FF
#define ADDR_DMA_DESC??? 0x0400 // 从0x0400地址开始存放16字节的数据
#define PROG_BLOCK_SIZE? 0xFD

// DMA Channels
#define CH_DBG_TO_BUF0?? 0x02?//使用通道1
#define CH_BUF0_TO_FLASH 0x04?//使用通道2

//--mcu使用的下载接口引脚,可以根据具体的mcu修改----
sbit DcPin?= PADBUF^5;
sbit DdPin?= PADBUF^3;
sbit ResetPin?= PADBUF^1;

sbit DcPinDir? = PADCON1^5;
sbit DdPinDir? = PADCON1^3;
sbit ResetPinDir = PADCON1^1;
//-------------------------------------------------------------------------

void Delayus(unsigned short us)
{
??????? while(us--)
??????? {
??????????????? _nop_();
??????????????? _nop_();
??????????????? _nop_();
??????????????? _nop_();
??????????????? _nop_();
??????????????? _nop_();
??????????????? _nop_();
??????????????? _nop_();
??????? }
}

/*********************************************************************************
?* Writes a byte on the debug interface. Sets the direction of port 0 at the end.
?* DdPin must be output when this function is called.
?* param:
?? num---Byte to write
? dir---Direction of all pins on port 0 that is to be written at the end.
*********************************************************************************/
void cc2530_Write_Debug_Byte(unsigned char num,unsigned char dir)
{
?unsigned char i;
?
?for (i=0; i<8; i++)
?{??
??DdPin = (num&0x80) ? 1 : 0;?????
??DcPin = 1;
??_nop_();
??_nop_();
??_nop_();
??_nop_();
??_nop_();???
??num <<= 1;???????
??DcPin = 0; //在时钟的下降沿把数据输出???? ??????????
?}
?
?DdPinDir = dir;??
}

/*****************************************************
?* Reads a byte from the debug interface.
?* Requires DdPin to be input when function is called.
?* return:
????? Byte read
*****************************************************/
unsigned char cc2530_Read_Debug_Byte(void)
{
?unsigned char i,num;
???
?for (i = 0; i < 8; i++)
?{??
??DcPin = 1; // clock out data??
??num <<= 1;??
??num |= DdPin;??
??DcPin = 0;??
?}
???
?return num;
}

/**********************************************************************************************************************
?* brief Issues a command on the debug interface. Only commands that return one
?* param:
?? cmd---Command byte
? input_bytes---Pointer to the array of input bytes
? num_input_bytes---The number of input bytes
?* return Data:
? returned by command
**********************************************************************************************************************/
unsigned char cc2530_Write_Debug_Command(unsigned char cmd,unsigned char *input_bytes,unsigned short num_input_bytes)
{??
?unsigned short i;??
?unsigned char output = 0;??
?unsigned char dir;
???????
?dir = (num_input_bytes == 0) ? 0 : 1;//如果没有输入字节,把方向改为输入??
?cc2530_Write_Debug_Byte(cmd,dir);
?????
?for(i = 0; i < num_input_bytes; i++)
?{??????
??dir = (i == num_input_bytes-1) ? 0 : 1;//在最后一个字节把方向改为输入??
??cc2530_Write_Debug_Byte(input_bytes[i],dir);??
?}
???????
?while( DdPin&1 ) //等待cc2530的引脚方向改变完成,拉低此引脚,说明cc2530已经准备好输出数据
?{??
??cc2530_Read_Debug_Byte();??
?}
?????
?output = cc2530_Read_Debug_Byte();
?
?//重新配置SDI引脚为输出
?DdPinDir = 1;

?return output;
}

/*************************************
* 读取cc2530的ID值
* 参数:
*?? buf:输出数据缓存,2个字节
*************************************/
void cc2530_Get_Id(unsigned char *buf)
{
?cc2530_Write_Debug_Byte(CMD_GET_CHIP_ID,0);

?while( DdPin&1 ) //等待cc2530的引脚方向改变完成,拉低此引脚,说明cc2530已经准备好输出数据
?{??
??cc2530_Read_Debug_Byte();??
?}
?????
?buf[0] = cc2530_Read_Debug_Byte();
?buf[1] = cc2530_Read_Debug_Byte();
}

/*************************************************************************
?* write a byte to the XDATA in the DUP

?* param:
?*??? address----XDATA address
?? values---the bytes to write
?*************************************************************************/
void cc2530_Write_Xdata_Memory(unsigned short address,unsigned char value)
{
?unsigned char instr[3];
?
?instr[0] = 0x90;??
?instr[1] = HIBYTE(address);??
?instr[2] = LOBYTE(address);??
?cc2530_Write_Debug_Command(CMD_DEBUG_INSTR | 3,instr,3); //MOV DPTR,#data16
?

?instr[0] = 0x74;?//把立即数送到寄存器A????
?instr[1] = value;????
?cc2530_Write_Debug_Command(CMD_DEBUG_INSTR | 2,2); //MOV A,#data
?
?instr[0] = 0xF0;?//把数据从寄存器A写入外部RAM????
?cc2530_Write_Debug_Command(CMD_DEBUG_INSTR | 1,1); //MOVX @DPTR,A
????
}

/**********************************************************************************************************
?* Writes a block of data to the XDATA region in the DUP
?* param:
????? address---XDATA start address
????? values---Pointer to the array of bytes to write
??? num_bytes---Number of bytes to write
***********************************************************************************************************/
void cc2530_Write_Xdata_Memory_Block(unsigned short address,const unsigned char *values,unsigned short num_bytes)
{
?unsigned char instr[3];
?unsigned short i;
?
?instr[0] = 0x90;??
?instr[1] = HIBYTE(address);??
?instr[2] = LOBYTE(address);??
?cc2530_Write_Debug_Command(CMD_DEBUG_INSTR | 3,#data16
?
?for (i = 0; i < num_bytes; i++)
?{
??instr[0] = 0x74;?//把立即数送到寄存器A????
??instr[1] = values[i];????
??cc2530_Write_Debug_Command(CMD_DEBUG_INSTR | 2,#data
??
??instr[0] = 0xF0;?//把数据从寄存器A写入外部RAM????
??cc2530_Write_Debug_Command(CMD_DEBUG_INSTR | 1,A
??
??instr[0] = 0xA3;?//增加数据指针????
??cc2530_Write_Debug_Command(CMD_DEBUG_INSTR | 1,1);//INC DPTR
?}
}

/***********************************************************
?* Read a byte from a specific address in XDATA in the DUP

?* param:
?*??? address----XDATA address

?* return Value
?*??? read from XDATA
?***********************************************************/
unsigned char cc2530_Read_Xdata_Memory(unsigned short address)
{
?unsigned char instr[3];

?instr[0] = 0x90;??
?instr[1] = HIBYTE(address);??
?instr[2] = LOBYTE(address);??
?cc2530_Write_Debug_Command(CMD_DEBUG_INSTR | 3,#data16??
?
?instr[0] = 0xE0;?//把外部RAM(16为地址)的值写入寄存器A??
?return cc2530_Write_Debug_Command(CMD_DEBUG_INSTR | 1,1); //MOVX A,@DPTR
}

/************************************************************************************************************
?* 读取cc2530 xdata区的数据
?* 参数:
?*?? address:xdata区地址
?*?? pOutBuf:输出数据缓存
?*?? num_bytes:要读取的数据长度
?* 返回值:
?*?? 无
?***********************************************************************************************************/
void cc2530_Read_Xdata_Memory_Block(unsigned short address,unsigned char *pOutBuf,unsigned short num_bytes)
{
?unsigned char instr[3];
?unsigned short i;

?instr[0] = 0x90;??
?instr[1] = HIBYTE(address);??
?instr[2] = LOBYTE(address);??
?cc2530_Write_Debug_Command(CMD_DEBUG_INSTR | 3,#data16
?
?for( i=0; i<num_bytes; i++ )
?{
??instr[0] = 0xE0;?//把外部RAM(16为地址)的值写入寄存器A??
??pOutBuf[i] = cc2530_Write_Debug_Command(CMD_DEBUG_INSTR | 1,@DPTR

??instr[0] = 0xA3;?//增加数据指针????
??cc2530_Write_Debug_Command(CMD_DEBUG_INSTR | 1,1); //INC DPTR
?}
}

/****************************************************
?* 写cc2530的sfr寄存器
?* 参数:
?*?? address:寄存器地址
?*?? value:要写入的值
?* 返回值:
?*?? 无
?***************************************************/
void cc2530_Write_Sfr(unsigned char address,unsigned char value)
{
?unsigned char instr[3];
?????
?instr[0] = 0x75;//移动一个立即数到直接地址,此处即把bank值写入寄存器address
?? ?instr[1] = address;
?instr[2] = value;
?cc2530_Write_Debug_Command(CMD_DEBUG_INSTR | 3,3); //MOV direct,#data
}

/****************************************************
?* 读取cc2530的sfr寄存器
?* 参数:
?*?? address:寄存器地址
?* 返回值:
?*?? 寄存器中的值
?***************************************************/
unsigned char cc2530_Read_Sfr(unsigned char address)
{
?unsigned char instr[2];
?
?instr[0] = 0xE5;//把寄存器0x9F中的值写入寄存器A
?? ?instr[1] = address;
?return cc2530_Write_Debug_Command(CMD_DEBUG_INSTR | 2,2);//MOV A,direct???
}

/********************************************************************
?* 依次把数据写入到调试接口
?* 参数:
?*?? buf:要写入的数据缓存
?*?? num_bytes:要写入的数据字节数
?********************************************************************/
void cc2530_Burst_Write(unsigned char *buf,unsigned char num_bytes)
{
?unsigned char i;
?
?cc2530_Write_Debug_Byte( CMD_BURST_WRITE,1 );??
?cc2530_Write_Debug_Byte( num_bytes,1 );
?
?for(i=0; i<num_bytes-1; i++)
?{
??cc2530_Write_Debug_Byte(buf[i],1); //
?}
?
?cc2530_Write_Debug_Byte(buf[i],0); // change dir. to input
?
?while( DdPin&1 )
?{
??cc2530_Read_Debug_Byte();
?}
?
?cc2530_Read_Debug_Byte(); // ignore output
?
?//重新配置SDI引脚为输出
?DdPinDir = 1;
}

/******************************************************************************************************************
* 往cc2530的flash中写入数据
* 参数:
*?? lAddr:flash中的线性地址
*?? buf:写入数据缓存
*?? num_bytes:要写入的字节数
* 返回值:
*?? 无
*******************************************************************************************************************/
void cc2530_Write_Code_Memory(unsigned long lAddr,unsigned char *buf,unsigned char num_bytes)
{????
?unsigned short sAddr;
??? ?unsigned char dma_desc[16] =
?{
??// Debug Interface -> Buffer 0 (Channel 1)??
??HIBYTE(DBGDATA),?? // src[15:8]??
??LOBYTE(DBGDATA),?? // src[7:0]
??
??HIBYTE(ADDR_BUF0),? // dest[15:8]??
??LOBYTE(ADDR_BUF0),? // dest[7:0]
??
??HIBYTE(PROG_BLOCK_SIZE),??
??LOBYTE(PROG_BLOCK_SIZE),
??
??31,????????????????????? // trigger DBG_BW??
??0x11,??????????????????? // increment destination
??
??// Buffer 0 -> Flash controller (Channel 2)
??HIBYTE(ADDR_BUF0),?? // src[15:8]??
??LOBYTE(ADDR_BUF0),?? // src[7:0]
??
??HIBYTE(FWDATA),??? // dest[15:8]??
??LOBYTE(FWDATA),??? // dest[7:0]
??
??HIBYTE(PROG_BLOCK_SIZE),
??
??18,???????????????????? // trigger FLASH??
??0x42,????????????????? // increment source???
?};//此处只配置了通道1与通道2,通道1把调试接口输入的数据搬移到ADD_BUF0开始的xdata空间,通道2把ADD_BUF0处的数据写入flash
?
?sAddr = (unsigned short)(lAddr>>2);//由于写入flash时是字(4字节)寻址的,用16位地址(64K)访问256k的空间,256K=64*4

?dma_desc[5] = dma_desc[13] = num_bytes;
?????
?// Write the 2 DMA descriptors??
?cc2530_Write_Xdata_Memory_Block(ADDR_DMA_DESC,dma_desc,16);// 16 bytes,从0x0400地址开始存放dma_desc数组中的数据
?????
?// Set the pointer to the DMA descriptors??
?cc2530_Write_Xdata_Memory(X_DMA1CFGH,HIBYTE(ADDR_DMA_DESC));??
?cc2530_Write_Xdata_Memory(X_DMA1CFGL,LOBYTE(ADDR_DMA_DESC));????
???
?cc2530_Write_Xdata_Memory(FADDRH,HIBYTE(sAddr));//设置flash的地址??
?cc2530_Write_Xdata_Memory(FADDRL,LOBYTE(sAddr));????
?????????
?cc2530_Write_Xdata_Memory(X_DMAARM,CH_DBG_TO_BUF0);//把数据从调试接口搬移到xdata区??
?cc2530_Burst_Write(buf,num_bytes);????
?
?// wait for write to finish??
?while(cc2530_Read_Xdata_Memory(FCTL) & 0x80);
?????
?// start programming current buffer??
?cc2530_Write_Xdata_Memory(X_DMAARM,CH_BUF0_TO_FLASH);??
?cc2530_Write_Xdata_Memory(FCTL,0x06); //把数据从xdata区写入flash中
?????
?// Programming last buffer in progress,wait until done??
?while(cc2530_Read_Xdata_Memory(FCTL) & 0x80);
}

/******************************************************************************************************************
* 读取cc2530flash中的代码
* 参数:
*?? sAddr:bank区中的地址值,其中bank0:0x0000--0x7FFF,bank1-bankn:0x8000--0xFFFF
*?? bank:对应的bank值
*?? pOutBuf:输出数据缓存
*?? num_bytes:要读取的字节数
* 返回值:
*?? 无
* 对应flash中的线性地址(linear address)与bank值和bank中的地址对应的计算公式如下:
* 如果sAddr<0x8000,linear address = sAddr;
* 如果sAddr>=0x8000,linear address = (sAddr&0x7fff) + bank*0x8000
*******************************************************************************************************************/
void cc2530_Read_Code_Memory(unsigned short sAddr,unsigned char bank,unsigned char num_bytes)
{?
?unsigned char i;
?unsigned char instr[3];
???????
?? ?instr[0] = 0x75;//移动一个立即数到直接地址,此处即把bank值写入寄存器0x9F
?? ?instr[1] = 0x9F;
?instr[2] = bank;
?cc2530_Write_Debug_Command(CMD_DEBUG_INSTR | 3,3);

?instr[0] = 0x90;??
?instr[1] = HIBYTE(sAddr);??
?instr[2] = LOBYTE(sAddr);??
?cc2530_Write_Debug_Command(CMD_DEBUG_INSTR | 3,3);
?
?for( i=0; i<num_bytes; i++)
?{
??instr[0] = 0xE4;?//清寄存器A????????
??cc2530_Write_Debug_Command(CMD_DEBUG_INSTR | 1,1);
??
??instr[0] = 0x93;?//把数据从外部RAM写入寄存器A????
??pOutBuf[i] = cc2530_Write_Debug_Command(CMD_DEBUG_INSTR | 1,1);
??
??instr[0] = 0xA3;?//增加数据指针????
??cc2530_Write_Debug_Command(CMD_DEBUG_INSTR | 1,1);
?}?
}

//配置下载主控器的编程引脚
void mcu_Init_Debug_Io()
{
?unsigned char debug_config;
?unsigned short X_CLKCONCMD = 0x70C6;
?unsigned short X_CLKCONSTA = 0x709E;

?//引脚方向性选择,初始化配置调试接口为输出
?DdPinDir = 1;//0->输入,1->输出
?DcPinDir = 1;
?ResetPinDir = 1;

?ResetPin = 1;?//初始化复位引脚为高电平
?DcPin = 0;?//初始化时钟电平为低电平
?DdPin = 0;
?Delayus(10);? ?//大约延时24us

?//在复位线拉低的情况下,输出两个clk
?ResetPin = 0;
?Delayus(10);

?DcPin = 1;
?_nop_();
?_nop_();
?_nop_();
?DcPin = 0;
?_nop_();
?_nop_();
?_nop_();

?DcPin = 1;
?_nop_();
?_nop_();
?_nop_();
?DcPin = 0;
?_nop_();
?_nop_();
?_nop_();

?Delayus(10);
?ResetPin = 1;??????

?debug_config = 0x22;??
?cc2530_Write_Debug_Command(CMD_WR_CONFIG,&debug_config,1);
?????
?// Switch to 32 Mhz and wait for it to be stable. This is recommended if??
?// 32 MHz crystal is available during programming. If 32 MHz crystal is??
?// not available,comment out these two lines.??
?cc2530_Write_Xdata_Memory(X_CLKCONCMD,0x80);??
?while(cc2530_Read_Xdata_Memory(X_CLKCONSTA) != 0x80);
}

//主控器通过调试接口擦除cc2530 void mcu_Erase_Cc2530() { ?cc2530_Write_Debug_Command(CMD_CHIP_ERASE,0);?? ?while(cc2530_Write_Debug_Command(CMD_READ_STATUS,0) & 0x80);//查询擦除是否完成,擦除完成后最高位清0 } </p>

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读