DX32在不断提供例程的同时,也会注意到程序中某些BUG的问题,毕竟例程也是程序,有程序的地方,就会有BUG.此公告页对于用户反映的一些情况和白菜自身检查中发现的问题都会马上写上,大家请多留意,任何用户发现例程中有BUG,请发邮件到hhh_ccboy@126.com告知白菜,白菜将抽空一一完善.

2010-5-29:25VF080读写底层中,多字节写函数的BUG:

25VF系列的FLASH芯片,多字节写入(AAI)方式,其起始地址不能是奇数,之前由于没有十分留意DATASHEET这个说明,所以之前的25VF读写函数中,所有的连续写入里,从奇地址开始的写入,第一个地址的数据都会丢失,现修正如下:

/***********************************
SST25Write 写多个字节
***********************************/
void SST25Write(u32 addr,u8* p_data,u32 no)
{
u8 ad[3];
u32 cnt;
if(no==0)
return;

SST25WriteEn();
//处理奇数地址,高速写是不能从奇地址开始的
if(addr%2)
{
SST25ByteProgram(addr,*p_data);
addr++;
p_data++;
no--;
SST25WriteEn();
}
if(no==0)
return;

if(no==1) //no<2则应使用普通单字节方式
{
SST25ByteProgram(addr,*p_data);
}
else
{
cnt=no;

ad[2]=(addr>>16)&0xff;
ad[1]=(addr>>8)&0xff;
ad[0]=addr&0xff;

SST_SELECT();
SPIByte(0xad);
SPIByte(ad[2]);
SPIByte(ad[1]);
SPIByte(ad[0]);
SPIByte(*p_data++);
SPIByte(*p_data++);
SST_DESELECT();
cnt-=2;
while(SST25BY());//判忙

//中间的双字节写
for(;cnt>1;cnt-=2)
{
SST_SELECT();
SPIByte(0xad);
SPIByte(*p_data++);
SPIByte(*p_data++);
SST_DESELECT();
while(SST25BY());//判忙
}

SST25WRDI();//WRDI用于退出AAI写模式

//如果有最后一个字节(no为奇数)
if(cnt==1)
{
SST25WriteEn();
SST25ByteProgram(addr+no-1,*p_data);
}
}
// SST25WPEN();//WP保护
}

所有的和25VF读写有关的代码,都有这个BUG,请大家在试用的时候注意!

2010-4-6:例程 提高篇4_Uart25FMDA的main.c文件中,对于DMA接收超时的处理如下:

//超时
if(Timer1==0)
{
//获取长度
len=512-DMA_GetCurrDataCounter(DMA1_Channel5);
//写入最后数据
if(Free_Buf_No==BUF_NO1)
SST25Write(addr,USART1_DMA_Buf1,len);
else
SST25Write(addr,USART1_DMA_Buf2,len);
addr+=len;

break;
}

以上的写入数据的BUF号错了,因为在超时的时候,Free_Buf_No==BUF_NO1时,有数据的是BUF2.所以应该改为如下:

//超时
if(Timer1==0)
{
//获取长度
len=512-DMA_GetCurrDataCounter(DMA1_Channel5);
//写入最后数据
if(Free_Buf_No==BUF_NO1)
SST25Write(addr,USART1_DMA_Buf2,len);
else
SST25Write(addr,USART1_DMA_Buf1,len);
addr+=len;

break;
}

2009-12-24:例程 基础篇5_SPILCD中的LCDS.C文件的函数:

void LcdSetXP(u8 x,u8 page)
{
while(page>8)
page-=8;

LcdCmd(page+0xb0); //设置页指针
LcdCmd((x>>4)|0x10);
LcdCmd(x&0x0f);
}

由于小LCD的页只有0-7,所以上面的page>8的判断是不合理的,应该是page>7.此句功能实为保护page值不能大于7.可以改成以下写法,则更有风格:

void LcdSetXP(u8 x,u8 page)
{
LcdCmd((page&0x07)+0xb0); //设置页指针
LcdCmd((x>>4)|0x10);
LcdCmd(x&0x0f);
}

此BUG一般只要合理应用,不会造成影响.另外在DX_PDA程序中,LCD.C文件上的这个函数同样有这个问题,大家注意自行修改.

2009-12-18:例程 基础篇3_UART MAIN.C文件中,有以下代码,是用于判断串口1是否收到数据的:

if(USART_GetFlagStatus(USART1,USART_IT_RXNE)==SET)
{
uart1_get_data = USART_ReceiveData(USART1);
USART1_Puts("\r\n获取到串口1数据:");
USART1_Putc(uart1_get_data);
USART1_Puts("\r\n");
}

其中上面的USART_IT_RXNE标志使用错误,应该使用USART_FLAG_RXNE标志,因为USART_IT_RXNE表示是用于判断接收中断的,而USART_FLAG_RXNE则是单纯的检测接收数据标志.

之所以两个标志在上面的判断中都都不会产生程序错误,是因为他们某个位都是相同的,而USART_GetFlagStatus函数正式判断那个位得知是否有接收数据.但正规的使用中,USART_GetFlagStatus函数就应该使用USART_FLAG_某某 标志,而在USART_GetITStatus函数就是使用USART_IT_某某 标志,请大家留意.

 

2009-12-11:此BUG存在于所有SD卡读写程序当中,注意到SD.C文件中,大概第54行的位置有如下声明:

extern volatile
unsigned int Timer1, Timer2;

以上声明的Timer1和Timer2变量类型为unsigned int,这个在KEIL编译器里,会编译成32位的整形,但实际上原型如下(一般在在RCC.C中 ,用于1毫秒定时器SYSTICK的自减):

volatile u16 Timer1,Timer2;

大家看到,原型定义是u16的,所以引用声明和定义原型 是不一样的,居然KEIL也编译通过了.

这个问题,使得对于大部分SD应用的时候,如果SD卡没插入,会引起一些命令的死循环.请在各位的程序中,SD.C文件中大约54行处,把Timer1和Timer2的引用声明改为:

extern volatile u16 Timer1,Timer2;

这样就不会再有死循环出现了,而是可以判断到SD卡响应超时.

2009-10-21:SPI读写串行FLASH,其中初始化IO的时候没有把CS脚提高,引起第一个FLASH操作会失败,这个BUG很早前就改了,并通过增值邮箱通知大家,为了没有遗漏,决定在这里再通知一次.此BUG也让大家明白,如果初始化IO为输出,则IO是默认拉低的!!

/* PC.13 作片选*/
GPIO_SetBits(GPIOC, GPIO_Pin_13);//加入这句 预置为高,这样初始化IO脚后,CS才不会是低.或者可以在操作25VF080的之前把IO脚设高.
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);

2009-10-9:例程\提高篇\5_TFT 这个程序展示了在彩屏上显示汉字,其中使用FLASH字库的汉字显示函数有BUG,如下:

static void TFTShowHZ16(LOC_X x,LOC_Y y,u16 hz,COLOR color)

{

u16 font_byte;
u8 i,j;
u8 c1,c2;
u16 addr;

.....

}

其中u16 addr这个局部变量的定义有误,应该定义为u32 形式,否则大部分汉字将显示错误.此BUG很早就发现,但后来由于一些管理上的失误,某些发出的光盘中此BUG依旧存在,故特此公告,请大家注意.