可直接用于项目开发的TWI/IIC头文件(GCC)

发布者:幸福之星最新更新时间:2019-11-21 来源: 51hei关键字:TWI  IIC头文件  GCC  ATmega16L 手机看文章 扫描二维码
随时随地手机看文章

/*--------------------------文件说明----------------------------------


文件用途 :TWI/I2C驱动,查询方式,主机模式


使用说明 :调用最后6个API应用程序接口函数进行I2C读写


调试说明 :ATmega16L+WinAVR-20090313+AVR studio 4 环境下调试通过。


注意事项 :根据原创者意愿,如用于商业用途请注明文件来源。


--------------------------------------------------------------------*/


#ifndef I2C_H


#define I2C_H


//主机模式启动状态码


#define I2C_START 0x08 //启动总线


#define I2C_RESTART 0x10 //重新启动总线


//主机发送模式状态码


#define I2C_MT_SLA_ACK 0x18 //SLA+W写地址已发送,收到应答位


#define I2C_MT_SLA_NACK 0x20 //SLA+W写地址已发送,收到非应答位


#define I2C_MT_DATA_ACK 0x28 //写入数据已发送,收到应答位


#define I2C_MT_DATA_NACK 0x30 //写入数据已发送,收到应答位


#define I2C_MT_ARB_LOST 0x38 //SLA+W或数据仲裁失败


//主机接收模式状态码


#define I2C_MR_ARB_LOST 0x38 //SLA+R或NOT ACK的仲裁失败


#define I2C_MR_SLA_ACK 0x40 //SLA+R已发送,收到应答位


#define I2C_MR_SLA_NACK 0x48 //SLA+R已发送,收到非应答位


#define I2C_MR_DATA_ACK 0x50 //接收到数据,应答位已返回


#define I2C_MR_DATA_NACK 0x58 //接收到数据,非应答位已返回


//从机接收模式状态码


#define I2C_SR_SLA_ACK 0x60 //自己的SLA+W已经被接收ACK已返回


#define I2C_SR_ARB_LOST_SLA_ACK 0x68 //SLA+R/W作为主机的仲裁失败,自己的SLA+W已经被接收ACK已返回


#define I2C_SR_GCALL_ACK 0x70 //接收到广播地址ACK已返回


#define I2C_SR_ARB_LOST_GCALL_ACK 0x78 //SLA+R/W作为主机的仲裁失败,接收到广播地址ACK已返回


#define I2C_SR_DATA_ACK 0x80 //以前以自己的SLA+W被寻址,数据已经被接收ACK已返回


#define I2C_SR_DATA_NACK 0x88 //以前以自己的SLA+W被寻址,数据已经被接收NOT ACK已返回


#define I2C_SR_GCALL_DATA_ACK 0x90 //以前以广播方式被寻址,数据已经被接收ACK已返回


#define I2C_SR_GCALL_DATA_NACK 0x98 //以前以广播方式被寻址,数据已经被接收NOT ACK已返回


#define I2C_SR_STOP 0xA0 //在以从机工作时接收到STOP或重复START


//从机发送模式状态码


#define I2C_ST_SLA_ACK 0xA8 //自己的SLA+R已经被接收ACK已返回


#define I2C_ST_ARB_LOST_SLA_ACK 0xB0 //SLA+R/W作为主机的仲裁失败,自己的SLA+R已经被接收ACK已返回


#define I2C_ST_DATA_ACK 0xB8 //TWDR里数据已经被发送接收到ACK


#define I2C_ST_DATA_NACK 0xC0 //TWDR里数据已经被发送接收到NOT ACK


#define I2C_ST_LAST_DATA 0xC8 //TWDR的一字节数据已经发送(TWAE='0'),接收到ACK


//其他状态码


#define I2C_NO_INFO 0xF8 //没有相关的状态信息,TWINT='0'


#define I2C_BUS_ERROR 0x00 //由于非法的START或STOP引起的总线错误


//定义SLA中读写控制位极性


#define I2C_READ 1


#define I2C_WRITE 0


#define I2CStart() (TWCR=(1<

#define I2CStop() (TWCR=(1<

#define I2C_STATUS (TWSR  0xf8)


#define I2CSendAck() (TWCR|=(1<

