- #include <reg52.h>
- #include <intrins.h>
- typedef unsigned char uint8;
- typedef unsigned int uint16;
- #define SLAVEADDR 0x90 //定義器件地址
- #define nops() do{_nop_();_nop_();_nop_();_nop_();_nop_();} while(0) //定義空指令
- sbit SCL = P2^1; //I2C 時鐘
- sbit SDA = P2^0; //I2C 數據
- void delay(uint16 n)
- {
- while (n--);
- }
- /**
- * 函數: i2c_start()
- * 功能: 啟動i2c 起始信號
- */
- void i2c_start()
- {
- SCL = 1;
- nops();
- SDA = 1;
- nops();
- SDA = 0;
- nops();
- SCL = 0;
- }
- /**
- * 函數: i2c_stop()
- * 功能: 停止i2c
- */
- void i2c_stop()
- {
- SCL = 0;
- nops();
- SDA = 0;
- nops();
- SCL = 1;
- nops();
- SDA = 1;
- nops();
- }
- /**
- * 函數: i2c_ACK(bit ck)
- * 功能: ck為1時發送應答信號ACK,
- * ck為0時不發送ACK
- */
- void i2c_ACK(bit ck)
- {
- if (ck)
- SDA = 0;
- else
- SDA = 1;
- nops();
- SCL = 1;
- nops();
- SCL = 0;
- nops();
- SDA = 1;
- nops();
- }
- /**
- * 函數: i2c_waitACK()
- * 功能: 返回為0時收到ACK
- * 返回為1時沒收到ACK
- */
- bit i2c_waitACK()
- {
- SDA = 1;
- nops();
- SCL = 1;
- nops();
- if (SDA)
- {
- SCL = 0;
- i2c_stop();
- return 1;
- }
- else
- {
- SCL = 0;
- return 0;
- }
- }
- /**
- * 函數: i2c_sendbyte(uint8 bt)
- * 功能: 將輸入的一字節數據bt發送
- */
- void i2c_sendbyte(uint8 bt)
- {
- uint8 i;
- for(i=0; i<8; i++)
- {
- if (bt & 0x80)
- SDA = 1;
- else
- SDA = 0;
- nops();
- SCL = 1;
- bt <<= 1;
- nops();
- SCL = 0;
- }
- }
- /**
- * 函數: i2c_recbyte( )
- * 功能: 從總線上接收1字節數據
- */
- uint8 i2c_recbyte()
- {
- uint8 dee, i;
- for (i=0; i<8; i++)
- {
- SCL = 1;
- nops();
- dee <<= 1;
- if (SDA)
- dee = dee | 0x01;
- SCL = 0;
- nops();
- }
- return dee;
- }
- /**
- * 函數: i2c_readbyte
- * 輸入: addr
- * 功能: 讀出一字節數據
- * 返回值: 0->成功 1->失敗
- */
- bit i2c_readbyte(uint8 com, uint8 *dat)
- {
- i2c_start();
- i2c_sendbyte(SLAVEADDR); //地址
- if (i2c_waitACK())
- return 1;
- i2c_sendbyte(com); //控制字節
- if (i2c_waitACK())
- return 1;
- i2c_start();
- i2c_sendbyte(SLAVEADDR+1); //地址
- if (i2c_waitACK())
- return 1;
- *dat = i2c_recbyte(); //讀數據
- i2c_ACK(0); //因為只讀一字節數據,不發送ACK信號
- i2c_stop();
- return 0;
- }
- /**
- * UART初始化
- * 波特率:9600
- */
- void uart_init(void)
- {
- ET1=0;
- TMOD = 0x21; // 定時器1工作在方式2(自動重裝)
- SCON = 0x50; // 10位uart,允許串行接受
- TH1 = 0xFD;
- TL1 = 0xFD;
- TR1 = 1;
- }
- /**
- * UART 發送一字節
- */
- void UART_Send_Byte(uint8 dat)
- {
- SBUF = dat;
- while (TI == 0);
- TI = 0;
- }
- main()
- {
- uint8 ans;
- uart_init();
- while(1)
- {
- i2c_readbyte(0x43, &ans);
- UART_Send_Byte(ans);
- delay(50000);
- }
- }
|