i2c.c
来自「上学时做的一个51单片机按键显示程序」· C语言 代码 · 共 283 行
C
283 行
/*
* Copyright(c)2005 - 2009 danise .China
* All rights reserved.
* Redistribution and use in source and bianry forms
* with or without modification ,are permitted provided
* that following conditions are met:
*
* 1.Redistrubution of source code must retain the
* above copyright notice,this list of conditions and
* following disclaimer.
*
* 2.Redistributions in binary form must reproduce the
* above copyright notice,this list of conditions and
* following disclaimer in the documentation and /or other
* materials provided with the distribution.
*
* Alternately, this acknowledgment may appear in the software
* itself,if and wherever such third-party acknowledgements
* normally appear.
*
* This software is designed for key board and led display.
*
*/
#include "./include/i2c.h"
#include "./include/global.h"
#include "./include/display.h"
#include "./include/system.h"
UINT8 idata I2CRC = 0;
UINT8 idata i2cbuf[13];
UINT8 idata i2recvbuf[13] ;//= {4,0x22,0x41,0x05};
UINT8 i2cSendOk=0;
UINT8 i2cRecvOk=0;
UINT8 sendindex = 0;
UINT8 recvindex = 0;
UINT16 i2cChkCount=0;
bit RcvByte(UINT8 *c)
{ I2CON = RELEASE_BUS_ACK; /* 清除标志位 */
while( SI==0 ); /* 放开总线,等待接收 */
if( I2STAT==0xA0 ) /* 接收到停止位或重新启动位 */
{ I2CON = RELEASE_BUS_ACK; /* 先放开总线,再返回0 */
return(0);
}
*c = I2DAT; /* 取数据 */
return(1);
}
/*
*/
bit SendByte(UINT8 c)
{ if( I2STAT==0xC0 ) /* 上次发送数据后,接收到非应答位 */
{ I2CON = RELEASE_BUS_ACK;
return(0);
}
I2DAT = c; /* 发送数据 */
I2CON = RELEASE_BUS_ACK; /* 释放总线 */
while( SI==0 ); /* 等待字节数据发送完成 */
return(1);
}
/*
*/
void SetBus(UINT8 addr)
{ I2ADR = addr&0xfe; /* 设置从地址不接收广播地址 */
I2CON = RELEASE_BUS_ACK; /* 启动硬件I2C */
}
/*
*/
void I2CISR(void) interrupt 6
{
bit i2csendresult = 0;
bit i2crecvresult = 0;
UINT8 temp = 0;
sendindex = 0;
recvindex = 0;
CPL932_ET0=0;
EI2C=0;
elapsetime = 0;
I2CRC= 0;
sreensaveclk = 0; /* clr screen save */
scrflag = 0; /* stop screen save */
switch(I2STAT)
{
case RDSLA: while(1)/* Sending */
{
EA =0;
i2csendresult=SendByte(i2cbuf[sendindex++]);
EA =1;
if(!i2csendresult){
i2cSendOk = 0x1;
break;
}
if( sendindex>i2cbuf[0] ){
i2cSendOk = 0x1;
break;
}
if(elapsetime>=40){
/*1 s*/
i2cSendOk=0x0;/* fail testing by time elapse */
break;
}
}
break;
case WRSLA: if(0x0 == i2cRecvOk){ //if_1
while(1)/* receiving */
{// while
EA =0;
i2crecvresult= RcvByte(&temp);
EA =1;
if(!i2crecvresult){
// I2CRC=I2CRC+temp; /* ? */
if( 0xff == I2CRC )
i2cRecvOk = 1;
else
i2cRecvOk = 0;
break;
}
i2recvbuf[recvindex++]=temp;
I2CRC=I2CRC+temp;
if(recvindex > i2recvbuf[0]){
if( I2CRC == 0xff ){
i2cRecvOk = 1;
}
else
i2cRecvOk =0;
break;
}
if(elapsetime>=50){
/*1 s*/
i2cRecvOk = 0;/* reception testing by time elapse */
break;
}
}//while
}//if_1
break;
default :break;
}
I2CON = 0x44;
EI2C=1;
CPL932_ET0=1;
}
/*
*/
void I2cSendFrame(UINT8 err )
{
UINT8 idata count = 0;
LWORD data i;
i2cSendOk = 0;
while(count <4 && i2cSendOk == 0 )
{
count++;
INT1 = 1;
INT1 = 0; /*pull down the INT1 to make main CPU recognise and start IIC */
for(i=0;i<20;i++); /*hold 0 for a moment */
INT1=1;
for(i=0;i<25000;i++)
{
/*kick dog*/
if(0x1 == i2cSendOk){
break;
}
}
if(0x0 == i2cSendOk){
i2cSendOk = 0;
SparkLights( LIGHT_PROBLEM );
error( err );
}
}
}
void RegisterMachine(void)
{
memset(i2cbuf,0,13);
i2cbuf[0] = 0x2;
i2cbuf[1] = 0xaa;
i2cbuf[2] = 0x53;
I2cSendFrame(0x0c);
}
void ProcessI2cRecvFrame(void)
{
UINT8 cmd = 0;
bit isdot;
bit updown;
if(0x1 == i2cRecvOk){
Enter_Critical_OS();
i2cRecvOk=0x0; /* clear the singal for next packet */
Exit_Critical_OS();
cmd = i2recvbuf[1];
switch( cmd )
{
case 0x01: ClearUpLeds();RESETLEDSHOWSTR();
break;
case 0x02: ClearDownLeds();RESETLEDSHOWSTR();
break;
case 0x22: FillStruLed( i2recvbuf+2 ,2,0 );
memcpy(&scrsavebuf[8],&LedsShowStr.ledbuf[4],4);
UpateLeds( POSITION_DOWN );
RESETLEDSHOWSTR();
break;
case 0x66: FillStruLed( i2recvbuf+2 ,1,0 );
LedsShowStr.ledbuf[5]=14; /*show H0 X*/
UpateLeds( POSITION_UP );
RESETLEDSHOWSTR();
break;
case 0xbb:
if( TestBit(i2recvbuf[2],7 )) isdot= 1;
else isdot= 0;
if(TestBit(i2recvbuf[2],6 )) updown=0;
else updown = 1;
SparkLights(i2recvbuf[2]);
FillStruLed(i2recvbuf+3,i2recvbuf[0]-3,isdot );
UpateLeds(updown);
RESETLEDSHOWSTR();
break;
default : break;
}
}
}
/*
*/
void FillStruLed(UINT8 *buf,UINT8 len, bit isdot )
{
INT8 idata i;
UINT8 idata j = LED_MAX_NUM -1;
if(len ==0){
LedsShowStr.isdot = 0;
LedsShowStr.dotposition = LED_MAX_NUM-1;
memset(&LedsShowStr.ledbuf[0],17, LED_MAX_NUM );
return;
}
if( isdot ){
LedsShowStr.isdot = 1;
LedsShowStr.dotposition = 0x5;
}
else{
LedsShowStr.isdot = 0;
LedsShowStr.dotposition = LED_MAX_NUM-1;
}
LedsShowStr.length = len*2 ;
memset(&LedsShowStr.ledbuf[0],0, LED_MAX_NUM );
for(i= len-1;i>=0;i--)
{
LedsShowStr.ledbuf[j--] = buf[i] & 0x0f;
LedsShowStr.ledbuf[j--] = buf[i] >> 4;
}
/* add E ->EEE */
/*when error code */
if(0x1 == len){
LedsShowStr.ledbuf[5] = 12;
}
}
bit TestBit(UINT8 dat,UINT8 n)
{
UINT8 temp;
temp = dat;
temp = temp >> n;
temp = temp & 0x01;
if(temp)
return 1;
else
return 0;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?