51单片机C语言常用模块与综合系统设计实例精讲
源代码在线查看: function.lst
C51 COMPILER V7.06 FUNCTION 10/29/2006 14:34:14 PAGE 1
C51 COMPILER V7.06, COMPILATION OF MODULE FUNCTION
OBJECT MODULE PLACED IN function.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE function.c LARGE BROWSE DEBUG OBJECTEXTEND
stmt level source
1 #include
2 #include
3 #include "source.h"
4 #include
5 #include
6 //_nop_();0.65us fosc=18.432
7 void delay_macnine_ncircle(unsigned char cnt){//11+6*cnt machin circle. /*延时ns*/
8 1 while(cnt--);
9 1 }
10 void delay_10us(unsigned char tus){//fosc=18.432 /*延时10us的整数倍,其中tus为10us的整数倍*/
11 1 tus--;
12 1 while(tus--){
13 2 _nop_();_nop_();_nop_();
14 2 _nop_();_nop_();_nop_();
15 2 _nop_();_nop_();_nop_();
16 2 }
17 1 }
18 /*i2c max rate: 100k, so delay is needed*/
19 /*定义宏,把I2C的函数进行抽象*/
20 #define DELAY _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop
-_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_()
21 #define I2CDATA SDA /*for read data from bit port*/
22 #define I2CSETDATA SDA=1 /*sda=1 macro*/
23 #define I2CCLRDATA SDA=0 /*sda=0 macro*/
24 #define I2CSETCLK SCL=1 /*scl=1 macro*/
25 #define I2CCLRCLK SCL=0 /*scl=0 macro*/
26
27 #define i2c_start AT24C64_start
28 #define i2c_stop AT24C64_stop
29 #define i2c_write_byte AT24C64_write_byte
30 #define i2c_read_byte AT24C64_read_byte
31 #define i2c_wait_ack AT24C64_wait_ack
32 #define i2c_send_ack AT24C64_send_ack
33 #define i2c_send_notack AT24C64_send_notack
34 void i2c_start(){/*I2C的开始函数*/
35 1 I2CSETDATA;
36 1 I2CSETCLK;
37 1 DELAY;
38 1 I2CCLRDATA;
39 1 DELAY;
40 1 I2CCLRCLK;
41 1 }
42 void i2c_stop(){/*I2C的停止函数*/
43 1 I2CCLRCLK;
44 1 I2CCLRDATA;
45 1 DELAY;
46 1 I2CSETCLK;
47 1 DELAY;
48 1 I2CSETDATA;
49 1 }
50 void i2c_write_byte(unsigned char ch)/*I2C的写一个字节*/
51 {
52 1 unsigned char i=8;
53 1 while(i--){
54 2 I2CCLRCLK;_nop_();
C51 COMPILER V7.06 FUNCTION 10/29/2006 14:34:14 PAGE 2
55 2 if(ch&0x80)
56 2 I2CSETDATA;
57 2 else
58 2 I2CCLRDATA;
59 2 ch 60 2 I2CSETCLK;DELAY;
61 2 }
62 1 I2CCLRCLK;
63 1 }
64
65 unsigned char i2c_read_byte(void)/*I2C读一个字节*/
66 {
67 1 unsigned char i=8;
68 1 unsigned char ddata=0;
69 1 I2CSETDATA ;
70 1 while (i--){
71 2 ddata 72 2 I2CCLRCLK;DELAY;
73 2 I2CSETCLK;DELAY;
74 2 ddata|=I2CDATA;
75 2 }
76 1 I2CCLRCLK;
77 1 return ddata;
78 1 }
79 bit i2c_wait_ack(void)/*I2C等待芯片的ACK*/
80 {
81 1 unsigned char errtime=255;//因故障接收方无ACK 超时值为255
82 1 I2CSETDATA;DELAY;
83 1 I2CSETCLK ;DELAY;
84 1 while(I2CDATA){
85 2 errtime--;
86 2 if (!errtime){
87 3 i2c_stop();
88 3 return 0;
89 3 }
90 2 }
91 1 I2CCLRCLK;
92 1 return 1;
93 1 }
94 void i2c_send_ack(void)/*对I2C芯片发送ACK*/
95 {
96 1 I2CCLRDATA; DELAY;
97 1 I2CSETCLK; DELAY;
98 1 I2CCLRCLK;
99 1 }
100
101 void i2c_send_notack(void)/*对I2C芯片发送NO ACK*/
102 {
103 1 I2CSETDATA ; DELAY;
104 1 I2CSETCLK ; DELAY;
105 1 I2CCLRCLK;
106 1 }
107
108 #define DEVICEAW 0Xa0
109 #define DEVICEAR 0Xa1
110 /*下面是把以上的I2C操作转换为对AT24C64的EEPROM的操作以上介绍,可以得出以下函数*/
111 void AT24C64_wbytes(unsigned char *add,unsigned char len,unsigned char *buf){//max 32 bytes
112 1 /*为对EEPROM写多个字节,由于地址回转的问题,最多写32个字节*/
113 1 unsigned char hadd,ladd;
114 1 unsigned char i;
115 1 hadd=add[0];
116 1 ladd=add[1];
C51 COMPILER V7.06 FUNCTION 10/29/2006 14:34:14 PAGE 3
117 1 AT24C64_start();
118 1 AT24C64_write_byte(DEVICEAW);
119 1 AT24C64_wait_ack();
120 1 AT24C64_write_byte(hadd);
121 1 AT24C64_wait_ack();
122 1 AT24C64_write_byte(ladd);
123 1 AT24C64_wait_ack();
124 1 for(i=0;i 125 2 AT24C64_write_byte(buf[i]);
126 2 AT24C64_wait_ack();
127 2 }
128 1 AT24C64_stop();
129 1 delay_10us(100);//delay 1 ms for write byte.
130 1 delay_10us(100);
131 1 delay_10us(100);
132 1 delay_10us(100);
133 1 delay_10us(100);/*延时5毫秒,因为在两次写操作之间必须有5ms的延时才能进行下一次写*/
134 1 }
135 void AT24C64_rbytes(unsigned char *add,unsigned char len,unsigned char *buf){
136 1 /*对EEPROM进行多个字节的读操作,同样由于地址回转的问题,最多只能读32个字节*/
137 1 unsigned char hadd,ladd;
138 1 unsigned char i;
139 1 hadd=add[0];
140 1 ladd=add[1];
141 1 AT24C64_start();
142 1 AT24C64_write_byte(DEVICEAW);
143 1 AT24C64_wait_ack();
144 1 AT24C64_write_byte(hadd);
145 1 AT24C64_wait_ack();
146 1 AT24C64_write_byte(ladd);
147 1 AT24C64_wait_ack();
148 1 for(i=0;i 149 2 AT24C64_start();
150 2 AT24C64_write_byte(DEVICEAR);
151 2 AT24C64_wait_ack();
152 2 buf[i]=AT24C64_read_byte();
153 2 }
154 1 AT24C64_stop();
155 1 }
156 void init_eeprom(void){/*开始时,对EEPROM进行初始化,把EEPROM的存储单元都设置为0*/
157 1 unsigned char temp;
158 1 unsigned int add;
159 1 temp=0;
160 1 for(add=0;add 161 2 AT24C64_wbytes((unsigned char *)&add,1,&temp);
162 2 }
163 1
164 1 }
165 unsigned char eeprom_write(unsigned int adr, unsigned int len, unsigned char *src){
166 1 /*为写EEPROM的进一步封装,这个函数的写的字节数可以任意长的*/
167 1 unsigned int temp;
168 1 unsigned int eeprom_grid;/*为取EEPROM一个页面64字节的整数地址*/
169 1 unsigned int eeprom_last;/*写EEPROM的最后存储单元的地址*/
170 1 unsigned char i;
171 1 eeprom_last=adr+len;
172 1 temp=adr/EEPROM_PAGE_LEN;
173 1 eeprom_grid=(temp+1)*EEPROM_PAGE_LEN;
174 1 temp=eeprom_last>eeprom_grid?eeprom_grid:eeprom_last;
175 1 AT24C64_wbytes((unsigned char *)&adr,temp-adr,src);
176 1 while(1){
177 2 if(eeprom_grid 178 3 adr=eeprom_grid;
C51 COMPILER V7.06 FUNCTION 10/29/2006 14:34:14 PAGE 4
179 3 eeprom_grid +=EEPROM_PAGE_LEN;
180 3 temp=eeprom_last>eeprom_grid?eeprom_grid:eeprom_last;
181 3 AT24C64_wbytes((unsigned char *)&adr,temp-adr,src);
182 3 }
183 2 else
184 2 break;//jump out the while
185 2 }
186 1 }
*** WARNING C173 IN LINE 186 OF FUNCTION.C: missing return-expression
*** WARNING C280 IN LINE 170 OF FUNCTION.C: 'i': unreferenced local variable
187
188 unsigned char eeprom_read(unsigned int adr, unsigned int len, unsigned char *src){
189 1 /**为对EEPROM的读函数的进一步封装,可以读任意个字节数*/
190 1 unsigned int i=0;
191 1 unsigned int rest;
192 1 while(1){
193 2 rest=len;
194 2 if(rest 195 3 AT24C64_rbytes((unsigned char *)&adr,(unsigned char)rest,src+i*EEPROM_PAGE_LEN);
196 3 break;
197 3 }
198 2 else{/*如果剩下的字节数大于EEPROM_PAGE_LEN就读EEPROM_PAGE_LEN个字节*/
199 3 AT24C64_rbytes((unsigned char *)&adr,EEPROM_PAGE_LEN,src+i*EEPROM_PAGE_LEN);
200 3 rest -=EEPROM_PAGE_LEN;
201 3 }
202 2 i++;
203 2 }
204 1 }
*** WARNING C173 IN LINE 204 OF FUNCTION.C: missing return-expression
205
206
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 1093 ----
CONSTANT SIZE = ---- ----
XDATA SIZE = ---- 42
PDATA SIZE = ---- ----
DATA SIZE = ---- ----
IDATA SIZE = ---- ----
BIT SIZE = ---- ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 3 WARNING(S), 0 ERROR(S)