"); //-->

#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <avr/delay.h>
#include <avr/pgmspace.h>
#ifndef cbi
#define cbi(reg,bit) reg &= ~_BV(bit)
#endif
#ifndef sbi
#define sbi(reg,bit) reg |= _BV(bit)
#endif
void delay_1ms(uint8_t xtal)
{
uint8_t i;
for(i=1;i<(uint8_t)(xtal*143-2);i++)
{;}
}
//2 延时nms
void delay_ms(uint8_t m, uint8_t fosc)
{
uint8_t i;
i=0;
while(i<m)
{
delay_1ms(fosc);
i++;
}
}
//-----------------------------IIC操作子程序-------------------------------
//IIC写操作
//address_device为器件地址,0xa0为24C64
//address_reg1为寄存器地址1,address_reg2为寄存器地址2
//data_package为写的数据
void twi_write(uint8_t address_reg1,uint8_t address_reg2, uint8_t data_package)
{
//TWI预分频为4分频
sbi(TWSR,TWPS0);
cbi(TWSR,TWPS1);
TWBR=0x20;//SCL频率92160HZ
begin:
TWCR=_BV(TWEN)|_BV(TWSTA)|_BV(TWINT);
while(!(TWCR&_BV(TWINT)))//等待TWINT置位,TWINT置位表示开始信号发送完毕
;
if(((TWSR&0xF8)!=0x08)&((TWSR&0xF8)!=0x10))//检查状态寄存器,如果状态字不是START或RESTART,重新发送开始信号
goto begin;
TWDR=0xa0;//将器件地址写入到TWDR寄存器,TWINT位清零,启动发送地址
TWDR="0xa0";//%%%%%%%%%%%%%%%
TWCR=_BV(TWEN)|_BV(TWINT);
while(!(TWCR&_BV(TWINT)))//等待TWINT置位,TWINT置位表示总线命令SLA+W已发出,及收到应答信号ACK/NACK
;
if((TWSR&0xF8)!=0x18)//检查TWI状态寄存器,如果状态字不是地址ACK,重新发送开始信号
goto begin;
//---发送寄存器地址
TWDR=address_reg1;//写寄存器地址
TWDR=address_reg1;//%%%%%%%%%%%%%%%
TWCR=_BV(TWEN)|_BV(TWINT);
while(!(TWCR&_BV(TWINT)))//等待TWINT置位,TWINT置位表示总线命令SLA+W已发出,及收到应答信号ACK/NACK
;
if((TWSR&0xF8)!=0x28)//检查TWI状态寄存器,如果状态字不是地址ACK,重新发送开始信号
goto begin;
//---发送EEPROM的第二个地址
TWDR=address_reg2;//写寄存器地址
TWDR=address_reg2;//%%%%%%%%%%%%%%%
TWCR=_BV(TWEN)|_BV(TWINT);
while(!(TWCR&_BV(TWINT)))//等待TWINT置位,TWINT置位表示总线命令SLA+W已发出,及收到应答信号ACK/NACK
;
if((TWSR&0xF8)!=0x28)//检查TWI状态寄存器,如果状态字不是地址ACK,重新发送开始信号
goto begin;
//---写入数据
TWDR=data_package;//将数据载入到TWDR寄存器,TWINT位清零,启动发送地址
TWDR=data_package;//%%%%%%%%%%%%%%%
TWCR=_BV(TWINT)|_BV(TWEN);
while(!(TWCR&_BV(TWINT)))//等待TWINT置位,TWINT置位表示总线数据已发出,及收到应答信号ACK/NACK
;
if((TWSR&0xF8)!=0x28)//检查TWI状态寄存器,如果状态字不是数据ACK,重新发送开始信号
goto begin;
TWCR=_BV(TWINT)|_BV(TWSTO)|_BV(TWEN);//发送STOP信号
delay_ms(2,8);
delay_ms(2,8);
delay_ms(2,8);
}
//-------------------------------------------
//IIC读操作
//address_reg1为寄存器地址,address_reg2为寄存器地址2
uint8_t twi_read(uint8_t address_reg1,uint8_t address_reg2)
{
uint8_t result1=0;
sbi(TWSR,TWPS0);//TWI预分频为4分频
cbi(TWSR,TWPS1);
TWBR=0x20;//SCL频率92160HZ
begin:
delay_ms(2,8);
TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);//发送开始信号
while(!(TWCR&(1<<TWINT)))//等待开始信号发送完毕
;
if(((TWSR&0xF8)!=0x08)&((TWSR&0xF8)!=0x10))//检查TWI状态寄存器,如果状态字不是START或RESTART,重新发送开始信号
goto begin;
//---发送器件地址
TWDR=0xa0;//发器件写地址,TWINT位清零,启动发送%%%%%%%%%%%%%%
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)))//等待TWINT置位,TWINT置位表示总线命令SLA+W已发出,及收到应答信号ACK/NACK
;
if((TWSR&0xF8)!=0x18)//检查TWI状态寄存器,如果状态字不是地址ACK,重新发送开始信号
goto begin;
//---发送寄存器地址
TWDR=address_reg1;//写寄存器地址,TWINT位清零,启动发送%%%%%%%%%%%%%%%%%%
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)))//等待TWINT置位,TWINT置位表示总线数据已发出,及收到应答信号ACK/NACK
;
if((TWSR&0xF8)!=0x28)//检查TWI状态寄存器,如果状态字不是数据ACK,重新发送开始信号
goto begin;
//---发送EEPROM的第二个地址
TWDR=address_reg2;//写寄存器地址
TWDR=address_reg2;//%%%%%%%%%%%%%%%
TWCR=_BV(TWEN)|_BV(TWINT);
while(!(TWCR&_BV(TWINT)))//等待TWINT置位,TWINT置位表示总线命令SLA+W已发出,及收到应答信号ACK/NACK
;
if((TWSR&0xF8)!=0x28)//检查TWI状态寄存器,如果状态字不是地址ACK,重新发送开始信号
goto begin;
//---发送起始信号
TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);//发送开始信号
while(!(TWCR&(1<<TWINT)))//等待TWINT置位,TWINT置位表示开始信号发送完毕
;
if(((TWSR&0xF8)!=0x08)&((TWSR&0xF8)!=0x10))//检查TWI状态寄存器,如果状态字不是START或RESTART,重新发送开始信号
goto begin;
//---发送读命令
TWDR=0xa0+1;//读器件地址写入到TWDR寄存器,TWINT位清零,启动发送
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)))//等待TWINT置位,TWINT置位表示总线命令SLA+W已发出,及收到应答信号ACK/NACK
;
if((TWSR&0xF8)!=0x40)//检查TWI状态寄存器,如果状态字不是地址ACK,重新发送开始信号
goto begin;
TWCR=(1<<TWINT)|(1<<TWEN);//发送NACK信号
while(!(TWCR&(1<<TWINT)))
;
if((TWSR&0xF8)!=0x58)
goto begin;
TWCR=(1<<TWSTO)|(1<<TWEN);//发送STOP信号
result1=TWDR;//将TWDR寄存器的数据读入
delay_ms(2,8);
delay_ms(2,8);
delay_ms(2,8);
return result1;
}
//================================================================== void main()
{
int i,jianzhi=0,ms=0,a[11];
for(i=0;i<=10;i++)
{
twi_write(0,i,i+0x32);//写入一串数据
}
for(i=0;i<=10;i++)
{
a[i]=twi_read(0,i);//读出一串数据
}}
专栏文章内容及配图由作者撰写发布,仅供工程师学习之用,如有侵权或者其他违规问题,请联系本站处理。 联系我们
相关推荐
Microchip BZPACK 碳化硅功率模块可应对 HV‑H3TRB 严苛环境
传导式EMI的测量技术
守卫工业设备的底层稳态,隔离电源为何成了必争之地?
[原创]停车场一米长距离读卡器
【工程师笔记】都可以升压,Boost、Buck-Boost、Sepic拓扑怎么选?
二维彩灯控制器
电磁兼容性整改的几种方法
独家拆解 | 英飞凌XENSIV™磁传感器,如何助力机器人规模化落地
折叠屏手机进入“阔型”时代
优化功率转换器的功率密度:顶部散热封装的作用
地线干扰与抑制
生产找我吧!
MSP430 学习套件(十)
NAND报价狂涨:LTA将成为存储器行业主流模式
MSP430 学习套件(八)
MSP430 学习套件(七)
JPR:全球AI处理器开发商已达135家
MSP430 学习套件(九)
[原创]3-5米远距离读卡器
指触式音乐彩灯电路(BH-SK-I)
多色广告灯箱伴乐曲发声电路(二)
《高速数字设计》
HJ94015圣诞树音乐彩灯控制电路
FPGA原型验证与硬件仿真如何成为两大验证流派,又如何走向融合
片上网络(NoC)至关重要:打造下一代AI SoC的核心骨架
WindML的Demo运行问题,有代表性!!!
电容滤波分析案例
多色广告灯箱伴乐曲发声电路(一)
MSP430 学习套件(六)
生产电路板(PCB)