/*****************************************************************************
*
* Atmel Corporation
*
* File : USI_TWI_Master.c
* Compiler : IAR EWAAVR 4.10B
* Revision : $Revision: 1.81 $
* Date : $Date: 18.03.2005 $
* Updated by : $Author: LTWA, KMe $
*
* Support mail : [email protected]
*
* Supported devices : This example is written for the ATmega169
*
* AppNote : AVR310 - Using the USI module as a TWI Master
*
* Description : This is an implementation of an TWI master using
* the USI module as basis. The implementation assumes the AVR to
* be the only TWI master in the system and can therefore not be
* used in a multi-master system.
* Usage : Initialize the USI module by calling the USI_TWI_Master_Initialise()
* function. Hence messages/data are transceived on the bus using
* the USI_TWI_Transceive() function. The transceive function
* returns a status byte, which can be used to evaluate the
* success of the transmission.
*
****************************************************************************/
//#include <inavr.h>
//#include <ioavr.h>
#include "main.h"
#include "USI_TWI_Master.h"
unsigned char USI_TWI_Master_Transfer( unsigned char );
unsigned char USI_TWI_Master_Stop( void );
union USI_TWI_state
{
unsigned char errorState; // Can reuse the TWI_state for error states due to that it will not be need if there exists an error.
struct
{
unsigned char addressMode : 1;
unsigned char masterWriteDataMode : 1;
unsigned char unused : 6;
};
} USI_TWI_state;
//#pragma vector = USI_STRT_vect
//SIGNAL(USI_START_vect)
//{
// USISR |= (1<<USISIF); // ignore start condition
//}
/*---------------------------------------------------------------
USI TWI single master initialization function
---------------------------------------------------------------*/
void USI_TWI_Master_Initialise( void )
{
PORT_USI |= (1<<PIN_USI_SDA); // Enable pullup on SDA, to set high as released state.
DDR_USI |= (1<<PIN_USI_SDA); // Enable SDA as output.
PORT_USI |= (1<<PIN_USI_SCL); // Enable pullup on SCL, to set high as released state.
DDR_USI |= (1<<PIN_USI_SCL); // Enable SCL as output.
USIDR = 0xFF; // Preload dataregister with "released level" data.
USICR = (1<<USISIE)|(0<<USIOIE)| // ENABLE Interrupts.
(1<<USIWM1)|(0<<USIWM0)| // Set USI in Two-wire mode.
(1<<USICS1)|(0<<USICS0)|(1<<USICLK)| // Software stobe as counter clock source
(0<<USITC);
USISR = (1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)| // Clear flags,
(0x0<<USICNT0); // and reset counter.
}
/*---------------------------------------------------------------
Use this function to get hold of the error message from the last transmission
---------------------------------------------------------------*/
unsigned char USI_TWI_Get_State_Info( void )
{
return ( USI_TWI_state.errorState ); // Return error state.
}
/*---------------------------------------------------------------
USI Transmit and receive function. LSB of first byte in data
indicates if a read or write cycles is performed. If set a read
operation is performed.
Function generates (Repeated) Start Condition, sends address and
R/W, Reads/Writes Data, and verifies/sends ACK.
Success or error code is returned. Error codes are defined in
USI_TWI_Master.h
---------------------------------------------------------------*/
unsigned char USI_TWI_Start_Transceiver_With_Data( unsigned char *msg, unsigned char msgSize)
{
unsigned char tempUSISR_8bit = (1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)| // Prepare register value to: Clear flags, and
(0x0<<USICNT0); // set USI to shift 8 bits i.e. count 16 clock edges.
unsigned char tempUSISR_1bit = (1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)| // Prepare register value to: Clear flags, and
(0xE<<USICNT0); // set USI to shift 1 bit i.e. count 2 clock edges.
USI_TWI_state.errorState = 0;
USI_TWI_state.addressMode = TRUE;
#ifdef PARAM_VERIFICATION
if(msg > (unsigned char*)RAMEND) // Test if address is outside SRAM space
{
LCD_Display(1000);
USI_TWI_state.errorState = USI_TWI_DATA_OUT_OF_BOUND;
return (FALSE);
}
if(msgSize <= 1) // Test if the transmission buffer is empty
{
USI_TWI_state.errorState = USI_TWI_NO_DATA;
LCD_Display(2000);
return (FALSE);
}
#endif
#ifdef NOISE_TESTING // Test if any unexpected conditions have arrived prior to this execution.
if( USISR & (1<<USISIF) )
{
USI_TWI_state.errorState = USI_TWI_UE_START_CON;
LCD_Display(1000);
return (FALSE);
}
if( USISR & (1<<USIPF) )
{
USI_TWI_state.errorState = USI_TWI_UE_STOP_CON;
LCD_Display(2000);
return (FALSE);
}
if( USISR & (1<<USIDC) )
{
USI_TWI_state.errorState = USI_TWI_UE_DATA_COL;
LCD_Display(3000);
return (FALSE);
}
#endif
if ( !(*msg & (1<<TWI_READ_BIT)) ) // The LSB in the address byte determines if is a masterRead or masterWrite operation.
{
USI_TWI_state.masterWriteDataMode = TRUE;
}
/* Release SCL to ensure that (repeated) Start can be performed */
PORT_USI |= (1<<PIN_USI_SCL); // Release SCL.
while( !(PORT_USI & (1<<PIN_USI_SCL)) ); // Verify that SCL becomes high.
#ifdef TWI_FAST_MODE
_delay_us( T4_TWI ); // Delay for T4TWI if TWI_FAST_MODE
#else
_delay_us( T2_TWI ); // Delay for T2TWI if TWI_STANDARD_MODE
#endif
/* Generate Start Condition */
PORT_USI &= ~(1<<PIN_USI_SDA); // Force SDA LOW.
_delay_us( T4_TWI );
PORT_USI &= ~(1<<PIN_USI_SCL); // Pull SCL LOW.
PORT_USI |= (1<<PIN_USI_SDA); // Release SDA.
#ifdef SIGNAL_VERIFY
if( !(USISR & (1<<USISIF)) )
{
USI_TWI_state.errorState = USI_TWI_MISSING_START_CON;
return (FALSE);
}
#endif
/*Write address and Read/Write data */
do
{
wdt_reset();
/* If masterWrite cycle (or inital address tranmission)*/
if (USI_TWI_state.addressMode || USI_TWI_state.masterWriteDataMode)
{
//LCD_Display(1000);
/* Write a byte */
PORT_USI &= ~(1<<PIN_USI_SCL); // Pull SCL LOW.
if ( USI_TWI_state.addressMode )USIDR=0x98;
else USIDR=0x0f;
//USIDR = *(msg++); // Setup data.
USI_TWI_Master_Transfer( tempUSISR_8bit ); // Send 8 bits on bus.
/* Clock and verify (N)ACK from slave */
PORT_USI |= (1<<PIN_USI_SDA); // Enable pullup on SDA, to set high as released state.
DDR_USI &= ~(1<<PIN_USI_SDA); // Enable SDA as input.
if( USI_TWI_Master_Transfer( tempUSISR_1bit ) & (1<<TWI_NACK_BIT) )
{
if ( USI_TWI_state.addressMode ) USI_TWI_state.errorState = USI_TWI_NO_ACK_ON_ADDRESS;
else USI_TWI_state.errorState = USI_TWI_NO_ACK_ON_DATA;
return (FALSE);
}
USI_TWI_state.addressMode = FALSE; // Only perform address transmission once.
}
/* Else masterRead cycle*/
else
{
usi.rar_USI avr_avr usi_usi_visual c
版权申诉
103 浏览量
2022-09-24
01:00:14
上传
评论
收藏 5KB RAR 举报
alvarocfc
- 粉丝: 109
- 资源: 1万+
最新资源
- 基于Python和PyTorch框架完成的一个手写数字识别实验源码(带MINIST手写数字数据集)+详细注释(高分项目)
- 基于Matlab在MNIST数据集上利用CNN完成手写体数字识别任务,并实现单层CNN反向传播算法+源代码+文档说明(高分项目)
- NVIDIA驱动、CUDA和Pytorch及其依赖
- html动态爱心代码一(附源码)
- c40539bc-071a-486c-9d52-9d0c18d62dac 4.html
- 基于物理的非视域成像(NLOS)算法,利用了nerf+python源码+文档说明
- yuluer知更鸟.7z(1).001
- python课程设计-基于tensorflow实现的图文生成程序,数据集flickr30k-images+源代码+文档说明+截图
- python作业-基于Flickr30k数据集实现图像文本跨模态搜索python源码+数据集+测试界面+项目说明(高分课程设计)
- 基于Qt实现医院信息管理系统c++源码+文档说明+数据库(期末大作业)
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