📄 twi_slave_drv.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 + -