O_LPC1114基本库
O_嵌入式专题目录
AT24C02
.h
#ifndef __AT24C02_H #define __AT24C02_H /* 注意:AT24C02的地址为(0x00~0xFF)(不可越界)*/ extern uint8_t AT24C02_ReadOneByte(uint8_t ReadAddr); //指定地址读取一个字节 extern void AT24C02_Read(uint8_t ReadAddr,uint8_t *Buffer,uint16_t Num); //从指定地址开始读出指定长度的数据 extern void AT24C02_WriteOneByte(uint8_t WriteAddr,uint8_t DataToWrite); //指定地址写入一个字节 extern void AT24C02_Write(uint8_t WriteAddr,uint8_t *Buffer,uint16_t Num); //从指定地址开始写入指定长度的数据 extern uint8_t AT24C02_Check(void); //检查器件 #endif.c
#include "INCLUDE.h" extern volatile uint8_t I2CMasterBuffer[BUFSIZE]; extern uint8_t I2CSlaveBuffer[BUFSIZE]; extern volatile uint32_t I2CReadLength, I2CWriteLength; /*********************************************/ /* 函数功能:延时函数 大于5ms */ /*********************************************/ void delay_AT24C02(void) { uint32_t i=50000; while(i--); } /*********************************************/ /* 函数功能:给AT24C02中写多个字节数据 */ /* 入口参数:WriteAddr:将要写数据的目标地址 */ /* *Buffer:把这个数组中的数据写入 */ /* Num:要写的数据字节个数 */ /* 注意:AT24C02的地址为(0x00~0xFF) */ /*********************************************/ void AT24C02_Write(uint8_t WriteAddr,uint8_t *Buffer,uint16_t Num) { uint8_t i=0; I2CWriteLength = 2+Num; I2CReadLength = 0; I2CMasterBuffer[0] = AT24C02_ADDR; I2CMasterBuffer[1] = WriteAddr; for(i=0;i<Num;i++) { I2CMasterBuffer[2+i] = Buffer[i]; } I2CEngine(); delay_AT24C02(); } /*********************************************/ /* 函数功能:从AT24C02中读一个字节数据 */ /* 出口参数:temp :读出的数据 */ /* 注意:AT24C02的地址为(0x00~0xFF) */ /*********************************************/ uint8_t AT24C02_ReadOneByte(uint8_t ReadAddr) { I2CWriteLength = 1; I2CReadLength = 1; I2CMasterBuffer[0] = AT24C02_ADDR; I2CMasterBuffer[1] = ReadAddr; I2CMasterBuffer[2] = AT24C02_ADDR | READ_WRITE; I2CEngine(); return I2CSlaveBuffer[0]; } /*********************************************/ /* 函数功能:从AT24C02中读多个字节数据 */ /* 入口参数:ReadAddr:将要读数据的目标地址 */ /* *Buffer:读出数据来放到这个数组 */ /* Num:要读的数据字节个数 */ /* 注意:AT24C02的地址为(0x00~0xFF) */ /*********************************************/ void AT24C02_Read(uint8_t ReadAddr,uint8_t *Buffer,uint16_t Num) { while(Num) { *Buffer++=AT24C02_ReadOneByte(ReadAddr++); Num--; } } /*********************************************/ /* 函数功能:给AT24C02中写一个字节数据 */ /* 入口参数:WriteAddr:将要写入的目标地址 */ /* DataToWrite:将要写入的字节数据 */ /* 注意:AT24C02的地址为(0x00~0xFF) */ /*********************************************/ void AT24C02_WriteOneByte(uint8_t WriteAddr, uint8_t DataToWrite) { I2C_Send_Ctrl(0XA0); I2C_Send_Byte(WriteAddr); //发送地址 I2C_Send_Byte(DataToWrite); //发送字节 I2C_Stop(); //产生一个停止条件 delay_AT24C02(); } /*********************************************/ /* 函数功能:从AT24C02中读一个字节数据 */ /* 出口参数:temp :读出的数据 */ /* 注意:AT24C02的地址为(0x00~0xFF) */ /*********************************************/ uint8_t AT24C02_ReadOneByte(uint8_t ReadAddr) { uint8_t temp=0; I2C_Send_Ctrl(0XA0); I2C_Send_Byte(ReadAddr); //发送地址 I2C_Send_Ctrl(0XA1); temp=I2C_Recieve_Byte(); I2C_Stop(); //产生一个停止条件 return temp; } /*********************************************/ /* 函数功能:从AT24C02中读多个字节数据 */ /* 入口参数:ReadAddr:将要读数据的目标地址 */ /* *Buffer:读出数据来放到这个数组 */ /* Num:要读的数据字节个数 */ /* 注意:AT24C02的地址为(0x00~0xFF) */ /*********************************************/ void AT24C02_Read(uint8_t ReadAddr,uint8_t *Buffer,uint16_t Num) { while(Num) { *Buffer++=AT24C02_ReadOneByte(ReadAddr++); Num--; } } /*********************************************/ /* 函数功能:给AT24C02中写多个字节数据 */ /* 入口参数:WriteAddr:将要写数据的目标地址 */ /* *Buffer:把这个数组中的数据写入 */ /* Num:要写的数据字节个数 */ /* 注意:AT24C02的地址为(0x00~0xFF) */ /*********************************************/ void AT24C02_Write(uint8_t WriteAddr,uint8_t *Buffer,uint16_t Num) { while(Num--) { AT24C02_WriteOneByte(WriteAddr,*Buffer); WriteAddr++; Buffer++; } } /***********************************************/ /* 函数功能:检测AT24C02是否存在 */ /* 出口参数:0:存在 */ /* 1:不存在 */ /***********************************************/ uint8_t AT24C02_Check(void) { uint8_t temp; temp = AT24C02_ReadOneByte(0x00); // 读字节 if(temp==0x88)return 0; else //排除第一次初始化的情况 { AT24C02_WriteOneByte(0x00,0x88); temp=AT24C02_ReadOneByte(0x00); if(temp==0X88)return 0; } return 1; }
CH452
.h
#ifndef __CH452_H #define __CH452_H /* CH451和CH452的常用命令码 */ #define CH452_NOP 0x0000 // 空操作 #define CH452_RESET 0x0201 // 复位 #define CH452_LEVEL 0x0100 // 加载光柱值,需另加7位数据 #define CH452_CLR_BIT 0x0180 // 段位清0,需另加6位数据 #define CH452_SET_BIT 0x01C0 // 段位置1,需另加6位数据 #define CH452_SLEEP 0x0202 // 进入睡眠状态 #define CH452_LEFTMOV 0x0300 // 设置移动方式-左移 #define CH452_LEFTCYC 0x0301 // 设置移动方式-左循环 #define CH452_RIGHTMOV 0x0302 // 设置移动方式-右移 #define CH452_RIGHTCYC 0x0303 // 设置移动方式-右循环 #define CH452_SELF_BCD 0x0380 // 自定义BCD码,需另加7位数据 #define CH452_SYSOFF 0x0400 // 关闭显示、关闭键盘 #define CH452_SYSON1 0x0411 // 开启显示 #define CH452_SYSON2 0x0415 // 开启显示、关闭键盘扫描、开看门狗、高速闪烁 #define CH452_SYSON3 0x0405 // 开启显示、关闭键盘扫描、开看门狗、低速闪烁 #define CH452_SYSON4 0x040d // 开启显示,关闭键盘扫描,开看门狗,低速闪烁,设置字选为高电平 #define CH452_SYSON5 0x041d // 开启显示,关闭键盘扫描,开看门狗,高速闪烁,设置字选为高电平 #define CH452_SYSON2W 0x0433 // 开启显示、键盘, 真正2线接口 #define CH452_NO_BCD 0x0500 // 设置默认显示方式,可另加3位扫描极限 #define CH452_BCD 0x0580 // 设置BCD译码方式,可另加3位扫描极限 #define CH452_TWINKLE 0x0600 // 设置闪烁控制,需另加8位数据 #define CH452_GET_KEY 0x0700 // 获取按键,返回按键代码 #define CH452_DIG0 0x0800 // 数码管位0显示,需另加8位数据 #define CH452_DIG1 0x0900 // 数码管位1显示,需另加8位数据 #define CH452_DIG2 0x0a00 // 数码管位2显示,需另加8位数据 #define CH452_DIG3 0x0b00 // 数码管位3显示,需另加8位数据 #define CH452_DIG4 0x0c00 // 数码管位4显示,需另加8位数据 #define CH452_DIG5 0x0d00 // 数码管位5显示,需另加8位数据 #define CH452_DIG6 0x0e00 // 数码管位6显示,需另加8位数据 #define CH452_DIG7 0x0f00 // 数码管位7显示,需另加8位数据 // BCD译码方式下的特殊字符 #define CH452_BCD_SPACE 0x10 #define CH452_BCD_PLUS 0x11 #define CH452_BCD_MINUS 0x12 #define CH452_BCD_EQU 0x13 #define CH452_BCD_LEFT 0x14 #define CH452_BCD_RIGHT 0x15 #define CH452_BCD_UNDER 0x16 #define CH452_BCD_CH_H 0x17 #define CH452_BCD_CH_L 0x18 #define CH452_BCD_CH_P 0x19 #define CH452_BCD_DOT 0x1A #define CH452_BCD_SELF 0x1E #define CH452_BCD_TEST 0x88 #define CH452_BCD_DOT_X 0x80 // 有效按键代码 #define CH452_KEY_MIN 0x40 #define CH452_KEY_MAX 0x7F // 2线接口的CH452定义 #define CH452_I2C_ADDR0 0x40 // CH452的ADDR=0时的地址 #define CH452_I2C_ADDR1 0x60 // CH452的ADDR=1时的地址,默认值 #define CH452_I2C_MASK 0x3E // CH452的2线接口高字节命令掩码 ///* 2线接口的位操作,与单片机有关 */ //#define CH452_SCL_SET {CH452_SCL=1;} //#define CH452_SCL_CLR {CH452_SCL=0;} //#define CH452_SCL_D_OUT {} //// 设置SCL为输出方向,对于双向I/O需切换为输出 //#define CH452_SDA_SET {CH452_SDA=1;} //#define CH452_SDA_CLR {CH452_SDA=0;} //#define CH452_SDA_IN (CH452_SDA) //#define CH452_SDA_D_OUT {} //// 设置SDA为输出方向,对于双向I/O需切换为输出 //#define CH452_SDA_D_IN {CH452_SDA=1;} //// 设置SDA为输入方向,对于双向I/O需切换为输入 /* 4线接口的位操作,与单片机有关 */ #define CH452_DCLK_SET {GPIO_SetValue(CH452_DCLK_port, CH452_DCLK_bit, 1);} #define CH452_DCLK_CLR {GPIO_SetValue(CH452_DCLK_port, CH452_DCLK_bit, 0);} #define CH452_DCLK_D_OUT {GPIO_SetDir(CH452_DCLK_port,CH452_DCLK_bit,DIR_OUT);} // 设置DCLK为输出方向,对于双向I/O需切换为输出 #define CH452_DIN_SET {GPIO_SetValue(CH452_DIN_port, CH452_DIN_bit, 1);} #define CH452_DIN_CLR {GPIO_SetValue(CH452_DIN_port, CH452_DIN_bit, 0);} #define CH452_DIN_D_OUT {GPIO_SetDir(CH452_DIN_port,CH452_DIN_bit,DIR_OUT);} // 设置DIN为输出方向,对于双向I/O需切换为输出 #define CH452_LOAD_SET {GPIO_SetValue(CH452_LOAD_port, CH452_LOAD_bit, 1);} #define CH452_LOAD_CLR {GPIO_SetValue(CH452_LOAD_port, CH452_LOAD_bit, 0);} #define CH452_LOAD_D_OUT {GPIO_SetDir(CH452_LOAD_port,CH452_LOAD_bit,DIR_OUT);} // 设置LOAD为输出方向,对于双向I/O需切换为输出 #define CH452_DOUT_D_IN {/*GPIO_SetDir(CH452_DOUT_port,CH452_DOUT_bit,DIR_IN);*/} // 设置DOUT为输入方向,对于双向I/O需切换为输入 /* 延时1uS子程序,主要用于2线接口,与单片机速度有关 */ //#define DELAY_1US {} // MCS51<=10MHz #define DELAY_1US {delay_us(1);} // MCS51<=20MHz //#define DELAY_1US {_nop_();_nop_();} // MCS51<=30MHz // 对外子程序 void CH452_Init(void); void CH452_Write(unsigned short cmd); // 向CH452发出操作命令 //unsigned char CH452_Read(void); // 从CH452读取按键代码 #endif.c
#include "INCLUDE.h" /****************************************************************** ** Function name :void InitCh452(void) ** Description :CH452初始化函数 ******************************************************************/ void CH452_Init(void) { CH452_Write(CH452_SYSON1); CH452_Write(CH452_BCD); } /****************************************************************** ** Function name :void CH452_Write(unsigned short cmd) ** Description :输出操作命令子程序 ******************************************************************/ void CH452_Write(unsigned short cmd) { unsigned char i; CH452_LOAD_CLR; //命令开始,LOAD=0 // CH452_LOAD_D_OUT; // 设置LOAD为输出方向 // CH452_DOUT_D_IN; // 设置DOUT为输入方向 // CH452_DIN_D_OUT; // 设置DIN为输出方向 // CH452_DCLK_D_OUT; // 设置DCLK为输出方向 for(i=0;i!=12;i++) //送入12位数据,低位在前 { if (cmd&1) {CH452_DIN_SET;} else {CH452_DIN_CLR;} // 输出位数据 // CH452_DIN=cmd&1; CH452_DCLK_CLR; cmd>>=1; CH452_DCLK_SET; //上升沿有效 } CH452_LOAD_SET; //加载数据,LOAD上升沿 delay_us(10); //命令数据加载周期不小于6US,CH451不需要该周期 }
GPIO
.h
/**************************************************************************** * Software that is described herein is for illustrative purposes only * which provides customers with programming information regarding the * products. This software is supplied "AS IS" without any warranties. * NXP Semiconductors assumes no responsibility or liability for the * use of the software, conveys no license or title under any patent, * copyright, or mask work right to the product. NXP Semiconductors * reserves the right to make changes in the software without * notification. NXP Semiconductors also make no representation or * warranty that such application will be suitable for the specified * use without further testing or modification. ****************************************************************************/ #ifndef __GPIO_H #define __GPIO_H #define DIR_OUT 1 //GPIO direction: in/out #define DIR_IN 0 #define LEDr1_port 2 //LED out port #define LEDr1_bit 7 //LED out bit #define LEDb1_port 2 //LED out port #define LEDb1_bit 8 //LED out bit #define LEDr2_port 2 //LED out port #define LEDr2_bit 6 //LED out bit #define LEDb2_port 2 //LED out port #define LEDb2_bit 0 //LED out bit #define Btn1_port 1 //Button 1 in port #define Btn1_bit 1 //Button 1 in bit #define Btn2_port 1 //Button 2 in port #define Btn2_bit 2 //Button 2 in bit //#define CH452_LOAD_port 0 //#define CH452_LOAD_bit 8 #define CH452_LOAD_port 2 #define CH452_LOAD_bit 2 #define CH452_DIN_port 2 #define CH452_DIN_bit 10 #define CH452_DCLK_port 2 #define CH452_DCLK_bit 9 #define Fan_port 2 #define Fan_bit 11 #define Alarm_port 1 #define Alarm_bit 10 static LPC_GPIO_TypeDef (* const LPC_GPIO[4]) = { LPC_GPIO0, LPC_GPIO1, LPC_GPIO2, LPC_GPIO3 }; void GPIO_Init( void ); uint32_t GPIO_GetIOStatus( uint32_t portNum, uint32_t bitPosi ); void GPIO_SetValue( uint32_t portNum, uint32_t bitPosi, uint32_t bitVal ); void GPIO_SetDir( uint32_t portNum, uint32_t bitPosi, uint32_t dir ); void GPIO_ToggleValue( uint32_t portNum, uint32_t bitPosi ); uint8_t Btn_Scan(void); #endif.c
#include "INCLUDE.h" /***************************************************************************** ** Function name: GPIOInit ** ** Descriptions: Initialize GPIO, install the ** GPIO interrupt handler ** ** parameters: None ** Returned value: true or false, return false if the VIC table ** is full and GPIO interrupt handler can be ** installed. ** *****************************************************************************/ void GPIO_Init( void ) { /* Enable AHB clock to the GPIO domain. */ LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 6); GPIO_SetDir(LEDr1_port, LEDr1_bit, DIR_OUT); // Set LED out GPIO_SetDir(LEDb1_port, LEDb1_bit, DIR_OUT); // Set LED out GPIO_SetDir(LEDr2_port, LEDr2_bit, DIR_OUT); // Set LED out GPIO_SetDir(LEDb2_port, LEDb2_bit, DIR_OUT); // Set LED out GPIO_SetDir(Btn1_port, Btn1_bit, DIR_IN); // Set button 1 in GPIO_SetDir(Btn2_port, Btn2_bit, DIR_IN); // Set button 2 in GPIO_SetDir(CH452_DIN_port, CH452_DIN_bit, DIR_OUT); // Set CH452_DIN out GPIO_SetDir(CH452_DCLK_port, CH452_DCLK_bit, DIR_OUT); // Set CH452_DCLK out GPIO_SetDir(CH452_LOAD_port, CH452_LOAD_bit, DIR_OUT); // Set CH452_LOAD out GPIO_SetDir(Fan_port, Fan_bit, DIR_OUT); GPIO_SetDir(Alarm_port, Alarm_bit, DIR_OUT); return ; } /***************************************************************************** ** Function name: GPIO_GetIOStatus ** ** Descriptions: Get IO status for a port pin. ** ** parameters: port num, bit position ** Returned value: None ** *****************************************************************************/ uint32_t GPIO_GetIOStatus( uint32_t portNum, uint32_t bitPosi ) { uint32_t regVal = 0; switch ( portNum ) { case 0: if ((LPC_GPIO0->DATA >> bitPosi) & 0x01) { regVal = 1; } break; case 1: if ((LPC_GPIO1->DATA >> bitPosi) & 0x01) { regVal = 1; } break; case 2: if ((LPC_GPIO2->DATA >> bitPosi) & 0x01) { regVal = 1; } break; case 3: if ((LPC_GPIO3->DATA >> bitPosi) & 0x01) { regVal = 1; } break; default: break; } return ( regVal ); } /***************************************************************************** ** Function name: Btn_Scan ** ** Descriptions: Scan btn state ** ** parameters: None ** Returned value: Btn state: ** 1-btn1 short ** 2-btn2 short ** 3-btn1 long ** 4-btn2 long ** *****************************************************************************/ uint8_t btnFlag=0; uint8_t btnCount[2]={0}; uint8_t Btn_Scan(void) { //Pull down for input pin in PCB if(!GPIO_GetIOStatus(Btn1_port, Btn1_bit) && btnCount[0]<=120) // 1 is btn1 short,3 is btn1 long { delay_ms(20); if(!GPIO_GetIOStatus(Btn1_port, Btn1_bit)) { btnCount[0]++; } } else if(!GPIO_GetIOStatus(Btn2_port, Btn2_bit) && btnCount[1]<=120) // 2 is btn2 short,4 is btn2 long { delay_ms(20); if(!GPIO_GetIOStatus(Btn2_port, Btn2_bit)) { btnCount[1]++; } } else { if(btnCount[0]>120) { if(GPIO_GetIOStatus(Btn1_port, Btn1_bit)) btnCount[0]=0; btnFlag=3; return 3; } else if(btnCount[0]<=120 && btnCount[0]>0) { btnCount[0]=0; btnFlag=1; return 1; } if(btnCount[1]>120) { if(GPIO_GetIOStatus(Btn1_port, Btn1_bit)) btnCount[1]=0; btnFlag=4; return 4; } else if(btnCount[1]<=120 && btnCount[1]>0) { btnCount[1]=0; btnFlag=2; return 2; } } return 0; } /***************************************************************************** ** Function name: GPIO_ToggleValue ** ** Descriptions: Toggle GPIO state ** ** parameters: port num, bit position ** Returned value: None ** *****************************************************************************/ void GPIO_ToggleValue( uint32_t portNum, uint32_t bitPosi ) { if(GPIO_GetIOStatus(portNum, bitPosi)) GPIO_SetValue(portNum, bitPosi, 0); else GPIO_SetValue(portNum, bitPosi, 1); } /***************************************************************************** ** Function name: GPIOSetValue ** ** Descriptions: Set/clear a bitvalue in a specific bit position ** in GPIO portX(X is the port number.) ** ** parameters: port num, bit position, bit value ** Returned value: None ** *****************************************************************************/ void GPIO_SetValue( uint32_t portNum, uint32_t bitPosi, uint32_t bitVal ) { LPC_GPIO[portNum]->MASKED_ACCESS[(1<<bitPosi)] = (bitVal<<bitPosi); } /***************************************************************************** ** Function name: GPIOSetDir ** ** Descriptions: Set the direction in GPIO port ** ** parameters: port num, bit position, direction (1 out, 0 input) ** Returned value: None ** *****************************************************************************/ void GPIO_SetDir( uint32_t portNum, uint32_t bitPosi, uint32_t dir ) { if (dir) { LPC_GPIO[portNum]->DIR |= 1 << bitPosi; } else { LPC_GPIO[portNum]->DIR &= ~(1 << bitPosi); } }
I2C
.h
#ifndef __I2CB_H #define __I2CB_H /* If I2C SEEPROM is tested, make sure FAST_MODE_PLUS is 0. For board to board test, this flag can be turned on. */ #define TRUE 1 #define FALSE 0 #define FAST_MODE_PLUS 0 #define BUFSIZE 6 #define MAX_TIMEOUT 0x00FFFFFF #define I2CMASTER 0x01 #define I2CSLAVE 0x02 #define TPS02R_ADDR 0x90 #define AT24C02_ADDR 0xA0 #define READ_WRITE 0x01 #define RD_BIT 0x01 #define I2C_IDLE 0 #define I2C_STARTED 1 #define I2C_RESTARTED 2 #define I2C_REPEATED_START 3 #define DATA_ACK 4 #define DATA_NACK 5 #define I2CONSET_I2EN 0x00000040 /* I2C Control Set Register */ #define I2CONSET_AA 0x00000004 #define I2CONSET_SI 0x00000008 #define I2CONSET_STO 0x00000010 #define I2CONSET_STA 0x00000020 #define I2CONCLR_AAC 0x00000004 /* I2C Control clear Register */ #define I2CONCLR_SIC 0x00000008 #define I2CONCLR_STAC 0x00000020 #define I2CONCLR_I2ENC 0x00000040 #define I2DAT_I2C 0x00000000 /* I2C Data Reg */ #define I2ADR_I2C 0x00000000 /* I2C Slave Address Reg */ #define I2SCLH_SCLH 0x00000180 /* I2C SCL Duty Cycle High Reg */ #define I2SCLL_SCLL 0x00000180 /* I2C SCL Duty Cycle Low Reg */ #define I2SCLH_HS_SCLH 0x00000030 /* Fast Plus I2C SCL Duty Cycle High Reg */ #define I2SCLL_HS_SCLL 0x00000030 /* Fast Plus I2C SCL Duty Cycle Low Reg */ extern void I2C_IRQHandler( void ); extern uint32_t I2CInit( uint32_t I2cMode ); extern uint32_t I2CStart( void ); extern uint32_t I2CStop( void ); extern uint32_t I2CEngine( void ); #endif.c
#include "INCLUDE.h" volatile uint32_t I2CMasterState = I2C_IDLE; volatile uint32_t I2CSlaveState = I2C_IDLE; volatile uint32_t I2CMode; volatile uint8_t I2CMasterBuffer[BUFSIZE]; uint8_t I2CSlaveBuffer[BUFSIZE]; volatile uint32_t I2CCount = 0; volatile uint32_t I2CReadLength; volatile uint32_t I2CWriteLength; volatile uint32_t RdIndex = 0; volatile uint32_t WrIndex = 0; /* From device to device, the I2C communication protocol may vary, in the example below, the protocol uses repeated start to read data from or write to the device: For master read: the sequence is: STA,Addr(W),offset,RE-STA,Addr(r),data...STO for master write: the sequence is: STA,Addr(W),offset,RE-STA,Addr(w),data...STO Thus, in state 8, the address is always WRITE. in state 10, the address could be READ or WRITE depending on the I2C command. */ /***************************************************************************** ** Function name: I2C_IRQHandler ** ** Descriptions: I2C interrupt handler, deal with master mode only. ** ** parameters: None ** Returned value: None *****************************************************************************/ void I2C_IRQHandler(void) { uint8_t StatValue; /* this handler deals with master read and master write only */ StatValue = LPC_I2C->STAT; switch ( StatValue ) { case 0x08: /* A Start condition is issued. */ WrIndex = 0; LPC_I2C->DAT = I2CMasterBuffer[WrIndex++]; LPC_I2C->CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC); I2CMasterState = I2C_STARTED; break; case 0x10: /* A repeated started is issued */ RdIndex = 0; /* Send SLA with R bit set, */ LPC_I2C->DAT = I2CMasterBuffer[WrIndex++]; LPC_I2C->CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC); I2CMasterState = I2C_RESTARTED; break; case 0x18: /* Regardless, it's a ACK */ if ( I2CMasterState == I2C_STARTED ) { LPC_I2C->DAT = I2CMasterBuffer[WrIndex++]; I2CMasterState = DATA_ACK; } LPC_I2C->CONCLR = I2CONCLR_SIC; break; case 0x28: /* Data byte has been transmitted, regardless ACK or NACK */ case 0x30: if ( WrIndex < I2CWriteLength ) { LPC_I2C->DAT = I2CMasterBuffer[WrIndex++]; /* this should be the last one */ I2CMasterState = DATA_ACK; } else { if ( I2CReadLength != 0 ) { LPC_I2C->CONSET = I2CONSET_STA; /* Set Repeated-start flag */ I2CMasterState = I2C_REPEATED_START; } else { I2CMasterState = DATA_NACK; LPC_I2C->CONSET = I2CONSET_STO; /* Set Stop flag */ } } LPC_I2C->CONCLR = I2CONCLR_SIC; break; case 0x40: /* Master Receive, SLA_R has been sent */ if ( I2CReadLength == 1 ) { /* Will go to State 0x58 */ LPC_I2C->CONCLR = I2CONCLR_AAC; /* assert NACK after data is received */ } else { /* Will go to State 0x50 */ LPC_I2C->CONSET = I2CONSET_AA; /* assert ACK after data is received */ } LPC_I2C->CONCLR = I2CONCLR_SIC; break; case 0x50: /* Data byte has been received, regardless following ACK or NACK */ I2CSlaveBuffer[RdIndex++] = LPC_I2C->DAT; if ( RdIndex < I2CReadLength ) { I2CMasterState = DATA_ACK; LPC_I2C->CONSET = I2CONSET_AA; /* assert ACK after data is received */ } else { I2CMasterState = DATA_NACK; LPC_I2C->CONCLR = I2CONCLR_AAC; /* assert NACK on last byte */ } LPC_I2C->CONCLR = I2CONCLR_SIC; break; case 0x58: I2CSlaveBuffer[RdIndex++] = LPC_I2C->DAT; I2CMasterState = DATA_NACK; LPC_I2C->CONSET = I2CONSET_STO; /* Set Stop flag */ LPC_I2C->CONCLR = I2CONCLR_SIC; /* Clear SI flag */ break; case 0x20: /* regardless, it's a NACK */ case 0x48: LPC_I2C->CONCLR = I2CONCLR_SIC; I2CMasterState = DATA_NACK; break; case 0x38: /* Arbitration lost, in this example, we don't deal with multiple master situation */ default: LPC_I2C->CONCLR = I2CONCLR_SIC; break; } return; } /***************************************************************************** ** Function name: I2CStart ** ** Descriptions: Create I2C start condition, a timeout ** value is set if the I2C never gets started, ** and timed out. It's a fatal error. ** ** parameters: None ** Returned value: true or false, return false if timed out ** *****************************************************************************/ uint32_t I2CStart( void ) { uint32_t timeout = 0; uint32_t retVal = FALSE; /*--- Issue a start condition ---*/ LPC_I2C->CONSET = I2CONSET_STA; /* Set Start flag */ /*--- Wait until START transmitted ---*/ while( 1 ) { if ( I2CMasterState == I2C_STARTED ) { retVal = TRUE; break; } if ( timeout >= MAX_TIMEOUT ) { retVal = FALSE; break; } timeout++; } return( retVal ); } /***************************************************************************** ** Function name: I2CStop ** ** Descriptions: Set the I2C stop condition, if the routine ** never exit, it's a fatal bus error. ** ** parameters: None ** Returned value: true or never return ** *****************************************************************************/ uint32_t I2CStop( void ) { LPC_I2C->CONSET = I2CONSET_STO; /* Set Stop flag */ LPC_I2C->CONCLR = I2CONCLR_SIC; /* Clear SI flag */ /*--- Wait for STOP detected ---*/ while( LPC_I2C->CONSET & I2CONSET_STO ); return TRUE; } /***************************************************************************** ** Function name: I2CInit ** ** Descriptions: Initialize I2C controller ** ** parameters: I2c mode is either MASTER or SLAVE ** Returned value: true or false, return false if the I2C ** interrupt handler was not installed correctly ** *****************************************************************************/ uint32_t I2CInit( uint32_t I2cMode ) { /* It seems to be bit0 is for I2C, different from UM. To be retested along with SSP reset. SSP and I2C reset are overlapped, a known bug, for now, both SSP and I2C use bit 0 for reset enable. Once the problem is fixed, change to "#if 1". */ #if 1 LPC_SYSCON->PRESETCTRL |= (0x1<<1); #else LPC_SYSCON->PRESETCTRL |= (0x1<<0); #endif LPC_SYSCON->SYSAHBCLKCTRL |= (1<<5); LPC_IOCON->PIO0_4 &= ~0x3F; /* I2C I/O config */ LPC_IOCON->PIO0_4 |= 0x01; /* I2C SCL */ LPC_IOCON->PIO0_5 &= ~0x3F; LPC_IOCON->PIO0_5 |= 0x01; /* I2C SDA */ /*--- Clear flags ---*/ LPC_I2C->CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC | I2CONCLR_I2ENC; /*--- Reset registers ---*/ #if FAST_MODE_PLUS LPC_IOCON->PIO0_4 |= (0x1<<9); LPC_IOCON->PIO0_5 |= (0x1<<9); LPC_I2C->SCLL = I2SCLL_HS_SCLL; LPC_I2C->SCLH = I2SCLH_HS_SCLH; #else LPC_I2C->SCLL = I2SCLL_SCLL; LPC_I2C->SCLH = I2SCLH_SCLH; #endif if ( I2cMode == I2CSLAVE ) { LPC_I2C->ADR0 = TPS02R_ADDR; } /* Enable the I2C Interrupt */ NVIC_EnableIRQ(I2C_IRQn); LPC_I2C->CONSET = I2CONSET_I2EN; return( TRUE ); } /***************************************************************************** ** Function name: I2CEngine ** ** Descriptions: The routine to complete a I2C transaction ** from start to stop. All the intermitten ** steps are handled in the interrupt handler. ** Before this routine is called, the read ** length, write length, I2C master buffer, ** and I2C command fields need to be filled. ** see i2cmst.c for more details. ** ** parameters: None ** Returned value: true or false, return false only if the ** start condition can never be generated and ** timed out. ** *****************************************************************************/ uint32_t I2CEngine( void ) { I2CMasterState = I2C_IDLE; RdIndex = 0; WrIndex = 0; if ( I2CStart() != TRUE ) { I2CStop(); return ( FALSE ); } while ( 1 ) { if ( I2CMasterState == DATA_NACK ) { I2CStop(); break; } } return ( TRUE ); }
TIMER
.h
#ifndef __TIMER_H #define __TIMER_H #define Timer32Interval0 1200000 //25ms #define Timer16Interval0 7273 //303/2us void Timer32_0_Init(void); uint32_t Timer32_0_GetCount(void) ; void delay_ms(uint32_t ms); //Delay 1-699ms void delay_us(uint32_t us); #endif.c
#include "INCLUDE.h" static volatile uint32_t TimeTick=0; uint16_t LedSpeed=600; /****************************************************************************** ** Function name: Timer32_0_GetCount ** ** Descriptions: Turn on timer interrupt ** ** parameters: None ** Returned value: None ** ******************************************************************************/ void Timer16_0_OpenInt(void) { LPC_TMR16B0->TCR = 0x01; } /****************************************************************************** ** Function name: Timer32_0_GetCount ** ** Descriptions: Turn off timer interrupt ** ** parameters: None ** Returned value: None ** ******************************************************************************/ void Timer16_0_CloseInt(void) { LPC_TMR16B0->TCR = 0; } /****************************************************************************** ** Function name: init_timer ** ** Descriptions: Initialize timer, set timer interval, reset timer, ** install timer interrupt handler ** ** parameters: None ** Returned value: None ** ******************************************************************************/ void Timer32_0_Init(void) { LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 9); //Turn on the 32 timer 0 clock LPC_TMR32B0->PR = 0; //Predivider counter LPC_TMR32B0->MR0 = Timer32Interval0; //Matching register(50ms) LPC_TMR32B0->TCR = 0x1; //Turn on and reset the timer counter LPC_TMR32B0->MCR = 3; //Matching control, Raise the interrupt and reset the timer NVIC_EnableIRQ(TIMER_32_0_IRQn); //Enable interrupt NVIC_SetPriority(TIMER_32_0_IRQn,1); } /****************************************************************************** ** Function name: TIMER32_0_IRQHandler ** ** Descriptions: Timer/Counter 0 interrupt handler ** executes each 10ms @ 60 MHz CPU Clock ** ** parameters: None ** Returned value: None ** ******************************************************************************/ void TIMER32_0_IRQHandler(void) { /* User Code Begin */ /* User Code End */ LPC_TMR32B0->IR = 1; //Clear the interrupt flag bit return; } /****************************************************************************** ** Function name: Timer32_0_GetCount ** ** Descriptions: Gets the current count value ** ** parameters: None ** Returned value: None ** ******************************************************************************/ uint32_t Timer32_0_GetCount(void) { uint32_t uitemp; uitemp = LPC_TMR32B0->TC; return uitemp; } void SysTick_Handler(void) { TimeTick++; } /****************************************************************************** ** Function name: delay_ms ** ** Descriptions: Delay 1-699ms ** ** parameters: Time of ms ** Returned value: None ** ******************************************************************************/ void delay_ms(uint32_t ms) { SysTick->LOAD = (((24000)*ms)-1); SysTick->VAL = 0; SysTick->CTRL |= ((1<<1)|(1<<0)); while(!TimeTick); TimeTick = 0; SysTick->CTRL =0; } /****************************************************************************** ** Function name: delay_us ** ** Descriptions: Delay n us ** ** parameters: Time of us ** Returned value: None ** ******************************************************************************/ void delay_us(uint32_t us) { SysTick->LOAD = (((24)*us)-1); SysTick->VAL = 0; SysTick->CTRL |= ((1<<1)|(1<<0)); while(!TimeTick); TimeTick = 0; SysTick->CTRL =0; }
TPS02R
.h
#ifndef __TPS02R_H #define __TPS02R_H #define __REG_TEMPERATURE 0x00 /* Temperature register address */ #define __REG_TEMPERATURE_LEN 0x06 /* Temperature register length */ static float __reg_to_temperature (uint8_t *p_dat); void dealTemperature(void); volatile void delay_TPS02R(void); void TPS02R_WriteOneByte(uint8_t WriteAddr, uint8_t DataToWrite); uint8_t TPS02R_ReadOneByte(uint8_t ReadAddr); void TPS02R_Read(uint8_t ReadAddr,uint8_t *Buffer,uint16_t Num); void TPS02R_Write(uint8_t WriteAddr,uint8_t *Buffer,uint16_t Num); #endif.c
#include "INCLUDE.h" float temperature; uint8_t reg_buf[3]; extern uint16_t valueT; extern volatile uint8_t I2CMasterBuffer[BUFSIZE]; extern uint8_t I2CSlaveBuffer[BUFSIZE]; extern volatile uint32_t I2CReadLength, I2CWriteLength; /***************************************************************************** ** Function name: __reg_to_temperature ** ** Descriptions: Chang TPS02R I2C data to float temperature value ** ** parameters: TPS02R I2C data ** Returned value: Float temperature value *****************************************************************************/ static float __reg_to_temperature (uint8_t *p_dat) { uint32_t temp = 0; temp |= p_dat[0] << 16; temp |= p_dat[1] << 8; temp |= p_dat[2]; if (temp >= 8388608) //Positive and negative of temperature, greater than 8388608 is negative, less than it is positive { return (-(float)((16777216 - temp) / (float)(0x1 << 13))); } else { return ((float)(temp / (float)(0x1 << 13))); } } /***************************************************************************** ** Function name: dealTemperature ** ** Descriptions: Get temperature register data from TPS02R I2C ** ** parameters: None ** Returned value: None *****************************************************************************/ void dealTemperature(void) { I2CWriteLength = 1; I2CReadLength = 3; I2CMasterBuffer[0] = TPS02R_ADDR; I2CMasterBuffer[1] = 0x00; I2CMasterBuffer[2] = TPS02R_ADDR | RD_BIT; I2CEngine(); // Uart_Send(I2CSlaveBuffer, BUFSIZE); valueT=__reg_to_temperature(I2CSlaveBuffer)*10; }
UART
.h
#ifndef __UART_H #define __UART_H #define IER_RBR 0x01 #define IER_THRE 0x02 #define IER_RLS 0x04 #define IIR_PEND 0x01 #define IIR_RLS 0x03 #define IIR_RDA 0x02 #define IIR_CTI 0x06 #define IIR_THRE 0x01 #define LSR_RDR 0x01 #define LSR_OE 0x02 #define LSR_PE 0x04 #define LSR_FE 0x08 #define LSR_BI 0x10 #define LSR_THRE 0x20 #define LSR_TEMT 0x40 #define LSR_RXFE 0x80 #define RECBUFSIZE 0x40 #define SENDBUFSIZE 0x10 #define COMMLENGTH 6 #define PinHead '@' #define PinEnd '!' void Uart_Init(uint32_t Baudrate); void UART_IRQHandler(void); void Uart_Send(uint8_t *BufferPtr, uint32_t Length); void Uart_SaveRecData(uint8_t u8RecData); #endif.c
#include "INCLUDE.h" volatile uint32_t m_uiUARTStatus; volatile uint8_t m_u8RecBuf[RECBUFSIZE]; volatile uint8_t m_u8RecPinH = 0; volatile uint8_t m_u8RecPinL = 0; volatile uint8_t m_u8SendBuf[SENDBUFSIZE]; volatile uint8_t DATA_COUNT=0; volatile uint8_t m_u8CommRecCount = 0; volatile uint8_t m_u8CommBuf[COMMLENGTH]; uint8_t TCount=0; uint32_t CountRes; extern uint32_t SystemFrequency; /***************************************************************************** ** Function name: UART_IRQHandler ** ** Descriptions: UART interrupt handler ** ** parameters: None ** Returned value: None ** *****************************************************************************/ void UART_IRQHandler(void) { uint8_t IIRValue, LSRValue; uint8_t Dummy = Dummy; uint8_t u8RecData; IIRValue = LPC_UART->IIR; IIRValue >>= 1; /* skip pending bit in IIR */ IIRValue &= 0x07; /* check bit 1~3, interrupt identification */ if (IIRValue == IIR_RLS) /* Receive Line Status */ { LSRValue = LPC_UART->LSR; /* Receive Line Status */ if (LSRValue & (LSR_OE | LSR_PE | LSR_FE | LSR_RXFE | LSR_BI)) { /* There are errors or break interrupt */ /* Read LSR will clear the interrupt */ m_uiUARTStatus = LSRValue; Dummy = LPC_UART->RBR; /* Dummy read on RX to clear interrupt, then bail out */ return; } if (LSRValue & LSR_RDR) /* Receive Data Ready */ { /* If no error on RLS, normal ready, save into the data buffer. */ /* Note: read RBR will clear the interrupt */ u8RecData = LPC_UART->RBR; Uart_SaveRecData(u8RecData); } } else if (IIRValue == IIR_RDA) /* Receive Data Available */ { /* Receive Data Available */ u8RecData = LPC_UART->RBR; Uart_SaveRecData(u8RecData); } else if (IIRValue == IIR_CTI) /* Character timeout indicator */ { /* Character Time-out indicator */ m_uiUARTStatus |= 0x100; /* Bit 9 as the CTI error */ } else if (IIRValue == IIR_THRE) /* THRE, transmit holding register empty */ { /* THRE interrupt */ LSRValue = LPC_UART->LSR; /* Check status in the LSR to see if valid data in U0THR or not */ } return; } /***************************************************************************** ** Function name: UARTInit ** ** Descriptions: Initialize UART0 port, setup pin select, ** clock, parity, stop bits, FIFO, etc. ** ** parameters: UART baudrate ** Returned value: None ** *****************************************************************************/ void Uart_Init(uint32_t baudrate) { uint32_t Fdiv; uint32_t regVal; m_u8RecPinH = 0; m_u8RecPinL = 0; m_u8CommRecCount = 0; NVIC_DisableIRQ(UART_IRQn); LPC_IOCON->PIO1_6 &= ~0x07; /* UART I/O config */ LPC_IOCON->PIO1_6 |= 0x01; /* UART RXD */ LPC_IOCON->PIO1_7 &= ~0x07; LPC_IOCON->PIO1_7 |= 0x01; /* UART TXD */ /* Enable UART clock */ LPC_SYSCON->SYSAHBCLKCTRL |= (1<<12); LPC_SYSCON->UARTCLKDIV = 0x1; /* divided by 1 */ LPC_UART->LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */ regVal = LPC_SYSCON->UARTCLKDIV; Fdiv = (((SystemFrequency/LPC_SYSCON->SYSAHBCLKDIV)/regVal)/16)/baudrate ; /*baud rate */ LPC_UART->DLM = Fdiv / 256; LPC_UART->DLL = Fdiv % 256; LPC_UART->LCR = 0x03; /* DLAB = 0 */ LPC_UART->FCR = 0x07; /* Enable and reset TX and RX FIFO. */ /* Read to clear the line status. */ regVal = LPC_UART->LSR; /* Ensure a clean start, no data in either TX or RX FIFO. */ while ( LPC_UART->LSR & (LSR_THRE|LSR_TEMT) != (LSR_THRE|LSR_TEMT) ); while ( LPC_UART->LSR & LSR_RDR ) { regVal = LPC_UART->RBR; /* Dump data from RX FIFO */ } /* Enable the UART Interrupt */ NVIC_EnableIRQ(UART_IRQn); NVIC_SetPriority(UART_IRQn,2); LPC_UART->IER = IER_RBR | IER_RLS;//| IER_THRE /* Enable UART interrupt */ return; } /***************************************************************************** ** Function name: UARTSend ** ** Descriptions: Send a block of data to the UART 0 port based ** on the data length ** ** parameters: buffer pointer, and data length ** Returned value: None ** *****************************************************************************/ void Uart_Send(uint8_t *BufferPtr, uint32_t Length) { while ( Length != 0 ) { /* THRE status, contain valid data */ while ( !(LPC_UART->LSR & LSR_THRE) ); LPC_UART->THR = *BufferPtr; BufferPtr++; Length--; } return; } /***************************************************************************** ** Function name: Uart_SaveRecData ** ** Descriptions: Save Receive Data ** ** parameters: Receive Data ** Returned value: None ** *****************************************************************************/ void Uart_SaveRecData(uint8_t u8RecData) { uint8_t u8BakRecPinH; m_u8RecBuf[m_u8RecPinH] = u8RecData; u8BakRecPinH = m_u8RecPinH + 1; if (u8BakRecPinH >= RECBUFSIZE) { u8BakRecPinH = 0; } if (u8BakRecPinH != m_u8RecPinL) { m_u8RecPinH = u8BakRecPinH; } }
WDT
.h
#ifndef __WDT_H #define __WDT_H #define WDEN 0x00000001 #define WDRESET 0x00000002 #define WDTOF 0x00000004 #define WDINT 0x00000008 #define WDT_FEED_VALUE 25000 #define WDTCLK_SRC_IRC_OSC 0 #define WDTCLK_SRC_MAIN_CLK 1 #define WDTCLK_SRC_WDT_OSC 2 void WDT_CLK_Setup(uint32_t timer_num); void WDT_Init(void); void WDT_Feed(void); #endif.c
#include "INCLUDE.h" /***************************************************************************** ** Function name: WDT_CLK_Setup ** ** Descriptions: Configure WDT clock. ** parameters: clock source: irc_osc(0), main_clk(1), wdt_osc(2). ** ** Returned value: None ** *****************************************************************************/ void WDT_CLK_Setup ( uint32_t clksrc ) { /* Watchdog configuration. */ /* Freq = 0.5Mhz, div_sel is 0, divided by 2. WDT_OSC should be 250khz */ LPC_SYSCON->WDTOSCCTRL = (0x1<<5)|0x00; LPC_SYSCON->WDTCLKSEL = clksrc; /* Select clock source */ LPC_SYSCON->WDTCLKUEN = 0x01; /* Update clock */ LPC_SYSCON->WDTCLKUEN = 0x00; /* Toggle update register once */ LPC_SYSCON->WDTCLKUEN = 0x01; while ( !(LPC_SYSCON->WDTCLKUEN & 0x01) ); /* Wait until updated */ LPC_SYSCON->WDTCLKDIV = 3; /* Divided by 1 */ LPC_SYSCON->PDRUNCFG &= ~(0x1<<6); /* Let WDT clock run */ return; } /***************************************************************************** ** Function name: WDT_Init ** ** Descriptions: Initialize watchdog timer, install the ** watchdog timer interrupt handler ** ** parameters: None ** Returned value: None ** *****************************************************************************/ void WDT_Init(void) { /* Enable clock to WDT */ LPC_SYSCON->SYSAHBCLKCTRL |= (1<<15); LPC_WDT->TC = WDT_FEED_VALUE; /* once WDEN is set, the WDT will start after feeding */ LPC_WDT->MOD = WDEN | WDRESET; LPC_WDT->MOD = WDEN; LPC_WDT->FEED = 0xAA; /* Feeding sequence */ LPC_WDT->FEED = 0x55; return; } /***************************************************************************** ** Function name: WDTFeed ** ** Descriptions: Feed watchdog timer to prevent it from timeout ** ** parameters: None ** Returned value: None ** *****************************************************************************/ void WDT_Feed(void) { LPC_WDT->FEED = 0xAA; /* Feeding sequence */ LPC_WDT->FEED = 0x55; return; }
INCLUDE
.h
#ifndef __INCLUDE_H #define __INCLUDE_H #include <LPC11xx.H> #include "main.h" #include "GPIO.h" #include "TIMER.h" #include "WDT.h" #include "I2C.h" #include "AT24C02.h" #include "CH452.h" #include "TPS02R.h" #include "UART.h" #endif
评论已关闭