在开发的过程中,我们经常会遇到在页面的底部有一排按钮,我们可以根据这些按钮切换页面,或者执行一些动作。在jquerymobile中我们可以在footer和header上添加这样的导航。下面看一个例子代码:
<!doctype html> <html> <head> <meta charset="utf-8"> <title>data-role="page"</title> <meta name="viewport" content="width=device-width,initial-scale=1" /> <link rel="stylesheet" href="/blog_article/jqm/jquery.mobile-1.2.0.min.css"/> <script src="/blog_article/jqm/jquery-1.8.2.min.js"></script> <script src="/blog_article/jqm/jquery.mobile-1.2.0.min.js"></script> </head> <body> <div data-role="page"> <div data-role="header"> <h1>Home</h1> <div data-role="navbar"> <ul> <li><a href="/blog_article/a.html" >Home</a></li> <li><a href="/blog_article/b.html" >Credits</a></li> <li><a href="/blog_article/c.html" >Contact</a></li> </ul> </div> </div> <div data-role="content"> <p> This is the Home Page </p> </div> <div data-role="footer" data-position="fixed" data-id="footernav"> <div data-role="navbar"> <ul> <li><a href="/blog_article/a.html" >Home</a></li> <li><a href="/blog_article/b.html" >Credits</a></li> <li><a href="/blog_article/c.html" >Contact</a></li> </ul> </div> </div> </div> </body> </html>
上述的代码中我们使用data-role="navbar"的div,这样jquerymobile会自动将div中li转换为相同的三个按钮。效果如下:
在使用一些手机应用的时候,在底部会有一个固定的导航或者叫做一组按钮,不会随着页面的切换而进行切换。使用jquerymobile我们也可以实现这样的效果,步骤如下:
1、在所有的页面中出现相同的footer
2、这些footer使用相同的data-id
3、在激活的页面对应的导航上添加两个class:ui-btn-active ui-state-persist
下面给出一个小例子:
<!doctype html> <html> <head> <meta charset="utf-8"> <title>data-role="page"</title> <meta name="viewport" content="width=device-width,initial-scale=1" /> <link rel="stylesheet" href="/blog_article/jqm/jquery.mobile-1.2.0.min.css"/> <script src="/blog_article/jqm/jquery-1.8.2.min.js"></script> <script src="/blog_article/jqm/jquery.mobile-1.2.0.min.js"></script> </head> <body> <div data-role="page"> <div data-role="page"> <div data-role="header"><h1>a</h1></div> <div data-role="content"> <p> This is the a Page </p> </div> <div data-role="footer" data-position="fixed" data-id="footernav"> <div data-role="navbar"> <ul> <li><a href="/blog_article/a.html" >a</a></li> <li><a href="/blog_article/b.html">b</a></li> </ul> </div> </div> </div> </div> </body> </html>
在b.html中修改如下:
<!doctype html> <html> <head> <meta charset="utf-8"> <title>data-role="page"</title> <meta name="viewport" content="width=device-width,initial-scale=1" /> <link rel="stylesheet" href="/blog_article/jqm/jquery.mobile-1.2.0.min.css"/> <script src="/blog_article/jqm/jquery-1.8.2.min.js"></script> <script src="/blog_article/jqm/jquery.mobile-1.2.0.min.js"></script> </head> <body> <div data-role="page"> <div data-role="page"> <div data-role="header"><h1>a</h1></div> <div data-role="content"> <p> This is the a Page </p> </div> <div data-role="footer" data-position="fixed" data-id="footernav"> <div data-role="navbar"> <ul> <li><a href="/blog_article/a.html">a</a></li> <li><a href="/blog_article/b.html" >b</a></li> </ul> </div> </div> </div> </div> </body> </html>
这样我们在这两个页面切换的时候,底部的导航栏至少在视觉上是感觉不出来动的,更深层次的我也没有研究。但是我猜测jquerymobile是固定了,然后在Dom中更新上面的内容,只是猜测没有根据。
原创作品,转载请注明原作者及地址!
by 飞鸿惊雪
http://blog.csdn.net/niyufeng
1 Learning ADSP-TS201系列--重要参考
2 Learning ADSP-TS201系列--EZ-KIT Lite评估板硬件资源
3 Learning ADSP-TS201系列--Flag Pins按键和LED灯
4 Learning ADSP-TS201系列--Interrupt Pin
Learning ADSP-TS201系列--Interrupt Pin
上一篇截图中还有另外的两个按键SW4和SW5,这两个按键涉及到中断,本篇就讲这个最简单的中断Interrupt Pin(IRQ0),后续再尝试其他的中断,例如timer定时计数器,DMA中断。。。
ADSP-TS201 EZ-KIT Lite评估板上每片DSP含有4个外部中断(IRQ3–0 ),其中IRQ0接到了一个按键上(SW4和SW5)。
当按键按下时,表现为低电平(可采用高低电平触发中断的模式)。
涉及到中断的主要有以下这几个寄存器:ILAT,IMASK,PMASK,以及SQCTL下的GIE位控制全局中断,和INTCTL控制IRQ3-0的触发方式、TIME1-0的启动。
ILAT,IMASK,PMASK这三者“相与”指明了正在执行的中断为哪一个。
ILAT:中断锁存寄存器,只要发生中断相应位置1;
IMASK:中断屏蔽寄存器,只有置1才允许响应相应的中断;
PMASK:锁存正在执行的中断,如果允许中断嵌套,只有在高于目前PMASK位的中断才可以响应。
2.1 ILAT IMASK PMASK (H)寄存器
我们本次要试验的IRQ0就在(H)寄存器中!
INTCTL控制IRQ3-0的触发方式、TIME1-0的启动。
SQCTL下的SQCTL_GIE位控制全局中断。
SQCTL还有两个别名SQCTLST和SQCTLCL。
和一般的单片机如MCS-51,MSP430,以及ARM处理器相比,DSP的中断很独特。
它的中断向量表是有专门的寄存器组来存储,而非像ARM处理、单片机那样放在存储器中,更不需要ARM那样复杂的地址映射之类操作。
第一种在C中定义中断服务程序的方法: 1 首先编写一个C函数,返回值和参数都是void;
void irq0_isr(void) {...}
2 将#pragma interrupt放在这个函数前面,定义这个函数为不可重入的中断服务;
#pragma interrupt void irq0_isr(void) {...}
3 在main中通过__builtin_sysreg_write将服务程序的函数指针放入中断向量表中,例如IRQ0的服务程序为irq0_isr,则:
__builtin_sysreg_write(__IVIRQ0, (int)irq0_isr);
第二种在C中定义中断服务程序的方法: 1 首先编写一个C函数,返回值是void(无返回),有一个参数int型;
void isr_irq0(int signal) {...}
2 不需将#pragma interrupt放在这个函数前面!
3 添加#include<signal.h>头文件(其中包含了SIGIRQ0等各种中断信号的定义),在main中通过interrupt系列函数将服务程序的函数指针放入中断向量表中,例如IRQ0的服务程序为isr_irq0,则:
interrupt(SIGIRQ0, isr_irq0);
4 编程实验
#include<stdio.h> #include<builtins.h> #include<sysreg.h> #include<defts201.h> #include<signal.h> void isr_irq0(int dummy); int main( void ) { //将FLAG2设为输出模式 __builtin_sysreg_write(__FLAGREGST,FLAGREG_FLAG2_EN); //允许外部IRQ0 int imaskh=0; imaskh = __builtin_sysreg_read(__IMASKH); imaskh |= (1<<INT_IRQ0_P); __builtin_sysreg_write(__IMASKH, imaskh); //设置IRQ0中断服务程序 interrupt(SIGIRQ0, isr_irq0); //设置跳沿触发 __builtin_sysreg_write(__INTCTL,0); //开全局中断使能 __builtin_sysreg_write(__SQCTLST, SQCTL_GIE); while(1); } void isr_irq0(int signal) { static int button=0; //按键按下进入本中断服务,每次都反转下button状态 button = !button; if(0==button){ __builtin_sysreg_write(__FLAGREGCL,~FLAGREG_FLAG2_OUT); } else { __builtin_sysreg_write(__FLAGREGST,FLAGREG_FLAG2_OUT); } }
对比上一个中断程序的写法,再列出另一中中断服务完整程序。
#include<stdio.h> #include<builtins.h> #include<sysreg.h> #include<defts201.h> void irq0_isr(void); int main( void ) { int v; //将FLAG2设为输出模式 __builtin_sysreg_write(__FLAGREGST,FLAGREG_FLAG2_EN); //设置IRQ0服务程序 __builtin_sysreg_write(__IVIRQ0,(int)irq0_isr); //设置跳沿触发 __builtin_sysreg_write(__INTCTL,0); //允许外部IRQ0 v=__builtin_sysreg_read(__IMASKH); v|=(1<<INT_IRQ0_P); __builtin_sysreg_write(__IMASKH,v); //开全局中断使能 __builtin_sysreg_write(__SQCTLST,SQCTL_GIE); while(1); } #pragma interrupt void irq0_isr(void) { static int button=0; button=!button; if(0==button){ __builtin_sysreg_write(__FLAGREGCL,~FLAGREG_FLAG2_OUT); } else { __builtin_sysreg_write(__FLAGREGST,FLAGREG_FLAG2_OUT); } }
ADSP-TS201 EZ-KIT Lite评估板上面有两个DSP处理器A和B。Emulator仿真时,如果不定义LDF链接文件,默认使用DSP_B。
最右边的两个LDE和3个Button按键就是DSP_B的,注意看右起第二个LED,可以使用按钮进行亮灭的控制。
#include <errno.h> //一些错误信息的处理
#include <stdio.h> // 标准输入输出
#include <sys/types.h> //基本系统数据类型
#include <netinet/in.h> //Internet address family 定义像sockaddr_in这个的地址族
#include <sys/socket.h> //socket
#include <unistd.h> //系统定义符号常量的头文件,包含了许多UNIX系统服务的函数原型,例如read函数、write函数
#include <netdb.h> //netdb.h 定义了与网络有关的结构,变量类型,宏,函数。如:struct hostent *gethostbyaddr(const void *addr, size_t len, int type);
#include <arpa/inet.h> // 定义了 inet_addr
#include <fcntl.h> //fcntl.h定义了很多宏和open,fcntl函数原型 close等
#include <stdlib.h> //标准库
#include <string.h> //string
int main(int argc, const char * argv[])
{
int sfp,nfp; //套接字描述符
struct sockaddr_in s_add,c_add; //服务端和客户端地址
unsigned int sin_size;
unsigned short portnum=3000; //绑定端口号
printf("Hello,welcome to my server !\r\n");
sfp = socket(AF_INET, SOCK_STREAM, 0); //套接字描述符
if(-1 == sfp)//如果失败
{
printf("socket fail ! \r\n");
return -1;
}
printf("socket ok !\r\n");
bzero(&s_add,sizeof(struct sockaddr_in));//清0
s_add.sin_family=AF_INET;
s_add.sin_addr.s_addr=htonl(INADDR_ANY);// 任何地址
s_add.sin_port=htons(portnum);//端口号
if(-1 == bind(sfp,(struct sockaddr *)(&s_add), sizeof(struct sockaddr))) //如果绑定失败
{
printf("bind fail !\r\n");
return -1;
}
printf("bind ok !\r\n");
if(-1 == listen(sfp,5))//如果listen失败
{
printf("listen fail !\r\n");
return -1;
}
printf("listen ok\r\n");
while(1)
{
sin_size = sizeof(struct sockaddr_in);
nfp = accept(sfp, (struct sockaddr *)(&c_add), &sin_size);//不断accept
//如果accpet成功的话,客户端的一些信息就在 c_add 中
if(-1 == nfp)//失败
{
printf("accept fail !\r\n");
return -1;
}
printf("accept ok!\r\nServer start get connect from %#x : %#x\r\n",
ntohl(c_add.sin_addr.s_addr),ntohs(c_add.sin_port));
// 打印客户端的地址和端口
if(-1 == write(nfp,"hello,welcome to my server \r\n",32))//写入数据
{
printf("write fail!\r\n");
return -1;
}
printf("write ok!\r\n");
close(nfp);//关闭
}
close(sfp);//关闭
return 0;
}
#include <errno.h>
#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int cfd;//套接字描述符
ssize_t recbytes;//接受字节长度
char buffer[1024]={0};//接收字节缓存区
struct sockaddr_in s_add;//连接的地址
unsigned short portnum=3000;//连接端口
printf("Hello,welcome to client !\r\n");
cfd = socket(AF_INET, SOCK_STREAM, 0);
if(-1 == cfd)
{
printf("socket fail ! \r\n");
return -1;
}
printf("socket ok !\r\n");
bzero(&s_add,sizeof(struct sockaddr_in));//清空
s_add.sin_family=AF_INET;
s_add.sin_addr.s_addr= inet_addr("192.168.1.101");
s_add.sin_port=htons(portnum);
printf("s_addr = %#x ,port : %#x\r\n",s_add.sin_addr.s_addr,s_add.sin_port);
if(-1 == connect(cfd,(struct sockaddr *)(&s_add), sizeof(struct sockaddr)))//开始连接
{
printf("connect fail !\r\n");
return -1;
}
printf("connect ok !\r\n");
ssize_t num=1024;
if(-1 == (recbytes = read(cfd,buffer,num)))//如果读取失败
{
printf("read data fail !\r\n");
return -1;
}
printf("read ok\r\nREC:\r\n");
buffer[recbytes]='\0';
printf("%s\r\n",buffer);
getchar();
close(cfd);
return 0;
}