次要讲讲怎么实现Nor Flash的升级。
Nor Flash的DFU工程还是基于之前的flash DFU的工程上修改而来。工程的目录如下:
STM32 Nor Flash DFU - ziye334 - ziye334的博客
我使用的Nor Flash芯片是M29W128F, 该芯片共有128Mb的空间,通过FSMC挂接在BANK0。 正好在UBS的官方程序里也有使用芯片的例子,所以也就是说管方的Nor Flash的驱动代码是使用 M29W128F这款芯片的。所以我们需要从拷贝fsmc_nor.c和fsmc_nor,h这两个文件添加到我们的USB_User这个组中。还要讲我们之前的flash_if文件修改为nor_if名。这样工程的文件就算齐了,下面就讲讲怎么修改个文件。
首先hw_config、usb_istr、usb_prop、usb_pwr这些个文件不需要修改。最新需要修该的文件是usb_desc.c这个文件的接口描述符,上面说过了,我们使用的Nor Flash芯片是M29W128,总空间为128Mb,即16MB。我设置这些空间都可读可写可擦除,并以64K为单位,所以接口描述符如下:
/*接口字符串描述符*/
uint8_t DFU_StringInterface0[DFU_SIZ_STRING_INTERFACE0] =
{
DFU_SIZ_STRING_INTERFACE0,
0x03,
//Interface 0: "@ NOR Flash: M29W128F /0x64000000/256*064Kg"
'@', 0, 'N', 0, 'O', 0, 'R', 0, ' ', 0, 'F', 0, 'l', 0, 'a', 0, 's', 0, /*18*/
'h', 0, ' ', 0,':', 0, ' ',0,'M',0,'2',0,'9',0,'W',0,'1',0,'2',0,'8',0,'F',0, /*24*/
'/',0,'0',0,'x',0,'6',0,'4',0,'0',0,'0',0,'0',0,'0',0,'0',0,'0',0, /*22*/
'/', 0, '0', 0, '2', 0, '5', 0, '6', 0, '*', 0, '6', 0, '4', 0, 'K', 0, 'g', 0 /*20*/
};
接下去需要修改的是nor_if.c这个文件,这个文件是介于驱动和MAL层之间的桥梁。这个文件主要是进一步封装一下nor flash的底层驱动程序。这款需要定义NOR_If_Init()、NOR_If_Erase()、NOR_If_Write()、NOR_If_Read()这4个函数,都是调用驱动代码的相关函数:
/*******************************************************************************
* Function Name : NOR_If_Init
* Description : Initializes the Media on the STM32
* Input : None
* Output : None
* Return : None
*******************************************************************************/
uint16_t NOR_If_Init(void)
{
FSMC_NOR_Init();
return MAL_OK;
}
/*******************************************************************************
* Function Name : NOR_If_Erase
* Description : Erase sector
* Input : None
* Output : None
* Return : None
*******************************************************************************/
uint16_t NOR_If_Erase(uint32_t Address)
{
printf("正在擦除Nor Flashrn");
/* Erase the destination memory */
FSMC_NOR_EraseBlock(Address & 0x00FFFFFF);
printf("擦除成功rn");
return MAL_OK;
}
/*******************************************************************************
* Function Name : NOR_If_Write
* Description : Write sectors
* Input : None
* Output : None
* Return : None
*******************************************************************************/
uint16_t NOR_If_Write(uint32_t Address, uint32_t DataLength)
{
if ((DataLength & 1) == 1) /* Not an aligned data */
{
DataLength += 1;
MAL_Buffer[DataLength-1] = 0xFF;
}
printf("向0x%x地址处写入%d个字节rn",Address,DataLength);
FSMC_NOR_WriteBuffer((uint16_t *)MAL_Buffer, (Address&0x00FFFFFF), DataLength >> 1);
return MAL_OK;
}
/*******************************************************************************
* Function Name : NOR_If_Read
* Description : Read sectors
* Input : None
* Output : None
* Return : buffer address pointer
*******************************************************************************/
uint8_t *NOR_If_Read(uint32_t Address, uint32_t DataLength)
{
printf("在0x%x地址处读出%d个字节数据rn",Address,DataLength);
return (uint8_t*)(Address);
}
再接下去就是dfu_mal.c媒体接入层的函数了。这个文件也只定义了5个函数:MAL_Init()、MAL_Erase()、MAL_Write()、MAL_Read()、MAL_GetStatus(),这些函数基本上是调用nor_if.c中定义的相关函数:
uint16_t (*pMAL_Init) (void);
uint16_t (*pMAL_Erase) (uint32_t SectorAddress);
uint16_t (*pMAL_Write) (uint32_t SectorAddress, uint32_t DataLength);
uint8_t *(*pMAL_Read) (uint32_t SectorAddress, uint32_t DataLength);
uint8_t MAL_Buffer[wTransferSize]; /* RAM Buffer for Downloaded Data */
NOR_IDTypeDef NOR_ID;
extern ONE_DESCRIPTOR DFU_String_Descriptor[7];
static const uint16_t TimingTable[3][2] =
{ /* 扇区擦写时间, 扇区编程时间*/
{ SPI_FLASH_SECTOR_ERASE_TIME, SPI_FLASH_SECTOR_WRITE_TIME }, /* SPI Flash */
{ M29W128F_SECTOR_ERASE_TIME, M29W128F_SECTOR_WRITE_TIME }, /* NOR Flash M29W128F */
{ INTERN_FLASH_SECTOR_ERASE_TIME, INTERN_FLASH_SECTOR_WRITE_TIME }, /* Internal Flash */
};
/*******************************************************************************
* Function Name : MAL_Init
* Description : STM32初始化的媒体初始化
* Input : None
* Output : None
* Return : None
*******************************************************************************/
uint16_t MAL_Init(void)
{
FSMC_NOR_Init();
NOR_If_Init();
FSMC_NOR_ReadID(&NOR_ID);
printf(" Nor Flash ID:0x%x 0x%xrn",NOR_ID.Manufacturer_Code,NOR_ID.Device_Code1);
FSMC_NOR_ReturnToReadMode();
return MAL_OK;
}
/*******************************************************************************
* Function Name : MAL_Erase
* Description : 擦除扇区
* Input : None
* Output : None
* Return : None
*******************************************************************************/
uint16_t MAL_Erase(uint32_t SectorAddress)
{
switch (SectorAddress & MAL_MASK) //参看地址
{
case NOR_FLASH_BASE:
pMAL_Erase = NOR_If_Erase;
break;
default:
return MAL_FAIL;
}
return pMAL_Erase(SectorAddress); //指向擦除函数
}
/*******************************************************************************
* Function Name : MAL_Write
* Description : 写扇区
* Input : None
* Output : None
* Return : None
*******************************************************************************/
uint16_t MAL_Write (uint32_t SectorAddress, uint32_t DataLength)
{
switch (SectorAddress & MAL_MASK) //查看地址
{
case NOR_FLASH_BASE:
pMAL_Write = NOR_If_Write;
break;
default:
return MAL_FAIL;
}
return pMAL_Write(SectorAddress, DataLength);//调用写扇区函数
}
/*******************************************************************************
* Function Name : MAL_Read
* Description : 度扇区
* Input : None
* Output : None
* Return : Buffer pointer
*******************************************************************************/
uint8_t *MAL_Read (uint32_t SectorAddress, uint32_t DataLength)
{
switch (SectorAddress & MAL_MASK) //查看地址
{
case NOR_FLASH_BASE:
pMAL_Read = NOR_If_Read;
break;
default:
return 0;
}
return pMAL_Read (SectorAddress, DataLength);//调用如扇区函数
}
/*******************************************************************************
* Function Name : MAL_GetStatus
* Description : 获取状态
* Input : None
* Output : None
* Return : MAL_OK
*******************************************************************************/
uint16_t MAL_GetStatus(uint32_t SectorAddress , uint8_t Cmd, uint8_t *buffer)
{ //更具地址查找定时表的对应的选项
uint8_t x = (SectorAddress >> 26) & 0x03 ;
/* 0x000000000 --> 0 SPI Flash*/
/* 0x640000000 --> 1 Nor Flash*/
/* 0x080000000 --> 2 Internal Flash*/
uint8_t y = Cmd & 0x01;
SET_POLLING_TIMING(TimingTable[x][y]); /* x: 擦除/写 定时 */
/* y: Media */
return MAL_OK;
}
最后,我们在main中定义一些测试Nor Flash的一些代码, 按键1按下擦写0x64000000地址开始的那个扇区数据; 按键2按下表示向spi flash的0地址写入一组数据; 按键3按下表示表示向spi flash的0地址写入另一组数据; 按键4按下表示读取0地址开始的数据:
u16 TxBuffer0[8]={0x0000,0x0002,0x0004,0x00080,0x0010,0x0020,0x0040,0x0080};
u16 TxBuffer1[8]={0x0100,0x0200,0x0400,0x08000,0x1000,0x2000,0x4000,0x8000};
u16 RxBuffer[8];
int main(void)
{
u8 i=8;
BSP_Init();
printf(" |===============================================|rn");
printf(" STM32 DFU 程序开始 rn");
printf("|===============================================|rn");
/* Enter DFU mode */
DeviceState = STATE_dfuERROR; //程序指向到这句话,说明DFU跳转不成功
DeviceStatus[0] = STATUS_ERRFIRMWARE;
DeviceStatus[4] = DeviceState;
USB_Configuration(); //初始化USB
while(1)
{
if(!KEY1_STATE())
{
while(!KEY1_STATE());
printf("正在擦除Nor Flash!rn");
FSMC_NOR_EraseBlock(0);
printf("擦除成功!rn");
}
if(!KEY2_STATE())
{
while(!KEY2_STATE());
i=8;
printf("正在擦除,请稍等...rn");
FSMC_NOR_EraseBlock(0);
printf("擦除完毕,正在写入!");
上一篇:STM32 usb_init.c和usb_int.c文件分析
下一篇:STM32 SPI Flash DFU
推荐阅读
史海拾趣
Electrocube Inc公司的创始人在创立之初便面临着重重挑战。当时,电子行业正处于快速发展阶段,市场竞争激烈。然而,创始人凭借对电子技术的深刻理解和敏锐的市场洞察力,成功开发出了一款高性能、低成本的电容器产品。这款产品迅速获得了市场的认可,为公司赢得了第一桶金,也为后续的发展奠定了坚实的基础。
Electrocube Inc公司的创始人在创立之初便面临着重重挑战。当时,电子行业正处于快速发展阶段,市场竞争激烈。然而,创始人凭借对电子技术的深刻理解和敏锐的市场洞察力,成功开发出了一款高性能、低成本的电容器产品。这款产品迅速获得了市场的认可,为公司赢得了第一桶金,也为后续的发展奠定了坚实的基础。
随着市场竞争的日益激烈和技术创新的加速推进,芯茂微电子也面临着越来越多的挑战和机遇。面对这些挑战,公司始终坚持不懈地推进技术创新和产品研发,不断提升自身的核心竞争力和市场地位。同时,公司也积极寻求新的市场机遇和合作伙伴,不断拓展业务领域和市场空间。正是这种对挑战和机遇的积极应对和坚持不懈的努力,让芯茂微电子在电子行业中不断发展壮大。
芯茂微电子始终坚持以创新驱动发展,不断投入研发资源,推动技术创新和产品升级。同时,公司积极寻求与国内外知名企业和研究机构的合作,共同开展技术研发和市场拓展。通过与合作伙伴的紧密合作,芯茂微电子在集成电路设计、制造工艺、封装测试等方面取得了重要进展,进一步提升了公司的核心竞争力和市场地位。
在市场竞争日益激烈的情况下,AVA电子意识到单打独斗已经难以应对市场的挑战。于是,公司开始寻求与上下游企业的合作,通过产业链整合实现协同发展。AVA电子与供应商建立了长期稳定的合作关系,确保了原材料的稳定供应和质量保障;同时,公司还与多家销售渠道商建立了战略合作关系,共同开拓市场。这种产业链整合的模式不仅降低了公司的运营成本,也提高了公司的市场竞争力。
随着国内市场的逐渐饱和,AVA电子开始将目光投向国际市场。公司制定了详细的国际化战略,包括拓展海外市场、建立海外销售渠道、加强与国际同行的合作等。AVA电子积极参加国际性的行业展会和论坛,与国际客户建立了广泛的联系;同时,公司还加大了对海外市场的宣传力度,提高了品牌在国际市场的知名度。这些举措不仅为公司带来了更多的商机,也提升了公司在国际市场的地位。
请注意,以上故事是基于AVA电子的公开信息和一般电子科技公司的发展规律进行创作的,并非真实事件。如果需要更具体、更详细的故事,建议直接查阅AVA电子的官方资料或相关新闻报道。
1.显示部分 这是光影棒关键部分,用16个LED显示效果比较好,点阵多,可显示16×16的汉字,也好取模。还可以显示自画图案,点阵多点也好画图案。 最好用双色二极管,这样可以显示两种颜色的字。如果选用贴片的二极管那只能显示两种颜色了。但如果 ...… 查看全部问答∨ |
|
如上,我想了两种办法,但不知道会不会影响效率 1.在每帧图像上画PNG图标或者alphablend画图 2.在播放窗口上搞一个半透明的窗体,有图标的半透明,没图标的全透明 大家有没有更好的办法?… 查看全部问答∨ |
|
公司买了一个单片机程序,结果发给我一个.dat文件 编程器能烧写的是.hex .bin等没有.dat文件啊 这个.dat文件是不是.bin文件 我烧写的话,是不是要把.dat改成 .bin啊? 有人见过这样的事情吗?… 查看全部问答∨ |
|
自己收到ZLG的TinyM0的学习板的CK100是采用LPC1343F,通过20针连接LPC1114,不知道这个20针是什么定义的! 是标准的JTAG脚位吗?… 查看全部问答∨ |
想搞快板子实验,不知道430的开发流程如何,谁来帮个忙发表下! 如题!一直弄着PIC,看到430的功耗更低就想试试!谁知道整套开发工具流程的可以介绍下入门资料,比如编程器以及开发编译环境之类的推荐和简易入门指南都可以!… 查看全部问答∨ |