📄 iic_comm.lst
字号:
237 2 SMB0CN |= 0x40;
238 2 break;
239 2 }
240 1 if (FAIL) // If the transfer failed,
241 1 {
C51 COMPILER V8.02 IIC_COMM 09/17/2008 10:45:02 PAGE 5
242 2 SMB0CN &= ~0x40; // Reset communication
243 2 SMB0CN |= 0x40;
244 2 SMBUS_BUSY = 0; // Free SMBus
245 2 }
246 1 SI=0; // Clear SMBus interrupt flag
247 1 }
248
249 /************************************************************
250 -----SMBUS数据处理程序-----
251 功能: 根据接收到的info_id,作相应的处理
252 //void DataProcess(void)
253 *************************************************************/
254
255 void DataProcess(DATA_BUFF *RcvData)
256 {
257 1 UCHAR temp = 0;
258 1 static UCHAR *pTxdCnt;
259 1 static UCHAR txLen = 0;
260 1 DATA_BUFF *pSndData;
261 1
262 1 // while(DataProcess);
263 1 // DataProcess = 1;
264 1 pTxdCnt = &SndDataLen; // 指针指向发送数据长度全局变量
265 1 pSndData = &unSndDataBuf; // 指针指向发送缓冲区首址
266 1
267 1 if(RcvDataFlag) // 缓冲区中有新收到的数据
268 1 {
269 2 temp = RcvData->databuf[0]; // info_id判断
270 2 switch (temp){
271 3 case 0x30:
272 3 txLen = ReturnScanCode(RcvData);
273 3 break;
274 3 case 0x31:
275 3 txLen = ReturnBatStatus(RcvData);
276 3 break;
277 3 default:
278 3 break;
279 3 }
280 2 RcvDataFlag = 0;
281 2 }
282 1 *pTxdCnt = txLen;
283 1 if(txLen != 0)
284 1 IIC_SndData(pSndData, pTxdCnt); // 启动iic主发送
285 1 }
286
287 /************************************************************
288 -----回复主机查询按键程序-----
289 功能: 将需要发送的扫描码送入发送缓冲区
290 返回: 发送缓冲区中数据的长度,
291 如果校验出错则返回长度为0,正确则为实际长度
292 //UCHAR ReturnScanCode(DATA_BUFF SndData)
293 *************************************************************/
294
295 UCHAR ReturnScanCode(DATA_BUFF *RcvData)
296 {
297 1 UCHAR temp;
298 1 UCHAR retlen;
299 1 DATA_BUFF *pSndBuf;
300 1
301 1 pSndBuf = &unSndDataBuf;
302 1
303 1 temp = CompChksum(RcvData);
C51 COMPILER V8.02 IIC_COMM 09/17/2008 10:45:02 PAGE 6
304 1 if(temp == 1) // 校验和正确,将发送数据填入发送缓冲区
305 1 {
306 2 pSndBuf->unDataUnion.stFRK.info_id = FRK_INFO_ID;
307 2 // if(KeyBuffer[0] == 0xd0) // KeyBuffer中保存的是通码
308 2 // {
309 2 // pSndBuf->unDataUnion.stFRK.info_len = 1;
310 2 // pSndBuf->unDataUnion.stFRK.info_scancode[0] = KeyBuffer[1];
311 2 // retlen = 4; //
312 2 // }
313 2 // else
314 2 // {
315 2 pSndBuf->unDataUnion.stFRK.info_len = 2;
316 2 pSndBuf->unDataUnion.stFRK.info_scancode[0] = KeyBuffer[0];
317 2 pSndBuf->unDataUnion.stFRK.info_scancode[1] = KeyBuffer[1];
318 2 retlen = 5;
319 2 // }
320 2 CalChksum(pSndBuf); //计算校验和并将其填入正确的位置
321 2 // pSndBuf->unDataUnion.stFRK.checksum = temp;
322 2 }
323 1 else // 校验和错误
324 1 retlen = 0;
325 1 return retlen;
326 1 }
327
328 /************************************************************
329 -----回复主机查询电池信息程序-----
330 功能: 将需要发送的电池信息送入发送缓冲区,本次暂时只支持电量
331 返回: 发送缓冲区中数据的长度,
332 如果校验出错则返回长度为0,正确则为实际长度
333 //UCHAR ReturnBatStatus(DATA_BUFF SndData)
334 *************************************************************/
335
336 UCHAR ReturnBatStatus(DATA_BUFF *RcvData)
337 {
338 1 UCHAR temp;
339 1 UCHAR retlen;
340 1 DATA_BUFF *pSndBuf;
341 1
342 1 pSndBuf = &unSndDataBuf;
343 1
344 1 temp = CompChksum(RcvData);
345 1 if(temp == 1) // 校验和正确,将发送数据填入发送缓冲区
346 1 {
347 2 pSndBuf->unDataUnion.stFRB.info_id = FRB_INFO_ID;
348 2 pSndBuf->unDataUnion.stFRB.info_len = 2;
349 2 pSndBuf->unDataUnion.stFRB.info_batvol[0] = BatVol[0];
350 2 pSndBuf->unDataUnion.stFRB.info_batvol[1] = BatVol[1];
351 2 CalChksum(pSndBuf);
352 2 pSndBuf->unDataUnion.stFRB.checksum = temp;
353 2 retlen = 5;
354 2 }
355 1 else // 校验和错误
356 1 retlen = 0;
357 1 return retlen;
358 1 }
359
360 /************************************************************
361 -----比较校验和程序-----
362 功能: 计算接收缓冲区数据校验和并与接收到的校验和比较
363 返回: 如果校验出错则返回0,正确则返回1
364 //UCHAR CompChksum(DATA_BUFF RcvData)
365 *************************************************************/
C51 COMPILER V8.02 IIC_COMM 09/17/2008 10:45:02 PAGE 7
366
367 UCHAR CompChksum(DATA_BUFF *RcvData)
368 {
369 1 UCHAR i, temp = 0;
370 1 UCHAR len = 0;
371 1 UINT sum = 0;
372 1
373 1 len = RcvData->databuf[1] + 2; // 接收缓冲区数据长度 = 信息长度 + info_id + info_len
374 1 for(i = 0; i < len; i++)
375 1 sum += RcvData->databuf[i];
376 1 temp = (UCHAR) sum;
377 1 if(temp != RcvData->databuf[i]) // 校验和不等
378 1 return 0;
379 1 else
380 1 return 1;
381 1 }
382
383 /************************************************************
384 -----计算校验和程序-----
385 功能: 计算发送缓冲区数据校验和
386 返回: 校验和
387 //void CalChksum(DATA_BUFF SndData)
388 *************************************************************/
389
390 void CalChksum(DATA_BUFF *SndData)
391 {
392 1 UCHAR i;
393 1 UCHAR len = 0;
394 1 UINT temp = 0;
395 1
396 1 len = SndData->databuf[1] + 2; // 接收缓冲区数据长度 = 信息长度 + info_id + info_len
397 1 for(i = 0; i < len; i++)
398 1 temp += SndData->databuf[i];
399 1 SndData->databuf[i] = (UCHAR) temp; // 将计算所得校验和填入发送缓冲区
400 1 }
401
402 ///************************************************************
403 //-----iic主发送程序-----
404 //功能: 将发送缓冲区的数据通过IIC总线发送出去
405 //返回: 发送缓冲区中数据的长度,
406 ////void IIC_SndData(DATA_BUFF *SndData, UCHAR *SndLen)
407 //*************************************************************/
408
409 void IIC_SndData(DATA_BUFF *SndData, UCHAR *SndLen)
410 {
411 1 UCHAR i;
412 1
413 1 while(SMBUS_BUSY); // 等待总线空闲
414 1 SMBUS_BUSY = 1; // 开始发送数据前,设置总线忙
415 1
416 1 iic_reset();
417 1 iic_init(SMB_MASTER);
418 1
419 1 for(i = 0; i < *SndLen; i++)
420 1 IIC_ByteWrite(SndData, i);
421 1
422 1 while(SMBUS_BUSY); // 等待总线空闲
423 1 // SMBUS_BUSY = 1;
424 1 iic_reset();
425 1 iic_init(SMB_SLAVE); // 发送完成后,将本机设置为从模式
426 1
427 1 }
C51 COMPILER V8.02 IIC_COMM 09/17/2008 10:45:02 PAGE 8
428
429 /************************************************************
430 -----iic总线复位程序-----
431 //void iic_reset(void)
432 *************************************************************/
433
434 void iic_reset(void)
435 {
436 1 SMB0CN &= ~0x40; // Disable SMBus
437 1 SMB0CN |= 0x40; // Re-enable SMBus
438 1 }
439
440 /************************************************************
441 -----iic主方式发送单个字节程序-----
442 功能: 将发送缓冲区中SndLocation位置的数据通过IIC总线发送出去
443 返回:
444 //void IIC_ByteWrite(DATA_BUFF *SndData, UCHAR SndLocation)
445 *************************************************************/
446
447 void IIC_ByteWrite( DATA_BUFF *SndData, unsigned char SndLocation)
448 {
449 1 while (SMBUS_BUSY); // Wait for SMBus to be free.
450 1 SMBUS_BUSY = 1; // Claim SMBus (set to busy)
451 1 // 设置中断中用到的参数
452 1 TARGET = MST_ADD; // 设置目标地址
453 1 SMB_RW = WRITE; // 标志总线为写操作
454 1 SMB_ACKPOLL = 1; // 中断程序将不断查询地址有无确认
455 1 // 准备要发送的数据(1字节)
456 1 SMB_SINGLEBYTE_OUT = SndData->databuf[SndLocation];
457 1 // 将要发送数据存储于SMB_SINGLEBYTE_OUT,中断程序
458 1 // 将会读取该位置的值并发送
459 1 pSMB_DATA_OUT = &SMB_SINGLEBYTE_OUT;
460 1 SMB_DATA_LEN = 1;
461 1 // Initiate SMBus Transfer
462 1 STA = 1;
463 1 }
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 808 ----
CONSTANT SIZE = ---- ----
XDATA SIZE = ---- ----
PDATA SIZE = ---- ----
DATA SIZE = 34 39
IDATA SIZE = ---- ----
BIT SIZE = 5 ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -