📄 iar11-4.c
字号:
#include <iom16.h>
#include<intrinsics.h>
#include "lcd1602_8bit.c"
#define GET_BIT(x,y) (x&(1<<y))
#define CPL_BIT(x,y) (x^=(1<<y))
#define SET_BIT(x,y) (x|=(1<<y))
#define CLR_BIT(x,y) (x&=~(1<<y))
#define S1 4
#define S2 5
#define S3 6
#define S4 7
#define TWINT 7
#define TWSTA 5
#define TWSTO 4
#define TWEN 2
//-----------------------------------------------
#define uchar unsigned char
#define uint unsigned int
#define rd_device_add 0xa1
#define wr_device_add 0xa0
//======================================
//TWI状态定义
//MT 主方式传输 MR 主方式接收
#define START 0x08
#define RE_START 0x10
#define MT_SLA_ACK 0x18
#define MT_SLA_NOACK 0x20
#define MT_DATA_ACK 0x28
#define MT_DATA_NOACK 0x30
#define MR_SLA_ACK 0x40
#define MR_SLA_NOACK 0x48
#define MR_DATA_ACK 0x50
#define MR_DATA_NOACK 0x58
//常用TWI操作(主模式写和主模式读)
#define Start() (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN))
#define Stop() (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN))
#define Wait() {while(!(TWCR&(1<<TWINT)));}
#define TestAck() (TWSR&0xf8)
#define SetAck() (TWCR|=(1<<TWEA))
#define SetNoAck() (TWCR&=~(1<<TWEA))
#define Twi() (TWCR=(1<<TWINT)|(1<<TWEN))
#define Write8Bit(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);}
//=====================================
uchar __flash str0[]={"Write : "};//待显字符串
uchar __flash str1[]={"Read : "};//待显字符串
/********************端口初始化******************/
void port_init(void)
{
PORTA = 0x00;
DDRA = 0xFF;
PORTB = 0x00;
DDRB = 0xFF;
PORTC = 0x00;
DDRC = 0x03;
PORTD = 0xFF;
DDRD = 0x00;
}
/** I2C总线读一个字节,如果读失败返回0***/
uchar i2c_Read(uchar RomAddress)
{
uchar temp;
Start();//I2C启动
Wait();
if (TestAck()!=START) return 0;//ACK
Write8Bit(wr_device_add);//写I2C从器件地址和写方式
Wait();
if (TestAck()!=MT_SLA_ACK) return 0;//ACK
Write8Bit(RomAddress);//写24C01的ROM地址
Wait();
if (TestAck()!=MT_DATA_ACK) return 0;
Start();//I2C重新启动
Wait();
if (TestAck()!=RE_START) return 0;
Write8Bit(rd_device_add);//写I2C从器件地址和读方式
Wait();
if(TestAck()!=MR_SLA_ACK) return 0;//ACK
Twi();//启动主I2C读方式
Wait();
if(TestAck()!=MR_DATA_NOACK) return 0;//ACK
temp=TWDR;//读取I2C接收数据
Stop();//I2C停止
return temp;
}
/**I2C总线写一个字节,返回0:写成功。返回非0:写失败***/
uchar i2c_Write(uchar RomAddress,uchar Wdata)
{
Start();//I2C启动
Wait();
if(TestAck()!=START) return 1;//ACK
Write8Bit(wr_device_add);//写I2C从器件地址和写方式
Wait();
if(TestAck()!=MT_SLA_ACK) return 1;//ACK
Write8Bit(RomAddress);//写24C01的ROM地址
Wait();
if(TestAck()!=MT_DATA_ACK) return 1;//ACK
Write8Bit(Wdata);//写数据到24C01的ROM
Wait();
if(TestAck()!=MT_DATA_ACK) return 1;//ACK
Stop();//I2C停止
Delay_nms(10);//延时等EEPROM写完
return 0;
}
//******************************************
void main(void) // 定义主函数
{
uchar wr_val=0,rd_val=0;
port_init();
Delay_nms(400);
InitLcd();
ePutstr(0,0,str0); //第一行显示Write :
ePutstr(0,1,str1); //第二行显示Read :
/********************************************/
while(1) //无限循环
{
DisplayOneChar(9,0,wr_val/100+0x30); //第一行的第9个字符位置显示百位
Delay_nms(10);
DisplayOneChar(10,0,(wr_val/10)%10+0x30); //第一行的第10个字符位置显示十位
Delay_nms(10);
DisplayOneChar(11,0,wr_val%10+0x30); //第一行的第11个字符位置显示个位
Delay_nms(10);
//-----------------------------------
DisplayOneChar(8,1,rd_val/100+0x30); //第二行的第8个字符位置显示百位
Delay_nms(10);
DisplayOneChar(9,1,(rd_val/10%10)+0x30); //第二行的第9个字符位置显示十位
Delay_nms(10);
DisplayOneChar(10,1,rd_val%10+0x30); //第二行的第10个字符位置显示个位
Delay_nms(10);
//-----------------------------------
if(GET_BIT(PIND,S1)==0){if(wr_val<255)wr_val++;}// 加法取数
if(GET_BIT(PIND,S2)==0){if(wr_val>0)wr_val--;} // 减法取数
if(GET_BIT(PIND,S3)==0)
{i2c_Write(88,wr_val); //将数写入AT24C01的10号单元中
DisplayOneChar(15,0,0xef);} //显示按下键的符号
if(GET_BIT(PIND,S4)==0)
{rd_val=i2c_Read(88); //从AT24C01的10号单元中读出该数
DisplayOneChar(15,1,0xef);} //显示按下键的符号
//-----------------------------------
Delay_nms(200); // 廷时200mS
DisplayOneChar(15,0,0x20);Delay_nms(10); //消除按下键的符号
DisplayOneChar(15,1,0x20);Delay_nms(10); //消除按下键的符号
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -