⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 twi.c

📁 一个通过串口与51通信的AVR的程序,还有一些其实功能
💻 C
字号:
#include <header.h>
#include <TWI.h>

unsigned char TWI_sen_dat[10];
unsigned char TWI_rev_dat[10];
unsigned char TWI_com_addr;
unsigned char TWI_set_len;
unsigned char TWI_send_len;
unsigned char TWI_rev_len;
unsigned char TWI_sended=0;
unsigned char TWI_reved=0;
unsigned char TWI_sending_str=0;

void TWI_int()
{
TWBR=0x00;	//比特率寄存器SCLfre=CPUCLK/(16+2*TWBR*4E(TWPS)),与ADS1100用2
TWSR=0x00;	//Bits1.0-TWPS:TWI预分频位1,4,16,64
//TWDR=0x00;	//TWI数据寄存器,在第一次中断发生之前用户不能够初始化数据寄存器。1读
TWAR=0x02;	//TWI(从机)地址寄存器,Bit0–TWGCE: 使能TWI广播识别
TWCR=(1<<TWEA)|(1<<TWEN);	//控制寄存器
/*
TWINT中断标志(清零必须通过软件写"1"来完成,只要这一位被清零,TWI立即开始工作。)
TWEA使能应答,
TWSTA: START状态标志(成为总线上的主机,发送START之后软件必须清零TWSTA),
TWSTO: STOP状态标志(在主机模式下,在总线上产生STOP状态,自动清零。在从机模式下,置位TWSTO 可以使接口从错误状态恢复到未被寻址的状态.),
TWWC: TWI写碰撞标志
TWEN: TWI使能
TWIE: 使能TWI中断
*/
}

void TWI_close()
{
TWCR=0;
}

void TWI_my_addr(unsigned char addr)
{
TWAR=addr;	//TWI(从机)地址寄存器,Bit0–TWGCE: 使能TWI广播识别
}

void TWI_set(unsigned char status_sel,unsigned char speed_sel)
{
if(status_sel<2)TWCR|=(1<<TWSTA);
else TWCR|=(1<<TWSTO);
TWSR=(TWSR&0xfc)|(speed_sel&0x03);	//Bits1.0-TWPS:TWI预分频位1,4,16,64
}

void TWI_send_dat(unsigned char *dat,unsigned char lng) //发送数据
{
memcpy(TWI_sen_dat, dat, lng);
TWI_send_len=lng;
}

void TWI_inr()
{
switch(TWSR&0xf8)
	{
	case 0x00://由于非法的START或STOP引起的总线错误
		break;
	case 0x08://start已发送
		if(TWI_sending_str){TWCR&=(~(1<<TWSTA));TWI_sending_str=0;return;}
		TWI_sended=0;
		TWDR=TWI_com_addr;
		TWCR=(TWCR|(1<<TWINT)|(1<<TWEN))&~(1<<TWSTA);
		break;
	case 0x10://重复start已发送
		TWI_sended=0;
		TWDR=TWI_com_addr;
		TWCR=(TWCR|(1<<TWINT)|(1<<TWEN))&~(1<<TWSTA);
		break;
	case 0x18://SLA+W已发送,接收到ACK
		if(TWI_sended<TWI_send_len)
			{
			TWDR=TWI_sen_dat[TWI_sended++];
			TWCR|=(1<<TWINT)|(1<<TWEN);
			}
		else
			{
			TWCR|=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
			TWI_sended=1;
			}
		break;
	case 0x20://SLA+W已发送,接收到NOT ACK
		TWCR|=(1<<TWINT)|(1<<TWEN)|(1<<TWSTA);
		break;
	case 0x28://数据已发送,接收到ACK
		if(TWI_sended<TWI_send_len)
			{
			TWDR=TWI_sen_dat[TWI_sended++];
			TWCR|=(1<<TWINT)|(1<<TWEN);
			}
		else
			{
			TWCR|=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
			TWI_sended=1;
			}
		break;
	case 0x30://数据已发送,接收到NOT ACK
		TWCR|=(1<<TWINT)|(1<<TWEN)|(1<<TWSTA);
		break;
	case 0x38://SLA或数据的仲裁失败
		TWCR|=(1<<TWINT)|(1<<TWEN)|(1<<TWSTA);
		break;
	case 0x40://SLA+R已发送,接收到ACK
		if(TWI_reved<TWI_rev_len)
			{
			TWDR=TWI_rev_dat[TWI_reved++];
			TWCR|=(1<<TWINT)|(1<<TWEN);
			}
		else
			{
			TWCR|=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
			TWI_reved=1;
			}
		break;
	case 0x48://SLA+R已发送,接收到NOT ACK
		TWCR|=(1<<TWINT)|(1<<TWEN)|(1<<TWSTA);
		break;
	case 0x50://接收到数据,ACK已返回
		if(TWI_reved<TWI_rev_len)
			{
			TWDR=TWI_rev_dat[TWI_reved++];
			TWCR|=(1<<TWINT)|(1<<TWEN);
			}
		else
			{
			TWCR|=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
			TWI_reved=1;
			}
		break;
	case 0x58://接收到数据,NOT ACK已返回
		TWCR|=(1<<TWINT)|(1<<TWEN)|(1<<TWSTA);
		break;
	case 0x60://自己的SLA+W已经被接收ACK已返回
	case 0x68://SLA+R/W作为主机的仲裁失败;自己的SLA+W已经被接收ACK已返回
	case 0x70://接收到广播地址ACK已返回
	case 0x78://SLA+R/W作为主机的仲裁失败;接收到广播地址ACK 已返回
	case 0x80://以前以自己的SLA+W被寻址;数据已经被接收ACK已返回
	case 0x88://以前以自己的SLA+W被寻址;数据已经被接收NOT ACK已返回
	case 0x90://以前以广播方式被寻址;数据已经被接收ACK已返回
	case 0x98://以前以广播方式被寻址;数据已经被接收NOT ACK已返回
	case 0xA0://在以从机工作时接收到STOP或重复START
	case 0xA8://自己的SLA+R 已经被接收ACK已返回
	case 0xB0://SLA+R/W作为主机的仲裁失败;自己的SLA+R已经被接收ACK已返回
	case 0xB8://TWDR里数据已经发送接收到ACK
	case 0xC0://TWDR里数据已经发送接收到NOT ACK
	case 0xC8://TWDR的一字节数据已经发送(TWAE="0");接收到ACK
	case 0xF0://没有相关的状态信息;TWINT="0"
	default:;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -