本帖最后由 莫道 于 2017-3-3 14:51 编辑
新手求助
我用CC2530 从外部输入数据通过DMA写入FLASH,第一次写能写进去,以后再写就不行了
代码如下:
/*********** flash ******/
//定义DMA通道配置数据结构,每个DMA通道配置由8个字节组成;
//#pragma bitfields=reversed//采用大端格式的意思是用于几位的意思
//通知编译器完成特定的操作
typedef struct {
uchar SRCADDRH; //Byte 0 通道源地址 高位[15:8]
uchar SRCADDRL; //Byte 1通道源地址 地位[7: 0]
uchar DESTADDRH; //Byte 2通道目标地址 高位[15:8],flash存储器不可直接写
uchar DESTADDRL; //Byte 3通道目标地址 低位[7: 0],flash存储器不可直接写
uchar LENH:5; //Byte 4 - Bit 4:0 DMA通道传送长度
uchar VLEN:3; //Byte 4 - Bit 7:5可变长度传送模式
uchar LENL; //Byte 5DMA通道传送长度
uchar TRIG:5; //Byte 6 - Bit 4:0; Timer 2, event pulse 1;选择要使用的DMA触发
uchar TMODE:2; //Byte 6 - Bit 6:5; Repeated single;DMA通道传送模式:重复单一模式
uchar WORDSIZE:1; //Byte 6 - Bit 7; Selects whether each DMA transfer is 8-bit (0) or 16-bit (1);传送长度8位还是16位
uchar PRIORITY:2; //Byte 7 - Bit 1:0;High, DMA has priority;DMA通道优先级:高
uchar M8:1; //Byte 7 - Bit 2 Use 7 LSB for transfer count;采用8th模式作为VLEN传送长度,仅应用在WORDSIZE =0且VLEN =000/111时;
uchar IRQMASK:1; //Byte 7 - Bit 3 Enable interrupt generation on DMA channel done;该通道的中断屏蔽
uchar DESTINC:2; //Byte 7 - Bit 5:4 Destination address increment mode (after each transfer);目标地址增量模式(传送之后)
uchar SRCINC:2; //Byte 7 - Bit 7:6 Source address increment mode (after each transfer);源地址增量模式(传送之后)
} DMA_DESC;
//#pragma bitfields=default //恢复默认的小端格式
/**********************************DMA 模式写数据************************************/
void WriteFlashDMA(uchar data[], int length, int flashadr)
{
//配置DMA通道每次传送一个字节
DMA_DESC dmaConfig0;//定义DMA通道
//MEMCTR|=0X07;//将bank 7 映射到Xdata区
dmaConfig0.SRCADDRH = ((int)data >> 8) & 0x00FF; //XData 存储data的高8位;
dmaConfig0.SRCADDRL = (int)data & 0x00FF; //存储data地址的低8位;
dmaConfig0.DESTADDRH = (((int)&FWDATA) >> 8) & 0x00FF; //存储写寄存器的地址的高8位
dmaConfig0.DESTADDRL = ((int)&FWDATA) & 0x00FF; //存储写寄存器的低8位;
dmaConfig0.VLEN = 0; //0=Fixed LEN Transfer//采用LEN作为传送长度
dmaConfig0.LENH = (length>>8) & 0x00FF; //Must be Divisible by 4 - NET_ADDR_SIZE=4//存储传送长度高5位
dmaConfig0.LENL = length & 0x00FF; //存储长度低8位;
dmaConfig0.WORDSIZE = 0; // 0=8 Bit;每个DMA传送采用8位传送
dmaConfig0.TMODE = 0; // 1=Block, 0=Single,传送模式为单一模式
dmaConfig0.TRIG = 18; // 0=Manual Via DMAREQ, 18=Flash;flash触发
dmaConfig0.SRCINC = 1; // 1=1 Byte//源地址增量模式为1字节/字
dmaConfig0.DESTINC = 0; // 0=0 Bytes (Always Write to FWDATA, No Need to Increment)目标地址增量模式0字节/字
dmaConfig0.IRQMASK = 0; //0=Disable Interrupts//禁止通道完成中断产生
dmaConfig0.M8 = 0; //0=Use All 8 Bits使用全部8位作为传送长度
dmaConfig0.PRIORITY = 2; //10(2)=High Priority优先级为DMA优先
//DMA模式写
while (FCTL & 0x80); //等待写或擦除状态被激活
/********* 存储写入flash页地址 ***********************************************/
FADDRH =(flashadr >> 10) & 0x00FF; // page size: 2048; select the flash page via FADDRH[7:1] bits//由于写入flash时是字(4字节)寻址的,所以存储高位需要右移2位;
FADDRL =(flashadr >> 2) & 0x00FF; //4字节寻址,存储要写入flash地址的低字节需要右移2位
//通道0配置地址
DMA0CFGH = (((int)&dmaConfig0) >> 8) & 0x00FF; //Pass DmaConfig0
DMA0CFGL = ((int)&dmaConfig0) & 0x00FF;
DMAIRQ = 0x01; //激活DMA通道0
DMAARM |= 0x01; //Arm the DMA Channel//通道0进去工作状态
FCTL |= 0x02; //Start Write
// while (!(DMAIRQ & 0x01)); //Wait Until Write Complete
// DMAIRQ &= 0xFE; //Clear Any DMA IRQ on Channel 0 - Bit 0
while (FCTL & (0x80)); //等待或者擦除状态激活
}
/***************flash 页擦除******************/
void Flash_PageErase(uchar byPage)
{
EA=0;
while(FCTL & 0x80); //等待闪存控制器整备好
FADDRH = byPage << 1; //选择擦除的页面
FCTL |= 0x01; //启动页面擦除
while(FCTL & 0x80); //等待擦除完成
EA=1;
}
/********flash 读数据到缓存buf中***************/
void Read_Flash_To_Buf(int read_adr, uchar *buf, uchar num_bytes)//read_adr=flashadr+0x8000
{
unsigned char i;
for( i=0; i<num_bytes; i++)
{
buf=*(volatile char *)(read_adr + i);
}
//外部写入
case HEAD3:
memcpy(recv_buf,rf_rx_buf,sizeof(rf_rx_buf));
Flash_PageErase(8); //擦除FLASH页
WriteFlashDMA(recv_buf,12,0x4100); //写入FLASH
memset(recv_buf,0,12);
memset(rf_rx_buf,0,rf_rx_buf[1]);
break;
//读取
Read_Flash_To_Buf(0xC100,t,12); //从FLASH读出数据
我试过页擦除之后直接读数据看,数据并没有变成0xFF,还是原来的数据,应该是擦除没有成功,这个是什么原因?
|