!!!LPC213x系列底层硬件驱动函数库
更新时间:2023-04-25 16:08:01 阅读量: 综合文库 文档下载
目录
LPC213x系列底层硬件驱动函数库 (1)
.1 GPIO (1)
.1.1 使用说明 (1)
.1.2 源码分析 (4)
.2 UART (7)
.2.1 使用说明 (7)
.2.2 源码分析 (9)
.3 I2C (13)
.3.1 使用说明 (13)
.3.2 源码分析 (15)
.4 SPI (26)
.4.1 使用说明 (26)
.4.2 源码分析 (27)
.5 SSP (29)
.5.1 使用说明 (29)
.5.2 源码分析 (30)
.6 定时/计数器 (32)
.6.1 使用说明 (32)
.6.2 源码分析 (36)
.7 PWM (41)
.7.1 使用说明 (41)
.7.2 源码分析 (43)
.8 ADC (46)
.8.1 使用说明 (46)
.8.2 源码分析 (47)
.9 DA (49)
.9.1 使用说明 (49)
.10 实时时钟 (50)
.10.1 使用说明 (50)
.10.2 源码分析 (51)
.11 看门狗 (53)
.11.1 使用说明 (53)
.12 中断控制器 (54)
.12.1 使用说明 (54)
.12.2 源码分析 (55)
.13 锁相环PLL (58)
.13.1 使用说明 (58)
.13.2 源码分析 (59)
.14 IAP (61)
.14.1 使用说明 (61)
.14.2 源码分析 (64)
i
LPC213x系列底层硬件驱动函数库
.1 GPIO
.1.1使用说明
1.P0口GPIO初始化
函数功能:将P0口中,num为1的位初始化为GPIO,并设置方向。
表格 1 P0口GPIO初始化函数
调用示例:
P0_GPIOInit((1<<4)|(1<<16),0);//将P0.4和P0.16初始化为GPIO
//并设置为输入模式
2.P1口GPIO初始化
函数功能:将P1口中,num为1的位初始化为GPIO,并设置方向。
表格 2 P1口GPIO初始化函数
调用示例:
P1_GPIOInit(1<<18,1);//将P1.18初始化为GPIO
//并设置为输出模式
1
3.P0口GPIO输入、输出方向设置
函数功能:在P0口中,设置num中“1”所对应位的输入、输出方式。
表格 3 P0口GPIO输入、输出方向设置
调用示例:
P0_GPIODir((1<<4)|(1<<16),1);//将P0.4和P0.16设置为输出模式
4.P1口GPIO输入、输出方向设置
函数功能:在P1口中,设置num中“1”所对应位的输入、输出方式。
表格 4 P1口GPIO输入、输出方向设置
调用示例:
P1_GPIODir(1<<18,1);//将P1.18设置为输出模式
5.P0口GPIO输出“1”
函数功能:在P0口中,置位num为1的位所对应的管脚。
表格 5 P0口GPIO输出“1”
2
调用示例:
P0_GPIOSet((1<<4)|(1<<16));//使P0.4和P0.16输出“1”
6.P0口GPIO输出“0”
函数功能:在P0口中,清零num为1的位所对应的管脚。
表格 6 P0口GPIO输出“0”
调用示例:
P0_ GPIOClr((1<<4)|(1<<16));//使P0.4和P0.16输出“0”
7.P0口GPIO输出
函数功能:将value所对应的值输出到P0口。
表格7 P0口GPIO输出
调用示例:
Write_P0(0xaa);//使P0.0~P0.7输出“0xaa”
8.P1口GPIO输出“1”
函数功能:在P1口中,置位num为1的位所对应的管脚。
表格8 P1口GPIO输出“1”
调用示例:
P1_ GPIOSet(1<<18);//使P1.18输出“1”
3
9.P1口GPIO输出“0”
函数功能:在P1口中,清零num为1的位所对应的管脚。
表格9 P1口GPIO输出“0”
调用示例:
P1_GPIOClr(1<<18);//使P1.18输出“0”
10.P1口GPIO输出
函数功能:将value所对应的值输出到P1口。
表格10 P1口GPIO输出
调用示例:
Write_P1(0xaa<<18);//使P1.18~P1.25输出“0xaa”
.1.2源码分析
程序清单0.1 GPIO.c源代码
/****************************************************************************************** ** 文件名称:GPIO.c
** 文件描述:LPC213x系列GPIO操作软件包。
** 文件说明:对于引脚的操作使用位操作方式。
******************************************************************************************/ #include "config.h"
/****************************************************************************************** ** 函数名称:void P0_GPIOInit(uint32 num,uint8 dir)
** 功能描述:将P0口中,num为1的位初始化为GPIO。
** 输入:num 需要初始化的管脚
** dir 管脚的输入输出方向
** 1——输出
** 0——输入
** 输出:无
** 说明:如果dir错误,则默认为输入方向。
4
** 调用模块:P0_GPIOInit((1<<4)|(1<<16),0);//将P0.4和P0.16初始化为GPIO
** //且设置为输入模式
******************************************************************************************/ void P0_GPIOInit(uint32 num,uint8 dir)
{
uint8 i;
if((num&0xffff)!=0)//初始化引脚P0.0~P0.15,需要设置PINSEL0 for(i=0;i<16;i++)
if((num&(1<
PINSEL0 = PINSEL0 & (~(0x03<<(2*i)));
if(num>0xffff)//初始化引脚P0.16~P0.31,需要设置PINSEL1 for(i=16;i<32;i++)
if((num&(1<
PINSEL1 = PINSEL1 & (~(0x03<<(2*(i-16))));
if(dir==1)IO0DIR = (IO0DIR&(~num))|num;
else IO0DIR = (IO0DIR&(~num));
}
/****************************************************************************************** ** 函数名称:void P1_GPIOInit(uint32 num,uint8 dir)
** 功能描述:将P1口中,num为1的位初始化为GPIO。
** 输入:num 需要初始化的管脚
** dir 管脚的输入输出方向
** 1——输出
** 0——输入
** 输出:无
** 说明:如果dir错误,则默认为输入方向。
******************************************************************************************/ void P1_GPIOInit(uint32 num,uint8 dir)
{
if((num&(0x3ff<<16))!=0)//P1.16~P1.25,由PINSEL2.3位控制
PINSEL2 = PINSEL2 & (~(1<<3));
if(num>(0x3ff<<16))//P1.26~P1.31,由PINSEL2.2位控制
PINSEL2 = PINSEL2 & (~(1<<2));
if(dir==1)IO1DIR = (IO1DIR&(~num))|num;
else IO1DIR = (IO1DIR&(~num));
}
/****************************************************************************************** ** 函数名称:uint8 P0_GPIODir(uint32 num,uint8 dir)
** 功能描述:在P0口中,设置num为1的位输入,输出方式。
** 输入:num 需要初始化的管脚
** dir 管脚的输入输出方向
** 1——输出
** 0——输入
** 输出: 1 操作成功
5
** 0 操作失败
******************************************************************************************/ uint8 P0_GPIODir(uint32 num,uint8 dir)
{
if((dir!=0)&&(dir!=1))return(0);
if(dir==1)IO0DIR = (IO0DIR&(~num))|num;//1 表示该位为输出模式
else IO0DIR = (IO0DIR&(~num));//0 表示该位为输入模式
return(1);
}
/****************************************************************************************** ** 函数名称:uint8 P1_GPIODir(uint32 num,uint8 dir)
** 功能描述:在P1口中,设置num为1的位输入,输出方式。
** 输入:num 需要初始化的管脚
** dir 管脚的输入输出方向
** 1——输出
** 0——输入
** 输出: 1 操作成功
** 0 操作失败
******************************************************************************************/ uint8 P1_GPIODir(uint32 num,uint8 dir)
{
if((dir!=0)&&(dir!=1))return(0);
if(dir==1)IO1DIR = (IO1DIR&(~num))|num;//1 表示该位为输出模式
else IO1DIR = (IO1DIR&(~num));//0 表示该位为输入模式
return(1);
}
程序清单0.2 GPIO软件包中定义的宏定义
#define Read_P0()IO0PIN // 将P0口的值读出
#define Read_P1()IO1PIN // 将P1口的值读出
#define Write_P0(value)IO0PIN = value // 将value的值写入到P0口中
#define Write_P1(value)IO1PIN = value // 将value的值写入到P1口中
#define P0_GPIOSet(num)IO0SET = num // 在P0口中,置位num为1的位所对应的管脚#define P0_GPIOClr(num)IO0CLR = num // 在P0口中,清零num为1的位所对应的管脚#define P1_GPIOSet(num)IO1SET = num // 在P1口中,置位num为1的位所对应的管脚#define P1_GPIOClr(num)IO1CLR = num // 在P1口中,清零num为1的位所对应的管脚
6
.2 UART
.2.1使用说明
1.初始化
函数功能:对UARTn进行初始化。
表格11 UART初始化
调用示例:
UARTn_Ini(0,9600,8,1,0);// UART0初始化,波特率9600,8位数据位
// 1位停止位,无奇偶校验位
2.设置FIFO
函数功能:对UARTn进行FIFO初始化。
表格12 UART FIFO初始化
调用示例:
Set_FIFO(0, 8);// UART0 FIFO初始化,8字节触发
7
3.发送1字节数据
函数功能:从UART发送一字节数据。
表格13 UART发送1字节数据
调用示例:
UARTn_SendByte(1,0x55);// 从UART1发送数据55H
4.发送多字节数据
函数功能:从UART发送多字节数据。
表格14 UART发送多字节数据
调用示例:
UARTn_SendData(0,*data_buf,8);//将data_buf缓冲区中的8个字节数据
//从UART0发送出去
5.接收数据
函数功能:从UART接收数据。
表格15 UART接收数据
8
调用示例:
UARTn_RcvData(0,*data_buf,8);//从UART0接收8字节数据
//并保存到data_buf缓冲区中
.2.2源码分析
程序清单0.3 UART.c源代码
/****************************************************************************************** ** 文件名称:UART.c
** 文件描述:LPC213x UARTn接口操作软件包。
** 文件说明:程序中全部采用查询方式对UART进行操作。
******************************************************************************************/ #include "config.h"
#define TXD0 1 //TXD0是引脚P0.0的第2功能
#define RXD0 (1<<2)//RXD0是引脚P0.1的第2功能
#define TXD1 (1<<16)//TXD1是引脚P0.8的第2功能
#define RXD1 (1<<18)//RXD1是引脚P0.9的第2功能
/****************************************************************************************** ** 函数名称:uint8 UARTn_Ini(uint8 n,uint32 baud,uint8 datab,uint8 stopb,
** uint8 parity,uint8 INT_En)
** 功能描述:对UARTn进行初始化。
** 输入:n 0——UART0 1——UART1
** baud 串口通信波特率
** datab 数据位个数,有效值为:5,6,7,8
** stopb 停止位个数,有效值为:1,2
** parity奇偶校验位,0-无校验
** 1——奇校验
** 2——偶校验
** 3——强制为1
** 4——强制为0
** INT_En 中断控制字节,按位操作
** bit0 1——RBR中断使能,0——RBR中断禁止
** bit1 1——THRE中断使能,0——THRE中断禁止
** bit3 1——RX线状态中断使能,0——RX线状态中断禁止
** 输出:0 初始化失败
** 1 初始化成功
******************************************************************************************/ uint8 UARTn_Ini(uint8 n,uint32 baud,uint8 datab,uint8 stopb,uint8 parity,uint8 INT_En)
{
uint32 bak;
/*检查参数的合理性*/
if((n != 0)&&(n != 1))return(0);//只有两个串口
if((baud==0)||(baud>115200))return(0);//波特率:1~115200,否则出错
9
if((datab<5)||(datab>8))return(0);//数据位数:1~8,否则出错
if((stopb==0)||(stopb>2))return(0);//停止位:1、2,否则出错
if(parity>4)return(0);//奇偶校验位有错
//设置UART引脚,且不影响其它引脚
if(n == 0)PINSEL0 = (PINSEL0 & (~0x0f))| TXD0 | RXD0;//设置UART0
else PINSEL0 = (PINSEL0 & (~(0x0f<<16)))| TXD1 | RXD1;//设置UART1
/*设置串口波特率*/
*(volatile uint8 *)((&U0LCR)+ n * 0x4000)= 0x80;//DLAB=1
*(volatile uint8 *)((&U0DLM)+ n * 0x4000)= ((Fpclk/16)/baud)/256;
*(volatile uint8 *)((&U0DLL)+ n * 0x4000)= ((Fpclk/16)/baud)%256;
/*设置串口模式*/
bak = datab - 5;//设置字长
if(stopb==2)
bak |= 0x04;//判断是否为2位停止位
if(parity != 0)
{
parity -= 1;
bak |= 0x08;
}
bak |= parity<<4;//设置奇偶校验位
*(volatile uint8 *)((&U0LCR)+ n * 0x4000)= bak;
*(volatile uint8 *)((&U0IER)+ n * 0x4000)= INT_En & 0x07;//设置中断使能寄存器
return(1);
}
/****************************************************************************************** ** 函数名称:void Set_FIFO(uint8 n,uint8 data)
** 功能描述:设置FIFO
** 输入: n 0——UART0 1——UART1
** data FIFO触发字节设定,只能为1,2,8、14个字节
** 输出: 0 初始化失败
** 1 初始化成功
******************************************************************************************/ uint8 Set_FIFO(uint8 n,uint8 data)
{
if(n == 0) // UART0
{
switch(data)
{
case 1:
U0FCR = 0x01; // 缓冲区为1个字节
return(1);
case 4:
10
U0FCR = 0x41; //缓冲区为4个字节
return(1);
case 8:
U0FCR = 0x81; //缓冲区为8个字节
return(1);
case 14:
U0FCR = 0xc1; //缓冲区为14个字节
return(1);
default:
return(0);
}
}
if(n == 1) //UART1
{
switch(data)
{
case 1:
U1FCR = 0x01; //缓冲区为1个字节
return(1);
case 4:
U1FCR = 0x41; //缓冲区为4个字节
return(1);
case 8:
U1FCR = 0x81; //缓冲区为8个字节
return(1);
case 14:
U1FCR = 0xc1; //缓冲区为14个字节
return(1);
default:
return(0);
}
}
return(0);
}
/****************************************************************************************** ** 函数名称:void UARTn_SendData(uint8 n,uint8 *data_buf,uint8 count)
** 功能描述:从串口发送数据。
** 输入:n 0——UART0 1——UART1
** data_buf 发送数据缓冲区首地址
** count 发送字节数
** 输出:无
******************************************************************************************/ void UARTn_SendData(uint8 n,uint8 *data_buf,uint8 count)
{
11
uint8 i;
for(i=0;i { *(volatile uint8 *)((&U0THR)+ n * 0x4000)= data_buf[i];//发送数据 //等待数据发送完毕 while(((*(volatile uint8 *)((&U0LSR)+ n * 0x4000))& 0x20)==0); } } /****************************************************************************************** ** 函数名称:void UARTn_SendByte(uint8 n,uint8 data) ** 功能描述:从串口发送数据。 ** 输入:n 0——UART0 1——UART1 ** data 发送的数据 ** 输出:无 ** 说明:程序采用查询方式,并且没有使用FIFO。 *****************************************************************************************/ void UARTn_SendByte(uint8 n,uint8 data) { *(volatile uint8 *)((&U0THR)+ n * 0x4000)= data;//发送数据 //等待数据发送完毕 while(((*(volatile uint8 *)((&U0LSR)+ n * 0x4000))& 0x20)==0); } /***************************************************************************************** ** 函数名称:void UARTn_RcvData(uint8 n,uint8 *data_buf,uint8 count) ** 功能描述:从串口接收数据。 ** 输入:n 0——UART0 1——UART1 ** data_buf 接收数据缓冲区首地址 ** count 接收字节数 ** 输出:无 ** 说明:程序采用查询方式,存在死等待,没有使用FIFO。 ******************************************************************************************/ void UARTn_RcvData(uint8 n,uint8 *data_buf,uint8 count) { uint8 i; for(i=0;i { //等待接收标志置位 while(((*(volatile uint8 *)((&U0LSR)+ n * 0x4000))& 0x01)== 0); //保存接收到的数据 data_buf[i] = (*(volatile uint8 *)((&U0RBR)+ n * 0x4000)); } } 12 .3 I2C .3.1使用说明 1.初始化 函数功能:I2C接口初始化。 表格16 I2C接口初始化 调用示例: I2C_Init(0,1,100000,0,0);//I2C0初始化为主模式,100K通信速率, //中断通道号为slot0,不关心从机地址I2C_Init(0,0,100000,0xA0,0);//I2C0初始化为从模式,从机地址为0xA0, //中断通道号为slot0,不关心通信速率 2.向无子地址器件发送1字节数据 函数功能:向无子地址器件发送1字节数据。 表格17 I2C接口向无子地址器件发送1字节数据 调用示例: I2C_SendByte(0,0xa0,0x55);//向器件地址为0xA0的器件发送数据55H 13 3.从无子地址器件读取1字节数据 函数功能:从无子地址器件读取1字节数据。 表格18 I2C接口从无子地址器件读取1字节数据 调用示例: I2C_RcvByte(0,0xa0,dat);//从器件地址为0xA0的器件接收1个字节的数据到 //dat缓冲区 4.从有子地址器件任意地址开始读取N字节数据 函数功能:从有子地址器件任意地址开始读取N字节数据。 表格19 I2C接口从有子地址器件任意地址开始读取N字节数据 调用示例: I2C_ReadNByte(0,0xa0,2,0x1000,*s,64);//从0xA0器件的1000H地址处读取 //64字节的数据,保存到s缓冲区 //器件地址为双字节,如24C128 14 5.向有子地址器件写入N字节数据 函数功能:向有子地址器件写入N字节数据。 表格20 I2C接口从有子地址器件任意地址开始读取N字节数据 调用示例: I2C_WriteNByte(0,0xa0,1,0x00,*s,8);//向0xA0器件的00地址处写入 //8字节数据,发送数据缓冲区为s。 //器件子地址为单字节,如24C02 I2C_WriteNByte(0,0xa0,3,0x00,*s,8);//向0xA0器件的00地址处写入 //8字节数据,发送数据缓冲区为s。 //器件子地址为8+X,如24C16 .3.2源码分析 程序清单0.4 I2C.c源代码 /****************************************************************************************** ** 文件名称:I2C.c ** 文件描述:LPC213x硬件I2C中断方式软件包。 ** 文件说明:软件包采用中断方式进行操作,程序仍会死等待操作完成。 ******************************************************************************************/ #include "config.h" /*定义用于和I2C中断传送信息的全局变量*/ volatile uint8 slarv;//子地址接收标志,为1时表示已接收从机子地址 volatile uint32 adrpoint;//定义从机缓冲区读写操作指针 volatile uint8 I2C_n;//I2C接口号 volatile uint8 I2C_sla;//I2C器件从地址 volatile uint32 I2C_suba;//I2C器件的内部子地址 15 volatile uint8 I2C_suba_num;//I2C子地址字节数 volatile uint8 *I2C_buf;//I2C数据缓冲区指针, //如果要将I2C接口设置为从机模式, //那么,在调用软件包前要设置I2C数据缓冲区指针I2C_buf volatile uint32 I2C_num;//要读取/写入的数据个数 volatile uint8 I2C_end;//I2C总线结束标志:结束总线是置1 volatile uint8 I2C_suba_en;/* 子地址控制 0——子地址已经处理或者不需要子地址 1——读取操作 2——写操作 */ /****************************************************************************************** ** 函数名称:__irq IRQ_I2C() ** 函数功能:硬件I2C服务程序。 ** 入口参数:无 ** 出口参数:无 ** 说明:注意处理子地址为2字节的情况。 ******************************************************************************************/ void __irq IRQ_I2C(void) { /* 读取I2C状态寄存器I2STA T 按照全局变量的设置进行操作及设置软件标志 清除中断逻辑,中断返回 */ uint8 stat;//用来读取I2C状态寄存器I2STA T stat = *((volatile uint32 *)(&I2C0STA T)+ (I2C_n*0x10000));//读取I2STA T, I2STAT=0xE001C004 switch(stat & 0xF8) { /*根据状态码进行相应的处理*/ case 0x08:/*已发送起始条件*/ //主发送和主接收都有 /*装入SLA+W或者SLA+R*/ if(I2C_suba_en == 1)/*SLA+R*/ //指定子地址读 { //先写入地址 *((volatile uint32 *)(&I2DAT)+ (I2C_n*0x10000))= I2C_sla &0xfe; } else /*SLA+W*/ { //直接发送从机地址 *((volatile uint32 *)(&I2DAT)+ (I2C_n*0x10000))= I2C_sla &0xfe; } /*清零SI位*/ *((volatile uint32 *)(&I2CONCLR)+ (I2C_n*0x10000))= (1<<3)| //SI (1<<5);//STA break; 16 case 0x10:/*已发送重复起始条件*/ //主发送和主接收都有 /*装入SLA+W或者SLA+R*/ //重起总线后,重发从地址 *((volatile uint32 *)(&I2DAT)+ (I2C_n*0x10000))= I2C_sla; *((volatile uint32 *)(&I2CONCLR)+ (I2C_n*0x10000))= 0x28;//清零SI,STA break; case 0x18: case 0x28:/*已发送I2DA T中的数据,已接收ACK*/ if(I2C_suba_en == 0) { if(I2C_num > 0)//如果还有数据需要读取 { //读取数据 *((volatile uint32 *)(&I2DAT)+ (I2C_n*0x10000))= *I2C_buf++; //清零SI,STA *((volatile uint32 *)(&I2CONCLR)+ (I2C_n*0x10000))= 0x28; I2C_num--;//字节数减1 } else /*没有数据发送了*/ { /*停止总线*/ *((volatile uint32 *)(&I2CONSET)+ (I2C_n*0x10000)) = (1<<4);//STO = 1 *((volatile uint32 *)(&I2CONCLR)+ (I2C_n*0x10000)) = 0x28;//清零SI,STA I2C_end = 1;//总线已经停止 } } if(I2C_suba_en == 1)/*若是指定地址读,则重新启动总线*/ { if(I2C_suba_num == 2)//如果是双字节子地址 { *((volatile uint32 *)(&I2DAT)+ (I2C_n*0x10000)) = ((I2C_suba>>8)& 0xff); //先发送地址字节 *((volatile uint32 *)(&I2CONCLR)+ (I2C_n*0x10000)) = 0x28;//清零SI,STA I2C_suba_num--;//子地址字节数减1 break; } if(I2C_suba_num == 1)//如果是双字节子地址 { *((volatile uint32 *)(&I2DAT)+ (I2C_n*0x10000)) = (I2C_suba & 0xff);//发送子地址低字节或单字节子地址*((volatile uint32 *)(&I2CONCLR)+ (I2C_n*0x10000)) = 0x28;//清零SI,STA I2C_suba_num--; 17 break; } if(I2C_suba_num == 0) { //清零SI *((volatile uint32 *)(&I2CONCLR)+ (I2C_n*0x10000))= 0x08; *((volatile uint32 *)(&I2CONSET)+ (I2C_n*0x10000)) = 0x20;//置位STA I2C_suba_en = 0;//子地址已经处理 break; } } if(I2C_suba_en == 2)/*指定子地址写,子地址尚未指定,则发送子地址*/ { if(I2C_suba_num > 0) { if(I2C_suba_num == 2)//如果是双字节子地址 { //先发送子地址高字节 *((volatile uint32 *)(&I2DAT)+ (I2C_n*0x10000)) =((I2C_suba>>8)& 0xff); *((volatile uint32 *)(&I2CONCLR)+ (I2C_n*0x10000)) =0x28;//清零SI,STA I2C_suba_num--;//子地址字节数减1 break; } if(I2C_suba_num == 1)//如果是双字节子地址 { *((volatile uint32 *)(&I2DAT)+ (I2C_n*0x10000)) = (I2C_suba & 0xff);//发送子地址低字节或单字节子地址*((volatile uint32 *)(&I2CONCLR)+ (I2C_n*0x10000)) =0x28;//清零SI,STA I2C_suba_num--; I2C_suba_en = 0; break; } } } break; case 0x40:/*已发送SLA+R,已接收ACK*/ if(I2C_num <= 1)/*如果是最后一个字节*/ { //下次发送非应答信号 *((volatile uint32 *)(&I2CONCLR)+ (I2C_n*0x10000))= 1<<2; } else { //下次发送应答信号 18 *((volatile uint32 *)(&I2CONSET)+ (I2C_n*0x10000))= 1<<2; } *((volatile uint32 *)(&I2CONCLR)+ (I2C_n*0x10000))= 0x28;//清零SI,SLA break; case 0x20:/*已发送SLA+W,已接收非应答*/ case 0x30:/*已发送I2DA T中的数据,已接收非应答*/ case 0x38:/*在SLA+R/W或数据字节中丢失仲裁*/ case 0x48:/*已发送SLA+R,已接收非应答*/ *((volatile uint32 *)(&I2CONCLR)+ (I2C_n*0x10000))= 0x28; I2C_end = 0xff;//总线出错 break; case 0x50:/*已接收数据字节,已返回ACK*/ *I2C_buf++ = *((volatile uint32 *)(&I2DAT)+ (I2C_n*0x10000)); I2C_num--; if(I2C_num == 1)/*接收最后一个字节*/ { *((volatile uint32 *)(&I2CONCLR)+ (I2C_n*0x10000)) = 0x2c; } else { *((volatile uint32 *)(&I2CONSET)+ (I2C_n*0x10000))= 0x04;//AA=1 *((volatile uint32 *)(&I2CONCLR)+ (I2C_n*0x10000))= 0x28; } break; case 0x58:/*已接收数据字节,已返回非应答*/ //读取最后一字节数据 *I2C_buf++ = *((volatile uint32 *)(&I2DAT)+ ((I2C_n*0x40000)/4)); *((volatile uint32 *)(&I2CONSET)+ (I2C_n*0x10000))= 0x10;//结束总线 *((volatile uint32 *)(&I2CONCLR)+ (I2C_n*0x10000))= 0x28; I2C_end = 1; break; /* 以下为从机模式所对应的状态信息*/ case 0x60://接收到自身SLA+W case 0x68: slarv = 0; *((volatile uint32 *)(&I2CONSET)+ (I2C_n*0x10000))= 0x04; *((volatile uint32 *)(&I2CONCLR)+ (I2C_n*0x10000)) = 0x38;//清除标志位break; case 0xa8:// 接收到SLA+R,或已经发送数据并接收到ACK位 case 0xb0: case 0xb8: //将对应地址处的数据放入I2DA T中 *((volatile uint32 *)(&I2DAT)+ (I2C_n*0x10000))= *(I2C_buf+adrpoint); adrpoint++; 19 *((volatile uint32 *)(&I2CONSET)+ (I2C_n*0x10000))= 0x04; //清除I2C标志位,STA、STO、SI *((volatile uint32 *)(&I2CONCLR)+ (I2C_n*0x10000))= 0x38; break; case 0x80://接收到数据 if(slarv==0) { adrpoint = *((volatile uint32 *)(&I2DAT)+ (I2C_n*0x10000)); slarv = 1; } else { *(I2C_buf+adrpoint)= *((volatile uint32 *)(&I2DAT)+ (I2C_n*0x10000)); adrpoint++; } *((volatile uint32 *)(&I2CONSET)+ (I2C_n*0x10000))= 0x04; //清除I2C标志位,STA、STO、SI *((volatile uint32 *)(&I2CONCLR)+ (I2C_n*0x10000))= 0x38; break; case 0xc0://总线结束,或总线重新启动 default://其它状态 *((volatile uint32 *)(&I2CONSET)+ (I2C_n*0x10000))= 0x04; //清除I2C标志位,STA、STO、SI *((volatile uint32 *)(&I2CONCLR)+ (I2C_n*0x10000))= 0x38; break; } VICVectAddr = 0x00;//中断处理结束 } /****************************************************************************************** ** 函数名称:void I2C_Init(uint8 n,uint8 MODE,uint32 Fi2c,uint8 Adr,uint8 slot) ** 函数功能:初始化I2C接口。 ** 入口参数:n I2C接口号,0--I2C0,1--I2C1 ** MODE 工作模式,0——从模式,1——主模式 ** Fi2c I2C通信速率,0~400K,如果超过400K,则会强制设置为400KHz ** 如果设置为从机,该参数无效 ** Adr 当设置为从模式时,Adr表示从地址, ** 在主模式下,该参数是无效的,可以任意设置 ** slot 由于I2C采用向量IRQ中断方式,所以需要指定对应的通道,0~15 ** 出口参数:1 操作成功 ** 0 操作失败 ** 说明:初始化函数会将I2Cn的中断设置为IRQ中断,并分为slot。 ******************************************************************************************/ uint8 I2C_Init(uint8 n,uint8 MODE,uint32 Fi2c,uint8 Adr,uint8 slot) { 20
正在阅读:
2015浙江教师招聘考试练习题二十07-24
苏科版八上物理期中模拟试卷(一)05-22
我在梦中当了一次小偷小学生三年级优秀作文06-13
2021年市卫生健康委工作总结暨2022年工作思路08-03
春日感悟作文500字07-06
高考数学考点分布内容07-23
内蒙古大学校本部新进教职工公寓申请表12-26
- 多层物业服务方案
- (审判实务)习惯法与少数民族地区民间纠纷解决问题(孙 潋)
- 人教版新课标六年级下册语文全册教案
- 词语打卡
- photoshop实习报告
- 钢结构设计原理综合测试2
- 2014年期末练习题
- 高中数学中的逆向思维解题方法探讨
- 名师原创 全国通用2014-2015学年高二寒假作业 政治(一)Word版
- 北航《建筑结构检测鉴定与加固》在线作业三
- XX县卫生监督所工程建设项目可行性研究报告
- 小学四年级观察作文经典评语
- 浅谈110KV变电站电气一次设计-程泉焱(1)
- 安全员考试题库
- 国家电网公司变电运维管理规定(试行)
- 义务教育课程标准稿征求意见提纲
- 教学秘书面试技巧
- 钢结构工程施工组织设计
- 水利工程概论论文
- 09届九年级数学第四次模拟试卷
- 底层
- 硬件驱动
- 函数
- 系列
- LPC
- 213
- 手动平行式双闸板闸阀
- 回放利器TASCAM线性录音笔DR100mkII
- §2.3.2抛物线的简单几何性质学案
- 肚子上有点赘肉,怎么才能练成6块腹肌
- 校园活动策划书方案.doc
- 如何帮助学困生提高学习成绩呢
- 【推荐】安徽省定远县育才学校2018-2019学年高一历史3月模拟月考
- 净空法师《楞严经清净明诲章亲闻记》
- 基因组水平上分析DNA与蛋白质相互作用
- 英语单词词性全部解析doc资料
- 1959年中医资料10 对针刺操作手法的研究和心得
- Eclipse教程(china)之二
- 男士五大护肤守旧观念要抛弃.docx
- 药品采购供应管理制度与流程
- 2014年司法考试备考方法
- 客厅墙上挂什么画吉祥 挂山水画非常好
- 以诚待客,信誉第一,合肥回收冬虫夏草
- 预算绩效目标管理填表说明
- 【毕业生自我鉴定】2020工程造价毕业生自我鉴定书
- 建业小高层住宅楼施工组织设计