📄 main.lst
字号:
C51 COMPILER V7.00 MAIN 06/16/2011 18:30:41 PAGE 1
C51 COMPILER V7.00, COMPILATION OF MODULE MAIN
OBJECT MODULE PLACED IN main.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE main.c BROWSE DEBUG OBJECTEXTEND
stmt level source
1 /*-----------------------------------------------
2 名称:IIC协议 PCF8591ADDA转换 显示有4个,注意只有一个可以调节电压的
3 内容:此程序通过IIC协议对DAAD芯片操作,读取电位器的电压通过液晶显示,并输出模拟量,用LED亮度渐变指示
4 ------------------------------------------------*/
5 #include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
6 #include <intrins.h> //包含NOP空指令函数_nop_();
7
8 #define AddWr 0x90 //写数据地址(理解手册)
9 #define AddRd 0x91 //读数据地址
10
11 sbit Sda=P2^0; //定义总线连接端口
12 sbit Scl=P2^1;
13
14 sbit dula=P2^6;
15 sbit wela=P2^7;
16
17 bit ADFlag; //定义AD采样标志位
18
19 char code dm[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //7段数共阴码管段码表0~9
20 //char wm[]={0XFE,0XFD,0XFB,0XF7,0XEF,0XDF}; //从左到右6位数码管(P0^0为0时,左1选中)
21
22 /****************************数码管显示有关***********************************/
23 void delayuint(unsigned int i)
24 {
25 1 while(i--);
26 1 }
27
28 //把三位整数的每一位取出
29 char q,b,s,g;
30 void convert(int DATA)
31 {
32 1 q=DATA/1000;
33 1 b=DATA%1000/100;
34 1 s=DATA%100/10;
35 1 g=DATA%10;
36 1 }
37
38 int DATA0; //用来存放上次的DATA值
39 void show_led8(float t) //把t送到数码管上扫描一遍 (0<t<100的四位浮点数(带2位小数))
40 {
41 1 int DATA=t*100; //若t带了多位小数也只取2位,赋给int型小数放弃
42 1 if(DATA0!=DATA)
43 1 convert(DATA0=DATA);
44 1
45 1 //处理千位
46 1 if(q!=0)
47 1 {
48 2 wela=1;
49 2 P0=0xfe;
50 2 wela=0;
51 2 //送百位段码
52 2 dula=1;
53 2 P0=dm[q];
54 2 dula=0;
55 2 delayuint(250); //delay(100)是916us(12M)
C51 COMPILER V7.00 MAIN 06/16/2011 18:30:41 PAGE 2
56 2 }
57 1
58 1 //处理百位 (对应小数的个位,须点亮dp点)
59 1 //先关段码(送暗码),再开下一位
60 1 dula=1;
61 1 P0=0;
62 1 dula=0;
63 1
64 1 wela=1;
65 1 P0=0xfd;
66 1 wela=0;
67 1 dula=1;
68 1 P0=dm[b]|0x80; //包含小数点
69 1 dula=0;
70 1 delayuint(250);
71 1
72 1 //处理十位 (对应小数的十分位)
73 1 //先关段码(送暗码),再开下一位
74 1 dula=1;
75 1 P0=0;
76 1 dula=0;
77 1
78 1 wela=1;
79 1 P0=0xfb;
80 1 wela=0;
81 1 dula=1;
82 1 P0=dm[s];
83 1 dula=0;
84 1 delayuint(250);
85 1
86 1 //处理个位 (对应小数的百分位)
87 1 //先关段码(送暗码),再开下一位
88 1 dula=1;
89 1 P0=0;
90 1 dula=0;
91 1
92 1 wela=1;
93 1 P0=0xf7;
94 1 wela=0;
95 1 dula=1;
96 1 P0=dm[g];
97 1 dula=0;
98 1 delayuint(250);
99 1
100 1 /*退出前关闭所有数码管,是必须要的,否则会可能出现单个数码管持续亮*/
101 1 dula=1;
102 1 P0=0;
103 1 dula=0;
104 1 }
105 /****************************数码管显示有关(OVER)********************************************/
106
107 /*------------------------------------------------
108 初始化定时器1
109 ------------------------------------------------*/
110 void Init_Timer1(void)
111 {
112 1 TMOD |= 0x10; //T1方式1
113 1
114 1 TH1=0x0B; //Init value
115 1 TL1=0xDC;
116 1 //PT1=1; // 优先级
117 1
C51 COMPILER V7.00 MAIN 06/16/2011 18:30:41 PAGE 3
118 1 EA=1; /* interupt enable */
119 1 ET1=1; /* enable timer1 interrupt */
120 1 TR1=1;
121 1 }
122 /*------------------------------------------------
123 启动IIC总线
124 ------------------------------------------------*/
125 void Start(void)
126 {
127 1 Sda=1;
128 1 _nop_();
129 1 Scl=1;
130 1 _nop_();
131 1 Sda=0;
132 1 _nop_(); //成功启动
133 1 Scl=0; //允许SDA改变
134 1 }
135
136 /*------------------------------------------------
137 停止IIC总线
138 ------------------------------------------------*/
139 void Stop(void)
140 {
141 1 Sda=0;
142 1 _nop_();
143 1 Scl=1;
144 1 _nop_();
145 1 Sda=1;
146 1 _nop_(); //成功停止
147 1 Scl=0; //允许SAD改变以准备数据
148 1 }
149
150 /*------------------------------------------------
151 (主机)应答IIC总线
152 ------------------------------------------------*/
153 void Ack(void) //时钟有效期间,SDA保持0
154 {
155 1 Sda=0;
156 1 _nop_();
157 1 Scl=1;
158 1 _nop_();
159 1 Scl=0;
160 1 _nop_();
161 1 }
162
163 /*------------------------------------------------
164 (主机)非应答IIC总线
165 ------------------------------------------------*/
166 void NoAck(void) //时钟有效期间,SDA保持1
167 {
168 1 Sda=1;
169 1 _nop_();
170 1 Scl=1;
171 1 _nop_();
172 1 Scl=0;
173 1 _nop_();
174 1 }
175 /*------------------------------------------------
176 发送一个字节
177 ------------------------------------------------*/
178 void Send(unsigned char Data)
179 {
C51 COMPILER V7.00 MAIN 06/16/2011 18:30:41 PAGE 4
180 1 unsigned char BitCounter=8;
181 1 unsigned char temp;
182 1
183 1 do
184 1 {
185 2 temp=Data;
186 2 Scl=0;
187 2 _nop_();
188 2 if((temp&0x80)==0x80)
189 2 Sda=1;
190 2 else
191 2 Sda=0;
192 2
193 2 Scl=1;
194 2 temp=Data<<1;
195 2 Data=temp;
196 2 BitCounter--;
197 2 }
198 1 while(BitCounter);
199 1 Scl=0;
200 1 }
201
202 /*------------------------------------------------
203 读入一个字节并返回
204 ------------------------------------------------*/
205 unsigned char Read(void)
206 {
207 1 unsigned char temp=0;
208 1 unsigned char temp1=0;
209 1 unsigned char BitCounter=8;
210 1
211 1 Sda=1; //让出数据总线给8591
212 1
213 1 do
214 1 {
215 2 Scl=0; //允许8591改变(准备)SDA数据
216 2 _nop_(); //等待数据有效
217 2 Scl=1; //使数据有效(单片机可用)
218 2 _nop_();
219 2 if(Sda) //单片机读SDA并判断
220 2 temp=temp|0x01;
221 2 else
222 2 temp=temp&0xfe;
223 2
224 2 if(BitCounter-1!=0)
225 2 {
226 3 temp1=temp<<1;
227 3 temp=temp1;
228 3 }
229 2 BitCounter--;
230 2 }
231 1 while(BitCounter);
232 1
233 1 return(temp);
234 1 }
235
236 /*------------------------------------------------
237 读取ch通道AD转换的值,有返回值
238 ------------------------------------------------*/
239 unsigned char ReadADC(unsigned char Ch)
240 {
241 1 unsigned char Data;
C51 COMPILER V7.00 MAIN 06/16/2011 18:30:41 PAGE 5
242 1 Start(); //启动
243 1 Send(AddWr); //写入芯片地址——写数据地址0x90
244 1 Ack(); //应该是等8591应答吧?
245 1 //发送”控制字“
246 1 Send(0x40|Ch); //写入选择的通道,本程序只用单端输入,差分部分需要自行设置
247 1 //Chl的值分别为0、1、2、3,分别代表1-4通道
248 1 //0100 00xx
249 1 Ack();
250 1
251 1 Start();
252 1 Send(AddRd); //写入地址---读数据地址0x91
253 1 Ack();
254 1 Data=Read(); //读数据
255 1 Scl=0;
256 1 NoAck();
257 1 Stop();
258 1 return Data; //返回值
259 1 }
260 /*------------------------------------------------
261 主程序
262 ------------------------------------------------*/
263 void main()
264 {
265 1 unsigned char ADtemp; //定义中间变量
266 1 float U=0; //电压值
267 1 //unsigned int TempData[6];
268 1
269 1 Init_Timer1();
270 1
271 1 while(1)
272 1 {
273 2 if(ADFlag) //定时采集输入模拟量
274 2 {
275 3 ADFlag=0;
276 3 ADtemp=ReadADC(0); //8位二进制温度值
277 3 U=ADtemp*5.0/255; //把采样的数字值再还原为模拟值
278 3 }
279 2 show_led8(U);
280 2 }
281 1 }
282
283 /*------------------------------------------------
284 定时器中断程序
285 ------------------------------------------------*/
286 void Timer1_isr(void) interrupt 3 using 1//定时器1执行数码管动态扫描
287 {
288 1 static unsigned int j;
289 1
290 1 TL1=0xDC; //重新赋值 62500US=62.5MS中断一次
291 1 TH1=0x0B;
292 1
293 1 j++;
294 1 if(j==4) //62.5*4=250ms 一秒钟采样四次
295 1 {j=0;ADFlag=1;} //定时置位AD采样标志位
296 1 }
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 537 ----
CONSTANT SIZE = 10 ----
XDATA SIZE = ---- ----
PDATA SIZE = ---- ----
C51 COMPILER V7.00 MAIN 06/16/2011 18:30:41 PAGE 6
DATA SIZE = 8 8
IDATA SIZE = ---- ----
BIT SIZE = 1 ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -