📄 twi372.c
字号:
#include <iom88v.h>
#include <macros.h>
//#include"TWI.H"
#define rd_device_add 0x65
#define wr_device_add 0x64
//#define wr_device_add 0x26
/***************************************************/
//TWI状态定义
//MT 主方式传输 MR 主方式接收
#define START 0x08
#define RE_START 0x10
//#define MT_SLA_ACK 0x38
#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
//////////////////////////////////
#define SCL_1 PORTC |= BIT(PC5)
#define SCL_0 PORTC &= ~BIT(PC5)
#define SDA_1 PORTC |= BIT(PC4)
#define SDA_0 PORTC &= ~BIT(PC4)
//常用TWI操作(主模式写和主模式读)
//TWCR TWI控制寄存器;TWINT BIT7;TWSTA BIT5 ;TWEN BIT 2;TWSTO BIT4;TWEA BIT 6
#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) //检验TWI的状态寄存器屏蔽预分频器 ,当状态字 不是MT——DATA——ACK转出错处理 和初值f8与
#define SetAck() (TWCR|=(1<<TWEA))
#define SetNoAck() (TWCR&=~(1<<TWEA))
#define Twi() (TWCR=(1<<TWINT)|(1<<TWEN)) //装入SLA-W到TWDR 寄存器TWINT位清零启动发送地址
#define Write8Bit(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);}
/***************************************************/
unsigned char R_datyy[8];
unsigned char R_datyyb[8];
/***************************************************/
struct date
{
unsigned char year;
unsigned char month;
unsigned char day;
unsigned char week;
unsigned char hour;
unsigned char minute;
unsigned char second;
};//datyy;
/***************************************************/
struct date datyy={05,05,0x21,06,0x11,0x38,0x10};//全局变量,包含年月日 星期 时分秒
/******************************************/
void delay_1ms(void) //1ms延时函数
{
unsigned int i;
for (i=0;i<1140;i++);
}
/******************************************/
void delay_ms(unsigned int n) //N ms延时函数
{
unsigned int i=0;
for (i=0;i<n;i++)
delay_1ms();
}
/******************************************
twi总线写一个字节
返回0:写成功
返回非0:写失败
*******************************************/
unsigned char twi_Write(unsigned int RomAddress,unsigned char Wdata)
{
//unsigned char ADDR=0;
unsigned char ACK_A=0;
unsigned char ACK_B=0;
unsigned char ACK_C=0;
Start();//twi启动
Wait();
if(TestAck()!=START) return 1;//ACK 0x08
//delay_ms(10);/////hhhh
//ADDR=wr_device_add;
Write8Bit(wr_device_add);//起动372从器件地址和写方式 0x64
//Write8Bit(ADDR);//起动372从器件地址和写方式 0x64
//delay_ms(10);
//SDA_0;///hhhhh
Wait();
ACK_A=TestAck();//hhhhhh
//if(TestAck()!=MT_SLA_NOACK) return 1;//hhhhh
if(TestAck()!=MT_SLA_ACK) return 1;//ACK MT_SLA_ACK 0x18 已发送从机地址和写方式主机已接受则续
Write8Bit(RomAddress); //向 TWDR写入数据
Wait();
ACK_B=TestAck();//hhhhhh
if(TestAck()!=MT_DATA_ACK) return 1;//ACK
Write8Bit(Wdata);//写数据到372
Wait();
ACK_C=TestAck();//hhhhhh
if(TestAck()!=MT_DATA_ACK) return 1;//ACK
Stop();//twi停止
delay_ms(20);//延时等EEPROM写完
return 0;
}
/******************************************
twi总线读一个字节
如果读失败也返回0
*******************************************/
unsigned char twi_Read(unsigned int RomAddress)//,unsigned char addr_len
{
unsigned char ACK_R1=0;
unsigned char ACK_R2=0;
unsigned char ACK_R3=0;
unsigned char ACK_R4=0;
unsigned char temp;
unsigned char ADDR;
Start(); //twi启动
Wait();
if (TestAck()!=START) return 0;//ACK
Write8Bit(wr_device_add);//起动372从器件地址和写方式
Wait();
if (TestAck()!=MT_SLA_ACK) return 0;//ACK
Write8Bit(RomAddress);
Wait();
ACK_R1=TestAck();//////////HHHH
if (TestAck()!=MT_DATA_ACK) return 0;
Start();//twi重新启动
Wait();
ACK_R2=TestAck();////////HHHH
if (TestAck()!=RE_START) return 0;
Write8Bit(rd_device_add);//写twi从器件地址和读方式
Wait();
ACK_R3=TestAck();////////HHHH
if(TestAck()!=MR_SLA_ACK) return 0;//ACK
Twi();//启动主twi读方式
Wait();
ACK_R4=TestAck();////////HHHH
if(TestAck()!=MR_DATA_NOACK) return 0;//ACK MR_DATA_NOACK 0x58
temp=TWDR;//读取twi接收数据 TWDR twi数据寄存器
Stop();//twi停止
return temp;
}
/******************************************/
void init372(void)
{
twi_Write(0x70,0);
twi_Write(0xe0,0x23);
//twi_Write(0xe0,0);
twi_Write(0xf0,0x28);//24h
//twi_Write(0xf0,0x38);//24h
}
/******************************************/
void Init_TWI(void)
{
(PRR&=~(1<<PRTWI));//启动两串行线 置能TWI
TWBR=0x16; //TWBR=0x16;TWBR=0x12;bps rigister
TWSR=00; //设置TWI时钟50K twi 状态寄存器
}
/******************************************/
/*
void Bcd2asc(void)
{
uchar i,j;
for (j=0,i=0; i<7; i++)
{
asc[j++] =(trdata[i]&0xf0)>>4|0x30 ;
asc[j++] =trdata[i]&0x0f|0x30;
}
}
*/
/******************************************/
void main(void)
{
PORTB = 0x0F; //00101111B
DDRB = 0x30; //00110000B
PORTC = 0x3F;//置TWI管脚上拉
DDRC = 0x0E;
PORTD = 0x40; //00000000B
//DDRD = 0x50; //01110010B
//MCUCR = 0x00;
//EICRA = 0x00; //extended ext ints
//EIMSK = 0x01;
Init_TWI();
init372();
twi_Write(0,datyy.second);
twi_Write(0x10,datyy.minute);
twi_Write(0x20,datyy.hour);
twi_Write(0x30,datyy.week);
twi_Write(0x40,datyy.day);
twi_Write(0x50,datyy.month);
twi_Write(0x60,datyy.year);
while(1)
{
R_datyy[0]=twi_Read(0x60);//Y
R_datyyb[0]=((R_datyy[0]>>4) & 0x7)*10+(R_datyy[0] & 0xf);
R_datyy[1]=twi_Read(0x50);//MO
R_datyyb[1]=((R_datyy[1]>>4) & 0x7)*10+(R_datyy[1] & 0xf);
R_datyy[2]=twi_Read(0x40);//D
R_datyyb[2]=((R_datyy[2]>>4) & 0x3)*10+(R_datyy[2] & 0xf);
R_datyy[3]=twi_Read(0x30);//W
R_datyyb[3]=((R_datyy[3]>>4) & 0x1)*10+(R_datyy[3] & 0xf);
R_datyy[4]=twi_Read(0x20);//H
R_datyyb[4]=((R_datyy[4]>>4) & 0x1)*10+(R_datyy[4] & 0xf);
R_datyy[5]=twi_Read(0x10);//MI
R_datyyb[5]=((R_datyy[5]>>4) & 0xf)*10+(R_datyy[5] & 0xf);
R_datyy[6]=twi_Read(0x00);//S
R_datyyb[6]=((R_datyy[6]>>4) & 0x7)*10+(R_datyy[6] & 0xf);
delay_ms(20);
/*
datyy.second=((datyy.second >> 4) & 0x7)*10+(datyy.second & 0xf);
datyy.minute=((datyy.minute>>4) & 0x7)*10+(datyy.minute & 0xf);
datyy.hour=((datyy.hour>>4) & 0x3)*10+(datyy.hour & 0xf);
datyy.day=((datyy.day>>4) & 0x3)*10+(datyy.day & 0xf);
datyy.month=((datyy.month>>4) & 0x1)*10+(datyy.month & 0xf);
datyy.year=((datyy.year>>4) & 0xf)*10+(datyy.year & 0xf);
R_datyy[0]=((R_datyy[0]>>4) & 0x7)*10+(R_datyy[0] & 0xf);
R_datyy[1]=((R_datyy[1]>>4) & 0x7)*10+(R_datyy[1] & 0xf);
R_datyy[2]=((R_datyy[2]>>4) & 0x3)*10+(R_datyy[2] & 0xf);
R_datyy[3]=((R_datyy[3]>>4) & 0x3)*10+(R_datyy[3] & 0xf);
R_datyy[4]=((R_datyy[4]>>4) & 0x1)*10+(R_datyy[4] & 0xf);
R_datyy[5]=((R_datyy[5]>>4) & 0xf)*10+(R_datyy[5] & 0xf);
R_datyy[6]=((R_datyy[6]>>4) & 0x7)*10+(R_datyy[6] & 0xf);
*/
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -