主程序:#include<IIC.h>
sbit SCL=P2^0;
sbit SDA=P2^1;
uchar code Tosin[255]={ //定義code數(shù)組,放在rom中。
0x80,0x83,0x86,0x89,0x8D,0x90,0x93,0x96,
0x99,0x9C,0x9F,0xA2,0xA5,0xA8,0xAB,0xAE,
0xB1,0xB4,0xB7,0xBA,0xBC,0xBF,0xC2,0xC5,
0xC7,0xCA,0xCC,0xCF,0xD1,0xD4,0xD6,0xD8,
0xDA,0xDD,0xDF,0xE1,0xE3,0xE5,0xE7,0xE9,
0xEA,0xEC,0xEE,0xEF,0xF1,0xF2,0xF4,0xF5,
0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,
0xFD,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFD,
0xFD,0xFC,0xFB,0xFA,0xF9,0xF8,0xF7,0xF6,
0xF5,0xF4,0xF2,0xF1,0xEF,0xEE,0xEC,0xEA,
0xE9,0xE7,0xE5,0xE3,0xE1,0xDE,0xDD,0xDA,
0xD8,0xD6,0xD4,0xD1,0xCF,0xCC,0xCA,0xC7,
0xC5,0xC2,0xBF,0xBC,0xBA,0xB7,0xB4,0xB1,
0xAE,0xAB,0xA8,0xA5,0xA2,0x9F,0x9C,0x99,
0x96,0x93,0x90,0x8D,0x89,0x86,0x83,0x80,
0x80,0x7C,0x79,0x78,0x72,0x6F,0x6C,0x69,
0x66,0x63,0x60,0x5D,0x5A,0x57,0x55,0x51,
0x4E,0x4C,0x48,0x45,0x43,0x40,0x3D,0x3A,
0x38,0x35,0x33,0x30,0x2E,0x2B,0x29,0x27,
0x25,0x22,0x20,0x1E,0x1C,0x1A,0x18,0x16,
0x15,0x13,0x11,0x10,0x0E,0x0D,0x0B,0x0A,
0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,
0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,
0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
0x0A,0x0B,0x0D,0x0E,0x10,0x11,0x13,0x15,
0x16,0x18,0x1A,0x1C,0x1E,0x20,0x22,0x25,
0x27,0x29,0x2B,0x2E,0x30,0x33,0x35,0x38,
0x3A,0x3D,0x40,0x43,0x45,0x48,0x4C,0x4E,
0x51,0x55,0x57,0x5A,0x5D,0x60,0x63,0x66,
0x69,0x6C,0x6F,0x72,0x76,0x79,0x7C
};
void main()
{
uint i;
I2C_init();
while(1)
{
for(i = 255; i > 0; i--)
{
I2C_TransmitData(0x40, Tosin[i]);
//0 0-analogue output enable glag 0 0 analogue input programming ,0 0-auto analogue increase flag 11-通道選擇位
}
}
}
頭文件:
#ifndef __IIC_H__
#define __IIC_H__
#include"reg52.h"
#include"intrins.h"
#define uchar unsigned char //定義無(wú)符號(hào)字符型變量
#define uint unsigned int //定義無(wú)符號(hào)整型變量
void I2C_init(); //IIC初始化
void I2C_Start(); //IIC開始
void I2C_Stop(); //IIC停止
void Master_ACK(bit i); //主機(jī)發(fā)送非應(yīng)答和應(yīng)答
bit Test_ACK(); //從機(jī)應(yīng)答和非應(yīng)答檢測(cè)
void I2C_send_byte(uchar byte); //IIC發(fā)送一字節(jié)數(shù)據(jù),8位
uchar I2C_read_byte(); //IIC讀取一字節(jié)數(shù)據(jù),8位
bit I2C_TransmitData(uchar ADDR, DATA); //IIC發(fā)送一字節(jié)數(shù)據(jù),給總線上的從機(jī)發(fā)送。bit返回值函數(shù)用來(lái)檢測(cè)一字節(jié)數(shù)據(jù)是否發(fā)送成功給從機(jī)。
uchar I2C_ReceiveData(uchar ADDR); //IIC接收一字節(jié)數(shù)據(jù),從總線的從機(jī)上接收數(shù)據(jù)。uchar返回值函數(shù)用來(lái)返回從從機(jī)所讀取的一字節(jié)數(shù)據(jù)。
void delay_5us(); //5us延時(shí)函數(shù)
void delayms(uint z); //ms級(jí)延時(shí)函數(shù)
#endif//定義結(jié)束
頭文件對(duì)應(yīng)的.c文件:
#include<IIC.h>
#include<reg52.h>
uchar device_ADDR=0x90; //在這里可以改器件地址
sbit SCL=P2^0;
sbit SDA=P2^1;
/*I2C初始化*/
void I2C_init()
{
SDA = 1;
_nop_();
SCL = 1;
_nop_();
}
/*I2C起始信號(hào)*/
void I2C_Start()
{
SCL = 1;
_nop_();
SDA = 1;
delay_5us();
SDA = 0;
delay_5us();
}
/*I2C終止信號(hào)*/
void I2C_Stop()
{
SDA = 0;
_nop_();
SCL = 1;
delay_5us();
SDA = 1;
delay_5us();
}
/*主機(jī)發(fā)送應(yīng)答*/
void Master_ACK(bit i)
{
SCL = 0; // 拉低時(shí)鐘總線允許SDA數(shù)據(jù)總線上的數(shù)據(jù)變化
_nop_(); // 讓總線穩(wěn)定
if (i) //如果i = 1 那么拉低數(shù)據(jù)總線 表示主機(jī)應(yīng)答
{
SDA = 0;
}
else
{
SDA = 1; //發(fā)送非應(yīng)答
}
_nop_();//讓總線穩(wěn)定
SCL = 1;//拉高時(shí)鐘總線 讓從機(jī)從SDA線上讀走 主機(jī)的應(yīng)答信號(hào)
delay_5us();
SCL = 0;//拉低時(shí)鐘總線, 占用總線繼續(xù)通信
_nop_();
SDA = 1;//釋放SDA數(shù)據(jù)總線。
_nop_();
}
/*檢測(cè)從機(jī)應(yīng)答*/
bit Test_ACK()
{
SCL = 1;
delay_5us();
if (SDA)
{
SCL = 0;
_nop_();
I2C_Stop();
return(0);
}
else
{
SCL = 0;
_nop_();
return(1);
}
}
/*發(fā)送一個(gè)字節(jié)*/
void I2C_send_byte(uchar byte)
{
uchar i;
for(i = 0 ; i < 8 ; i++)
{
SCL = 0;
_nop_();
if (byte & 0x80)
{
SDA = 1;
_nop_();
}
else
{
SDA = 0;
_nop_();
}
SCL = 1;
_nop_();
byte <<= 1; // 0101 0100B
}
SCL = 0;
_nop_();
SDA = 1;
_nop_();
}
/*I2C 讀一字節(jié)*/
uchar I2C_read_byte()
{
uchar dat,i;
SCL = 0;
_nop_();
SDA = 1;
_nop_();
for(i = 0 ; i < 8 ; i++)
{
SCL = 1;
_nop_();
if (SDA)
{
dat |= 0x01; //
}
else
{
dat &= 0xfe; //1111 1110
}
_nop_();
SCL = 0 ;
_nop_();
if(i < 7)
{
dat = dat << 1;
}
}
return(dat);
}
/*I2C發(fā)送數(shù)據(jù)*/
bit I2C_TransmitData(uchar ADDR, DATA)
{
I2C_Start();
I2C_send_byte(device_ADDR+0); //器件地址+0;寫入,1010,0000=0xa0.
if (!Test_ACK())
{
return(0);
}
I2C_send_byte(ADDR); //寫入IIC總線上的哪一個(gè)存儲(chǔ)單元,如果是PCF8591的話,就是控制字
if (!Test_ACK())
{
return(0);
}
I2C_send_byte(DATA);
if (!Test_ACK())
{
return(0);
}
I2C_Stop();
return(1);
}
/*I2C接收數(shù)據(jù)*/
uchar I2C_ReceiveData(uchar ADDR)
{
uchar DATA;
I2C_Start();
I2C_send_byte(device_ADDR+0);
if (!Test_ACK())
{
return(0);
}
I2C_send_byte(ADDR); //從哪個(gè)存儲(chǔ)單元讀取數(shù)據(jù),例如AT24C02的話,有256個(gè)字節(jié)存儲(chǔ)單元(256*8=2048位。)ADDR可以是0-255之間的數(shù)。
//如果是PCF8591的話,ADDR就是控制字,控制字假如為0000 0010.則讀取通道2上的模擬量轉(zhuǎn)化為的數(shù)字量。
Master_ACK(0); //
I2C_Start();
I2C_send_byte(device_ADDR+1); //發(fā)送一字節(jié)從機(jī)地址,且方向?yàn)?,為寫
if (!Test_ACK())
{
return(0);
}
DATA = I2C_read_byte();
Master_ACK(0);
I2C_Stop();
return(DATA);
}
/*5us延時(shí)函數(shù)*/
void delay_5us()
{
_nop_();
}
/*1Ms延時(shí)*/
void delayms(uint z)
{
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
這是一個(gè)簡(jiǎn)單一點(diǎn)的程序,以后看情況加其他波形和波形按鍵選擇。PCF8591是8位DA輸出。Vref接的+5V。希望在這里得到大家的指正,同時(shí)歡迎大家一起交流學(xué)習(xí)!
|