1) source codes for ATmega128 UART
UARTM128.H
/* Prototypes */
void InitUART0( unsigned char baudrateL,unsigned char baudrateH );
unsigned char ReceiveByte0( void );
void TransmitByte0( unsigned char data );
void InitUART1( unsigned char baudrateL,unsigned char baudrateH );
unsigned char ReceiveByte1( void );
void TransmitByte1( unsigned char data );
...
UARTM128.C
/* Code adapted from Atmel AVR Application Note AVR306
* Interrupt mode driver for UART.
*/
#include < span>h>
#include < span>h>
#include "uartM128.h"
/* IMPORTANT: these vector numbers are for 8515! If you use other devices
* you must change them to the different set of numbers.
*
* UART_RX_interrupt set to UART, Rx Complete
* UART_TX_interrupt set to UART Data Register Empty
*/
#pragma interrupt_handler UART0_RX_interrupt:iv_USART0_RX UART0_TX_interrupt:iv_USART0_TX
#pragma interrupt_handler UART1_RX_interrupt:iv_USART1_RX UART1_TX_interrupt:iv_USART1_TX
/* UART Buffer Defines */
#define UART0_RX_BUFFER_SIZE 128 /* 1,2,4,8,16,32,64,128 or 256 bytes */
#define UART0_RX_BUFFER_MASK ( UART0_RX_BUFFER_SIZE - 1 )
#define UART0_TX_BUFFER_SIZE 128 /* 1,2,4,8,16,32,64,128 or 256 bytes */
#define UART0_TX_BUFFER_MASK ( UART0_TX_BUFFER_SIZE - 1 )
#define UART1_RX_BUFFER_SIZE 128 /* 1,2,4,8,16,32,64,128 or 256 bytes */
#define UART1_RX_BUFFER_MASK ( UART1_RX_BUFFER_SIZE - 1 )
#define UART1_TX_BUFFER_SIZE 128 /* 1,2,4,8,16,32,64,128 or 256 bytes */
#define UART1_TX_BUFFER_MASK ( UART1_TX_BUFFER_SIZE - 1 )
#if ( UART0_RX_BUFFER_SIZE & UART0_RX_BUFFER_MASK )
#error RX0 buffer size is not a power of 2
#endif
#if ( UART1_RX_BUFFER_SIZE & UART1_RX_BUFFER_MASK )
#error RX1 buffer size is not a power of 2
#endif
/* Static Variables */
static unsigned char UART0_RxBuf[UART0_RX_BUFFER_SIZE];
static volatile unsigned char UART0_RxHead;
static volatile unsigned char UART0_RxTail;
static unsigned char UART0_TxBuf[UART0_TX_BUFFER_SIZE];
static volatile unsigned char UART0_TxHead;
static volatile unsigned char UART0_TxTail;
static unsigned char UART1_RxBuf[UART1_RX_BUFFER_SIZE];
static volatile unsigned char UART1_RxHead;
static volatile unsigned char UART1_RxTail;
static unsigned char UART1_TxBuf[UART1_TX_BUFFER_SIZE];
static volatile unsigned char UART1_TxHead;
static volatile unsigned char UART1_TxTail;
/* initialize UART */
void InitUART0( unsigned char baudrateL,unsigned char baudrateH )
{
unsigned char x;
UBRR0H = baudrateH;
UBRR0L = baudrateL; /* set the baud rate */
/* enable UART receiver and transmitter, and
receive interrupt */
UCSR0B = ( (1<<RXCIE0) | (1<EN0) | (1< /* flush receive buffer */
UART0_RxTail = x;
UART0_RxHead = x;
UART0_TxTail = x;
UART0_TxHead = x;
}
void InitUART1( unsigned char baudrateL,unsigned char baudrateH )
{ unsigned char x;
UBRR1H = baudrateH;
UBRR1H = baudrateL;
UCSR1B = ( (1< (1< = x;
UART1_RxHead = x;
UART1_TxTail = x;
UART1_TxHead = x;
}
/* interrupt handlers */
void UART0_RX_interrupt( void )
{
unsigned char data;
unsigned char tmphead;
data = UDR0; /* read the received data */
/* calculate buffer index */
tmphead = ( UART0_RxHead + 1 ) & UART0_RX_BUFFER_MASK;
UART0_RxHead = tmphead; /* store new index */
if ( tmphead == UART0_RxTail )
{
/* ERROR! Receive buffer overflow */
}
UART0_RxBuf[tmphead] = data; /* store received data in buffer */
}
void UART0_TX_interrupt( void )
{
unsigned char tmptail;
/* check if all data is transmitted */
if ( UART0_TxHead != UART0_TxTail )
{
/* calculate buffer index */
tmptail = ( UART0_TxTail + 1 ) & UART0_TX_BUFFER_MASK;
UART0_TxTail = tmptail; /* store new index */
UDR0 = UART0_TxBuf[tmptail]; /* start transmition */
}
else
{
UCSR0B &= ~(1<<UDRIE0); /* disable UDRE interrupt */
}
}
/* Read and write functions */
unsigned char ReceiveByte0( void )
{
unsigned char tmptail;
while ( UART0_RxHead == UART0_RxTail ) /* wait for incomming data */
;
tmptail = ( UART0_RxTail + 1 ) & UART0_RX_BUFFER_MASK;/* calculate buffer index */
UART0_RxTail = tmptail; /* store new index */
return UART0_RxBuf[tmptail]; /* return data */
}
void TransmitByte0( unsigned char data )
{
unsigned char tmphead;
/* calculate buffer index */
tmphead = ( UART0_TxHead + 1 ) & UART0_TX_BUFFER_MASK;
/* wait for free space in buffer */
while ( tmphead == UART0_TxTail )
;
UART0_TxBuf[tmphead] = data; /* store data in buffer */
UART0_TxHead = tmphead; /* store new index */
UCSR0B |= (1< }
unsigned char DataInReceiveBuffer0( void )
{
return ( UART0_RxHead != UART0_RxTail );
/* return 0 (FALSE) if the receive buffer is empty */
}
/* interrupt handlers1*/
void UART1_RX_interrupt( void )
{
unsigned char data;
unsigned char tmphead;
data = UDR1; /* read the received data */
/* calculate buffer index */
tmphead = ( UART1_RxHead + 1 ) & UART1_RX_BUFFER_MASK;
UART1_RxHead = tmphead; /* store new index */
if ( tmphead == UART1_RxTail )
{
/* ERROR! Receive buffer overflow */
}
UART1_RxBuf[tmphead] = data; /* store received data in buffer */
}
void UART1_TX_interrupt( void )
{
unsigned char tmptail;
/* check if all data is transmitted */
if ( UART1_TxHead != UART1_TxTail )
{
/* calculate buffer index */
tmptail = ( UART1_TxTail + 1 ) & UART1_TX_BUFFER_MASK;
UART1_TxTail = tmptail; /* store new index */
UDR1 = UART1_TxBuf[tmptail]; /* start transmition */
}
else
{
UCSR1B &= ~(1< terrupt */
}
}
/* Read and write functions */
unsigned char ReceiveByte1( void ) {
unsigned char tmptail;
while ( UART1_RxHead == UART1_RxTail ) /* wait for incomming data */
;
tmptail = ( UART1_RxTail + 1 ) & UART1_RX_BUFFER_MASK;/* calculate buffer index */
UART1_RxTail = tmptail; /* store new index */
return UART1_RxBuf[tmptail]; /* return data */ }
void TransmitByte1( unsigned char data )
{
unsigned char tmphead;
/* calculate buffer index */
tmphead = ( UART1_TxHead + 1 ) & UART1_TX_BUFFER_MASK;
/* wait for free space in buffer */
while ( tmphead == UART1_TxTail )
;
UART0_TxBuf[tmphead] = data; /* store data in buffer */
UART1_TxHead = tmphead; /* store new index */
UCSR1B |= (1< enable UDRE interrupt */
}
unsigned char DataInReceiveBuffer1( void )
{
return ( UART1_RxHead != UART1_RxTail );
/* return 0 (FALSE) if the receive buffer is empty */
}
/* main - a simple test program*/
void main( void )
{
InitUART0( 51,0 ); /*set the baudrate to 9600 bps using a 4MHz crystal*/
InitUART1( 51,0 );
_SEI(); /* enable interrupts => enable UART interrupts */
while ( 1 ) /* forever */
{
/*echo the received character*/
TransmitByte0( ReceiveByte0() );
/* echo the received character */
TransmitByte0( ReceiveByte0() );
}
}
...
2)source codes for ATmega128 SPI
SPI.h
/*
** Header file : spi.h
*/
#if defined(_AVR)
/* SPI header for AVR */
#ifndef __SPI__H
#define __SPI__H
/*
** Constants for SpiInit()
*/
#define SPI_DATA_ORDER_MSB_FIRST 0x00
#define SPI_DATA_ORDER_LSB_FIRST 0x40
#define SPI_CLOCK_POLARITY 0x08
#define SPI_CLOCK_PHASE 0x04
#define SPI_CLOCK_RATE_DIV4 0x00
#define SPI_CLOCK_RATE_DIV16 0x01
#define SPI_CLOCK_RATE_DIV64 0x02
#define SPI_CLOCK_RATE_DIV128 0x03
void SpiInit(unsigned char);
void SpiWriteByte(unsigned char);
unsigned char SpiReadByte(void);
unsigned char SpiReadDataReg(void);
#endif
/*
** End of Header file
*/
#endif
SPI.c
/*
** Purpose: SPI init, read & write routines without interrupt.
** These routines works only as an SPI Master.
**
** Version: 1.0.0, 29:th of July 1999
**
** Author: Lars Wictorsson
** LAWICEL / SWEDEN
** http://www.lawicel.com lars@lawicel.com**
** History: 1999-07-29 Created
*/
#include
#include "spi.h"
/*
** SpiInit() initializes the SPI as a master, enable it
** and set it up as requested by parameter Controlregister.
** See "spi.h" for availible parameter values, they could
** be ORed together. See AVR SPI documentation for more
** detailed information.
*/
void SpiInit(unsigned char ControlRegister)
{
DDRB |= 0xB0; // Set SCK, MOSI & SS as outputs
PORTB &= 0x5F; // clear bits MOSI, & SCK
SPCR = ControlRegister + SPE + MSTR; // Write to control register.
}
/*
** SpiWriteByte() writes a byte to the SPI and waits until
** it has been transmitted. This function doesn't
** return any value back.
*/
void SpiWriteByte(unsigned char byte)
{
SPDR = byte;
while (!(SPSR & 0x80));
byte = SPDR;
}
/*
** SpiReadByte() first writes a byte (a dummy, since
** that byte is to generate clock signals to "poll" home** the byte from the slave. The function returns the
** received byte.
*/
unsigned char SpiReadByte(void)
{
SPDR = 0x00;
while (!(SPSR & 0x80));
return SPDR;
}
/*
** SpiReadDataReg() reads the last byte in the SPI register
** without any clock signals generated. Could be used
** as reading the last byte received.
*/
unsigned char SpiReadDataReg(void)
{
return SPDR;
}
...
3)source codes for ATmega128 I2C
I2C.h
// *************** I2C driver V 1.0 ***************
// *** Written By P. Fletcher-Jones ***
// *** Written on 06/6/01 ***
// *** Last MOD 15/11/01 ***
// *** Compiled using ImageCraft C Comiler ***
// *******************************************************
// ****************************** //
// *** I2C Hardware Interface *** //
// ****************************** //
#define SDA BIT1
#define SCL BIT0
#define I2C_PORT PORTD
#define I2C_DIR DDRD
#define I2C_IN PIND
void Init_I2C(void);
void I2C_Start (void);
void I2C_Stop (void);
void I2C_Clock (void);
unsigned char I2C_Ackn(void);
void Write_I2C_Control (unsigned char,unsigned char,unsigned char);
void Write_I2C_Byte(unsigned char);
unsigned char Read_I2C_Byte(void);
...
I2C.C
// *************** I2C driver Demo V 1.0 *************
// *** Written By P. Fletcher-Jones ***
// *** Written on 16/11/01 ***
// *** Last MOD 21/11/01 ***
// *******************************************************
// *************** I2C driver V 1.0 ***************
// *** Written By P. Fletcher-Jones ***
// *** Written on 16/11/01 ***
// *** Last MOD 21/11/01 ***
// *** Compiled using ImageCraft C Comiler ***
// *******************************************************
#include
#include < span>>
#include
#include "I2C.h"
// ******************************************** //
// *** This routine will setup the I2C Port *** //
// ******************************************** //
void Init_I2C(void)
{
SETBIT(I2C_DIR,SCL); // Set SCL to output
SETBIT(I2C_DIR,SDA ); // Set SDA to output
SETBIT(I2C_PORT,SCL); // Set SCL high
SETBIT(I2C_PORT,SDA ); // Set SDA high
}
// ************************************************ //
// *** This routine will send the I2C Start Bit *** //
// ************************************************ //
void I2C_Start (void)
{
SETBIT(I2C_PORT,SCL); // Set SCL High
SETBIT(I2C_PORT,SDA); // Set SDA High
SETBIT(I2C_DIR,SDA); // Set SDA to output
CLEARBIT(I2C_PORT,SDA); // Clear SDA
}
// *********************************************** //
// *** This routine will send the I2C Stop Bit *** //
// *********************************************** //
void I2C_Stop (void)
{
SETBIT(I2C_DIR,SDA); // Set SDA to output
CLEARBIT(I2C_PORT,SDA); // Clear SDA
CLEARBIT(I2C_PORT,SCL); // Clear SCL
SETBIT(I2C_PORT,SCL); // Set SCL High
SETBIT(I2C_PORT,SDA); // Set SDA High
}
// ************************************************** //
// *** This routine will send the I2C clock pulse *** //// ************************************************** //
void I2C_Clock (void)
{
SETBIT(I2C_PORT,SCL); // Set SCL high
NOP(); // Small Delay
CLEARBIT(I2C_PORT,SCL); // Set SCL low
}
// ******************************************************** //
// *** This routine will write a byte to the I2C device *** //
// ******************************************************** //
void Write_I2C_Byte(unsigned char byte)
{
unsigned char i;
SETBIT(I2C_DIR,SDA); // Set SDA to output
CLEARBIT(I2C_PORT,SCL);
for (i = 0; i < 8; i++){ // Loop for our 8 bits
// Set or Clear SDA pin
if((byte & 0x80) == 0x80) SETBIT(I2C_PORT, SDA); // Set I2C SDA PIN
else CLEARBIT(I2C_PORT,SDA); // Clear I2C SDA PIN
SETBIT(I2C_PORT,SCL); // Set SCL High, Clock data
byte = byte << 1; // Shift data in buffer right one
CLEARBIT(I2C_PORT,SCL); // Clear SCL
}
while(I2C_Ackn() ); // Check for acknowledge from I2C device }
// ********************************************************* //
// *** This routine will read a byte from the I2C device *** //
// ********************************************************* //
unsigned char Read_I2C_Byte(void)
{
unsigned char i,buff = 0;
for (i = 0; i < 8; i++){
buff = buff << 1;
CLEARBIT(I2C_DIR,SDA); // Set SDA to input
SETBIT(I2C_PORT,SCL); // Set SCL High,Clock bit out
// Read data on SDA pin
if ( CHECKBIT( I2C_IN,SDA ) ) buff = buff | 0x01;
CLEARBIT(I2C_PORT,SCL); // Clear SCL
}
// *** No ACK *** //
I2C_Clock(); // Clock I2C bit
return buff; // Return our I2C byte
}
// *********************************************************************** //
// *** This routine returns a 0 if the I2C device sends an acknowledge *** //
// *********************************************************************** //
unsigned char I2C_Ackn(void)
{
unsigned char Ackn = 0; // Temp RAM for Ackn flag
CLEARBIT(I2C_PORT,SCL);
CLEARBIT(I2C_DIR,SDA); // Set SDA to input
SETBIT(I2C_PORT,SCL); // Clock the ACK bit
if ( CHECKBIT( I2C_IN,SDA ) ) Ackn = 1; // Check the ACK bit on SDA
CLEARBIT(I2C_PORT,SCL); // Clear the clock
return Ackn; // Return our ACK bit
}
// ***************************************************** //
// *** This routine will write the I2C device code, *** //
// *** set the device chip select bits, *** //
// *** and set or clear the I2C R/W bit *** //
// ***************************************************** //
void Write_I2C_Control(unsigned char D_Code,unsigned char H_ADD,unsigned char RW)
{
// *** Send the I2C device Control code *** //
CLEARBIT(I2C_PORT,SCL); // Clear SCL clock
if( (D_Code & 0x08) == 0x08) SETBIT(I2C_PORT, SDA); // Set I2C SDA PIN
else CLEARBIT(I2C_PORT,SDA); // Clear I2C SDA PIN
I2C_Clock(); // Clock I2C bit
if( (D_Code & 0x04) == 0x04) SETBIT(I2C_PORT, SDA); // Set I2C SDA PIN
else CLEARBIT(I2C_PORT,SDA); // Clear I2C SDA PIN
I2C_Clock(); // Clock I2C bit
if( (D_Code & 0x02) == 0x02) SETBIT(I2C_PORT, SDA); // Set I2C SDA PIN
else CLEARBIT(I2C_PORT,SDA); // Clear I2C SDA PIN
I2C_Clock(); // Clock I2C bit
if( (D_Code & 0x01) == 0x01) SETBIT(I2C_PORT, SDA); // Set I2C SDA PIN
else CLEARBIT(I2C_PORT,SDA); // Clear I2C SDA PIN
I2C_Clock(); // Clock I2C bit
// *** Send the I2C Control byte chip selects bits *** //
if( (H_ADD & 0x04) == 0x04) SETBIT(I2C_PORT, SDA); // Set I2C SDA PIN
else CLEARBIT(I2C_PORT,SDA); // Clear I2C SDA PIN
I2C_Clock(); // Clock I2C bit
if( (H_ADD & 0x02) == 0x02) SETBIT(I2C_PORT, SDA); // Set I2C SDA PIN
else CLEARBIT(I2C_PORT,SDA); // Clear I2C SDA PIN
I2C_Clock(); // Clock I2C bit
if( (H_ADD & 0x01) == 0x01) SETBIT(I2C_PORT, SDA); // Set I2C SDA PIN
else CLEARBIT(I2C_PORT,SDA); // Clear I2C SDA PIN
I2C_Clock(); // Clock I2C bit
// *** Set or Clear the read / write bit for I2C control *** //
if(RW) SETBIT(I2C_PORT,SDA); // Set I2C SDA PIN
else CLEARBIT(I2C_PORT,SDA); // Clear I2C SDA PIN
I2C_Clock(); // Clock I2C bit
while(I2C_Ackn() ); // Check for acknowledge from I2C device
}
void EEPROM_Write(unsigned char, unsigned char, unsigned char);
unsigned char EEPROM_Read(unsigned char, unsigned char);
// **************************************************************** //
// *** Init_I2C(); *** //
// *** This routine will setup the I2C port direction registers *** //
// **************************************************************** //
// ***************************************************************** //// *** I2C_Start(); *** //
// *** This routine will set the I2C start condition on the bus, *** //
// *** All commands must be preceded by a START condition *** //
// ***************************************************************** //
// ***************************************************************** //
// *** I2C_Stop(); *** //
// *** This routine will set the I2C stop condition on the bus, *** //
// *** All commands must end with a STOP condition *** //
// ***************************************************************** //
// *********************************************************************** //
// *** Write_I2C_Control(0x0A,0,0); *** //
// *** This routine will write the I2C device code, the device address *** //
// *** setup on the hardware pins A0,A1 & A2, and also the W/R bit *** //
// *** So for an external EEPROM, such as the 24LC04B you would need *** //
// *** a device code of 1010 (0x0A), *** //
// *** hardware address 0 (if pins A0,A1 & A2 are left unconnected, *** //
// *** and the last parameter is R/W. Write is active low *** //
// *********************************************************************** //
// *********************************************************************** //
// *** I2C_Ackn(); *** //
// *** This routine will clock the ACK bit from the I2C slave device *** //
// *** it will return TRUE for a fail, and FALSE for a correct ACK bit *** //
// *********************************************************************** //
// ************************************************************** //// *** Write_I2C_Byte(); *** //
// *** This routine will clock a byte to the slave I2C device *** //
// ************************************************************** //
// ************************************************************************** //
// *** Read_I2C_Byte(); *** //
// *** This routine will read and return a byte from the I2C slave device *** //
// ************************************************************************** //
// *********************************************************************** //
// *** Example of using Imagecraft I2C driver *** //
// *** to write to an external 8 bit address EEPROM *** //
// *** H_ADD is the hardware address set on the device A0,A1 & A2 pins *** //
// *** M_ADD is the devices internal memory address *** //
// *** Data is user data to be writen *** //
// *********************************************************************** //
void EEPROM_Write(unsigned char H_ADD, unsigned char M_ADD, unsigned char Data)
{
I2C_Start(); // Set I2C start condition
Write_I2C_Control(0x0A,H_ADD,0); // Send the EEPROM control Byte
Write_I2C_Byte(M_ADD); // Send the EEPROM internal Address
Write_I2C_Byte(Data); // Send the EEPROM Data
I2C_Stop(); // Set I2C Stop condition
}
// *********************************************************************** //
// *** Example of using Imagecraft I2C driver *** //
// *** to Read an external 8 bit address EEPROM *** //
// *** H_ADD is the hardware address set on the device A0,A1 & A2 pins *** //
// *** M_ADD is the devices internal memory address *** //
// *** Data is user data to be writen *** //
// *********************************************************************** //
unsigned char EEPROM_Read(unsigned char H_ADD, unsigned char M_ADD)
{
unsigned char Temp; // Temp RAM for EEPROM Read
I2C_Start(); // Set I2C start condition
Write_I2C_Control(0x0A,H_ADD,0); // Send the EEPROM control Byte
// Dummy write to set address
Write_I2C_Byte(M_ADD); // Send the EEPROM internal Address
I2C_Start(); // Set I2C start condition
Write_I2C_Control(0x0A,H_ADD,1); // Send the EEPROM control Byte
Temp = Read_I2C_Byte(); // Read data from EEPROM
I2C_Stop(); // Set I2C Stop condition
return Temp; // Return data from EEPROM
}
void main (void)
{
unsigned long c; // Temp Ram used for write delay
DDRB = 0xFF; // Set Port B to Outputs
Init_I2C(); // Setup the hardware port
EEPROM_Write(0xa2,1,0xAA); // Write to device 0, memory address 1, Data 0xAA
for(c=0;c<1000;c++); // Delay for EEPROM Write
PORTB = EEPROM_Read(0xa3,1); // Read device 0, memory address 1
} ...
http://www.codeforge.com/read/183736/I2C.h__html
CodeForge.com
Free Open Source Codes Forge and Sharing
http://www.codeforge.com/
沒有留言:
張貼留言
注意:只有此網誌的成員可以留言。