||
祝贺UARTV1.0用在产品上经过20天的强度测试,没有发生任何意外。
-------------------------------------------------------------------------------------
测试结果备忘录:
测试数据量 正确率 典型通信特征
软件模拟串口 15MB 98% 1200,e,8,1
LPC221xUART0 103MB 99.9% 9600,o,8,1
LPC221xUART1 210MB 99.7% 38400,n,8,1
外扩串口A 43MB 99.2% 9600,e,8,1
外扩串口B 57MB 100% 1200,e,8,1
-------------------------------------------------------------------------------------
大侠指点一下.
我用的是SST39VF160--FLASH
我的CODE 放在0x80000000开始的1M空间里,后面的1M放要存储的数据,这应当是可行的吧?
可是我怎么写不进去数据!
以下为blog主人的回复:
|
放在RAM里是可以读写FLASH成功,但是RESET之后或者掉电再上电.程序就丢掉了,
这样的情况该怎么处理,如何实现将程序在FLASH中固化,并能把程序调入到ram中执行?
谢谢了:(
以下为blog主人的回复:
|
供你参考:
假定你的对Flash操作的文件为Prog.c。
你的Scatter文件可能是这样的:
ROM_LOAD 0x0
{
ROM_EXEC 0x00000000//FlashRom起始地址
{
Startup.o (vectors, +First)//把startup文件的code段放在0x00000000处
* (+RO)//其他code段接下来放
}
IRAM 0x40000200//内部RAM起始地址
{
Startup.o (MyStacks)//放startup文件中的MyStacks变量
}
......
}
修改为
ROM_LOAD 0x0
{
ROM_EXEC 0x00000000
{
Startup.o (vectors, +First)
* (+RO)
}
IRAM 0x40000200//内部RAM起始地址
{
Prog.o (+RO)//把文件prog中的code段放在IRAM中
Startup.o (MyStacks))//放startup文件中的MyStacks变量
}
......
}
我使用了你以前发布的串口代码,在ucos多任务中,经常出现无法打开串口的情况,而在单步运行是很少出现,why?
以下为blog主人的回复:
|
每个uart是临界资源,也就是说每个uart同时只能被一个任务使用。如果试图打开一个已经被其他任务打开的串口,该任务就会被挂起,直到那个占用了该串口的任务关闭该串口(即释放临界资源)。
我的uart串口打开串口基于以上原理,不过在打开串口时提供了超时机制,即在一定时间里如果其它任务仍然没有释放该串口,则返回失败(当然这时此任务不能使用此串口)。这样做的好处是希望打开某串口的任务不会因为其他任务始终不释放该串口而导致本任务永远挂起。
希望以上说明对你的现象提供解释。
ROM_LOAD 0x80000000
{
ROM_EXEC 0x80000000
{
Startup.o (vectors, +First)
* (+RO)
}
IRAM 0x40000000
{
;HardWareDRV.o (+RO)//把文件HardWareDRV.c中的code段放在IRAM中
;databagcommand.0 (+RO)
Startup.o (MyStacks)
}
STACKS_BOTTOM +0 UNINIT
{
Startup.o (StackBottom)
}
STACKS 0x40004000 UNINIT
{
Startup.o (Stacks)
}
ERAM 0x81000000
{
* (+RW,+ZI)
}
HEAP +0 UNINIT
{
Startup.o (Heap)
}
HEAP_BOTTOM 0x81080000 UNINIT
{
Startup.o (HeapTop)
}
}
以下为blog主人的回复:
|
使用IAP你一定用了这个函数吧:
static void RamToFlash(unsigned long dst, unsigned long src, unsigned long no)
我记得src必须是IRAM地址,你用的是哪个缓冲区呢?
我打算换有内部FLASH的CPU或者加一个外部FLASH来解决它.你可以先帮我看看,呵呵,非常感谢.
另外我想通过您的串口程序中串口1或者串口2接一个外挂MODEM,好象读消息的时候,读中断没有出来.读不到东西,写是返回的TRUE.我不明白,请大侠提示一下.代码如下:
//向MODEM发送AT指令,进行MODEM初始化工作
void ModemInit(int port)
{
INT16U len,i=0;
char buff[10];
char * str,* s;
//
s="\r\nATE0\r";
if (UART_write(port,s,sizeof(s),200)==true)
len=UART_read(port,buff,sizeof(buff),200);
//OSTimeDly(OS_TICKS_PER_SEC);
//
for (i=0;i<10;i++) *str++=buff;
s="\r\nAT+CMGF=1\r";
if(0==strcmp(str,"OK"))
UART_write(port,s,sizeof(s),200);
//OSTimeDly(OS_TICKS_PER_SEC);
//
len=UART_read(port,buff,sizeof(buff),200);
for (i=0;i<10;i++) *str++=buff;
s="\r\nAT+CNMI=1,1,0,0,1\r";
if(0==strcmp(str,"OK"))
UART_write(port,s,sizeof(s),0);
//OSTimeDly(OS_TICKS_PER_SEC);
//
len=UART_read(port,buff,sizeof(buff),200);
OSTimeDly(OS_TICKS_PER_SEC);
for (i=0;i<10;i++) *str++=buff;
s="\r\nAT+CMGL=ALL\r";
if(0==strcmp(str,"OK"))
UART_write(port,s,sizeof(s),200);
//OSTimeDly(OS_TICKS_PER_SEC);
//
}
void ModemInitTask(void * argv)
{
argv=argv;
for(;;)
{
ModemInit(1);
OSTimeDly(OS_TICKS_PER_SEC);
}
}
以下为blog主人的回复:
|
看了你的程序,我觉得这句话有问题。你可以用PC上用Turbo C确认一下,这句话是否达到了你的预期。
for (i=0;i<10;i++) *str++=buff;
以下为blog主人的回复:
|
以下为blog主人的回复:
|
以下为blog主人的回复:
|
MODEM没有返回数据,我在超级终端中检测MODEM是正常的,这是怎么回事呢
void ModemInitTask(void * argv)
{
argv=argv;
UART_Init(1);
for(;;)
{
UART_open(1,9600,8,'n',1,0);
ModemInit(1);
UART_close(1);
OSTimeDly(OS_TICKS_PER_SEC);
}
}
以下为blog主人的回复:
|
这句话有问题:
if (UART_write(port,s,sizeof(s),2000)==true)
sizeof(s)=4,
strlen(s)为s的长度,仔细想想
//向MODEM发送AT指令,进行MODEM初始化工作
bool ModemInit(int port)
{
INT16U i,len;
const INT16U tempLen=10;
char buff[10];
char * s;
char * str="OKOKERROE\0";
/*s="\r\nATZ\0\r";
UART_write(port,s,strlen(s),0);
while(i<tempLen) buff[i++]=0;
DelayNS(20);*/
s="\r\nATE0\0\r";
if (true==UART_write(port,s,strlen(s),2000)) //向MODEM发AT命令
{
DelayNS(20);
while(i<tempLen) buff[i++]=0;
len=UART_read(port,buff,sizeof(buff),2000); //读AT命令的返回信息
str=buff;
if(0==strcmp(str,"\r\nOK\r\n\0"))
{
str=NULL;
s="\r\nAT+CMGF=1\0\r";
DelayNS(20);
if(true==UART_write(port,s,strlen(s),2000)) //向MODEM发AT命令
{
DelayNS(20);
while(i<tempLen) buff[i++]=0;
len=UART_read(port,buff,sizeof(buff),2000);//读AT命令的返回信息
str=buff;
if(0==strcmp(str,"\r\nOK\r\n\0"))
{
str=NULL;
s="\r\nAT+CNMI=1,1,0,0,1\0\r";
DelayNS(20);
if(true==UART_write(port,s,strlen(s),2000)) //向MODEM发AT命令
{
DelayNS(20);
while(i<tempLen) buff[i++]=0;
len=UART_read(port,buff,sizeof(buff),2000);//读AT命令的返回信息
str=buff;
if(0==strcmp(str,"\r\nOK\r\n\0"))
{
str=NULL;
s="\r\nAT+CMGL=ALL\0\r";
DelayNS(20);
if(true==UART_write(port,s,strlen(s),2000)) //向MODEM发AT命令
{
DelayNS(20);
return true;
}
}
}
}
}
}
}
return false;
}
已经解决好了.谢谢你给我提出的错误.我把MODEM初始化的代码贴出来给你看看,也希望能对别人有所帮助.有没有需要改进的地方.比如延时方面,我对时间的概念比较薄弱.
以下为blog主人的回复:
|
祝贺祝贺。
建议:在判断Modem对AT命令的响应时不要用strcmp完全比较,而用strstr串包含。因为Modem返回:某些Modem或者某些条件下会有更多的字符返回。
使用IAP你一定用了这个函数吧:
static void RamToFlash(unsigned long dst, unsigned long src, unsigned long no)
我记得src必须是IRAM地址,你用的是哪个缓冲区呢?
uint8 WrDatatoInChip(uint16 write_addr ,uint8 * strSendMes, uint8 datalen )
{
uint16 i;
uint8 j;
volatile uint8 *ip;
uint8 strProtBuff[ByteINSector]; //用来在扇区擦除前保存扇区中的内容
ip=GetAddrInChip(0);//(volatile uint16 *)FLASH_ADDR+0;
for(i=0;i<ByteINSector;i++)
{
strProtBuff = *ip++;
}
for(j=0;j<datalen;j++)
strProtBuff[write_addr+j] = strSendMes[j];
OS_ENTER_CRITICAL();
/*
MAMCR = 0; // 关闭MAM
PLLCON = 0; // 关闭PLL
PLLFEED = 0xaa;
PLLFEED = 0x55;
*/
ReadParID();
BootCodeID();
SelSector(1,1); // 选择扇区1
EraseSector(1,1); // 擦除扇区1
BlankCHK(1,1) ; // 查空扇区1
SelSector(1,1);
RamToFlash(FLASH_ADDR_InChip, (uint32)strProtBuff, ByteINSector); // 写数据到扇区1
BlankCHK(1,1) ;
Compare(FLASH_ADDR_InChip, (uint32)strProtBuff, ByteINSector); // 比较数据
/*
MAMCR = 2; // MAM完全使能
PLLCON = 3; //PLL使能并连接
PLLFEED = 0xaa;
PLLFEED = 0x55;
*/
OS_EXIT_CRITICAL();
return TRUE;
}
这是IAP编程的代码,我在没有操作系统的环境下运行,写内部FALSH是成功的.
但是在有操作系统的环境下,写不成功.这是怎么回事呢?
* 要设置编译参数-apcs /interwork,因为IAP为Thumb指令。
* 使用IAP功能时,片内RAM的顶端的32字节保留给IAP操作使用,所以在STARTUP.S文件中
* 初始化用户模式堆栈为StackUsr-20*4,以保证IAP正常操作。
这些设置都做了.
MAMCR = 0; // 关闭MAM
PLLCON = 0; // 关闭PLL
PLLFEED = 0xaa;
PLLFEED = 0x55;
这些设置我发现没有影响,加和不加对运行没有影响,而且都写不成功.
还有一个现象.我将程序烧写在内部FLASH中运行.将BANK0设置为外部RAM,BANK1设置为外部FLASH.读写外部FALSH是可以的.
但是:将BANK0设置为外部FLASH,BANK1设置为外部RAM.读外部FALSH是可以的.但是写FLASH却不行.这是为什么呢.
好几天了,想不通
原来是ISP跳线忘记断开了.呵呵.不好意思啊.
还有一个现象.我将程序烧写在内部FLASH中运行.将BANK0设置为外部RAM,BANK1设置为外部FLASH.读写外部FALSH是可以的.
但是:将BANK0设置为外部FLASH,BANK1设置为外部RAM.读外部FALSH是可以的.但是写FLASH却不行.这是为什么呢.
好几天了,想不通
以下为blog主人的回复:
|
这个星期比较忙,今天才上来看一看。很抱歉没有思考你提出的问题,同时又很惭愧,这几次你提的问题我给不了建议,因为我没有遇到你所讲的问题。
将外置GSM MODEM的收发程序奉献出来.
这个是经过测试的.很好用.稍微慢了点.
//GSM MODEM通信任务
void ModemInitTask(void * argv)
{
argv=argv;
UART_Init(COMPORT);
for(;;)
{
UART_open(COMPORT,9600,8,'n',1,0);
OSTimeDly(OS_TICKS_PER_SEC);
if (ModemInit(COMPORT)==true)
{
char * s;
s="\r\nAT+CMGL=ALL\r\0";
OSTimeDlyHMSM(0,0,1,0);//延时1s读一次MODEM,时间自定
if(true==UART_write(COMPORT,s,strlen(s),200)) //向MODEM发AT命令
{
INT16U i=0, len;
char databuff[1024];;
OSTimeDly(OS_TICKS_PER_SEC);
i=0;while(i<1024) databuff[i++]=0;
len=UART_read(COMPORT,databuff,sizeof(databuff),OS_TICKS_PER_SEC);//读AT命令的返回信息 览?€€€ €€€ €€
if (len>27)
{
char * p[20],* buff;
char strtel[20];
char num[4];
INT16U ii=0;
buff=databuff;
i=0;
while((p=strtok(buff,"\n"))!=NULL) //分割字符串
{
buff=NULL;
if (i==0) {i++; continue;}
if(i%2!=0)
{
char * temp;
if((temp=strstr(p,"+86"))!=NULL)//14手机号码
{
ii=0;while(ii<14) strtel[ii++]=0;
ii=0;while(ii<14) strtel[ii++]=*temp++;
strcat(strtel,"\r\n\0");
}
if((temp=strstr(p,"+CMGL:"))!=NULL)//取短消息序号
{
char strnum[4];
INT16U j=0;
char * p=temp+6;//+6去掉"+CMGL:"
ii=0;while(ii<4)
{
num[ii]=0;
strnum[ii]=0;
strnum[ii]=*p++;
ii++;
}
ii=0;while(ii<4)
{
if (strnum[ii]>=0x30 && strnum[ii]<=0x39)
num[j++]=strnum[ii];
ii++;
}
}
}
else /////if(i%2==0)
{
char strbuff[SMSLEN];
char CMGD[20];
char temp[40];
char *pCMGS;
char *pCMGD;
/////CMGD删除短消息AT命令
ii=0;while(ii<20) CMGD[ii++]=0;
s=NULL;
s="\r\nAT+CMGD=";
strcat(CMGD,s);
strcat(CMGD,num);
ii=0;while(ii<4) num[ii++]=0;//清除序号
strcat(CMGD,"\r\n\0");
///////////////////////
if(*p!='!')
{
//删除非法短信
pCMGD=CMGD;
if (TRUE==UART_write(COMPORT,pCMGD,sizeof(pCMGD),OS_TICKS_PER_SEC))
{
pCMGD=NULL;
DelayNS(2000);
OSTimeDly(OS_TICKS_PER_SEC);
//ii=0;while(ii<20) CMGD[ii++]=0;
}
i++;continue;
}
if(strlen(p)<40)
{
//删除非法短信
pCMGD=CMGD;
if (TRUE==UART_write(COMPORT,pCMGD,sizeof(pCMGD),OS_TICKS_PER_SEC))
{
pCMGD=NULL;
DelayNS(2000);
OSTimeDly(OS_TICKS_PER_SEC);
//ii=0;while(ii<20) CMGD[ii++]=0;
}
i++;continue;
}
//////////////////////
///////////////////////发送电话号码AT命令
ii=0; while(ii<(40)) temp[ii++]=0;
strcat(temp,"\r\nAT+CMGS=");
strcat(temp,strtel);
ii=0; while(ii<20) strtel[ii++]=0;//清除TEL
///////////////////////监控协议解析
ii=0; while(ii<SMSLEN) strbuff[ii++]=0;
ii=0; while(*p!='\0') strbuff[ii++]=*p++;
if (TRUE==ParseCode(strbuff))
{
OSTimeDly(OS_TICKS_PER_SEC);
//发送电话号码AT命令
pCMGS=temp;
if (TRUE==UART_write(COMPORT,pCMGS,strlen(pCMGS),OS_TICKS_PER_SEC))
{
char tempbuff[20];
char * pBUFF;
char * str;
char context[SMSLEN+4];
pCMGS=NULL;
ii=0; while(ii<(SMSLEN+4)) context[ii++]=0;
strcat(context,strbuff);
strcat(context,"\x01a");
DelayNS(5);
ii=0; while(ii<20) tempbuff[ii++]=0;
len=UART_read(COMPORT,tempbuff,sizeof(tempbuff),OS_TICKS_PER_SEC); //读AT命令的返回信息
str=tempbuff;
if(NULL!=strstr(str,"\r\n>"))
{
str=NULL;
//发送回应
pBUFF=context;
if (TRUE==UART_write(COMPORT,pBUFF,strlen(pBUFF),OS_TICKS_PER_SEC))
{
pBUFF=NULL;
DelayNS(2000);
ii=0; while(ii<20) tempbuff[ii++]=0;
len=UART_read(COMPORT,tempbuff,sizeof(tempbuff),OS_TICKS_PER_SEC); //读AT命令的返回信息
str=tempbuff;
if(NULL!=strstr(str,"\r\nOK\r\n"))
{
str=NULL;
//发送回应成功后,删除此短信
pCMGD=CMGD;
if (TRUE==UART_write(COMPORT,pCMGD,strlen(pCMGD),OS_TICKS_PER_SEC))
{
pCMGD=NULL;
DelayNS(2000);
ii=0;while(ii<20) tempbuff[ii++]=0;
len=UART_read(COMPORT,tempbuff,sizeof(tempbuff),OS_TICKS_PER_SEC); //读AT命令的返回信息
str=tempbuff;
if(NULL!=strstr(str,"\r\nOK\r\n"))
str=NULL;
}
}
}
}
}
}
else
{
//解析不成功,删除不合格短信
pCMGD=CMGD;
if (TRUE==UART_write(COMPORT,CMGD,sizeof(CMGD),OS_TICKS_PER_SEC))
{
pCMGD=NULL;
DelayNS(2000);
OSTimeDly(OS_TICKS_PER_SEC);
ii=0;while(ii<20) CMGD[ii++]=0;
}
}
}
i++;
}
i=0;while(i<SMSLEN) databuff[i++]=0;
}
}
}
UART_close(COMPORT);
OSTimeDly(OS_TICKS_PER_SEC);
}
}
以下为blog主人的回复:
|
脉冲宽度测量
我用TIME0进行测量,T0TC(time)的值为94515(10进制)左右.这是什么值啊,是什么单位?书上说是定时器计数器.而且说这个就是脉宽.
但是我输入的500us的方波啊.这样应该测量出来的是多少呢.我现在不知道定时值该设置多少.也不知道测量出来的对不对,是什么东西.
谢谢大侠给指点一下.不胜感激
void Time0Init(void)
{ /* Fcclk = Fosc*4 = 11.0592MHz*4 = 44.2368MHz
Fpclk = Fcclk/4 = 44.2368MHz/4 = 11.0592MHz
*/
T0TC=0;
T0PR = 0; // 设置定时器0预分频值
T0MCR = 0x03; // 匹配通道0匹配中断并复位T0TC
T0MR0 = Fpclk*1000; // 比较值(定时值)
T0TCR = 0x03; // 启动并复位T0TC
T0TCR = 0x01;
}
/****************************************************************************
* 名称:main()
* 功能:初始化I/O及定时器,然后不断的查询定时器中断标志。当定时时间到达时,取反BEEPCON
* 控制口。
****************************************************************************/
int main(void)
{
char s[20];
int temp=0;
int time=0;
PINSEL0 = 0x00000000; // 设置管脚连接GPIO
IO0DIR =0x00000000; // 设置I/O为输入
Time0Init(); // 初始化定时器0
while(1)
{
T0TC=0;
T0PR=0;
temp=IO0PIN;
while((IO0PIN&(0x01<<9))!=0); //等待引脚电平变低
T0TCR=0x01; //启动定时器0
while((IO0PIN&(0x01<<9))==0); //等待引脚电平变高
T0TCR=0x00; //关闭定时器0
time=T0TC; //读取定时器的值,即为脉宽
sprintf(s,"%4d",time);
}
return(0);
}
以下为blog主人的回复:
|