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

📄 twi_slave_drv.c

📁 at90can128底层驱动 有SPI,TWI,总线,CAN接口等
💻 C
字号:
/*头文件*/
#include "twi_slave_drv.h"

/*全局变量定义*/
uchar       twi_busy;	//=FALSE,TWI通讯空闲;=TRUE,TWI通讯忙
uchar       twi_err;	//TWI通讯状态
uchar       twi_recptr;	//TWI数据字节数

uchar 		Sdisbuf[3];//显示缓存区
uchar		Skeybuf[4];//键值缓存区

/*****************************************************************************
函数介绍:TWI初始化,设置从机地址和启动通讯
输入参数:
输出参数:
返回值:无
*****************************************************************************/
void twi_lib_init(void)
{
  Twi_set_address(0x42);		//设置从机地址0x21
  //Twi_set_address(0x44);		//设置从机地址0x22
  
  Twi_init_hw(TWI_CONFIG);		//salve TWEA=1,TwEN=1
}


/*****************************************************************************
函数介绍:在从机或主机模式下,TWI信息的收发的主流程状态。
此函数在TWI通讯事件发生时,对各个状态进行解码,查询和中断方式都可以。
输入参数:
输出参数:
返回值:无
*****************************************************************************/
void twi_decode_status()
{
switch ( Twi_get_status() ) // switch (SSTA)
    {
    //  STATE 00h: Bus Error has occurred
    //  ACTION:    Enter not addressed SLV mode and release bus
    case  0x00 :
    twi_busy = FALSE;
    twi_err  = TWI_BUS_ERROR;
    break;

    //STATE 60h:   Own SLA+W has been received,ACK returned
    //ACTION:      Read DATA. return ACK
    case 0x60 :
    Twi_set_aa();
    twi_busy = TRUE;
    twi_recptr=0;
    break;

    //STATE 68h:   Arbitration lost in SLA and R/W as MASTER. Own SLA + W has been received. ACK returned
    //ACTION:      Read DATA. return ACK ;re-start MASTER,
    case 0x68 :
    Twi_set_start();
    break;

    //STATE 70h:   General call received, ACK returned
    //ACTION:      Receive DATA. return ACK
    case 0x70 :
    Twi_set_aa();
    twi_busy = TRUE;
    break;

    //STATE 78h:   Arbitration lost in SLA+R/W as MASTER. General call has arrived ack returned
    //ACTION:      Receive DATA. return ACK. Restart master
    case 0x78 :
    Twi_set_start();
    twi_busy = TRUE;
    break;

    //STATE 80h:   Previously addressed with own SLA. Data received and ACK returned
    //ACTION:      Read DATA.
    case 0x80 :
    Sdisbuf[twi_recptr] = Twi_get_data();
    twi_recptr ++;
    if ( twi_recptr < TWI_NB_SLAVE_DATA ) Twi_set_aa();  // ACK will be returned
    else
    {
      Twi_clear_aa(); // it was last data not ACK will be returned ( buffer full )
      Twi_clear_si();
    }
    break;

    //STATE 88h:   Previously addressed with own SLA. Data received and NOT ACK returned
    //ACTION:      Dont' Read DATA. Enter NOT addressed SLV mode
    case 0x88 :
    //STATE 98h:   Previously addressed with general call. Data arrved and NOT ACK returned
    //ACTION:      Dont Read DATA. Enter NOT addressed SLV mode
    case 0x98 :
    Twi_set_aa();  // ready to send another ACK if addresed as slave
    break;

    //STATE 90h:   Previously addressed with general call. Data received and ACK returned
    //ACTION:      Read DATA.
    case 0x90 :
    Sdisbuf[twi_recptr] = Twi_get_data();
    twi_recptr = twi_recptr + 1;
    Twi_clear_si();
    break;

    //STATE A0h:   A stop or repeated start has arrived, whilst still addressed as SLV/REC or SLV/TRX
    //ACTION:      Dont Read DATA. Enter NOT addressed SLV mode
    case 0xA0 :
    Twi_set_aa();
    twi_busy = FALSE;
    twi_err = TWI_RECEIVE_OK;
    break;

    //STATE A8h:   addressed with own SLA+R
    //ACTION:      Prepare first data to be transmited
    case 0xA8 :

    twi_busy = TRUE;
    twi_recptr=0;
    Twi_set_data(Skeybuf[0]); // Prepare next data
    Twi_set_aa();
    break;


    //STATE B8h:   Previously addressed with own SLA. Data sent
    //             and ACK returned
    //ACTION:      Write DATA.
    case 0xB8 :
    twi_recptr++;
    if ( twi_recptr < TWI_NB_SLAVE_DATA ) Twi_set_data(Skeybuf[twi_recptr]);
    else ///////// FIX ME : addressed with as slave + R : but not enought data"
         Twi_clear_aa(); // it was last data not ACK will be returned ( buffer full )
    Twi_clear_si();
    break;


    //STATE C0h:   Previously addressed with own SLA. Data sent and NACK returned
    //ACTION:      It was last data to be sent
    case 0xC0 :
    twi_busy=FALSE;
    twi_err  = TWI_TRANSFER_OK;
    Twi_clear_si();
    break;


    //if we arrived here, unknown state has occurred.....
    default :
    Twi_set_stop();
    twi_busy = FALSE;
    twi_err  = TWI_UNKNOWN;
    break;
    }
}


