LPC1768开发板教程
注意:本文档基于LPC1768.h头文件和EZ1768.h头文件(在文档结尾附出)
文章目录
- LPC1768开发板教程
- 1.GPIO
- 1.1 设置GPIO
- 1.2 设置输入输出
- 1.3 查看引脚值
- 1.4 GPIO中断
- 2.外部中断
- 2.1 中断引脚
- 2.2 中断触发模式
- 2.3 初始化中断
- 3.八段数码管
-
- 4. 74LS164芯片
- 4.1 引脚介绍
- 4.2 真值表&时序图
- 4.3 应用示例
- 5.定时器
-
- 6.UART串行通信
- 6.1 发送&接收单元
- 6.2 寄存器介绍
- 6.3 UART中断
- 6.4 UART初始化
- 7.SPI串行通信
- 7.1 引脚介绍
- 7.2 寄存器介绍
- 7.3 应用示例
- 8. 74HC95芯片
-
- 9.LCD1602显示
- 9.1 引脚&功能
- 9.2 指令说明及时序
- 9.3 地址映射
- 9.4 初始化&显示
- 9.5 自定义字符
- 10.矩阵键盘
-
- 11.RTC时钟模块
-
- 12.EZ1768.h
1.GPIO
*基础,重中之重
1.1 设置GPIO
-
PINSELX(X的值为:0 ~ 4 ,7~10)
引脚的对应寄存器位为两位(如PINSEL0 的0~1位是引脚p0.0的位置)
设置引脚对应的寄存器位为00
-
引脚 p0.Y(Y的值为0~ 31,其中0~ 15属于PINSEL0、16~31属于PINSEL1)
注意:设置引脚前请查阅数据手册
PINSEL0 &= ~(0x3<<2);
PINSEL1 &= ~(0x3<<2);
1.2 设置输入输出
PINSEL0 &= ~(0x3<<2);
FIO0DIR &= ~(1ul<<1);
PINSEL0 &= ~(0x3<<2);
FIO0DIR |= (1ul<<1);
FIO0SET |= (1ul<<1);
FIO0CLR |= (1ul<<1);
1.3 查看引脚值
PinStat=FIO0PIN & (1ul<<1);
1.4 GPIO中断
void set_GPIO_interrupt(void){
PINSEL0 &= ~(0x3<<8);
FIO0DIR &= ~(1ul<<4);
IO0IntEnF = 0x010;
IO0IntClr = 0xFFFFFFF;
NVIC_SetPriority(EINT3_IRQn,4);
NVIC_EnableIRQ(EINT3_IRQn);
}
void EINT3_IRQHandler (void){
IO0IntClr=0xFFFFFFF;
}
if((FIO0PIN&0x010)==0){
myDelay(5);
if((FIO0PIN&0x010)==0){
}
}
2.外部中断
外部中断与GPIO中断相似,但可用引脚相较于GPIO更少。
2.1 中断引脚
外部中断引脚 | CPU引脚 | 描述 |
---|
EINT0 | P2.10 | 外部中断0引脚 |
EINT1 | P2.11 | 外部中断1引脚 |
EINT2 | P2.12 | 外部中断2引脚 |
EINT3 | P2.13 | 外部中断3引脚 |
注意:设置引脚对应的寄存器位为01。
2.2 中断触发模式
注意:设置触发模式时,请将两个寄存器配合使用。
2.3 初始化中断
PINSEL4 |=(0x01<<20);
EXTMODE |=0x01;
EXTPOLAR &=0xFE;
EXTINT =0x01;
NVIC_SetPriority(EINT0_IRQn,3);
NVIC_EnableIRQ(EINT0_IRQn);
void EINT0_IRQHandler(void){
EXTINT =0x01;
}
3.八段数码管
3.1 引脚介绍
3.2 显示方式&策略
{0,0,0,0,0,0,1,1}
digital_com[]
DL_MOD[][]
void reset_D(void)={
int i;
for(i=4;i<12;i++){
pin_out(digital_com[i],HIGH);
}
}
void select_com(int n){
int i;
for(i=0;i<4;i++){
pin_out(digital_com[i],LOW);
}
switch(n){
case 0:pin_out(digital_com[0],HIGH);break;
case 1:pin_out(digital_com[1],HIGH);break;
case 2:pin_out(digital_com[2],HIGH);break;
case 3:pin_out(digital_com[3],HIGH);break;
default:break;
}
}
void print_Dnum(int pin,int n){
int i;
int j=0;
select_com(pin);
reset_D();
for(i=4;i<12;i++){
pin_out(digital_com[i],DL_MOD[n][j++]);
}
}
void print_digital_num(int n){
int result[10]={0};
int temp=n,i=0,j,flag=0;
int result_l=0;
if(n<0)temp=-temp;
result_l=0;
while(temp){
result[result_l++]=temp%10;
temp=temp/10;
}
if(n<0){
result[result_l++]=17;
}
if(result_l<4)result_l=4;
if(flag==0)temp=result_l;
for(j=temp-1;j>=0;j--){
reset_D();
print_Dnum(i++,result[j]);
}
flag++;
if(flag%5000==0)temp--;
else if(temp<4)flag=0;
}
4. 74LS164芯片
4.1 引脚介绍
- 引脚介绍
- DSA(A)/ DSB(B):串行数据输入端
- Q0~Q7:数据输出端
- CP(clock):时钟输入端
- nMR(clear):清零端,低电平有效
- VCC(VDD):接电源
- GND:接地
- 引脚图
4.2 真值表&时序图
-
真值表
-
时序图
注意:使用XMUT开发板的引脚A与B引脚经过处理,可以只接其中一个引脚
4.3 应用示例
set_pin_out(C_CLK,LOW);
set_pin_out(C_CLR,LOW);
set_pin_out(C_A,LOW);
void Send_data(uint8_t data)
{
int i;
pin_out(C_CLR,LOW);
pin_out(C_CLR,HIGH);
for(i=0;i<8;i++){
pin_out(C_CLK,LOW);
if((data&0x01)!=0)
pin_out(C_A,HIGH);
else
pin_out(C_A,LOW);
data>>=1;
pin_out(C_CLK,HIGH);
}
pin_out(C_CLK,LOW);
}
5.定时器
*本文档只介详细绍定时器的基本使用方法,对匹配和捕获的原理只进行简单介绍
5.1 寄存器介绍
-
分频器寄存器(复位值为0)
- 预分频控制寄存器 PR :用于设定预分频值,为32位寄存器。
- 预分频计数器 PC :32位计数器,计数频率为PCLK,当计数值等于预分频计数器的值时,TC计数器加1。
- 定时器计数器 TC :32位计数器,计数频率为PCLK经过预分频计数器后频率值。
- 定时器计数时钟频率 = Fpclk / (PR+1)。Fpclk:24000000
-
匹配功能寄存器(复位值为0)
- 匹配控制寄存器 MCR :用于控制在匹配时是否产生中断或复位TC。
- 匹配寄存器 MRX(X为0~3):通过MCR寄存器可以设置匹配发生时的动作。
- 外部匹配寄存器 EMR :EMR控制外部匹配管脚MATx.0~MATx.3。
- 匹配控制寄存器 MCR : 0~2位为MR0部分(0:中断、1:复位、2:停止)。
-
捕获功能寄存器(复位值为0)
- 捕获控制寄存器 CCR :用于设置捕获信号的触发特征,以及捕获发生时是否产生中断。
- 捕获寄存器 CRX(X为0~3):在捕获X引脚上产生捕获时间时,CRX装载TC的值。
-
定时器使能&中断标志寄存器
5.2 定时器初始化
#define Fpclk 24000000
T0TC=0;
T0PR=0;
T0MCR=0x03;
T0MR0=Fpclk;
T0TCR=0x01;
NVIC_SetPriority(TIMER0_IRQn,4);
NVIC_EnableIRQ(TIMER0_IRQn);
void TIMER0_IRQHandler (void){
T0IR=1;
}
6.UART串行通信
*十分适合用于程序的debug
6.1 发送&接收单元
- UART发送单元(X:0~1)
- 发送流程:CPU ==》UXTHR ==》UXTSR ==》TXD
- 发送器保持寄存器 UXTHR :写入该寄存器的值保存到发送FIFO中,当该字节到达FIFO底部时,它将被送入发送移位寄存器(UXTSR)进行发送。
- 发送FIFO缓冲区 :UART0、UART1各含有1个16字节的发送FIFO缓冲区,一直处于使能状态。
- UART接收单元 (X:0~1)
- 接收流程:RXD ==》UXRSR ==》UXRBR ==》CPU (X:0~1)
- 接收缓存寄存器UXRBR :包含了接收FIFO中最早接收到的字节。
- 接收FIFO缓冲区 :UART0、UART1各含有1个16字节的接收FIFO缓冲区,软件设置触发字节。
6.2 寄存器介绍
-
UART线状态寄存器----UXLSR (X:0~1)
线状态寄存器(UXLSR)为只读寄存器,它提供UARTX发送和接收模块的状态信息 。
-
UART波特率发生器
UART0和UART1各含有一个单独的波特率发生器,两者的功能相同,且相互独立。
这两个寄存器决定波特率时钟的频率,而波特率时钟必须是波特率的16倍。波特率计算公式如下:
BaudRate = Fpclk/ ([U0DLM,U0DLL]×16)
-
UART中断使能寄存器-----UXIER(X:0~1)
UXIER可以控制UARTX的4个中断源。其中RBR中断使能包括两个中断,一个是接收数据可用(RDA)中断,一个是接收超时中断(CTI)。
-
中断标识寄存器-----UXIIR
UXIIR提供状态代码用于指示一个挂起中断的中断源和优先级。在访问UXIIR过程中,中断被冻结。如果在访问UXIIR时产生了中断,该中断将被记录,在下次访问UXIIR时可以读出,避免了中断的丢失。
6.3 UART中断
-
RLS中断
优先级最高,在UARTX发生下面的错误时产生中断,通过查看UXLSR[4:1]可以了解到产生该中断的错误条件。读取UXLSR时清除该中断。
- 溢出错误(OE)
- 奇偶错误(PE)
- 帧错误(FE)
- 间隔中断(BI)
-
RDA中断
与CTI中断并列为第二优先级,当接收的有效数据到达接收FIFO设置寄存器(UXFCR)中设置的触发点时,RDA被激活。当接收FIFO中的有效数据少于触发点时,RDA复位。
以下为产生中断的流程
- 移位寄存器(UXRSR)从RxDn引脚接收串行数据后,送入接收FIFO中。
- 当接收FIFO中的有效数据数量到达预定的触发点时,置位RDA中断。
- 从UXRBR寄存器中读取FIFO中最早到达的数据,当FIFO中的有效数据小于预定触发点时,清零RDA中断
-
CTI中断
当接收FIFO中的有效数据少于预定的触发点数量(至少有一个字节)时,如果在一定时间内仍然没有接收到新的数据,那将触发该中断。这个时间为:3.5~4.5个字节所需要的时间。注:对接收FIFO的任何操作都会清零该中断标志。
- 移位寄存器(UXRSR)从RxDn引脚接收串行数据后,送入接收FIFO中。
- 当接收FIFO中的有效数据少于触发个数,但至少有一个时,如果长时间没有数据到达,将触发CTI中断。
- 从UXRBR中读取接收FIFO中的数据,或者有新的数据送入接收FIFO,都将清零CTI中断。
-
THRE中断
该中断为第三优先级。当发送FIFO为空并且满足一定的条件时,该中断将被触发。
条件:
- 系统启动时,虽然发送FIFO为空,但不会产生THRE中断。
- 在上一次发生THRE中断后,向发送FIFO中写入1个字节数据,将在延时一个字节加上一个停止位后发生THRE中断。
- 如果在发送FIFO中有过两个字节以上的数据,但是现在发送FIFO为空时,将立即触发THRE中断。
6.4 UART初始化
#define Fpclk 24000000
#define UART_BPS 9600
uint16_t Fdiv;
PINSEL0=(PINSEL0 & ~(0x0F))|(0x05<<4);
U0FCR=0x07;
U0LCR=0x83;
Fdiv=(Fpclk/16)/UART_BPS;
U0DLM=Fdiv/256;
U0DLL=Fdiv%256;
U0LCR=0x03;
NVIC_SetPriority(UART0_IRQn, 2);
NVIC_EnableIRQ(UART0_IRQn);
U0IER=0x01;
void UART0_SendByte(uint8_t data){
U0THR = data;
while((U0LSR&(1<<6))==0);
}
uint8_t UART0_RcvByte(void){
uint8_t rcv_data;
while((U0LSR & 0x01) == 0);
rcv_data = U0RBR;
return(rcv_data);
}
void UART0_IRQHandler(void){
char c=UART0_RcvByte();
}
7.SPI串行通信
*SPI可简化对一些电子器件的使用
7.1 引脚介绍
引脚名称 | 类型 | 描述 |
---|
SCK | I/O | 串行时钟。用于同步SPI接口间数据传输的时钟信号。该时钟信号总是由主机输出。 |
SSEL | I | 从机选择。SPI从机选择信号是一个低有效信号。 |
MISO | I/O | 主入从出。MISO信号是一个单向的信号,它将数据由从机传输到主机。 |
MOSI | I/O | 主出从入。MOSI信号是一个单向的信号,它将数据从主机传输到从机。 |
7.2 寄存器介绍
位 | 7 | 6 | 5 | 4 | 3 | 2 : 0 |
---|
功能 | SPIE | LSBF | MSTR | CPOL | CPHA | 保留 |
-
CPHA:时钟相位控制(复位值 :0)
该位决定SPI传输时数据和时钟的关系,并控制从机传输的起始和结束
1 : 时钟前沿数据输出,后沿数据采样;
0 : 时钟前沿数据采样,后沿数据输出;
-
CPOL:时钟极性控制(复位值:0)
1 : SCK为低电平有效;
0 : SCK为高电平有效;
-
MSTR:主模式控制(复位值:0)
1 : SPI处于主模式;
0 : SPI处于从模式
-
LSBF:字节移动方向控制(复位值:0)
1 : 每字节数据从低位(LSB)开始传输;
0 : 每字节数据从高位(MSB)开始传输;
-
SPIE:SPI中断使能(复位值:0)
1 : 每次SPIF或MODF置位时都会产生硬件中断;
0 : SPI中断被禁止;
SPDR | 功能 | 描述 | 复位值 |
---|
7 : 0 | 数据 | SPI双向数据 | 0 |
SPDR寄存器为SPI提供数据的发送和接收。
处于主模式时,向该寄存器写入数据,将启动SPI数据传输。从数据传输开始到SPIF状态位置位并且没有读取状 态寄存器的这段时间内不能对该寄存器执行写操作。
SPCCR | 功能 | 描述 | 复位值 |
---|
7 : 0 | 计数值 | 设定SPI时钟计数值 | 0 |
SPI速率 = Fpclk / SPCCR
注意:作为主机时,SPCCR寄存器控制SCK的频率。寄存器的值为一位SCK时钟所占用的PCLK周期数。该寄存器 的 值必 须为偶数,并且必须不小于8。
- SPI中断寄存器——SPINT
7.3 应用示例
#define MSTR (1<<5)
#define CPOL (1<<4)
#define CPHA (1<<3)
#define LSBF (1<<6)
#define SPI_MODE (MSTR|CPOL)
#define Fpclk 24000000
void MSpiIni(uint8_t fdiv){
if(fdiv<8)
fdiv=8;
S0SPCCR=fdiv&0xFE;
S0SPCR=SPI_MODE;
}
void SPI_Init(void){
PINSEL0=(PINSEL0 &~(0x03<<30))|(0x03<<30);
PINSEL1=(PINSEL1 &~(0x0F<<2))|(0x0F<<2);
MSpiIni(0x56);
}
uint8_t MSendData(uint8_t data){
S0SPDR=data;
while(0==(S0SPSR&0x80));
return data;
}
8. 74HC95芯片
8.1 接线图
*本图来源CCP
8.2 应用示例
uint8_t MSendData(uint8_t data){
S0SPDR=data;
while(0==(S0SPSR&0x80));
set_pin_out(ST_CP,HIGH);
set_pin_out(ST_CP,LOW);
return data;
}
9.LCD1602显示
9.1 引脚&功能
编号 | 符号 | 引脚说明 | 编号 | 符号 | 引脚说明 |
---|
1 | VSS | 电源地 | 9 | D2 | 数据 |
2 | VDD | 电源正极(5V) | 10 | D3 | 数据 |
3 | VL | 液晶显示偏压 | 11 | D4 | 数据 |
4 | RS | 数据/命令选择 | 12 | D5 | 数据 |
5 | R/W | 读/写选择 | 13 | D6 | 数据 |
6 | E | 使能信号 | 14 | D7 | 数据 |
7 | D0 | 数据 | 15 | BLA | 背光源正极 |
8 | D1 | 数据 | 16 | BLK | 背光源负极 |
- 部分引脚说明
- 第3脚:VL为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度。
- 第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。
- 第5脚:R/W为读写信号线,高电平时进行读操作,低电平时进行写操作。当RS和R/W共同为低电平时可以写入指令或者显示地址,当RS为低电平R/W为高电平时可以读忙信号,当RS为高电平R/W为低电平时可以写入数据。
- 第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。
9.2 指令说明及时序
序号 | 指令 | RS | R/W | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
1 | 清除显示 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
2 | 光标返回 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | * |
3 | 置为输入模式 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | I/D | S |
4 | 显示开关控制 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | D | C | B |
5 | 光标或字符移位 | 0 | 0 | 0 | 0 | 0 | 1 | S/C | R/L | * | * |
6 | 置功能 | 0 | 0 | 0 | 0 | 1 | DL | N | F | * | * |
7 | 置字符发生存贮器地址 | 0 | 0 | 0 | 1 | 字符发生存贮器地址 |
8 | 置数据存贮器地址 | 0 | 0 | 1 | 显示数据存贮器地址 |
9 | 置数据存贮器地址 | 0 | 1 | BF | 计数器地址 |
10 | 写数到CGRAM或DDRAM | 1 | 0 | 要写的数据内容 |
11 | 从CGRAM或DDRAM读数 | 1 | 1 | 读出的数据内容 |
9.3 地址映射
- 地址映射图
9.4 初始化&显示
void lcd_Wcmd(uint8_t data){
myDelay(15);
pin_out(RS,LOW);
pin_out(RW,LOW);
pin_out(E,HIGH);
MSendData(data);
pin_out(E,LOW);
}
void lcd_Wdata(uint8_t data){
myDelay(15);
pin_out(RS,HIGH);
pin_out(RW,LOW);
pin_out(E,HIGH);
MSendData(data);
pin_out(E,LOW);
}
void LCD_Init(void){
lcd_Wcmd(0x38);
myDelay(1);
lcd_Wcmd(0x0C);
myDelay(1);
lcd_Wcmd(0x06);
myDelay(1);
lcd_Wcmd(0x01);
myDelay(1);
}
void lcd_pos(uint8_t pos){
lcd_Wcmd(pos|0x80);
}
void LCD_print(uint8_t pos,uint8_t c){
lcd_pos(pos);
lcd_Wdata(c);
}
LCD_print(0x00,'a');
9.5 自定义字符
-
显示汉字参考
LCD显示汉字
-
自定义字符
- LCD1602字符位为5*8的点阵。
- 字符格式:一个自定义字符由8个5位无字符数过程(例如:0x00,0x04,0x15,0x0E,0x1F,0x0E,0x11,0x00)。
- 字符示例:无符号5位数0x1E(11110)显示一行的前4个像素点。
-
示例
font_map[]={0x00,0x04,0x15,0x0E,0x1F,0x0E,0x11,0x00};
void flesh_RAM(uint8_t font_map[],int line){
lcd_Wcmd(0x40);
for(int i=0;i<line*8;i++){
lcd_Wdata(font_map[i]);
myDelay(5);
}
}
LCD_print(0x40,0x00);
10.矩阵键盘
10.1 扫描策略
-
扫描法
通过高四位轮流输出低电平来对矩阵键盘进行逐行扫描,当低四位接收到的数据不全为1的时候,说明有按键按下,然后通过接收到的数据是哪一位为0来判断是哪一个按键被按下。
-
行列反转法
通过高四位全部输出低电平,低四位设为输入模式。当接收到的数据,低四位不全为高电平时,说明有按键按下,然后通过接收的数据值,判断是哪一列有按键按下,然后再反过来,高四位设置为输入模式,低四位输出低电平,然后根据接收到的高四位的值判断是那一行有按键按下,这样就能够确定是哪一个按键按下了。
10.2 示例
*该示例使用方法并非最佳方案
float key_up[4];
float key_down[4];
char switch_key(int num){
switch(num){
case 11:return '1';
case 21:return '2';
case 31:return '3';
case 12:return '4';
case 22:return '5';
case 32:return '6';
case 13:return '7';
case 23:return '8';
case 33:return '9';
case 41:return 'a';
case 42:return 'b';
case 43:return 'c';
case 44:return 'd';
case 14:return '*';
case 24:return '0';
case 34:return '#';
}
return 0;
}
void set_low(int n,float key_up[]){
for(int i=0;i<4;i++){
set_pin_out(key_up[i],HIGH);
}
set_pin_out(key_up[n],LOW);
}
char keyBoard(float key_up[],float key_down[]){
myDelay(350);
for(int i=0;i<4;i++){
set_low(i,key_up);
for(int j=0;j<4;j++){
set_pin(key_down[j],INPUT);
if(judge_pin(key_down[j])==0){
myDelay(10);
char c=switch_key((i+1)+(j+1)*10);
return c;
}
}
}
return 0;
}
char keyBoard(float key_up[],float key_down[]){
myDelay(400);
int up=-1,down=-1;
for(int i=0;i<4;i++){
set_pin_out(key_up[i],LOW);
}
for(int i=0;i<4;i++){
set_pin(key_down[i],INPUT);
}
for(int i=0;i<4;i++){
if(judge_pin(key_down[i])==0){
myDelay(20);
if(judge_pin(key_down[i])==0){
up=i+1;
break;
}
}
}
myDelay(20);
for(int i=0;i<4;i++){
set_pin_out(key_down[i],LOW);
}
for(int i=0;i<4;i++){
set_pin(key_up[i],INPUT);
}
for(int i=0;i<4;i++){
if(judge_pin(key_up[i])==0){
myDelay(20);
if(judge_pin(key_up[i])==0){
down=i+1;
break;
}
}
}
if(down>0&&up>0){
char n=switch_key(up*10+down);
return n;
}
return 0;
}
11.RTC时钟模块
RTC时钟
11.1 寄存器介绍
时钟产生寄存器组
名称 | 有效位 | 描述 | 访问 |
---|
PREINT | 13 | 预分频值,整数部分 | 读写 |
PREFRAC | 15 | 预分频值,小数部分 | 读写 |
CCR | 4 | 时钟控制寄存器 | 读写 |
CTC | 15 | 时钟节拍计数器 | 只读 |
预分频整数部分为13位有效位,小数部分为15位有效位
预分频整数部分的计算公式为:PREINT = int(PCLK / 32768) – 1
预分频小数部分的计算公式为:PREFRAC = PCLK – ((PREINT + 1) × 32768)
时间寄存器组
名称 | 有效位 | 描述 |
---|
CTIME0 | 32 | 包含秒、分、时和星期 |
CTIME1 | 32 | 包含日期(月)、月和年 |
CTIME2 | 32 | 包含日期(年) |
- CTIME0
CTIME0 | 31:27 | 26:24 | 23:21 | 30:16 | 15:14 | 13:8 | 7:6 | 5:0 |
---|
功能 | 保留 | 星期 | 保留 | 小时 | 保留 | 分 | 保留 | 秒 |
取值范围 | — | (0~6) | — | (0~23) | — | (0~59) | — | (0~59) |
- CTIME1
CTIME1 | 31:28 | 27:16 | 15:12 | 11:8 | 7:5 | 4:0 |
---|
功能 | 保留 | 年 | 保留 | 月 | 保留 | 日期(月) |
选取范围 | — | (0~4095) | — | (1~12) | — | (1~28,29,30) |
- CTIME2
CTIME2 | 31:9 | 8:0 |
---|
功能 | 保留 | 日期(年) |
取值范围 | — | (1~365,366) |
注意:CTIME1与CTIME2这两个寄存器意义不同,(月)表示当日在当月中的序号,(年)表示当日在当年中的序号
名称 | 有效位 | 描述 |
---|
SEC | 6 | 秒值。该值的范围为0~59。 |
MIN | 6 | 分值。该值的范围为0~59。 |
HOUR | 5 | 小时值。该值的范围为0~23。 |
DOM | 5 | 日期(月)值。该值的范围为1~28,29,30或31(取决于月份以及是否为闰年)。 |
DOW | 3 | 星期值。该值的范围为1~365(闰年为366)。 |
DOY | 9 | 日期(年)值。该值的范围为1~365。 |
注意:
这些日期的寄存器只能在适当的时间间隔处递增,而在定义的溢出点处复位。为了使这些值有意义,它们不能进行计算且必须正确初始化。
其中DOY寄存器需要单独初始化,也就是说该寄存器的值不会因为对年、月、日寄存器进行初始化而自动确定到一个正确的值。
中断产生控制寄存器
名称 | 描述 | 访问 |
---|
ILR | 中断位置寄存器 | 读写 |
CIIR | 递增中断寄存器 | 读写 |
AMR | 报警屏蔽寄存器 | 读写 |
报警寄存器组 | 设定报警时间 | 读写 |
RTC中断分为两类:
-
时间计数器的增量中断,由增量中断寄存器控制。
-
报警匹配产生的中断,由报警屏蔽寄存器控制。
11.2 应用示例
typedef struct TIME{
uint8_t sec;
uint8_t min;
uint8_t hour;
uint8_t day;
uint8_t mon;
uint8_t week;
uint16_t year;
}time_data;
void set_time_now(time_data *time){
SEC=time->sec;
MIN=time->min;
HOUR=time->hour;
DOM=time->day;
MONTH=time->mon;
DOW=time->week;
YEAR=time->year;
}
void set_time_alarm(time_data *time){
ALSEC=time->sec;
ALMIN=time->min;
ALHOUR=time->hour;
ALDOM=time->day;
ALMONTH=time->mon;
ALDOW=time->week;
ALYEAR=time->year;
}
void RTC_Init(time_data *time){
CCR=0x00;
ILR=0x03;
CIIR=0x01;
AMR=0xFF;
set_time_now(time);
NVIC_SetPriority(RTC_IRQn,4);
NVIC_EnableIRQ(RTC_IRQn);
CCR=0x01;
}
void RTC_IRQHandler(void){
if((ILR&0x02)!=0){
ILR |=0x02;
}
if((ILR&0x01)!=0){
ILR |=0x01;
}
}
12.EZ1768.h
*本部分仅供参考
#include "LPC17xx.h"
#include "LPC1768.h"
#define PULLUP 4
#define HIGH 1
#define LOW 0
#define OUTPUT 1
#define INPUT 0
#define RISING 2
#define FALLING 3
int DL_MOD[][8]={
{0,0,0,0,0,0,1,1},
{1,0,0,1,1,1,1,1},
{0,0,1,0,0,1,0,1},
{0,0,0,0,1,1,0,1},
{1,0,0,1,1,0,0,1},
{0,1,0,0,1,0,0,1},
{0,1,0,0,0,0,0,1},
{0,0,0,1,1,1,1,1},
{0,0,0,0,0,0,0,1},
{0,0,0,0,1,0,0,1},
{0,0,0,1,0,1,0,1},
{1,1,0,0,0,0,0,1},
{0,1,1,0,0,0,1,1},
{1,0,0,0,0,1,0,1},
{0,1,1,0,0,0,0,1},
{0,1,1,1,0,0,0,1},
{1,1,1,0,0,0,1,1},
{1,1,1,1,1,1,0,1},
{1,1,1,0,1,1,1,1},
};
float digital_com[12];
volatile unsigned long *select_pin(int i){
switch(i){
case 0:return &PINSEL0;
case 1:return &PINSEL1;
case 2:return &PINSEL2;
case 3:return &PINSEL3;
case 4:return &PINSEL4;
case 7:return &PINSEL7;
case 8:return &PINSEL8;
case 9:return &PINSEL9;
case 10:return &PINSEL10;
}
return 0;
}
volatile unsigned long * select_mode(int i){
switch(i){
case 0:return &PINMODE0;
case 1:return &PINMODE1;
case 2:return &PINMODE2;
case 3:return &PINMODE3;
case 4:return &PINMODE4;
case 5:return &PINMODE5;
case 6:return &PINMODE6;
case 7:return &PINMODE7;
case 9:return &PINMODE9;
}
return 0;
}
volatile unsigned long * fio_dir(int i){
switch(i){
case 0:return &FIO0DIR;
case 1:return &FIO1DIR;
case 2:return &FIO2DIR;
case 3:return &FIO3DIR;
case 4:return &FIO4DIR;
}
return 0;
}
volatile unsigned long * fio_set(int i){
switch(i){
case 0:return &FIO0SET;
case 1:return &FIO1SET;
case 2:return &FIO2SET;
case 3:return &FIO3SET;
case 4:return &FIO4SET;
}
return 0;
}
volatile unsigned long *fio_clr(int i){
switch(i){
case 0:return &FIO0CLR;
case 1:return &FIO1CLR;
case 2:return &FIO2CLR;
case 3:return &FIO3CLR;
case 4:return &FIO4CLR;
}
return 0;
}
volatile unsigned long * fio_pin(int i){
switch(i){
case 0:return &FIO0PIN;
case 1:return &FIO1PIN;
case 2:return &FIO2PIN;
case 3:return &FIO3PIN;
case 4:return &FIO4PIN;
}
return 0;
}
void set_inter(int i){
switch(i){
case 0:PINSEL4 |=(0x01<<20);break;
case 1:PINSEL4 |=(0x01<<22);break;
case 2:PINSEL4 |=(0x01<<24);break;
case 3:PINSEL4 |=(0x01<<26);break;
}
}
void set_inter_mod(int mod,int i){
switch(mod){
case 0:{EXTMODE &=(~(0x01<<i));EXTPOLAR &=(~(0x01<<i));break;}
case 1:{EXTMODE &=(~(0x00<<i));EXTPOLAR |=(0x01<<i);break;}
case 2:{EXTMODE |=(0x01<<i);EXTPOLAR |=(0x01<<i);break;}
case 3:{EXTMODE |=(0x01<<i);EXTPOLAR &=(~(0x01<<i));break;}
}
}
IRQn_Type EINTx_IRQn(int i){
switch(i){
case 0:return EINT0_IRQn;
case 1:return EINT1_IRQn;
case 2:return EINT2_IRQn;
case 3:return EINT3_IRQn;
}
return EINT0_IRQn;
}
int order_pin(float n,int *num){
int i;
i=(int)n;
*num=((int)(n*100))%100;
return i;
}
int judge_pin(float pin){
int fn,bn;
fn=order_pin(pin,&bn);
return (*fio_pin(fn)&(1ul<<bn));
}
int set_GPIO(float pin){
int fn,bn;
fn=order_pin(pin,&bn);
*select_pin(bn<16?fn:fn+1)&= ~(0x3 << bn<16?bn:bn-16);
return 0;
}
int set_pin(float pin,int c){
int fn,bn;
set_GPIO(pin);
fn=order_pin(pin,&bn);
if(c==1)
*fio_dir(fn)|=(1ul<<bn);
else if(c==0)
*fio_dir(fn)&=~(1ul<<bn);
return 0;
}
int pin_out(float pin,int i){
int fn,bn;
fn=order_pin(pin,&bn);
if(i==1){
*fio_set(fn)=(1ul<<bn);
}
else if(i==0){
*fio_clr(fn)=(1ul<<bn);
}
return 0;
}
int set_pin_out(float pin,int c){
set_GPIO(pin);
set_pin(pin,OUTPUT);
pin_out(pin,c);
return 1;
}
void set_interrupt(int com,int mod,int level){
set_inter(com);
set_inter_mod(mod,com);
EXTINT =0x0F;
NVIC_SetPriority(EINTx_IRQn(com),level);
NVIC_EnableIRQ(EINTx_IRQn(com));
}
void set_Dlight_com(float n1,float n2,float n3,float n4,float A,float B,float C,float D,float E,float F,float G,float pd){
digital_com[0]=n1;
digital_com[1]=n2;
digital_com[2]=n3;
digital_com[3]=n4;
digital_com[4]=A;
digital_com[5]=B;
digital_com[6]=C;
digital_com[7]=D;
digital_com[8]=E;
digital_com[9]=F;
digital_com[10]=G;
digital_com[11]=pd;
}
void select_com(int n){
int i;
for(i=0;i<4;i++){
pin_out(digital_com[i],LOW);
}
switch(n){
case 0:pin_out(digital_com[0],HIGH);break;
case 1:pin_out(digital_com[1],HIGH);break;
case 2:pin_out(digital_com[2],HIGH);break;
case 3:pin_out(digital_com[3],HIGH);break;
default:break;
}
}
void reset_D(void)
{
int i;
for(i=4;i<12;i++)
{
pin_out(digital_com[i],HIGH);
}
}
void print_Dnum(int pin,int n)
{
int i;
int j=0;
select_com(pin);
reset_D();
for(i=4;i<12;i++){
pin_out(digital_com[i],DL_MOD[n][j++]);
}
}
void print_digital_num(int n){
int result[10]={0};
int temp=n,i=0,j,flag=0;
int result_l=0;
if(n<0)temp=-temp;
result_l=0;
while(temp){
result[result_l++]=temp%10;
temp=temp/10;
}
if(n<0){
result[result_l++]=16;
}
if(result_l<4)result_l=4;
if(flag==0)temp=result_l;
for(j=temp-1;j>=0;j--){
reset_D();
print_Dnum(i++,result[j]);
}
flag++;
if(flag%5000==0)temp--;
else if(temp<4)flag=0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)