LPC1768IAP(详解,有上位机)
扫描二维码
随时随地手机看文章
之前说了stm32的iap编程,今天天气真好,顺手就来说说lpc1788的iap编程(没看前面的请查看stm笔记下的内容)
首先是flash的算法,lpc1768并没有寄存器来让我们操作flash,他内置了iap的flash算法,在技术手册的525页有如下说明
其支持的iap命令有这些
这样我们就能够做出相关的flash读写借口呢(具体请查看lpc1768的技术手册)
unsigned param_table[5];//传递参数列表
unsigned result_table[5];//返回结果列表
//调用iap命令
void iap_entry(unsigned param_tab[],unsigned result_tab[])
{
void (*iap)(unsigned [],unsigned []);
iap = (void (*)(unsigned [],unsigned []))IAP_ADDRESS;
iap(param_tab,result_tab);
}
通过这种手段就能够调用iap命令,我们演示性的看一个命令
//扇区准备好指令
//起始扇区号 结束扇区号 系统时钟
void prepare_sector(unsigned start_sector,unsigned end_sector,unsigned cclk)
{
param_table[0] = PREPARE_SECTOR_FOR_WRITE;
param_table[1] = start_sector;
param_table[2] = end_sector;
param_table[3] = cclk;
iap_entry(param_table,result_table);
}
该指令在写flash和擦除flash之前必须调用
具体的完整flash代码请查看工程文件,会在文章末尾上传
然后依旧是五个指令
"iap_down"
"iap_jump_app"
"iap_over"
"iap_set_flag"
"iap_clear_flag"
功能和之前的stm32差不多,但是下载算法变化了,因为stm32支持的写入是每次写入一个十六位数据,而lpc1768每次写入8位数据,而且每次写入数据的量为128/256/512/1024/4096,正好没有我们之前所用的2048,所以算法修改成如下的样子
u8 iapbuf[1024] = {0}; //用于缓存数据的数组
u16 receiveDataCur = 0; //当前iapbuffer中已经填充的数据长度,一次填充满了之后写入flash并清零
u32 addrCur = FLASH_APP1_ADDR; //当前系统写入地址,每次写入之后地址增加2048
#define vu32 volatile unsigned int
//开始下载
void iap_down_s(void)
{
u16 i = 0;
u16 receiveCount;
if(erase_user_flash())
{
printf("errorrn");
return;
}
printf("begin,wait data downloadrn");
receiveMode = 1;//串口进入下载接收数据模式
while(1)
{
//循环接收数据,每次必须要发128个数据下来,如果没有128,说明这是最后一包数据
//接收到一包数据之后,返回一个小数点,发送完成,系统编程完成之后返回一个iap_over
if(serial_Buffer_Length & 0x8000)
{
receiveCount = (u8)(serial_Buffer_Length&0x00ff);
if(receiveCount == 128)//满足一包,填充并查看是否有了1024字节,有了写入闪存
{
for(i = 0; i < receiveCount; i++)
{
iapbuf[receiveDataCur] = serial_Buffer[i];
receiveDataCur++;//完成之后receiveDataCur++;
}
receiveExpectCount = 0;//清除期望接收模式
serial_Buffer_Length = 0;//清除串口满标志
printf(".");//每次接受一次数据打一个点
//此时需要检测receiveDataCur的值,要是放满了,就需要写入
if(receiveDataCur == 1024)
{
//写入flash中
if(write_flash(100000,addrCur,(unsigned*)iapbuf,1024))
{
receiveMode = 0;
addrCur = FLASH_APP1_ADDR;
receiveDataCur = 0;
return;
}
addrCur += 1024;//地址+2048
//写完之后receiveDataCur要清零等待下一次传输
receiveDataCur = 0;
}
else //有可能最后一包有128个数据但是最终没有2048个数据,此时扩展一个指令用于完成最后一个的写入
{
}
//还没放满,等待下一次数据过来
}
else //不满足一包,说明数据传送这是最后一包,写入闪存
{
//没有一包也要传送到缓存中
for(i = 0; i < receiveCount; i++)
{
iapbuf[receiveDataCur] = serial_Buffer[i];
receiveDataCur++;//完成之后receiveDataCur++;
}
receiveExpectCount = 0;//清除期望接收模式
serial_Buffer_Length = 0;//清除串口满标志
printf(".");//每次接受一次数据打一个点
//要将没接收满的数据变成0xff
for(i= receiveDataCur; i < 1024; i++)
{
iapbuf[i] = 0xff;
}
//之后就要将这数据写入到闪存中
if(write_flash(100000,addrCur,(unsigned*)iapbuf,1024))
{
receiveMode = 0;
addrCur = FLASH_APP1_ADDR;
receiveDataCur = 0;
return;
}
//printf("rnwrite addr %x,length %drn",addrCur,receiveDataCur);
//写完之后要把地址恢复到原来的位置
addrCur = FLASH_APP1_ADDR;
receiveDataCur = 0;