/*****************************************************************************
函数介绍:TWI从机模式,查询方式
输入参数:
输出参数:
返回值:twi_err:TWI通讯状态
 - TWI_TRANSFER_OK		发送完成
 - TWI_RECEIVE_OK		接收完成
 - TWI_BUS_ERROR		总线冲突
 - TWI_HOST_ADR_NACK	从机地址无应答
 - TWI_HOST_DATA_NACK	从机数据无应答(不存在)
 - TWI_ARBITRATION_LOST	仲裁失败
 - TWI_UNKNOWN			TWI状态错误	
 - TWI_NOT_FREE			TWI通信忙
 - TWI_OK				TWI通信开始
*****************************************************************************/
uchar twi_slave_polling(void)
{
  Twi_wait_event();
  twi_decode_status();
  Twi_clear_si();
  while (twi_busy)
  {
    Twi_wait_event();
    twi_decode_status();
    Twi_clear_si();//REMOVE FROM MAIN LOOP, ADDED IN ALL NECESARY CASE (See JSB /RLE)
  }
  return twi_err;
}

/*****************************************************************************
函数介绍:TWI从机模式,中断方式
输入参数:
输出参数:
返回值:twi_err:TWI通讯状态
 - TWI_TRANSFER_OK		发送完成
 - TWI_RECEIVE_OK		接收完成
 - TWI_BUS_ERROR		总线冲突
 - TWI_HOST_ADR_NACK	从机地址无应答
 - TWI_HOST_DATA_NACK	从机数据无应答(不存在)
 - TWI_ARBITRATION_LOST	仲裁失败
 - TWI_UNKNOWN			TWI状态错误	
 - TWI_NOT_FREE			TWI通信忙
 - TWI_OK				TWI通信开始
*****************************************************************************/
void twi_slave_interrupt(void)
{
  //Enable_interrupt();
  Enable_twi_interrupt();
}


/*****************************************************************************
函数介绍:TWI中断例程
输入参数:
输出参数:
返回值:无
*****************************************************************************/
//#pragma vector = TWI_vect
//__interrupt void twi_interrupt()
#pragma interrupt_handler twi_interrupt:18
void twi_interrupt()
{
  twi_decode_status();
//  Twi_clear_si(); //REMOVE FROM MAIN LOOP, ADDED IN ALL NECESARY CASE (See JSB /RLE)
}

/*void main (void)
{	
  twi_busy = FALSE;
  twi_lib_init();

  //twi_slave_polling();
while(1)
	if(!twi_busy)
  		twi_slave_interrupt();

  while(1);
}*/

	

⌨️ 快捷键说明

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