#define I2CSendNoAck() (TWCR=~(1<

#define I2CRcvNckByte() (TWCR=(1<

#define I2CRcvAckByte() (TWCR=(1<

//定义运行状态返回值极性


#define I2C_ERR 0 //错误


#define I2C_CRR 1 //正确


//定义TWINT位置位查询等待时间


#define WAITCOUNT 60 //3.6864M时,此处必须大于60,验证得知小于60,程序均不能正常工作


/*--------------------------------------------------------------------


函数名称:I2C_Init


函数功能:TWI初始化


注意事项:(须根据具体情况设置)


提示说明:


输 入:


返 回:


--------------------------------------------------------------------*/


void I2C_Init(void)


{


TWBR=0x0f; //波特率设置,必须大于 10


TWSR=0; //状态寄存器初始化


//TWAR= //从机地址和通用呼叫设置,多CPU时使用


}


/*--------------------------------------------------------------------


函数名称:I2C_WaitINT


函数功能:等待TWINT位置位


注意事项:需定义 WAITCOUNT


提示说明:


输 入:


返 回:运行状况 I2C_ERR :错误 I2C_CRR :正确


--------------------------------------------------------------------*/


unsigned char I2C_WaitINT(void) 


{


unsigned int i=WAITCOUNT;


while(!(TWCR(1<

{if((--i)==0) return I2C_ERR;}


return I2C_CRR;


}


/*--------------------------------------------------------------------


函数名称:I2C_SendByte


函数功能:发送一字节数据


注意事项:


提示说明:


输 入:待发送数据


返 回:运行状况 I2C_ERR :错误 I2C_CRR :正确


--------------------------------------------------------------------*/


void I2C_SendByte(unsigned char x)


{


TWDR=(x);


TWCR=(1<

}


/*--------------------------------------------------------------------


函数名称:I2C Start


函数功能:发出起始信号


注意事项:


提示说明:


输 入:


返 回:运行状况 I2C_ERR :错误 I2C_CRR :正确


--------------------------------------------------------------------*/


unsigned char I2C_Start(void) 


{


I2CStart(); //发出起始信号


if(!I2C_WaitINT()) return I2C_ERR; //等待启动完成


if( I2C_STATUS!=I2C_START ) //检查是否启动成功


return I2C_ERR; //启动失败,返回0


return I2C_CRR; //启动成功,返回1


}


/*--------------------------------------------------------------------


函数名称:I2C ReStart


函数功能:发出重复起始信号


注意事项:


提示说明:


输 入:


返 回:运行状况 I2C_ERR :错误 I2C_CRR :正确


--------------------------------------------------------------------*/


unsigned char I2C_Restart(void) 


{


I2CStart(); 


if(!I2C_WaitINT()) return I2C_ERR;


if( I2C_STATUS!=I2C_RESTART ) //检查是否重复启动成功


return I2C_ERR;


return I2C_CRR;


}


/*--------------------------------------------------------------------


函数名称:I2C_SendWrDAdr


函数功能:发送 7位 器件写地址: XXXX XXX0


注意事项:


提示说明:


输 入:写地址


返 回:运行状况 I2C_ERR :错误 I2C_CRR :正确


--------------------------------------------------------------------*/


unsigned char I2C_SendWrDAdr(unsigned char wrDAdr) 


{


I2C_SendByte(wrDAdr); //设置器件写地址


if(!I2C_WaitINT()) return I2C_ERR;


if( I2C_STATUS!=I2C_MT_SLA_ACK ) 


return I2C_ERR;


return I2C_CRR; 


}


/*--------------------------------------------------------------------


函数名称:I2C_SendWrDAdr_


函数功能:发送 10位 器件写地址: 1111 0XX0, XXXX XXXX


注意事项:


提示说明:兼容 发送 7位 器件写地址: XXXX XXX0


输 入:


返 回:运行状况 I2C_ERR :错误 I2C_CRR :正确


--------------------------------------------------------------------*/


unsigned char I2C_SendWrDAdr_(unsigned int wrDAdr) 


{


if( (wrDAdr0xF000) == 0xF000 ) //判断是否为 10位 器件地址


if( I2C_SendWrDAdr((unsigned char )wrDAdr>>8)==I2C_ERR ) //设置(高位)器件写地址


return I2C_ERR;


if( I2C_SendWrDAdr( (unsigned char)wrDAdr )==I2C_ERR ) //设置 (低位)器件写地址


return I2C_ERR;


return I2C_CRR;


}


/*--------------------------------------------------------------------


函数名称:I2C_SendRdDAdr


函数功能:发送7位器件读地址: XXXX XXX1


注意事项:


提示说明:


输 入:读地址


返 回:运行状况 I2C_ERR :错误 I2C_CRR :正确


--------------------------------------------------------------------*/


unsigned char I2C_SendRdDAdr(unsigned char rdDAdr) 


{


I2C_SendByte(rdDAdr); //设置器件读地址


if(!I2C_WaitINT()) return I2C_ERR;


if( I2C_STATUS!=I2C_MR_SLA_ACK ) 


return I2C_ERR;


return I2C_CRR; 


}


/*--------------------------------------------------------------------


函数名称:I2C_SendRdDAdr_


函数功能:发送 10位 器件读地址: 1111 0XX0, XXXX XXXX


注意事项:


提示说明:兼容 发送 7位 器件读地址: XXXX XXX1


输 入:


返 回:运行状况 I2C_ERR :错误 I2C_CRR :正确


--------------------------------------------------------------------*/


unsigned char I2C_SendRdDAdr_(unsigned char rdDAdr) 


{


if( (rdDAdr0xF000) == 0xF000 ) //判断是否为 10位 器件地址


if( I2C_SendWrDAdr( (unsigned char)rdDAdr>>8 )==I2C_ERR ) //设置 (高位)器件读地址


return I2C_ERR;


if( I2C_SendWrDAdr( (unsigned char)rdDAdr )==I2C_ERR ) //设置 (低位)器件读地址


return I2C_ERR;


return I2C_CRR;


}


/*--------------------------------------------------------------------


函数名称:I2C_SendDat


函数功能:I2C发送数据


注意事项:


提示说明:


输 入:待发送的字节数据


返 回:运行状况 I2C_ERR :错误 I2C_CRR :正确


--------------------------------------------------------------------*/


unsigned char I2C_SendDat(unsigned char data) 


{


I2C_SendByte(data); 


if(!I2C_WaitINT()) return I2C_ERR;


if( I2C_STATUS!=I2C_MT_DATA_ACK ) 


return I2C_ERR;


return I2C_CRR; 


}


/*--------------------------------------------------------------------


函数名称:I2C_RcvNAckDat


函数功能:I2C接收数据且不产生应答


注意事项:


提示说明:


输 入:接收数据存储空间指针


返 回:运行状况 I2C_ERR :错误 I2C_CRR :正确


--------------------------------------------------------------------*/


unsigned char I2C_RcvNAckDat(unsigned char *pRdDat) 


{


I2CRcvNckByte();


if(!I2C_WaitINT()) return I2C_ERR;


if( I2C_STATUS!=I2C_MR_DATA_NACK )


return I2C_ERR;


*pRdDat=TWDR;


return I2C_CRR;


}


/*--------------------------------------------------------------------


函数名称:I2C_RcvAckDat


函数功能:I2C接收数据且产生应答


注意事项:


提示说明:


输 入:接收数据存储空间指针


返 回:运行状况 I2C_ERR :错误 I2C_CRR :正确


--------------------------------------------------------------------*/


unsigned char I2C_RcvAckDat(unsigned char *pRdDat) 


{


I2CRcvAckByte(); 


if(!I2C_WaitINT()) return I2C_ERR;


if( I2C_STATUS!=I2C_MR_DATA_ACK )


return I2C_ERR;


*pRdDat=TWDR;


return I2C_CRR;


}


/*以下是API函数*/


//(Application Program Interface 应用程序接口)


/*--------------------------------------------------------------------


函数名称:I2C_Write(unsigned int wrDAdr,unsigned char wordAdr,unsigned char dat)


函数功能:I2C写器件,写一个字节


注意事项:


提示说明:


输 入:wrDAdr : write device-address 写器件地址


wordAdr: word address 从地址


dat: data 数据


返 回:运行状况 I2C_ERR :错误 I2C_CRR :正确


--------------------------------------------------------------------*/


unsigned char I2C_Write(unsigned int wrDAdr,unsigned char wordAdr,unsigned char dat)


{


if( I2C_Start()==I2C_ERR )


return I2C_ERR;


//wrDAdr =0xfffe;


if( I2C_SendWrDAdr_((wrDAdr0xfffe)|I2C_WRITE)==I2C_ERR )//保证写控制位正确


return I2C_ERR;


if( I2C_SendDat(wordAdr)==I2C_ERR )//从地址当作一般数据发送


return I2C_ERR;


if( I2C_SendDat(dat)==I2C_ERR )


return I2C_ERR;


I2CStop();


return I2C_CRR;


}


/*--------------------------------------------------------------------


函数名称:I2C_Write_


函数功能:I2C写器件,写N个数据


注意事项:


提示说明:


输 入:wrDAdr : write device-address 写器件地址


wordAdr: word address 从地址


*pWrDat: p->write data 写入数据的指针


num : number 写入数据个数


返 回:运行状况 I2C_ERR :错误 I2C_CRR :正确


--------------------------------------------------------------------*/


unsigned char I2C_Write_(unsigned int wrDAdr,unsigned char wordAdr,


unsigned char *pWrDat,unsigned char num)


{


unsigned char i;


if( I2C_Start()==I2C_ERR )


return I2C_ERR;


//wrDAdr =0xfffe;


if( I2C_SendWrDAdr_((wrDAdr0xfffe)|I2C_WRITE)==I2C_ERR )//保证写控制位正确


return I2C_ERR;


if( I2C_SendDat(wordAdr)==I2C_ERR )//从地址当作一般数据发送


return I2C_ERR;


for(i=0;i

if( I2C_SendDat(*(pWrDat++))==I2C_ERR )


return I2C_ERR;


I2CStop();


return I2C_CRR;



/*--------------------------------------------------------------------


函数名称:I2C_Read


函数功能:I2C读器件,读一个数据


注意事项:


提示说明:


输 入:rdDAdr : read device-address 读器件地址


wordAdr: word address 从地址


*pRdDat: p->read data 读取数据指针


返 回:运行状况 I2C_ERR :错误 I2C_CRR :正确


--------------------------------------------------------------------*/


unsigned char I2C_Read(unsigned int rdDAdr,unsigned char wordAdr,unsigned char *pRdDat)


{


if( I2C_Start()==I2C_ERR )


return I2C_ERR;


//rdDAdr =0xfffe;


if( I2C_SendWrDAdr_((rdDAdr0xfffe)|I2C_WRITE)==I2C_ERR )//保证写控制位正确


return I2C_ERR;


if( I2C_SendDat(wordAdr)==I2C_ERR )//从地址当作一般数据发送。


return I2C_ERR;


if( I2C_Restart()==I2C_ERR )//重启动


return I2C_ERR;


//rdDAdr =0xfffe;


if( I2C_SendRdDAdr((rdDAdr0xfffe)|I2C_READ)==I2C_ERR )//保证读控制位正确


return I2C_ERR;


if( I2C_RcvNAckDat(pRdDat)==I2C_ERR )//接收数据


return I2C_ERR;


I2CStop();


return I2C_CRR;


}


/*--------------------------------------------------------------------


函数名称:I2C_Read_


函数功能:I2C读器件,读N个数据


注意事项:


提示说明:


输 入:rdDAdr : read device-address 读器件地址


wordAdr: word address 字地址


*pRdDat: p->read data 读取数据指针


num : number 读取数据个数


返 回:运行状况 I2C_ERR :错误 I2C_CRR :正确

[1] [2]
关键字:TWI  IIC头文件  GCC  ATmega16L 引用地址:可直接用于项目开发的TWI/IIC头文件(GCC)

上一篇:M128 PWM程序
下一篇:ATmega128 time1溢出中断。定时器1在该模式下用法和51的一样

推荐阅读最新更新时间:2024-11-07 11:12

ATmega16L-----外部中断0,1中断嵌套
/***************************************   取自周兴华《AVR单片机C语言高级程序设计》   进入INT1中断的时候,再开启全局中断,   这时候INT0中断触发,可以形成中断嵌套 ***************************************/   #include iom16v.h   #include macros.h   #define uchar unsigned char   #define uint unsigned int   uint shu;   /***************************************   delay   ***
[单片机]
从源码编译安装msp430-gcc 4.7.2
背景 遇到的问题 最近在做关于Contiki操作系统在TelosB节点上的一些实验,但是在编译一些Contiki样例的时候遇到了 .text 和 .rodata 段出现重合无法成功编译的情况,查阅资料显示需要更新Instant Contiki中自带的msp430-gcc来解决这个问题。 本文将我的操作过程做一个记录,希望对读者有所帮助。 硬软件环境 Instant Contiki3.0(Ubuntu 14.04LTS) 1. 安装编译安装必需的应用 sudo apt-get install patch ncurses-dev build-essential bison flex libgmp3-dev libmpfr-de
[单片机]
单工无线呼叫及数据传输系统的设计
  本文基于ATMEGA16L单片机实现一个具有单工语音和数据传输功能的无线呼叫系统。通过编码电路、单片调频发射电路和高频功放电路实现主站的语音及数据发送;通过解码电路、调频解调和语音功放电路实现从站的语音及数据接收。编码和解码用MSK调制方式的调制解调芯片MSM6882实现;主从机的显示电路采用LCD液晶显示,输入电路则采用PS2键盘扫描。   一、概述   目前,无线语音和数据通信的应用领域不断扩大,应用形式也趋于多样化。如移动通信系统、智能交通系统、远程控制网络等。本设计完成了一个单工无线呼叫系统,实现主站至多个从站的单工语音及数据传输业务。主站传送一路语音信号或短信,其发射频率为36MHz,发射峰值功率可调,实现小功率
[单片机]
单工无线呼叫及数据传输系统的设计
STM32高级开发(12)-在GCC中使用printf打印串口数据
在大家使用keil或是iar开发stm32等arm芯片的时候,想来最不陌生的就是使用print通过串口输出一些数据,用来调试或是其他作用。但是要明确的是由于keil iar gcc 他们使用的标准C语言库虽然都遵循一个标准,但他们底层的函数实现方式都是不同的,那么在GCC中我们能否像在keil中一样重映射print的输出流到串口上呢?答案是肯定的。 keil中的重映射方式及原理 /* * libc_printf.c * * Created on: Dec 26, 2015 * Author: Yang * * 使用标准C库时,重映射printf等输出函数的文件 * 添加在工程内即可生效(切勿选择semi
[单片机]
基于ATmega16L的便携设备电源系统设计
随着科技的进步,便携设备应用日益普遍,这些设备给我们的工作和生活带来越来越多的便利,同时,其对内部的电源系统提出更高的要求。便携设备一般需要满足市电和蓄电池两种供电方式,完成蓄电池的充放电控制和电池剩余电量的估算;需要与嵌入式主板进行开关机交互和数据交互;需要具备体积小、重量轻、效率高等特点。虽然针对笔记本和手机产品有成熟的电源方案,但是一般仅适用于小功率的场合,对于专业的便携设备缺乏适应性。 在上述背景下,急需设计一款较大功率,具备以上功能特点的电源系统,从而满足一般便携设备对电源的需求。 1 电源系统总体设计 本系统以微控制器为检测和控制的核心,包括适配器、电池组、电池充放电模块、DC/DC变换等功能模块。系统的总
[单片机]
基于<font color='red'>ATmega16L</font>的便携设备电源系统设计
arm gcc交叉编译工具链建立
1.1. Arm交叉编译工具链 下载地址Gnu.org binutils-2.21.1.tar.bz2 gcc-4.4.4.tar.bz2 glibc-2.11.2.tar.bz2 Glibc-ports-2.11.tar.bz2 Gmp-4.2.tar.bz2 Mpfr-2.4.0.tar.bz2 1.1.1. 建立工作目录 创建工具链文件夹: # mkdirembedded-toolchains 在建立了顶层文件夹embedded-toolchains,下面在此文件夹下建立如下几个目录: setup-dir,存放下载的压缩包; src-dir,存放binutils、gc
[单片机]
ATmega16L-定时器应用于数码管
/**************************************** 扫描数码管,数据口接PA 段码接PC7 位码接PC6 稳定显示01234567 ****************************************/ #include iom16v.h #include macros.h unsigned int i; const unsigned char duanma ={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved