关于硬件I2C的,用的是I2C1

2019-03-24 10:21发布

/*
---------------------------------------------------------------------------------------------------------
*********************************************************************************************************
** 文件名称 : I2CINT.c
** 功能说明 : Luminary硬件I2C中断方式软件包。
** 使用说明 :  主程序要配置好I2C总线接口(I2C引脚功能和I2C中断,并已使能I2C主模式)
*********************************************************************************************************
---------------------------------------------------------------------------------------------------------
*/
#include "hw_ints.h"
#include "hw_memmap.h"
#include "hw_types.h"
#include "hw_i2c.h"
#include "gpio.h"
#include "sysctl.h"
#include "i2c.h"
#include "interrupt.h"
#include "I2CINT.h" #define uchar   unsigned char
#define ulong   unsigned long /*******************************************************************************************
** 中断中的状态
*******************************************************************************************/
#define STATE_IDLE         0     /* 总线空闲状态   */
#define STATE_WRITE_ONE    1     /* 写单个字节状态   */
#define STATE_WRITE_NEXT   2     /* 写下一个字节状态  */
#define STATE_WRITE_FINAL  3     /* 写最后一个字节状态  */
#define STATE_READ_ONE     4     /* 读单个字节状态   */
#define STATE_READ_FIRST   5     /* 读第一个字节状态  */
#define STATE_READ_NEXT    6     /* 读下一个字节状态  */
#define STATE_READ_FINAL   7     /* 读最后一个字节状态  */
#define STATE_READ_WAIT    8     /* 读字节等待状态   */ /*******************************************************************************************
** 全局变量定义
*******************************************************************************************/
static volatile uchar  I2C_sla;    /* I2C器件从地址      */
static volatile ulong I2C_suba;    /* I2C器件内部子地址     */
static volatile uchar  I2C_suba_num;   /* I2C子地址字节数     */
static volatile uchar  *I2C_buf;          /* 数据缓冲区指针       */
static volatile ulong   I2C_num;    /* 要读取/写入的数据个数    */
static volatile uchar   I2C_opt;     /* I2c读写操作,0为读操作,1为写操作 */
static volatile uchar  I2C_state = STATE_IDLE; /* 中断服务程序的当前状态     */
/*
******************************************************************************************
** 函数名称: Delays()
** 函数功能: 延时
** 入口参数: dly
** 出口参数: 无
******************************************************************************************
*/
void Delays (ulong dly)
{
 int i,j;
 for (; dly>0; dly--)
 {
  for (i=0; i<150; i++)
   for (j=0; j<255; j++);
 }
} /*
*********************************************************************************************************
** 函数名称:I2CInit()
** 函数功能:I2C接口初始化。
** 入口参数:spd  总线速度100K(参数值为100000)或400K(参数值为4000000)
**           pri  中断优先级0~7
** 出口参数:返回值为false时表示操作出错,为true时表示操作正确。
** 说明:
*********************************************************************************************************
*/
int I2CInit(ulong spd, uchar pri)
{
 if ((spd == 400000) || (spd == 100000))
 {
     // 使能所使用的外设
     SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);
 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
  
     // 配置相关引脚,以进行I2C操作
     GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_6 | GPIO_PIN_7);      // 初始化I2C主机,设置主机为低速.
     if(spd == 400000)
      I2CMasterInit(I2C1_MASTER_BASE, true);
  else
   I2CMasterInit(I2C1_MASTER_BASE, false);
  
     // 使能处理器中断
     IntMasterEnable();
     
     // 使能I2C中断
     IntEnable(INT_I2C1);      // 使能I2C主机中断
     I2CMasterIntEnable(I2C1_MASTER_BASE);
     
     // 设置I2C中断的优先级
     IntPrioritySet(INT_I2C1, (pri << 5));
   
     return(true);
    }
    else
     return(false);
} /*
*********************************************************************************************************
** 函数名称:ISendByte()
** 函数功能:向无子地址器件发送1字节数据。
** 入口参数:sla  器件地址
**           c   要发送的数据
** 出口参数:返回值为false时表示操作出错,为true时表示操作正确。
** 说明: 使用前要初始化好I2C引脚功能和I2C中断,并已使能I2C主模式
*********************************************************************************************************
*/
int ISendByte(uchar sla, uchar c)
{
 I2C_sla = sla >> 1;
 I2C_buf = &c;
 I2C_state = STATE_WRITE_ONE;
 
 I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, I2C_sla, false);   // 主机写操作
 I2CMasterDataPut(I2C1_MASTER_BASE, *I2C_buf);     // 写一个数据
    I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_SINGLE_SEND); // 启动单次发送
 
 while(I2C_state != STATE_IDLE);
 if(true == I2CMasterBusy(I2C_MASTER_BASE))
  return (false);
 else
  return (true);
} /*
*********************************************************************************************************
** 函数名称 :ISendStr()
** 函数功能 :向有子地址器件任意地址开始写入N字节数据
** 入口参数 : sla   器件从地址
**    suba_type 子地址结构 0-8+X结构  1-单字节地址  2-双字节地址  3-三字节地址
**    suba  器件子地址
**    s   数据发送缓冲区指针
**    no   写入的个数
** 出口参数 : TRUE  操作成功
**    FALSE  操作失败
*********************************************************************************************************
*/
int ISendStr(uchar sla, ulong suba, uchar sub_type, uchar *s, ulong no)
{
 I2C_sla = sla >> 1;
 I2C_buf = s;
 I2C_num = no;
 I2C_suba = suba;
 
 switch(sub_type)
 {
  // 子地址为“8+x”类型
  case 0:
   I2C_sla = I2C_sla | ((suba >> 8) & 0x07);
   I2C_suba_num = 1;
   break; 
  // 子地址为1个字节  
  case 1:
   I2C_suba_num = 1; 
   break;
  // 子地址为2个字节
  case 2:
   I2C_suba_num = 2; 
   break;
  // 子地址为3个字节
  case 3:
   I2C_suba_num = 3; 
   break;
  default: break;
 }
 
 if((no == 1) && (I2C_suba_num == 1))
  I2C_state = STATE_WRITE_FINAL; // 单字节地址或8+x结构地址发送1个字节数据
 else
  I2C_state = STATE_WRITE_NEXT; // 多字节地址或发送多个字节数据 
      
 I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, I2C_sla, false);  // 主机写操作          
    I2C_suba_num--;
    I2CMasterDataPut(I2C1_MASTER_BASE,
        (I2C_suba >> (8 * I2C_suba_num)));   // 写子地址高字节
    I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_START);// 突发写操作启动
   
 while(I2C_state != STATE_IDLE);
 if(true == I2CMasterBusy(I2C1_MASTER_BASE))
  return (false);
 else
  return (true);
} /*
*********************************************************************************************************
** 函数名称:ISendStrExt()
** 函数功能:向无子地址器件发送多字节数据。
** 入口参数:sla  器件地址
**           s   要发送的数据
**     no   发送的字节个数
** 出口参数:返回值为false时表示操作出错,为true时表示操作正确。
** 说明:  发送数据字节至少2个字节
*********************************************************************************************************
*/
int ISendStrExt(uchar sla, uchar *s, uchar no)
{
 I2C_sla = sla >> 1;
 I2C_buf = s;
 I2C_num = no;
 if (no > 1)        // 发送的字节参数过滤
 {
  if(no == 2)
   I2C_state = STATE_WRITE_FINAL;
  else
   I2C_state = STATE_WRITE_NEXT;
 
  I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, I2C_sla, false); // 主机写操作
     I2CMasterDataPut(I2C1_MASTER_BASE, *I2C_buf++);
     I2C_num--;
     I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_START);// 突发写操作启动
       
  while(I2C_state != STATE_IDLE);
  if(true == I2CMasterBusy(I2C1_MASTER_BASE))
   return (false);
  else
   return (true);
 }
 else
  return(false);
} /*
*********************************************************************************************************
** 函数名称:IRcvByte()
** 函数功能:向无子地址器件读取1字节数据。
** 入口参数:sla  器件地址
**           c   接收数据的变量指针
** 出口参数:返回值为false时表示操作出错,为true时表示操作正确。
** 说明: 使用前要初始化好I2C引脚功能和I2C中断,并已使能I2C主模式
*********************************************************************************************************
*/
int IRcvByte(uchar sla, uchar *c)
{
 I2C_sla = sla >> 1;
 I2C_buf = c;
 I2C_state = STATE_READ_WAIT;
 
 I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, I2C_sla, true); // 主机读操作
 I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);// 启动单次读取
 
 while(I2C_state != STATE_IDLE);
 if(true == I2CMasterBusy(I2C1_MASTER_BASE))
  return (false);
 else
  return (true);
} /*
*********************************************************************************************************
** 函数名称 :IRcvStr()
** 函数功能 :向有子地址器件读取N字节数据
** 入口参数 : sla   器件从地址
**    suba_type 子地址结构 0-8+X结构  1-单字节地址  2-双字节地址  3-三字节地址
**      suba  器件内部物理地址
**      *s   将要读取的数据的指针
**      no   将要读取的数据的个数
** 出口参数 : TRUE  操作成功
**      FALSE  操作失败
*********************************************************************************************************
*/
int IRcvStr(uchar sla, ulong suba, uchar sub_type, uchar *s, uchar no)
{
 I2C_sla = sla >> 1;
 I2C_buf = s;
 I2C_num = no;
 I2C_suba = suba;
 I2C_opt = 1;
 
 switch(sub_type)
 {
  // 子地址为“8+x”类型
  case 0:
   I2C_sla = I2C_sla | ((suba >> 8) & 0x07);
   I2C_suba_num = 1;
   break; 
  // 子地址为1个字节  
  case 1:
   I2C_suba_num = 1; 
   break;
  // 子地址为2个字节
  case 2:
   I2C_suba_num = 2; 
   break;
  // 子地址为3个字节
  case 3:
   I2C_suba_num = 3; 
   break;
  default: break;
 }
 
 if(I2C_suba_num == 1)
 {
  if(I2C_num == 1)
   I2C_state = STATE_READ_ONE;
  else
    I2C_state = STATE_READ_FIRST;
 }
 else
  I2C_state = STATE_WRITE_NEXT;
      
 I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, I2C_sla, false);  // 主机写操作          
    I2C_suba_num--;
    I2CMasterDataPut(I2C1_MASTER_BASE,
        (I2C_suba >> (8 * I2C_suba_num)));   // 写子地址高字节
    I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_START);// 突发写操作启动
   
 while(I2C_state != STATE_IDLE);
 if(true == I2CMasterBusy(I2C1_MASTER_BASE))
  return (false);
 else
  return (true);
} /*
此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
6条回答
kzdtdyy
2019-03-24 14:41
 精彩回答 2  元偷偷看……0人看过

一周热门 更多>

相关问题

    相关文章