RTC
概述
在系统电源关掉时RTC可以在备份电池的支持下来工作.RTC可以使用STRB/LDRB指令传输8bit的BCD值到CPU.数据包括秒,分,时,日期,天,月和年.RTC工作在外部32.768KHz的晶振下,而且有报警功能.
属性
BCD:秒,分,时,日期,天,月和年
闰年产生器
报警功能:报警中断 从power-off模式唤醒
独立的电源管脚(RTCVDD)
为RTOS kernel time tick支持毫秒级的tick.
闰年产生器
闰年产生器通过BCDDATA,BCDMON和BCDYEAR来决定每个月最后一天的日期.一个8bit的计数器只能表示两个BCD码,所以无法决定'00'年是否是闰年.举个例子,它不能区分1900和2000.为了解决这个问题,s3c2440的RTC模块在硬件逻辑上支持闰年是2000.1900不是闰年而2000时闰年.因此s3c2440的00表示2000,而不是1900.
READ/WRITE REGISTERS
为了写BCD寄存器,RTCCON寄存器的第0位必须置高.为了显示秒,分,时,日期,月和年,CPU从BCDSEC,BCDMIN,BCDHOUR,BCDDAY,BCDDATE,BCDMON和BCDYEAR寄存器中读数据.然而,在读取多个寄存器时,可能会有1秒的偏移.比如,当user读数据的时候,假设结果是2059(Year),12(Month),31(Date),23(Hour)和59(Minute).当user读BCDSEC寄存器,值的范围是1--59s,到这没有问题,但是,如果这个值是0s,由于刚才提到的那一s的偏移,年月日时分就会变为2060(year),1(Month),1(Date),0(Hour)和0(Minute).在这种情况下,如果BCDSEC是0 user应该重读各个寄存器.
BACKUP BATTERY OPERATION
RTC由备份电池驱动,及时系统电源断了,备份电池可以通过RTCVDD管脚向RTC模块供电.当系统关闭,CPU和RTC逻辑之间的接口是封闭的,备份电池只是驱动晶振电路和BCD计数器来减少电源消耗.
ALARM FUNCTION
在power-off模式或者正常操作模式下,RTC可以在一个指定的时间产生一个报警信号.在正常操作模式下,报警中断(INT_RTC)是激活的.在power-off模式,电源管理唤醒信号(PMWKUP)和INT_RTC都是激活的.RTC报警寄存器(RTCALM)决定是否开启报警状态和报警时间的设置.
TICK TIME INTERRUPT
RTC的tick time用于中断请求.TICNT寄存器有中断使能位和中断的计数值.当tick time中断产生计数值为0.中断的周期:
Period = (n+1)/128 second
n:Tick time count value(1~127)
REAL TIME CLOCK SPECIAL REGISTERS
RTCCON
RTCCON控制4个bits,比如RTCEN控制BCD寄存器的读写使能,CLKSEL,CNTSEL和CLKRST是用于测试的.
RTCEN bit控制CPU与RTC之间的所有接口,所以在系统重启后应该在RTC控制程序中将其设为1来使能数据的读写.在电源关闭前,RTCEN应该清0来防止对RTC寄存器的不经意的写入.
Register Address R/W Description Reset Value
RTCCON 0x57000040(L)/0x57000043(B) R/W RTC control register 0x0
RTCCON Bit Description Initial State
RTCEN [0] RTC控制使能 0
注意:所有的RTC寄存器都要以字节为单位来访问,可以用STRB和LDRB汇编指令或者char类型的指针.
TICNT
Register Address R/W Description Reset Value
TICNT 0x57000044(L)/0x57000047(B) R/W(by byte) Tick time count register 0x0
TICNT BIT Description Initial State
TICK INT ENABLE [7] tick time 中断使能 0
TICK TIME COUNT [6:0] tick time 计数值(1~127) 000000
RTCALM
RTCALM决定alarm使能和alarm时间.在power-off模式下RTCALM寄存器通过INT_RTC和PWMKUP产生报警信号,而在正常模式下只通过INT_RTC.
Register Address R/W Description Reset Value
RTCALM 0x57000050(L)/0x57000053(B) R/W(by type) RTC报警控制寄存器 0x0
RTCALM Bit Description Initial State
ALMEN [6] 报警总开关 0
YEAREN [5] Year报警开关 0
MONREN [4] Month报警开关 0
DATEEN [3] Date报警开关 0
HOUREN [2] Hour报警开关 0
MINEN [1] Minute报警开关 0
SECEN [0] Second报警开关 0
ALMSEC
设置Second报警的具体秒数
ALMMIN
设置Minute报警的具体分钟数
ALMHOUR
设置Hour报警的具体小时数
ALMDATE
设置Date报警的具体日期
ALMMON
设置Mon报警的具体月份
ALMYEAR
设置Year报警的具体年份
BCDSEC BCDMIN BCDHOUR BCDDATE BCDMON BCDYEAR
用BCD码表示的秒 分 时 日期 月份 年
给出报警中断的rtc汇编和c代码如下,在报警中断时是调用PWM的蜂鸣器来做闹钟的:
start.S:
/* watchdog timer with disable reset copyleft@ dndxhej@gmail.com */ .equ NOINT, 0xc0 .equ GPBCON, 0x56000010 @led .equ GPBDAT, 0x56000014 @led .equ GPBUP, 0x56000018 @led .equ GPFCON, 0x56000050 @interrupt config .equ EINTMASK, 0x560000a4 .equ EXTINT0, 0x56000088 .equ EXTINT1, 0x5600008c .equ EXTINT2, 0x56000090 .equ INTMSK, 0x4A000008 .equ EINTPEND, 0x560000a8 .equ SUBSRCPND, 0x4a000018 .equ INTSUBMSK, 0x4a00001c .equ SRCPND, 0X4A000000 .equ INTPND, 0X4A000010 .equ GPHCON, 0x56000070 .equ GPHDAT, 0x56000074 .equ GPB5_out, (1<<(5*2)) .equ GPB6_out, (1<<(6*2)) .equ GPB7_out, (1<<(7*2)) .equ GPB8_out, (1<<(8*2)) .equ GPBVALUE, (GPB5_out | GPB6_out | GPB7_out | GPB8_out) .equ LOCKTIME, 0x4c000000 .equ MPLLCON, 0x4c000004 .equ UPLLCON, 0x4c000008 .equ M_MDIV, 92 .equ M_PDIV, 1 .equ M_SDIV, 1 .equ U_MDIV, 56 .equ U_PDIV, 2 .equ U_SDIV, 2 .equ CLKDIVN, 0x4c000014 .equ DIVN_UPLL, 0 .equ HDIVN, 1 .equ PDIVN, 1 @FCLK : HCLK : PCLK = 1:2:4 .equ WTCON, 0x53000000 .equ Pre_scaler, 249 .equ wd_timer, 1 .equ clock_select, 00 @316 .equ int_gen, 1 @开中断 .equ reset_enable, 0 @关掉重启信号 .equ WTDAT,0x53000004 .equ Count_reload,50000 @定时器定为2S PCLK = 100M PCLK/(Pre_scaler+1)/clock_select = 100M/(249+1)/16=25k 50000/25k=2s .equ WTCNT,0x53000008 .equ Count,50000 .equ TCFG0,0x51000000 .equ Prescaler1,0x00 @[15:8]Timer234 .equ Prescaler0,249 @[7:0]Timer01 .equ TCFG1,0x51000004 .equ DMA_MODE,0x0 @[23:20]no dma channal .equ MUX0,0x2 @[3:0] 1/8 @定时器输入时钟周期 = PCLK/(prescaler + 1)/(divider value) @clk = 100M/(249+1)/8=25k .equ TCON,0x51000008 .equ DZ_eable,0 @[4]关闭死区的操作 .equ auto_reload,1 @[3]auto_reload .equ inverter,1 @[2]打开电平反转 .equ man_update,1 @[1]手动更新 .equ clear_man_update,0 .equ start,1 @[0]开始 .equ stop,0 @[0]停止 .equ TCNTB0,0x5100000c .equ TCMPB0,0x51000010 .equ TCNTO0,0x51000014 .equ ULCON0, 0x50000000 .equ IR_MODE, 0x0 @[6]正常模式 .equ Parity_Mode, 0x0 @[5:3]无校验位 .equ Num_of_stop_bit, 0x0 @[2]一个停止位 .equ Word_length, 0b11 @[1:0]8个数据位 .equ UCON0, 0x50000004 .equ FCLK_Div, 0 @[15:12] 时钟源选择用PCLK,所以这里用默认值 .equ Clk_select, 0b00 @[11:10] 时钟源选择使用PCLK .equ Tx_Int_Type, 1 @[9] 中断请求类型为Level .equ Rx_Int_Type, 0 @1 @[8] 中断请求类型为Level .equ Rx_Timeout, 0 @[7] .equ Rx_Error_Stat_Int, 1 @[6] .equ Loopback_Mode, 0 @[5] 正常模式 .equ Break_Sig, 0 @[4] 不发送终止信号 .equ Tx_Mode, 0b01 @[3:2] 中断请求或轮循模式 .equ Rx_Mode, 0b01 @[1:0] 中断请求或轮循模式 .equ UFCON0, 0x50000008 .equ Tx_FIFO_Trig_Level, 0b00 @[7:6] .equ Rx_FIFO_Trig_Level, 0b00 @[5:4] .equ Tx_FIFO_Reset, 0b0 @[2] .equ Rx_FIFO_Reset, 0b0 @[1] .equ FIFO_Enable, 0b0 @[0] 非FIFO模式 .equ UMCON0, 0x5000000C @这个寄存器可以不管的 .equ UTRSTAT0, 0x50000010 .equ UERSTAT0, 0x50000014 .equ UFSTAT0, 0x50000018 .equ UMSTAT0, 0x5000001C .equ UTXH0, 0x50000020 @(L 小端) .equ URXH0, 0x50000024 @(L 小端) .equ UBRDIV0, 0x50000028 .equ UBRDIV, 0x35 @PCLK=400M/4=100M UBRDIV = (int)(100M/115200/16) - 1 = 53 = 0x35 .equ BCDMIN,0x57000074 .equ BCDSEC,0x57000070 //.global Buzzer_Freq_Set .global _start _start: b reset ldr pc, _undefined_instruction ldr pc, _software_interrupt ldr pc, _prefetch_abort ldr pc, _data_abort ldr pc, _not_used @b irq ldr pc, _irq ldr pc, _fiq _undefined_instruction: .word undefined_instruction _software_interrupt: .word software_interrupt _prefetch_abort: .word prefetch_abort _data_abort: .word data_abort _not_used: .word not_used _irq: .word irq _fiq: .word fiq .balignl 16,0xdeadbeef reset: ldr r3, =WTCON mov r4, #0x0 str r4, [r3] @ disable watchdog ldr r0, =GPBCON ldr r1, =0x15400 @这个时候暂不配置GPB0为TOUT0 str r1, [r0] ldr r2, =GPBDAT ldr r1, =0x160 str r1, [r2] bl clock_setup bl uart_init bl delay msr cpsr_c, #0xd2 @进入中断模式 ldr sp, =3072 @中断模式的栈指针定义 msr cpsr_c, #0xd3 @进入系统模式 ldr sp, =4096 @设置系统模式的栈指针 @-------------------------------------------- ldr r0, =GPBUP ldr r1, =0x03f0 str r1, [r0] ldr r0, =GPFCON ldr r1, =0x2ea@0x2 str r1, [r0] ldr r0, =EXTINT0 @ldr r1, =0x8f888@0x0@0x8f888 @~(7|(7<<4)|(7<<8)|(7<<16)) //低电平触发中断 ldr r1, =0xafaaa@0x0@0x8f888 //下降沿触发中断 str r1, [r0] ldr r0, =EINTPEND ldr r1, =0xf0@0b10000 str r1, [r0] ldr r0, =EINTMASK ldr r1, =0x00@0b00000 str r1, [r0] ldr r0, =SRCPND ldr r1, =0x3ff | (1<<30) @0x1@0b11111 str r1, [r0] ldr r0, =SUBSRCPND ldr r1, =0x1<<13 str r1, [r0] ldr r0, =INTPND ldr r1, =0x3ff | (1<<30) @0x1@0b11111 str r1, [r0] ldr r0, =INTSUBMSK ldr r1, =0x0<<13 str r1, [r0] ldr r0, =INTMSK ldr r1, =0x1ffff000@0b00000 str r1, [r0] MRS r1, cpsr BIC r1, r1, #0x80 MSR cpsr_c, r1 bl main irq: sub lr,lr,#4 stmfd sp!,{r0-r12,lr} bl irq_isr ldmfd sp!,{r0-r12,pc}^ irq_isr: ldr r2, =GPBDAT ldr r1, =0x0e0 str r1, [r2] ldr r3,=0xffffff delay2: sub r3,r3,#1 cmp r3,#0x0 bne delay2 //这上面的延时必须要,否则蜂鸣器的声音有问题 ldr r0,=EINTPEND ldr r1,=0xf0 str r1,[r0] ldr r0, =SRCPND ldr r1, =0x3ff | (1<<30) @0b11111 str r1, [r0] ldr r0, =SUBSRCPND ldr r1, =0x1<<13 str r1, [r0] ldr r0, =INTPND ldr r1, =0x3ff | (1<<30) @0b11111 str r1, [r0] ldr r2, =GPBCON ldr r1,[r2] ldr r1,[r1] //ldr r1, =0x15400 bic r1,r1,#0x3 orr r1,r1,#0x2 str r1,[r2] ldr r2, =GPBDAT ldr r1, =0x1a0 str r1, [r2] ldr r1,=TCFG0 ldr r2,=(Prescaler0<<0) str r2, [r1] ldr r1,=TCFG1 ldr r2,=(DMA_MODE<<20) | (MUX0<<0) str r2, [r1] // ldr r3,[r0] // str r3,[r2] //mov r2, r0 ldr r1,=TCNTB0 ldr r2,=10 str r2, [r1] //r0就是c调用汇编的传递参数 //mov r0,r0,LSR #2 ldr r1,=TCMPB0 ldr r2,=2 str r2, [r1] ldr r1,=TCON ldr r2,=(DZ_eable<<4) | (auto_reload<<3) | (inverter<<2) | (man_update<<1) | (start<<0) str r2, [r1] ldr r1,=TCON ldr r2,=(DZ_eable<<4) | (auto_reload<<3) | (inverter<<2) | (clear_man_update<<1) | (start<<0) str r2, [r1] ldr r2, =GPBDAT ldr r1, =0x1a0 str r1, [r2] mov pc,lr delay: ldr r3,=0xffffff delay1: sub r3,r3,#1 cmp r3,#0x0 bne delay1 mov pc,lr clock_setup: ldr r0,=LOCKTIME ldr r1,=0xffffffff str r1, [r0] ldr r0,=CLKDIVN ldr r1,=(DIVN_UPLL<<3) | (HDIVN<<1) | (PDIVN<<0) str r1, [r0] ldr r0,=UPLLCON ldr r1,=(U_MDIV<<12) | (U_PDIV<<4) | (U_SDIV<<0) @Fin=12M UPLL=48M str r1, [r0] nop nop nop nop nop nop nop ldr r0,=MPLLCON ldr r1,=(M_MDIV<<12) | (M_PDIV<<4) | (M_SDIV<<0) @Fin=12M FCLK=400M str r1, [r0] mov pc,lr uart_init: ldr r0,=GPHCON ldr r1,=0x2aaaa @配置GPIO复用规则为串口 str r1, [r0] ldr r0,=ULCON0 ldr r1,=(IR_MODE<<6) | (Parity_Mode<<3) | (Num_of_stop_bit<<2) | (Word_length<<0) @ str r1, [r0] ldr r0,=UCON0 ldr r1,=(FCLK_Div<<12) | (Clk_select<<10) | (Tx_Int_Type<<9) | (Rx_Int_Type<<8) | (Rx_Timeout<<7) | (Rx_Error_Stat_Int<<6) |(Loopback_Mode<<5) | (Break_Sig<<4) | (Tx_Mode<<2) | (Rx_Mode<<0) str r1, [r0] ldr r0,=UFCON0 ldr r1,=(Tx_FIFO_Trig_Level<<6) | (Rx_FIFO_Trig_Level<<4) | (Tx_FIFO_Reset<<2) | (Rx_FIFO_Reset<<1) | (FIFO_Enable<<0) @ str r1, [r0] ldr r0,=UBRDIV0 ldr r1,=(UBRDIV<<0) str r1, [r0] mov pc,lr /* Buzzer_Freq_Set: //ldr r0, =GPBCON //ldr r1, =0x15400 @这个时候暂不配置GPB0为TOUT0,这时候只是配置GPB0为TOUT0 //str r1, [r0] ldr r2, =GPBCON ldr r1,[r2] ldr r1,[r1] //ldr r1, =0x15400 bic r1,r1,#0x3 orr r1,r1,#0x2 str r1,[r2] ldr r2, =GPBDAT ldr r1, =0x1a0 str r1, [r2] ldr r1,=TCFG0 ldr r2,=(Prescaler0<<0) str r2, [r1] ldr r1,=TCFG1 ldr r2,=(DMA_MODE<<20) | (MUX0<<0) str r2, [r1] // ldr r3,[r0] // str r3,[r2] //mov r2, r0 ldr r1,=TCNTB0 ldr r2,=10 str r2, [r1] //r0就是c调用汇编的传递参数 //mov r0,r0,LSR #2 ldr r1,=TCMPB0 ldr r2,=2 str r2, [r1] ldr r1,=TCON ldr r2,=(DZ_eable<<4) | (auto_reload<<3) | (inverter<<2) | (man_update<<1) | (start<<0) str r2, [r1] ldr r1,=TCON ldr r2,=(DZ_eable<<4) | (auto_reload<<3) | (inverter<<2) | (clear_man_update<<1) | (start<<0) str r2, [r1] ldr r2, =GPBDAT ldr r1, =0x1a0 str r1, [r2] mov pc,lr */ main: ldr r2, =GPBDAT ldr r1, =0x1a0 str r1, [r2] bl delay //ldr r1,=TCON //ldr r2,=(DZ_eable<<4) | (auto_reload<<3) | (inverter<<2) | (man_update<<1) | (stop<<0) //str r2, [r1] /* ldr r2, =GPBCON ldr r1,[r2] ldr r1,[r1] //ldr r1, =0x15400 bic r1,r1,#0x3 orr r1,r1,#0x2 str r1,[r2] ldr r0,=TCFG0 ldr r1,=(Prescaler0<<0) str r1, [r0] ldr r0,=TCFG1 ldr r1,=(DMA_MODE<<20) | (MUX0<<0) str r1, [r0] ldr r0,=TCNTB0 ldr r1,=10 str r1, [r0] ldr r0,=TCMPB0 ldr r1,=2 str r1, [r0] ldr r0,=TCON ldr r1,=(DZ_eable<<4) | (auto_reload<<3) | (inverter<<2) | (man_update<<1) | (start<<0) str r1, [r0] ldr r0,=TCON ldr r1,=(DZ_eable<<4) | (auto_reload<<3) | (inverter<<2) | (clear_man_update<<1) | (start<<0) str r1, [r0] */ ldr lr, =loop // ldr pc, _rtc_uart_test //_rtc_uart_test: .word rtc_uart_test bl rtc_uart_test ldr r2, =GPBDAT ldr r1, =0x1c0 str r1, [r2] bl delay loop: ldr r2, =BCDSEC @BCDMIN ldr r1,[r2] cmp r1, #0x06 bleq ledon b loop @ 死循环 ledon: ldr r2, =GPBDAT ldr r1, =0x160 str r1, [r2] ldr r3,=0xffffff delay3: sub r3,r3,#1 cmp r3,#0x0 bne delay3 mov pc,lr undefined_instruction: nop software_interrupt: nop prefetch_abort: nop data_abort: nop not_used: nop fiq: nop
rtc_uart_test.s:
#include <stdarg.h> #include <string.h> #include <stdlib.h> #include <stdio.h> #include <ctype.h> #include "rtc_uart_test.h" extern void Buzzer_Freq_Set(int freq); //extern void Buzzer_Freq_Set( void ); char uart_GetByte(void) { while(!(rUTRSTAT0 & 0x1)); //Wait until THR is empty. return RdURXH0(); } void uart_GetString(char *pt) { while(*pt) uart_GetByte(); } void uart_SendByte(int data) { if(data=='\n') { while(!(rUTRSTAT0 & 0x2)); WrUTXH0('\r'); } while(!(rUTRSTAT0 & 0x2)); //Wait until THR is empty. WrUTXH0(data); } //==================================================================== void uart_SendString(char *pt) { while(*pt) uart_SendByte(*pt++); } void uart_Printf(char *fmt,...) { va_list ap; char string[256]; va_start(ap,fmt); //vsprintf(string,fmt,ap); uart_SendString(string); va_end(ap); } void uart_test(void) { char str[20] = "\nhello world\n"; int a = 97; //while(1) // uart_SendByte(a); uart_SendString(str); char s = uart_GetByte(); //if(s == 'a') if(s == 97) rGPBDAT = 0x1c0; //uart_SendByte(a); //uart_SendByte(97); //uart_SendByte('a'); uart_SendByte((int)s); uart_SendByte((int)'s'); } void rtc_uart_test(void) { rRTCCON = 0x1; rTICNT = 0x0; rRTCALM = 0x42; rBCDYEAR = 0x10 ; rBCDMON = 0x11 ; rBCDDATE = 0x07 ; rBCDDAY = 0x05 ; rBCDHOUR = 0x12 ; rBCDMIN = 0x03 ; rBCDSEC = 0x00 ; rALMMIN = 0x04; uart_SendString("begin\n"); //uart_Printf("year:%d\n",rBCDYEAR); } void pwm_uart_test(void) { int freq = 10; int i; for(i=0; i<100;i++) uart_SendString("app\n"); //Buzzer_Freq_Set( freq ) ; //Buzzer_Freq_Set( ) ; //uart_test(); uart_SendString("start\n"); /* int i; for(i=0;i<1000;i++) uart_SendString("wait\n"); while( 1 ) { char key = uart_GetByte(); uart_SendByte(key); if( key == 'a' || key == 'A' ) { if( freq < 2000 ) //lci 20000 freq += 10 ; uart_SendByte('a'); Buzzer_Freq_Set( freq ) ; } if( key == 'b' || key == 'B' ) { if( freq > 11 ) freq -= 10 ; uart_SendByte('b'); Buzzer_Freq_Set( freq ) ; } //uart_SendString( "\tFreq = %d\n", freq ) ; //if( key == ESC_KEY ) //{ // Buzzer_Stop() ; // return ; //} } */ }
在调这个过程中,因为RTCCON中的CLKRST最初被我置为1,导致时间根本不走,为了查这个问题,专门通过led显示来判断这个时间是不是不走:
ldr r2, =BCDSEC @BCDMIN
ldr r1,[r2]
cmp r1, #0x06
bleq ledon
通过这里的判断,可以明确时间有被设进去,可是时间不走.经过google,才确定是寄存器的设置问题.
到此,rtc的闹钟也实现了功能.明天就用这个做闹钟吧~~
转载请注明出处:http://blog.csdn.net/horkychen
1. XCode 4打开时,自动加载上次的工程,需要较长时间。
这是因为Lion提供了新功能让应用程序恢复上次关闭时的状态。如果仅是临时不希望下去打开时不要打开现在使用的项目,可以在退出使用CMD+Q+OPTION代替CMD+Q。
如果默认不希望再打开,就可以使用下面的指令:
defaults write com.apple.Xcode ApplePersistenceIgnoreState YES
*对其它程序,只要改变中间的App ID就可以了。
2. 在Mac Lion下使用XCode 4时,调试大型的工程,速度慢得让人无语。划到一个地方,就可能让你一顿慢悠悠的等待。XCode 4的indexing系统消耗太大,这会导致在调试时经常会卡住。它带来的好处很多,比如自动补全、查找定义等。但为了提升调试的性能,可以使用下面的方式:
defaults write com.apple.dt.Xcode IDEIndexDisable 1
* 需要时候,把1改为0就可以了。
3. 编译速度优化
正像在VS2010使用/MP选项提供多进程编译一样。XCode也有相似的功能,可以使用下面的指令设定:
defaults write com.apple.Xcode PBXNumberOfParallelBuildSubtasks 8
defaults write com.apple.Xcode IDEBuildOperationMaxNumberOfConcurrentCompileTasks 8
* 8是你期望的并行的编译进程数
备注:
defaults是Mac OS下用于改写应用程序的Preference文件的指令,而对应的preference文件可以在~/Library/Preferences下找到。
详细的说明可以官方的这个地址找到: XCode User Defaults.
2楼HorkyChen昨天 21:28我猜你说的“不懂”指的是第2点吧,我是遇到问题后在Stack Overflow上查到的。下面是两个链接给你参考:n 1. How to disable indexing in Xcode 4? n http://stackoverflow.com/questions/5392139/how-to-disable-indexing-in-xcode-4n 2. Disable indexing in XCode 4 for better performancen http://www.kumobius.com/2011/09/disable-indexing-in-xcode-4-for-better-performance/1楼lixing333前天 13:12看不太懂啊。。。请问这些内容在哪里有介绍?
/*
* 建立自己的手写笔画图案
* Gesture对象是自GestureOverlay.getGesture()所取得的手写
* 对象。GestureLibraries保存手写背后所包含的意义,程序中利
* 用GestureLibraries.fromFile()方法来加载预设的Gesture文件
* 倘若默认手机的SD存储卡中尚未创建Gesture手写数据文件,此程序
* 也会处理创建新文件的工作。此外还应用了GestureLibraries.addGesture()
* 新建手写数据;GestureLibraries.save()保存写入的手写数据
* GestureLibraries.load()加载手写数据;GestureLibraries.removeGesture()
* 删除手写数据等方法。
*/
import 略;
public class Ex05_25Activity extends Activity { private Gesture ges; private GestureLibrary lib; private GestureOverlayView overlay; private Button bt1, bt2; private EditText et; private String getPath; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 查看SD卡是否存在 if (!Environment.MEDIA_MOUNTED.equals(Environment .getExternalStorageState())) { // SD卡不存在,提示信息 Toast.makeText(Ex05_25Activity.this, "SD卡不存在,程序无法执行!", Toast.LENGTH_SHORT).show(); this.finish(); } et = (EditText) findViewById(R.id.myEditText1); bt1 = (Button) findViewById(R.id.myButton1); bt2 = (Button) findViewById(R.id.myButton1); overlay = (GestureOverlayView) findViewById(R.id.myGestures1); // 取得系统默认的GestureLibrary文件路径 getPath = new File(Environment.getExternalStorageDirectory(), "gestures").getAbsolutePath(); // 设置EditText的onKeyListener et.setOnKeyListener(new EditText.OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { // TODO Auto-generated method stub // 名称和手写都设置好时 将新建的Button enable if (ges != null && et.getText().length() != 0) { bt1.setEnabled(true); } else { bt1.setEnabled(false); } return false; } }); // 设置overlay的OnGestureListener overlay.addOnGestureListener(new GestureOverlayView.OnGestureListener() { // 开始手写时将添加的Button disable,并清除Gesture @Override public void onGestureStarted(GestureOverlayView overlay, MotionEvent event) { // TODO Auto-generated method stub bt1.setEnabled(false); ges = null; } // 手写完时判断名称和手写时候完整建立 @Override public void onGestureEnded(GestureOverlayView overlay, MotionEvent event) { // TODO Auto-generated method stub ges = overlay.getGesture(); if (ges != null && et.getText().length() != 0) { bt1.setEnabled(true); } } @Override public void onGestureCancelled(GestureOverlayView overlay, MotionEvent event) { // TODO Auto-generated method stub } @Override public void onGesture(GestureOverlayView overlay, MotionEvent event) { // TODO Auto-generated method stub } }); bt1.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub String gesName = et.getText().toString(); try { File file = new File(getPath); lib = GestureLibraries.fromFile(getPath); if (!file.exists()) { // 文件不存在就直接写入 lib.addGesture(gesName, ges); if (lib.save()) {// 保存成功 // 将设置画面数据清除 et.setTag(""); bt1.setEnabled(false); overlay.clear(true); Toast.makeText( Ex05_25Activity.this, getString(R.string.save_success) + ":" + getPath, Toast.LENGTH_SHORT) .show(); } else {// 保存失败 Toast.makeText( Ex05_25Activity.this, getString(R.string.save_failed) + ":" + getPath, Toast.LENGTH_LONG) .show(); } } else {// 文件存在时,想读取以保存的Gesture if (!lib.load()) {// 读取失败 Toast.makeText( Ex05_25Activity.this, getString(R.string.load_failed) + ":" + getPath, Toast.LENGTH_SHORT) .show(); } else {// 读取成功 // 如果存在相同的名称,则先将其移除再写入 Set<String> en = lib.getGestureEntries(); if (en.contains(gesName)) { ArrayList<Gesture> al = lib .getGestures(gesName); for (int i = 0; i < al.size(); i++) { lib.removeGesture(gesName, al.get(i)); } } lib.addGesture(gesName, ges); if (lib.save()) {// 保存成功 // 将设置画面数据清除 et.setTag(""); bt1.setEnabled(false); overlay.clear(true); Toast.makeText( Ex05_25Activity.this, getString(R.string.save_success) + ":" + getPath, Toast.LENGTH_SHORT) .show(); } else {// 保存失败 Toast.makeText( Ex05_25Activity.this, getString(R.string.save_failed) + ":" + getPath, Toast.LENGTH_LONG) .show(); } } } } catch (Exception e) { e.printStackTrace(); } } }); bt2.setOnClickListener(new Button.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub et.setText(""); bt1.setEnabled(false); overlay.clear(true); } }); } }
main.xml文件代码:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/white" android:orientation="vertical" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/myTextView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/title" android:textColor="@drawable/blue" /> <EditText android:id="@+id/myEditText1" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout> <android.gesture.GestureOverlayView android:id="@+id/myGestures1" android:layout_width="fill_parent" android:layout_height="0dip" android:layout_weight="1.0" android:gestureStrokeType="multiple" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <Button android:id="@+id/myButton1" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:enabled="false" android:text="@string/button_done" /> <Button android:id="@+id/myButton2" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:text="@string/button_cancel" /> </LinearLayout> </LinearLayout>
下面我们来看看程序运行后的结果: