/*---------------------------------------------------------
名称: IIC_24C02
版本: v1.0
MCU: MCU:IAP15F2K61S2
主频: 11.0592MHz
功能: 将ascii_table[i]内的144字节数据存储到EEPROM 24C02内,并通过串口通信(9600pbs)发送,同时通过P1口8位显示。
说明:
1. I/O口分配:STC15F2K61S2
output display --> P1
SCL --> P0^0
SDA --> P0^1
注:
I2C 16位寄存器地址的读写(如24C256):
写IIC 设备地址|0+寄存器地址高八位+寄存器地址低八位+八位数据
读IIC 设备地址|0+寄存器地址高八位+寄存器地址低八位+设备地址|1
---------------------------------------------------------*/
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
//I/O 口特殊功能寄存器
sbit P00 = P0^0;
sbit P01 = P0^1;
sbit P02 = P0^2;
sbit P03 = P0^3;
sbit P04 = P0^4;
sbit P05 = P0^5;
sbit P06 = P0^6;
sbit P07 = P0^7;
sbit P10 = P1^0;
sbit P11 = P1^1;
sbit P12 = P1^2;
sbit P13 = P1^3;
sbit P14 = P1^4;
sbit P15 = P1^5;
sbit P16 = P1^6;
sbit P17 = P1^7;
sfr AUXR = 0x8E;
sfr P0M0 = 0x94; //0000,0000 端口0模式寄存器0
sfr P0M1 = 0x93; //0000,0000 端口0模式寄存器1
sfr P1M0 = 0x92; //0000,0000 端口1模式寄存器0
sfr P1M1 = 0x91; //0000,0000 端口1模式寄存器1
sfr P2M0 = 0x96; //0000,0000 端口2模式寄存器0
sfr P2M1 = 0x95; //0000,0000 端口2模式寄存器1
sbit SCL = P0^0;
sbit SDA = P0^1;
uint i;
uchar temp;
uchar code ascii_table[]=
{
//宽*高(12*16)
/* 新宋体 字号[24点] 上移[-5] +粗体*/
/* 0[0x0030] 12x16 */ //384
0x0F,0xF0,0x3F,0xFC,0x7F,0xFE,0xF0,0x0F,0xC0,0x03,0x80,0x01,
0xC0,0x03,0xF0,0x0F,0x7F,0xFE,0x3F,0xFC,0x0F,0xF0,0x00,0x00,
/* 新宋体 字号[24点] 上移[-5] +粗体*/
/* 3[0x0033] 12x16 */
0x00,0x00,0x38,0x1C,0x78,0x1E,0xF8,0x1F,0x80,0x81,0x80,0x81,
0x80,0xC3,0xC1,0xFF,0xFF,0x7E,0x7F,0x3C,0x3C,0x00,0x00,0x00,
/* 新宋体 字号[24点] 上移[-5] +粗体*/
/* 4[0x0034] 12x16 */
0x06,0x00,0x07,0x80,0x05,0xC0,0x04,0x70,0x84,0x38,0x84,0x0E,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x84,0x00,0x84,0x00,0x00,0x00,
/* 新宋体 字号[24点] 上移[-5] +粗体*/
/* 5[0x0035] 12x16 */
0x00,0x00,0x38,0x00,0x79,0xFF,0xD9,0xFF,0x80,0xC3,0x80,0x43,
0x80,0x43,0xE0,0xC3,0xFF,0xC3,0x7F,0x83,0x1F,0x03,0x00,0x00,
/* 新宋体 字号[20点]*/
/* °[0xA1E3] 12x16 */
0x00,0x00,0x00,0x1C,0x00,0x22,0x00,0x22,0x00,0x1C,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* 新宋体 字号[21点] 上移[-4] +粗体*/
/* F[0x0046] 12x16 */
0x00,0x00,0x40,0x02,0x7F,0xFE,0x7F,0xFE,0x40,0x82,0x00,0x82,
0x00,0x82,0x03,0xE2,0x03,0xE6,0x00,0x0E,0x00,0x08,0x00,0x00,
};
void delay4us() //延时4us。
{_nop_(); _nop_(); _nop_(); _nop_(); }
void delay(uint x) //延时函数,12MHz晶振频率时,delay(1)延时1ms
{
uchar i;
while(x--)
for(i=0;i<120;i++);
}
/*IIC开始:把SDA置1再置0。准备发送或接收数据。*/
void start()
{
SDA = 1;
SCL = 1;
delay4us();
SDA = 0;
delay4us();
SCL =0;
}
/*IIC停止:把SDA置0再置1。准备结束发送或接收数据。*/
void stop()
{
SDA = 0;
SCL = 0;
delay4us();
SCL = 1;
delay4us();
SDA = 1;
}
/*读取应答:
注意为主机设备信号,从机应答信号,参考一般教材*/
void rack()
{
SDA = 1;
delay4us();
SCL = 1;
delay4us();
SCL = 0;
}
/*发送非应答信号*/
void noack()
{
SDA = 1;
SCL = 1;
delay4us();
SCL = 0;
SDA = 0;
}
/*向24C04写一字节数据*/
void wbyte(uchar b)
{
uchar i;
for(i=0;i<8;i++)
{
b <<= 1;
SDA = CY;
_nop_();
SCL = 1;
delay4us();
SCL = 0;
}
rack(); //每发送一个字节数据要读取应答。
}
/*向指定地址写数据
IIC器件地址:每一个IIC器件都有一个器件地址,有的器件地址在出厂时地址就设定好了,
用户不可以更改,比如OV7670的地址为0x42。有的器件例如EEPROM,前四个地址已经确定
为1010,后三个地址是由硬件链接确定的,所以一个IIC总线最多能连8个EEPROM芯片。*/
void wdata(uchar addr,uchar dat)
{
start();
wbyte(0xA0); //寻找器件地址为0xA0的芯片,即为1010 0000高四位固定为1010。因为本例中24C02的A2,A1接地,且A0为空脚。所以,得到低四位当中,前3位编码为000。最低位为0,表示主机给从机写数据,这里主机为单片机,从机为24C04芯片。
wbyte(addr); //指定地址。
wbyte(dat); //向指定地址写数据。
stop();
delay(10);
}
/*从24C04读一字节数据*/
uchar read_byte()
{
uchar i,b;
for(i=0;i<8;i++)
{
SCL = 1;
b <<= 1;
b =b|SDA;
SCL = 0;
}
return b;
}
/*从当前地址读取数据*/
uchar read_current()
{
uchar d;
start();
wbyte(0xA1); //寻址器件地址为0xA1的芯片,0xA1即1010 0001 最低位为1,表示主机由从机读数据,可以理解为1时,把主机SDA置1,当读取read_byte()中接收到的数据SDA为0时,则b取0。
d = read_byte();
noack(); //读时序时:注意最后产生无应答信号
stop();
return d;
}
/*从任意地址addr读取数据*/
uchar random_read(uchar addr)
{
start();
wbyte(0xA0); //寻址器件。
wbyte(addr); //指定地址。
return read_current(); //从指定地址读数据。
}
void UART_Init()
{
AUXR=0x00;
TMOD=0x20; //设置定时器T1为方式2
TH1=0xFD; //波特率9600
TL1=0xFD;
SCON=0x50; //设置串口为方式1,可接收,REN=1
PCON=0x00; //SMOD=0
TR1=1; //启动T1
}
void main()
{
P1M1=0x00;
P1M0=0xFF;
UART_Init();
for(i=0;i<144;i++)
{
wdata(i,ascii_table[i]); //i:写指定地址;ascii_table[i];写数据。
}
while(1)
{
for(i=0;i<144;i++)
{
temp = random_read(i);
P1 = temp;
SBUF=temp; //数据送串行口发送
while(TI==0); //如果TI=0,未发送完,循环等待
TI=0;
delay(5000);
}
}
}
评论0