AT24C02
.h
1
2
3
4
5
6
7
8
9
10
11
/* 注意: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); //检查器件.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/* CH451和CH452的常用命令码 */
// BCD译码方式下的特殊字符
// 有效按键代码
// 2线接口的CH452定义
///* 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线接口的位操作,与单片机有关 */
// 设置DCLK为输出方向,对于双向I/O需切换为输出
// 设置DIN为输出方向,对于双向I/O需切换为输出
// 设置LOAD为输出方向,对于双向I/O需切换为输出
// 设置DOUT为输入方向,对于双向I/O需切换为输入
/* 延时1uS子程序,主要用于2线接口,与单片机速度有关 */
//#define DELAY_1US {} // MCS51<=10MHz
//#define DELAY_1US {_nop_();_nop_();} // MCS51<=30MHz
// 对外子程序
void CH452_Init(void);
void CH452_Write(unsigned short cmd); // 向CH452发出操作命令
//unsigned char CH452_Read(void); // 从CH452读取按键代码.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/******************************************************************
** 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57/****************************************************************************
* 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.
****************************************************************************/
//#define CH452_LOAD_port 0
//#define CH452_LOAD_bit 8
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);.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/*****************************************************************************
** 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/* If I2C SEEPROM is tested, make sure FAST_MODE_PLUS is 0.
For board to board test, this flag can be turned on. */
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 );.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
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". */
LPC_SYSCON->PRESETCTRL |= (0x1<<1);
LPC_SYSCON->PRESETCTRL |= (0x1<<0);
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 ---*/
LPC_IOCON->PIO0_4 |= (0x1<<9);
LPC_IOCON->PIO0_5 |= (0x1<<9);
LPC_I2C->SCLL = I2SCLL_HS_SCLL;
LPC_I2C->SCLH = I2SCLH_HS_SCLH;
LPC_I2C->SCLL = I2SCLL_SCLL;
LPC_I2C->SCLH = I2SCLH_SCLH;
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
1
2
3
4
5
6
7
8
9
10
11
12
13
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);.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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);.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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);.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void WDT_CLK_Setup(uint32_t timer_num);
void WDT_Init(void);
void WDT_Feed(void);.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/*****************************************************************************
** 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15