📄 main.c
字号:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <avr/delay.h>
#include <avr/wdt.h>
#include <compat/twi.h>
#include "main.h"
#include "init.h"
#include "inter.h"
#include "func.h"
#define rd_device_add 0xa1 //读地址:0b10100001
#define wr_device_add 0xa0 //写地址:0b10100000
#define EE_READ 0xf0
#define EE_READ_OK 0x50
#define EE_WRITE 0x0f
#define EE_WRITE_OK 0x05
#define EE_WRITE_OVER 0xa5
#define Start() (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE))
//清除中断标志位,在总线上发出起始信号,激活TWI功能,开放TWI中断
#define Stop() (TWCR=((1<<TWINT)|(1<<TWSTO)|(1<<TWEN))&(~(1<<TWIE)))
//清除中断标志位,在总线上发出终止信号,激活TWI功能,关闭TWI中断
#define TestAck() (TWSR&0xf8)
//TWSR--I2C状态寄存器,检查TWI状态,应该将预分频位屏蔽(第三位是保留位)
#define MT_NACK (TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWIE))
//清除中断标志位,使能TWI功能,开放TWI中断,在主控接收状态下不对SDA线作应答
#define MT_ACK (TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWIE)|(1<<TWEA))
//清除中断标志位,使能TWI功能,开放TWI中断,在主控接收状态下对SDA线作应答
#define TWItransmit(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWIE);}
//写入8位数据到数据寄存器中,同时清除中断标志位,使能TWI功能,开放TWI中断
uchar charData;//TWI中断中,传送的数据
uchar charAddr;//TWI中断中,数据所处的EEPROM地址
uchar charState;//TWI中断中,中断所处的状态
/**********************ATEEPROM读写过程*********************************
字节写:Start→器件地址&W→应答→选ROM地址→应答→写数据→应答→Stop
中断过程 START→MT_SLA_ACK→MT_DATA_ACK(地址)→MT_DATA_ACK(数据)(STOP中止)
页面写:Start→器件地址&W→应答→选ROM地址→应答→写数据→应答→写NEXT地址数据→应答→。。。写NEXT地址数据→应答→Stop
中断过程 START→MT_SLA_ACK→MT_DATA_ACK(地址)→MT_DATA_ACK(数据)→MT_DATA_ACK(数据)→。。。MT_DATA_ACK(数据)(STOP中止)
字节读:Start→器件地址&W→应答→选ROM地址→应答→Restart→器件地址&R→应答→读数据→无应答→Stop
中断过程 START→MT_SLA_ACK→MT_DATA_ACK(地址)→RE_START→MR_SLA_ACK→MR_DATA_NOACK(STOP中止)
页面读:Start→器件地址&W→应答→选ROM地址→应答→Restart→器件地址&R→应答→读数据→应答→读NEXT地址数据→应答→。。。读NEXT地址数据→无应答→Stop
中断过程 START→MT_SLA_ACK→MT_DATA_ACK(地址)→RE_START→MR_SLA_ACK→MR_DATA_ACK→MR_DATA_ACK→。。。MR_DATA_NOACK(STOP中止)
*************************************************************************/
extern volatile uchar flag0;
extern volatile uint16_t cnt_t0;
extern volatile uint8_t remote[4];
SIGNAL(SIG_2WIRE_SERIAL)
{//IIC中断
switch (TestAck())//检查状态标志字
{
case TW_START:
{putchar(1);
TWItransmit(wr_device_add);
//选取I2C从器件地址,进行主控写模式
break;
}
case TW_REP_START:
{
TWItransmit(rd_device_add);
//选取I2C从器件地址,进行主控读模式
break;
}
case TW_MT_SLA_ACK:
//Slave器件被识别并产生应答
{putchar(2);
TWItransmit(charAddr);
//写24C02ROM的字地址
break;
}
case TW_MT_DATA_ACK:
//主控发送数据,并得到响应
{
switch(charState)
{
case EE_WRITE://写数据到24C02的ROM
{
TWItransmit(charData);
charState=EE_WRITE_OVER;
break;
}
case EE_WRITE_OVER://I2C停止
{
Stop();
charState=EE_WRITE_OK;
break;
}
case EE_READ:
{
Start();
break;
}
//I2C重新启动
}
break;
}
case TW_MR_SLA_ACK:
{
MT_NACK;
break;
}
//启动主I2C读方式
case TW_MR_DATA_NACK:
{
charData=TWDR;
Stop();
charState=EE_READ_OK;
break;
}
//读取I2C接收数据,I2C停止
default:
putchar(9);
putchar(TestAck());
Stop();//I2C停止
}
}
/*
常用TWI操作(主模式写和主模式读)
*/
void i2c_write(uchar Wdata,uchar RomAddress)
{
charData=Wdata;//I2C总线写一个字节
charAddr=RomAddress;//返回0:写成功
charState=EE_WRITE;//返回非0:写失败
Start();//I2C启动(TWI中断启动)
while(charState!=EE_WRITE_OK);
delay_ms(10);
}
uchar i2c_read(uchar RomAddress)
{
charAddr=RomAddress;
charState=EE_READ;
Start();//I2C启动
while(charState!=EE_READ_OK);
return charData;
}
int main (void)
{ uint8_t i;
cli();
init_devices();
charState=EE_READ;
wdt_enable(WDTO_2S);
wdt_reset();
sei();
while(1)
{
delay_ms(100);
// putchar(3);
i=i2c_read(0x00);
// putchar(i);
// putchar(0);
if((flag0 & _BV(FLAG0_KEEP)) == 0x40)
{
flag0 &= ~_BV(FLAG0_KEEP);
if((remote[0] + remote[1])==0xff)
{
remote[0] = remote[0];
remote[1] = remote[1];
}
if((remote[2] + remote[3])==0xff)
{
remote[2] = remote[2];
remote[3] = remote[3];
remote[4] = 1;
putchar(remote[0]);
putchar(remote[1]);
putchar(remote[2]);
putchar(remote[3]);
putchar(remote[4]);
}
}
if((flag0 & _BV(FLAG0_CODE)) == 0x80)
{
flag0 &= ~_BV(FLAG0_CODE);
if((remote[0] + remote[1])==0xff)
{
remote[0] = remote[0];
remote[1] = remote[1];
}
if((remote[2] + remote[3])==0xff)
{
remote[2] = remote[2];
remote[3] = remote[3];
remote[4] = 0;
putchar(remote[0]);
putchar(remote[1]);
putchar(remote[2]);
putchar(remote[3]);
putchar(remote[4]);
}
}
if(read_key()==1)
{
putchar(1);
twi_start();
delay_ms(100);
twi_writebyte(TWI_ADDRESS|TW_WRITE);
delay_ms(100);
for (i=0;i<10;i++)
{
twi_writebyte(i);
delay_ms(100);
}
twi_stop();
}
if(read_key()==2)
{
putchar(2);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -