STM32F10x 学习笔记6(USART实现串口通讯 2)
这次讲讲利用串口收发中断来进行串口通讯。STM32 上为每个串口分配了一个中断。也就是说无论是发送完成还是收到数据或是数据溢出都产生同一个中断。程序需在中断处理函数中读取状态寄存器(USART_SR)来判断当前的是什么中断。下面的中断映像图给出了这些中断源是如何汇合成最终的中断信号的。图中也给出了如何控制每一个单独的中断源是否起作用。
另外,Cortex-M3 内核中还有个NVIC,可以控制这里的中断信号是否触发中断处理函数的执行,还有这些外部中断的级别。关于NVIC 可以参考《ARM CortexM3 权威指南》,里面讲解的非常详细。
简单的说,为了开启中断,我们需要如下的代码:
NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ; NVIC_InitStructure.NVIC_IRQChannelSubPriority = ; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启接收中断 USART_ITConfig(USART1, USART_IT_TXE, ENABLE); // 开启发送中断
这里多说一句,串口的发送中断有两个,分别是:
- l发送数据寄存器空中断(TXE)
- l发送完成中断(TC)
一般来说我们会使用发送数据寄存器空中断,用这个中断发送的效率会高一些。
中断处理函数的框架如下,如果检测到错误就清除错误,收到数了就处理。发完当前数据了就发下一个。
void USART1_IRQHandler(void)
{
unsigned int data;
if(USART1->SR & 0x0F)
{
// See if we have some kind of error, Clear interrupt
data = USART1->DR;
}
else if(USART1->SR & USART_FLAG_RXNE) //Receive Data Reg Full Flag
{
data = USART1->DR;
// 对收到的数据进行处理,或者干些其他的事
}
else if(USART1->SR & USART_FLAG_TXE)
{
{ // 可以发送数据了,如果没有数据需要发送,就在这里关闭发送中断
USART1->DR = something; // Yes, Send character
}
}
}
下面给一个利用环形缓冲区的串口驱动程序。
#ifndef _COM_BUFFERED_H_ #define _COM_BUFFERED_H_ #define COM1 0 #define COM2 1 #define COM_RX_BUF_SIZE 64 /* Number of characters in Rx ring buffer */ #define COM_TX_BUF_SIZE 64 /* Number of characters in Tx ring buffer */ #define COM_NO_ERR 0 /* Function call was successful */ #define COM_BAD_CH 1 /* Invalid communications port channel */ #define COM_RX_EMPTY 2 /* Rx buffer is empty, no character available */ #define COM_TX_FULL 3 /* Tx buffer is full, could not deposit character */ #define COM_TX_EMPTY 4 /* If the Tx buffer is empty. */ /************************************************************ * function : COMGetCharB * parameter: char port, port can be COM1 / COM2 * parameter: char* err is a pointer to where an error code will be placed: * *err is set to COM_NO_ERR if a character is available * *err is set to COM_RX_EMPTY if the Rx buffer is empty * *err is set to COM_BAD_CH if you have specified an invalid channel * return : char * usage : This function is called by your application to obtain a character from the communications * channel. * changelog: *************************************************************/ unsigned char COMGetCharB (unsigned char ch, unsigned char *err); /************************************************************ * function : COMPutCharB * parameter: char port, port can be COM1 / COM2 * return : COMM_NO_ERR if the function was successful (the buffer was not full) * COMM_TX_FULL if the buffer was full * COMM_BAD_CH if you have specified an incorrect channel * usage : This function is called by your application to send a character on the communications * channel. The character to send is first inserted into the Tx buffer and will be sent by * the Tx ISR. If this is the first character placed into the buffer, the Tx ISR will be * enabled. If the Tx buffer is full, the character will not be sent (i.e. it will be lost) * changelog: *************************************************************/ unsigned char COMPutCharB (unsigned char port, unsigned char c); /************************************************************ * function : COMBufferInit * parameter: * return : * usage : This function is called by your application to initialize the communications module. You * must call this function before calling any other functions. * changelog: *************************************************************/ void COMBufferInit (void); /************************************************************ * function : COMBufferIsEmpty * parameter: char port, port can be COM1 / COM2 * return : char * usage : This function is called by your application to see * if any character is available from the communications channel. * If at least one character is available, the function returns * FALSE(0) otherwise, the function returns TRUE(1). * changelog: *************************************************************/ unsigned char COMBufferIsEmpty (unsigned char port); /************************************************************ * function : COMBufferIsFull * parameter: char port, port can be COM1 / COM2 * return : char * usage : This function is called by your application to see if any more characters can be placed * in the Tx buffer. In other words, this function check to see if the Tx buffer is full. * If the buffer is full, the function returns TRUE otherwise, the function returns FALSE. * changelog: *************************************************************/ unsigned char COMBufferIsFull (unsigned char port); #endif
/*
* file: com_buffered.c
* author: Li Yuan
* platform: STM32F107
* date: 2013-5-5
* version: 0.0.1
* description: UART Ring Buffer
**/
#include "stm32f10x_usart.h"
#include "com_buffered.h"
#define OS_ENTER_CRITICAL() __set_PRIMASK(1)
#define OS_EXIT_CRITICAL() __set_PRIMASK(0)
/**
* Enables Transmiter interrupt.
**/
static void COMEnableTxInt(unsigned char port)
{
] = {USART1, USART2};
USART_ITConfig(map[port], USART_IT_TXE, ENABLE);
}
/*
*********************************************************************************************************
* DATA TYPES
*********************************************************************************************************
*/
typedef struct {
short RingBufRxCtr; /* Number of characters in the Rx ring buffer */
unsigned char *RingBufRxInPtr; /* Pointer to where next character will be inserted */
unsigned char *RingBufRxOutPtr; /* Pointer from where next character will be extracted */
unsigned char RingBufRx[COM_RX_BUF_SIZE]; /* Ring buffer character storage (Rx) */
short RingBufTxCtr; /* Number of characters in the Tx ring buffer */
unsigned char *RingBufTxInPtr; /* Pointer to where next character will be inserted */
unsigned char *RingBufTxOutPtr; /* Pointer from where next character will be extracted */
unsigned char RingBufTx[COM_TX_BUF_SIZE]; /* Ring buffer character storage (Tx) */
} COM_RING_BUF;
/*
*********************************************************************************************************
* GLOBAL VARIABLES
*********************************************************************************************************
*/
COM_RING_BUF COM1Buf;
COM_RING_BUF COM2Buf;
/************************************************************
* function : COMGetCharB
* parameter: char port, port can be COM1 / COM2
* parameter: char* err is a pointer to where an error code will be placed:
* *err is set to COM_NO_ERR if a character is available
* *err is set to COM_RX_EMPTY if the Rx buffer is empty
* *err is set to COM_BAD_CH if you have specified an invalid channel
* return : char
* usage : This function is called by your application to obtain a character from the communications
* channel.
* changelog:
*************************************************************/
unsigned char COMGetCharB (unsigned char port, unsigned char *err)
{
// unsigned char cpu_sr;
unsigned char c;
COM_RING_BUF *pbuf;
switch (port)
{ /* Obtain pointer to communications channel */
case COM1:
pbuf = &COM1Buf;
break;
case COM2:
pbuf = &COM2Buf;
break;
default:
*err = COM_BAD_CH;
);
}
OS_ENTER_CRITICAL();
) /* See if buffer is empty */
{
pbuf->RingBufRxCtr--; /* No, decrement character count */
c = *pbuf->RingBufRxOutPtr++; /* Get character from buffer */
if (pbuf->RingBufRxOutPtr == &pbuf->RingBufRx[COM_RX_BUF_SIZE])
{
pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[]; /* Wrap OUT pointer */
}
OS_EXIT_CRITICAL();
*err = COM_NO_ERR;
return (c);
} else {
OS_EXIT_CRITICAL();
*err = COM_RX_EMPTY;
c = ; /* Buffer is empty, return 0 */
return (c);
}
}
/************************************************************
* function : COMPutCharB
* parameter: char port, port can be COM1 / COM2
* return : COMM_NO_ERR if the function was successful (the buffer was not full)
* COMM_TX_FULL if the buffer was full
* COMM_BAD_CH if you have specified an incorrect channel
* usage : This function is called by your application to send a character on the communications
* channel. The character to send is first inserted into the Tx buffer and will be sent by
* the Tx ISR. If this is the first character placed into the buffer, the Tx ISR will be
* enabled. If the Tx buffer is full, the character will not be sent (i.e. it will be lost)
* changelog:
* 1.first implimented by liyuan 2010.11.5
*************************************************************/
unsigned char COMPutCharB (unsigned char port, unsigned char c)
{
// unsigned char cpu_sr;
COM_RING_BUF *pbuf;
switch (port)
{ /* Obtain pointer to communications channel */
case COM1:
pbuf = &COM1Buf;
break;
case COM2:
pbuf = &COM2Buf;
break;
default:
return (COM_BAD_CH);
}
OS_ENTER_CRITICAL();
if (pbuf->RingBufTxCtr < COM_TX_BUF_SIZE) { /* See if buffer is full */
pbuf->RingBufTxCtr++; /* No, increment character count */
*pbuf->RingBufTxInPtr++ = c; /* Put character into buffer */
if (pbuf->RingBufTxInPtr == &pbuf->RingBufTx[COM_TX_BUF_SIZE]) { /* Wrap IN pointer */
pbuf->RingBufTxInPtr = &pbuf->RingBufTx[];
}
) { /* See if this is the first character */
COMEnableTxInt(port); /* Yes, Enable Tx interrupts */
OS_EXIT_CRITICAL();
} else {
OS_EXIT_CRITICAL();
}
return (COM_NO_ERR);
} else {
OS_EXIT_CRITICAL();
return (COM_TX_FULL);
}
}
/************************************************************
* function : COMBufferInit
* parameter:
* return :
* usage : This function is called by your application to initialize the communications module. You
* must call this function before calling any other functions.
* changelog:
*************************************************************/
void COMBufferInit (void)
{
COM_RING_BUF *pbuf;
pbuf = &COM1Buf; /* Initialize the ring buffer for COM0 */
pbuf->RingBufRxCtr = ;
pbuf->RingBufRxInPtr = &pbuf->RingBufRx[];
pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[];
pbuf->RingBufTxCtr = ;
pbuf->RingBufTxInPtr = &pbuf->RingBufTx[];
pbuf->RingBufTxOutPtr = &pbuf->RingBufTx[];
pbuf = &COM2Buf; /* Initialize the ring buffer for COM1 */
pbuf->RingBufRxCtr = ;
pbuf->RingBufRxInPtr = &pbuf->RingBufRx[];
pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[];
pbuf->RingBufTxCtr = ;
pbuf->RingBufTxInPtr = &pbuf->RingBufTx[];
pbuf->RingBufTxOutPtr = &pbuf->RingBufTx[];
}
/************************************************************
* function : COMBufferIsEmpty
* parameter: char port, port can be COM1 / COM2
* return : char
* usage : This function is called by your application to see
* if any character is available from the communications channel.
* If at least one character is available, the function returns
* FALSE(0) otherwise, the function returns TRUE(1).
* changelog:
*************************************************************/
unsigned char COMBufferIsEmpty (unsigned char port)
{
// unsigned char cpu_sr;
unsigned char empty;
COM_RING_BUF *pbuf;
switch (port)
{ /* Obtain pointer to communications channel */
case COM1:
pbuf = &COM1Buf;
break;
case COM2:
pbuf = &COM2Buf;
break;
default:
);
}
OS_ENTER_CRITICAL();
)
{ /* See if buffer is empty */
empty = ; /* Buffer is NOT empty */
}
else
{
empty = ; /* Buffer is empty */
}
OS_EXIT_CRITICAL();
return (empty);
}
/************************************************************
* function : COMBufferIsFull
* parameter: char port, port can be COM1 / COM2
* return : char
* usage : This function is called by your application to see if any more characters can be placed
* in the Tx buffer. In other words, this function check to see if the Tx buffer is full.
* If the buffer is full, the function returns TRUE otherwise, the function returns FALSE.
* changelog:
*************************************************************/
unsigned char COMBufferIsFull (unsigned char port)
{
// unsigned char cpu_sr;
char full;
COM_RING_BUF *pbuf;
switch (port)
{ /* Obtain pointer to communications channel */
case COM1:
pbuf = &COM1Buf;
break;
case COM2:
pbuf = &COM2Buf;
break;
default:
);
}
OS_ENTER_CRITICAL();
if (pbuf->RingBufTxCtr < COM_TX_BUF_SIZE) { /* See if buffer is full */
full = ; /* Buffer is NOT full */
} else {
full = ; /* Buffer is full */
}
OS_EXIT_CRITICAL();
return (full);
}
// This function is called by the Rx ISR to insert a character into the receive ring buffer.
static void COMPutRxChar (unsigned char port, unsigned char c)
{
COM_RING_BUF *pbuf;
switch (port)
{ /* Obtain pointer to communications channel */
case COM1:
pbuf = &COM1Buf;
break;
case COM2:
pbuf = &COM2Buf;
break;
default:
return;
}
if (pbuf->RingBufRxCtr < COM_RX_BUF_SIZE) { /* See if buffer is full */
pbuf->RingBufRxCtr++; /* No, increment character count */
*pbuf->RingBufRxInPtr++ = c; /* Put character into buffer */
if (pbuf->RingBufRxInPtr == &pbuf->RingBufRx[COM_RX_BUF_SIZE]) { /* Wrap IN pointer */
pbuf->RingBufRxInPtr = &pbuf->RingBufRx[];
}
}
}
// This function is called by the Tx ISR to extract the next character from the Tx buffer.
// The function returns FALSE if the buffer is empty after the character is extracted from
// the buffer. This is done to signal the Tx ISR to disable interrupts because this is the
// last character to send.
static unsigned char COMGetTxChar (unsigned char port, unsigned char *err)
{
unsigned char c;
COM_RING_BUF *pbuf;
switch (port)
{ /* Obtain pointer to communications channel */
case COM1:
pbuf = &COM1Buf;
break;
case COM2:
pbuf = &COM2Buf;
break;
default:
*err = COM_BAD_CH;
);
}
) { /* See if buffer is empty */
pbuf->RingBufTxCtr--; /* No, decrement character count */
c = *pbuf->RingBufTxOutPtr++; /* Get character from buffer */
if (pbuf->RingBufTxOutPtr == &pbuf->RingBufTx[COM_TX_BUF_SIZE])
{
pbuf->RingBufTxOutPtr = &pbuf->RingBufTx[]; /* Wrap OUT pointer */
}
*err = COM_NO_ERR;
return (c); /* Characters are still available */
} else {
*err = COM_TX_EMPTY;
); /* Buffer is empty */
}
}
void USART1_IRQHandler(void)
{
unsigned int data;
unsigned char err;
if(USART1->SR & 0x0F)
{
// See if we have some kind of error
// Clear interrupt (do nothing about it!)
data = USART1->DR;
}
else if(USART1->SR & USART_FLAG_RXNE) //Receive Data Reg Full Flag
{
data = USART1->DR;
COMPutRxChar(COM1, data); // Insert received character into buffer
}
else if(USART1->SR & USART_FLAG_TXE)
{
data = COMGetTxChar(COM1, &err); // Get next character to send.
if (err == COM_TX_EMPTY)
{ // Do we have anymore characters to send ?
// No, Disable Tx interrupts
//USART_ITConfig(USART1, USART_IT_TXE| USART_IT_TC, ENABLE);
USART1->CR1 &= ~USART_FLAG_TXE | USART_FLAG_TC;
}
else
{
USART1->DR = data; // Yes, Send character
}
}
}
void USART2_IRQHandler(void)
{
unsigned int data;
unsigned char err;
if(USART2->SR & 0x0F)
{
// See if we have some kind of error
// Clear interrupt (do nothing about it!)
data = USART2->DR;
}
else if(USART2->SR & USART_FLAG_RXNE) //Receive Data Reg Full Flag
{
data = USART2->DR;
COMPutRxChar(COM2, data); // Insert received character into buffer
}
else if(USART2->SR & USART_FLAG_TXE)
{
data = COMGetTxChar(COM2, &err); // Get next character to send.
if (err == COM_TX_EMPTY)
{ // Do we have anymore characters to send ?
// No, Disable Tx interrupts
//USART_ITConfig(USART2, USART_IT_TXE| USART_IT_TC, ENABLE);
USART2->CR1 &= ~USART_FLAG_TXE | USART_FLAG_TC;
}
else
{
USART2->DR = data; // Yes, Send character
}
}
}
下面给个例子主程序,来演示如何使用上面的串口驱动代码。
#include "misc.h"
#include "stm32f10x.h"
#include "com_buffered.h"
void UART_PutStrB (unsigned char port, uint8_t *str)
{
!= *str)
{
COMPutCharB(port, *str);
str++;
}
}
void USART1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);
/* Configure USART Tx as alternate function push-pull */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure USART Rx as input floating */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = ;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure );
USART_Cmd(USART1, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = ;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void USART2_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE);
/* Configure USART Tx as alternate function push-pull */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* Configure USART Rx as input floating */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
USART_InitStructure.USART_BaudRate = ;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART2, &USART_InitStructure );
USART_Cmd(USART2, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = ;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
int main(void)
{
unsigned char c;
unsigned char err;
USART1_Init();
USART2_Init();
COMBufferInit();
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
UART_PutStrB(COM1, "Hello World!\n");
for(;;)
{
c = COMGetCharB(COM1, &err);
if(err == COM_NO_ERR)
{
COMPutCharB(COM1, c);
}
}
}
STM32F10x 学习笔记6(USART实现串口通讯 2)的更多相关文章
- STM32学习笔记(四)——串口控制LED(中断方式)
目录: 一.时钟使能,包括GPIO的时钟和串口的时钟使能 二.设置引脚复用映射 三.GPIO的初始化配置,注意要设置为复用模式 四.串口参数初始化配置 五.中断分组和中断优先级配置 六.设置串口中断类 ...
- STM32F10x 学习笔记5(USART实现串口通讯 1)
STM32F10x 系列单片机中都包含了USART 模块,所谓USART,就是通用同步异步收发器.通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间 ...
- ARM-LINUX学习笔记-(虚拟机linux串口终端以及USB程序下载,基于TQ2440)
昨天安装了ssh服务之后今天在windows上用xshell登陆发现登录不上,原因是使用了virtualbox的NAT模式,在NAT模式下,客户机可以很方便地上网,但是想要链接宿主机就需要打开网络地址 ...
- STM32学习笔记(二)——串口控制LED
开发板芯片:STM32F407ZGT6 PA9-USART1_TX,PA10-USART1_RX; PF9-LED0,PF10-LED1; 一.串口1配置过程(不使用串口中断): 1.使能时钟,包括G ...
- 串口(USART)通信-串口通讯协议简介
物理层:规定通讯系统中具有机械.电子功能部分的特性,确保原始数据在物理媒体的传输.其实就是硬件部分. 协议层:协议层主要规定通讯逻辑,统一收发双方的数据打包.解包标准.其实就是软件部分. 简单来说物理 ...
- STM32学习笔记(五) USART异步串行口输入输出(轮询模式)
学习是一个简单的过程,只要有善于发掘的眼睛,总能学到新知识,然而如何坚持不懈的学习却很困难,对我亦如此,生活中有太多的诱惑,最后只想说一句勿忘初心.闲话不多扯,本篇讲诉的是异步串行口的输入输出,串口在 ...
- 【STM32学习笔记】USART 硬件流控
流控的概念源于 RS232 这个标准,在 RS232 标准里面包含了串口.流控的定义.大家一定了解,RS232 中的"RS"是Recommend Standard 的缩写,即&qu ...
- CC2540开发板学习笔记(五)——串口通信
(一)串口发送 一.实验现象: 开发板实现功能发送 二.实验过程 1.PL2303 USB转串口电路图 2.串口发送 (1)查看用户手册有: UART0 对应的外部设备 IO 引脚关系为: P0_2 ...
- Arduino101学习笔记(十)—— 串口通信
//打开串口 Serial.begin(); //获取串口上可读取的数据的字节数.该数据是指已经到达并存储在接收缓存(共有64字节)中 Serial.available(); //读串口数据,串口上第 ...
随机推荐
- [io PWA] Great libraries and tools for great Progressive Web Apps
sw-toolbox: Github It provides a cononical implementation of all the runtime caching strategies that ...
- Android 自定义Spinner和其下拉窗口
: 自定义Spinner其实包括两个部分: 第一部分是用来打开下拉列表的按钮,如图,这个绿色背景直接设置Spinner的背景就行,素材文件如下: 里面的文字需要注意下,Spinner控件没有直接修改文 ...
- 使用 asp.net mv4开发企业级办公OA
大家好!这是我第一次写asp.net 开发笔记,哪里写的不好,请见谅! 本程序是一个在线办公(OA)系统 B/S项目: 项目开发环境:Microsoft Visual Studio 2012 + Sq ...
- 外观模式-Facade
外观模式是为了解决类与类之间依赖关系的,外观模式将类间关系放在一个Facade类中,降低了类类之间的耦合度,该模式中不涉及接口 举一个经典的例子: CPU类: public class CPU { p ...
- android反编译经验谈
反编译这事,找对了工具其实非常简单. 反编译工具下载地址http://pan.baidu.com/s/1eQvshwu android的反编译要经过两个步骤: 1.把dex文件转为jar 2.jar转 ...
- CSS Clip剪切元素动画实例
1.CSS .fixed { position: fixed; width: 90px; height: 90px; background: red; border: 0px solid blue; ...
- 前端过滤XSS攻击
日常开发过程中,对于存在用户交互的一些门户网站等,过滤xss攻击是必不可少的. 此处主要记录下我在工作过程中的简单处理方法. 前端过滤XSS攻击, 我这里用的是开源工程 js-xss,官网地址:htt ...
- angularjs-ngTable select filter
jsp <td title="'Status'" filter="{status: 'select'}" filter-data="fn.sta ...
- Tomcat- java.lang.NoSuchMethodException: org.apache.catalina.deploy.WebXml addServlet
在MyEclipse中启动Tomcat的时候报错: java.lang.NoSuchMethodException: org.apache.catalina.deploy.WebXml addServ ...
- JavaScript - 测试 jQuery
测试 JavaScript 框架库 - jQuery 引用 jQuery 如需测试 JavaScript 库,您需要在网页中引用它. 为了引用某个库,请使用 <script> 标签,其 s ...