Showing posts with label Atmega 32. Show all posts
Showing posts with label Atmega 32. Show all posts

Monday, 29 December 2014

How to set a Simple Timer with Atmega

This program is to show how to write a simple timer in atmel to make your own delay function using the timer.

The basic registers which we will use:

 1.   TCNTx : load the timer values

                  Timer 0 and Timer 2  >>  TCNT0/TCNT2  >>   8 bit timers hence  can store 00 to FF.

                  Timer 1 >>  TCNT1L, TCNT1H  >>  0000 to FFFF.

2. TCCRX : Timer / Counter Control Register



                 This controls the way in which timer will function.
                 Here our aim is to make a simple delay function so we will focus in last three bits only and set the                      remaining bits to 0

                These are the clock select bits which decides the frequency that will be used to run the timer.

                Now suppose you select a prescaler of 64. If the crystal frequency is 16Mhz, then the frequency of timer will become 16/64 = 0.25 Mhz.

                hence the TCNTx register will increment 2,50,000 times in a second or say once every 4 micro seconds.

NOTE : if the last 3 bits are 000, that means there is no clock source and the timer wont run..
This way you can turn off the timer.
 ANd when TCNTx again becomes zero, TIFR register comes into picture:

3. TIFR : Timer Interrupt Flag register



The bits of this register are the flags whose values will change when the TCNTx register overflows.

The flags are by default  zero and when overflow occurs, they are set. This flag has to cleared and to clear the flag, we have to write "1" to it!! 

Note : Each timer has its own ISR(Interrupt Service Routine). When overflow occurs, interrupt occurs and the code inside ISR will be executed.

Our code here is very simple..
 >> Set the value in TCTN0 register
>> Set the prescaler in TCCR0.
>> Wait till the Overflow occurs.

Waiting is not timers are meant for..

But this makes clear the basic functions of various registers.

Run it in proteus, and you can see the LED blinking.



Get the codes from here:






Saturday, 8 March 2014

Simple Program to see whether Termite / Hyper terminal is workin or not

/* download the two files "uart.c" and "uart.h" from the blog and include it in the same folder where your file is saved*/

#include<avr/io.h>
#include "uart.h"
#include "uart.c"
#include <avr/interrupt.h>
#include<util/delay.h>
 void main()
 {
 uart_init(UART_BAUD_SELECT(9600,F_CPU)); // Syntax to select baud rate.

 while(1)
 {
  uart_puts("Termite Working!!");
  uart_puts("\n");
  uart_puts("\r");
  _delay_ms(1000);

 }
}

/* You need to install 1) Prolific Driver to attach serial cable with PC  2) Termite or 2) Hyper terminal to view data on the computer screen.*/

/*In case you are not able to download them, kindly comment here*/

"uart.c" file for serial data transfer using Atmega16/32

<pre class="brush: csharp">

/*----------------------------------------------------------------
-----------------HEADER FILES-------------------------------------
-----------------------------------------------------------------*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include "uart.h"

/*----------------------------------------------------------------
-----------------constants and macros-----------------------------
-----------------------------------------------------------------*/
/* size of RX/TX buffers */
#define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1)
#define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1)
#if ( UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK )
#error RX buffer size is not a power of 2
#endif
#if ( UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK )
#error TX buffer size is not a power of 2
#endif
#if defined(__AVR_AT90S2313__) \
 || defined(__AVR_AT90S4414__) || defined(__AVR_AT90S4434__) \
 || defined(__AVR_AT90S8515__) || defined(__AVR_AT90S8535__) \
 || defined(__AVR_ATmega103__)
 /* old AVR classic or ATmega103 with one UART */
 #define AT90_UART
 #define UART0_RECEIVE_INTERRUPT   SIG_UART_RECV
 #define UART0_TRANSMIT_INTERRUPT  SIG_UART_DATA
 #define UART0_STATUS   USR
 #define UART0_CONTROL  UCR
 #define UART0_DATA     UDR 
 #define UART0_UDRIE    UDRIE
#elif defined(__AVR_AT90S2333__) || defined(__AVR_AT90S4433__)
 /* old AVR classic with one UART */
 #define AT90_UART
 #define UART0_RECEIVE_INTERRUPT   SIG_UART_RECV
 #define UART0_TRANSMIT_INTERRUPT  SIG_UART_DATA
 #define UART0_STATUS   UCSRA
 #define UART0_CONTROL  UCSRB
 #define UART0_DATA     UDR
 #define UART0_UDRIE    UDRIE
#elif  defined(__AVR_ATmega8__)  || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \
  || defined(__AVR_ATmega8515__) || defined(__AVR_ATmega8535__) \
  || defined(__AVR_ATmega323__)
  /* ATmega with one USART */
 #define ATMEGA_USART
 #define UART0_RECEIVE_INTERRUPT   SIG_UART_RECV
 #define UART0_TRANSMIT_INTERRUPT  SIG_UART_DATA
 #define UART0_STATUS   UCSRA
 #define UART0_CONTROL  UCSRB
 #define UART0_DATA     UDR
 #define UART0_UDRIE    UDRIE
#elif defined(__AVR_ATmega163__)
  /* ATmega163 with one UART */
 #define ATMEGA_UART
 #define UART0_RECEIVE_INTERRUPT   SIG_UART_RECV
 #define UART0_TRANSMIT_INTERRUPT  SIG_UART_DATA
 #define UART0_STATUS   UCSRA
 #define UART0_CONTROL  UCSRB
 #define UART0_DATA     UDR
 #define UART0_UDRIE    UDRIE
#elif defined(__AVR_ATmega162__)
 /* ATmega with two USART */
 #define ATMEGA_USART0
 #define ATMEGA_USART1
 #define UART0_RECEIVE_INTERRUPT   SIG_USART0_RECV
 #define UART1_RECEIVE_INTERRUPT   SIG_USART1_RECV
 #define UART0_TRANSMIT_INTERRUPT  SIG_USART0_DATA
 #define UART1_TRANSMIT_INTERRUPT  SIG_USART1_DATA
 #define UART0_STATUS   UCSR0A
 #define UART0_CONTROL  UCSR0B
 #define UART0_DATA     UDR0
 #define UART0_UDRIE    UDRIE0
 #define UART1_STATUS   UCSR1A
 #define UART1_CONTROL  UCSR1B
 #define UART1_DATA     UDR1
 #define UART1_UDRIE    UDRIE1
#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__)
 /* ATmega with two USART */
 #define ATMEGA_USART0
 #define ATMEGA_USART1
 #define UART0_RECEIVE_INTERRUPT   SIG_UART0_RECV
 #define UART1_RECEIVE_INTERRUPT   SIG_UART1_RECV
 #define UART0_TRANSMIT_INTERRUPT  SIG_UART0_DATA
 #define UART1_TRANSMIT_INTERRUPT  SIG_UART1_DATA
 #define UART0_STATUS   UCSR0A
 #define UART0_CONTROL  UCSR0B
 #define UART0_DATA     UDR0
 #define UART0_UDRIE    UDRIE0
 #define UART1_STATUS   UCSR1A
 #define UART1_CONTROL  UCSR1B
 #define UART1_DATA     UDR1
 #define UART1_UDRIE    UDRIE1
#elif defined(__AVR_ATmega161__)
 /* ATmega with UART */
 #error "AVR ATmega161 currently not supported by this libaray !"
#elif defined(__AVR_ATmega169__)
 /* ATmega with one USART */
 #define ATMEGA_USART
 #define UART0_RECEIVE_INTERRUPT   SIG_USART_RECV
 #define UART0_TRANSMIT_INTERRUPT  SIG_USART_DATA
 #define UART0_STATUS   UCSRA
 #define UART0_CONTROL  UCSRB
 #define UART0_DATA     UDR
 #define UART0_UDRIE    UDRIE
#elif defined(__AVR_ATmega48__) ||defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__)
 #define ATMEGA_USART0
 #define UART0_RECEIVE_INTERRUPT   SIG_USART_RECV
 #define UART0_TRANSMIT_INTERRUPT  SIG_USART_DATA
 #define UART0_STATUS   UCSR0A
 #define UART0_CONTROL  UCSR0B
 #define UART0_DATA     UDR0
 #define UART0_UDRIE    UDRIE0
#elif defined(__AVR_ATtiny2313__)
 #define ATMEGA_USART
 #define UART0_RECEIVE_INTERRUPT   SIG_USART0_RX
 #define UART0_TRANSMIT_INTERRUPT  SIG_USART0_UDRE
 #define UART0_STATUS   UCSRA
 #define UART0_CONTROL  UCSRB
 #define UART0_DATA     UDR
 #define UART0_UDRIE    UDRIE
#else
 #error "no UART definition for MCU available"
#endif

/*
 *  module global variables
 */
static volatile unsigned char UART_TxBuf[UART_TX_BUFFER_SIZE];
static volatile unsigned char UART_RxBuf[UART_RX_BUFFER_SIZE];
static volatile unsigned char UART_TxHead;
static volatile unsigned char UART_TxTail;
static volatile unsigned char UART_RxHead;
static volatile unsigned char UART_RxTail;
static volatile unsigned char UART_LastRxError;
#if defined( ATMEGA_USART1 )
static volatile unsigned char UART1_TxBuf[UART_TX_BUFFER_SIZE];
static volatile unsigned char UART1_RxBuf[UART_RX_BUFFER_SIZE];
static volatile unsigned char UART1_TxHead;
static volatile unsigned char UART1_TxTail;
static volatile unsigned char UART1_RxHead;
static volatile unsigned char UART1_RxTail;
static volatile unsigned char UART1_LastRxError;
#endif

SIGNAL(UART0_RECEIVE_INTERRUPT)
/*************************************************************************
Function: UART Receive Complete interrupt
Purpose:  called when the UART has received a character
**************************************************************************/
{
    unsigned char tmphead;
    unsigned char data;
    unsigned char usr;
    unsigned char lastRxError;


    /* read UART status register and UART data register */
    usr  = UART0_STATUS;
    data = UART0_DATA;
   
    /* */
#if defined( AT90_UART )
    lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
#elif defined( ATMEGA_USART )
    lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
#elif defined( ATMEGA_USART0 )
    lastRxError = (usr & (_BV(FE0)|_BV(DOR0)) );
#elif defined ( ATMEGA_UART )
    lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
#endif
       
    /* calculate buffer index */
    tmphead = ( UART_RxHead + 1) & UART_RX_BUFFER_MASK;
   
    if ( tmphead == UART_RxTail ) {
        /* error: receive buffer overflow */
        lastRxError = UART_BUFFER_OVERFLOW >> 8;
    }else{
        /* store new index */
        UART_RxHead = tmphead;
        /* store received data in buffer */
        UART_RxBuf[tmphead] = data;
    }
    UART_LastRxError = lastRxError;  
}

SIGNAL(UART0_TRANSMIT_INTERRUPT)
/*************************************************************************
Function: UART Data Register Empty interrupt
Purpose:  called when the UART is ready to transmit the next byte
**************************************************************************/
{
    unsigned char tmptail;
   
    if ( UART_TxHead != UART_TxTail) {
        /* calculate and store new buffer index */
        tmptail = (UART_TxTail + 1) & UART_TX_BUFFER_MASK;
        UART_TxTail = tmptail;
        /* get one byte from buffer and write it to UART */
        UART0_DATA = UART_TxBuf[tmptail];  /* start transmission */
    }else{
        /* tx buffer empty, disable UDRE interrupt */
        UART0_CONTROL &= ~_BV(UART0_UDRIE);
    }
}

//Try to clear the already buffered data
void clearBuffer(){

 UART_RxHead = 0;
    UART_RxTail = 0;
}
/*************************************************************************
Function: uart_init()
Purpose:  initialize UART and set baudrate
Input:    baudrate using macro UART_BAUD_SELECT()
Returns:  none
**************************************************************************/
void uart_init(unsigned int baudrate)
{
    UART_TxHead = 0;
    UART_TxTail = 0;
    UART_RxHead = 0;
    UART_RxTail = 0;
   
#if defined( AT90_UART )
    /* set baud rate */
    UBRR = (unsigned char)baudrate;
    /* enable UART receiver and transmmitter and receive complete interrupt */
    UART0_CONTROL = _BV(RXCIE)|_BV(RXEN)|_BV(TXEN);
#elif defined (ATMEGA_USART)
    /* Set baud rate */
    if ( baudrate & 0x8000 )
    {
      UART0_STATUS = (1<<U2X);  //Enable 2x speed
      baudrate &= ~0x8000;
    }
    UBRRH = (unsigned char)(baudrate>>8);
    UBRRL = (unsigned char) baudrate;
  
    /* Enable USART receiver and transmitter and receive complete interrupt */
    UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
   
    /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
    #ifdef URSEL
    UCSRC = (1<<URSEL)|(3<<UCSZ0);
    #else
    UCSRC = (3<<UCSZ0);
    #endif
   
#elif defined (ATMEGA_USART0 )
    /* Set baud rate */
    if ( baudrate & 0x8000 )
    {
     UART0_STATUS = (1<<U2X0);  //Enable 2x speed
     baudrate &= ~0x8000;
    }
    UBRR0H = (unsigned char)(baudrate>>8);
    UBRR0L = (unsigned char) baudrate;
    /* Enable USART receiver and transmitter and receive complete interrupt */
    UART0_CONTROL = _BV(RXCIE0)|(1<<RXEN0)|(1<<TXEN0);
   
    /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
    #ifdef URSEL0
    UCSR0C = (1<<URSEL0)|(3<<UCSZ00);
    #else
    UCSR0C = (3<<UCSZ00);
    #endif
#elif defined ( ATMEGA_UART )
    /* set baud rate */
    if ( baudrate & 0x8000 )
    {
     UART0_STATUS = (1<<U2X);  //Enable 2x speed
     baudrate &= ~0x8000;
    }
    UBRRHI = (unsigned char)(baudrate>>8);
    UBRR   = (unsigned char) baudrate;
    /* Enable UART receiver and transmitter and receive complete interrupt */
    UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
#endif
}/* uart_init */

/*************************************************************************
Function: uart_getc()
Purpose:  return byte from ringbuffer 
Returns:  lower byte:  received byte from ringbuffer
          higher byte: last receive error
**************************************************************************/
unsigned int uart_getc(void)
{   
    unsigned char tmptail;
    unsigned char data;

    if ( UART_RxHead == UART_RxTail ) {
        return UART_NO_DATA;   /* no data available */
    }
   
    /* calculate /store buffer index */
    tmptail = (UART_RxTail + 1) & UART_RX_BUFFER_MASK;
    UART_RxTail = tmptail;
   
    /* get data from receive buffer */
    data = UART_RxBuf[tmptail];
   
    return (UART_LastRxError << 8) + data;
}/* uart_getc */

void transmitByte( unsigned char data )
{
 while ( !(UCSRA & (1<<UDRE)) )
  ;                    /* Wait for empty transmit buffer */
 UDR = data;            /* Start transmition */
}
/*************************************************************************
Function: uart_putc()
Purpose:  write byte to ringbuffer for transmitting via UART
Input:    byte to be transmitted
Returns:  none         
**************************************************************************/
void uart_putc(unsigned char data)
{
    /*unsigned char tmphead;
   
    tmphead  = (UART_TxHead + 1) & UART_TX_BUFFER_MASK;
   
    while ( tmphead == UART_TxTail ){
        ;/* wait for free space in buffer */
   /* }
   
    UART_TxBuf[tmphead] = data;
    UART_TxHead = tmphead;
    /* enable UDRE interrupt */
    /*UART0_CONTROL    |= _BV(UART0_UDRIE);*/

 transmitByte(data);
}/* uart_putc */

/*************************************************************************
Function: uart_puts()
Purpose:  transmit string to UART
Input:    string to be transmitted
Returns:  none         
**************************************************************************/
void uart_puts(const char *s )
{
    while (*s)
      uart_putc(*s++);
}/* uart_puts */

/*************************************************************************
Function: uart_puts_p()
Purpose:  transmit string from program memory to UART
Input:    program memory string to be transmitted
Returns:  none
**************************************************************************/
void uart_puts_p(const char *progmem_s )
{
    register char c;
   
    while ( (c = pgm_read_byte(progmem_s++)) )
      uart_putc(c);
}/* uart_puts_p */
//***************************************************

/*
 * these functions are only for ATmegas with two USART
 */
#if defined( ATMEGA_USART1 )
SIGNAL(UART1_RECEIVE_INTERRUPT)
/*************************************************************************
Function: UART1 Receive Complete interrupt
Purpose:  called when the UART1 has received a character
**************************************************************************/
{
    unsigned char tmphead;
    unsigned char data;
    unsigned char usr;
    unsigned char lastRxError;


    /* read UART status register and UART data register */
    usr  = UART1_STATUS;
    data = UART1_DATA;
   
    /* */
    lastRxError = (usr & (_BV(FE1)|_BV(DOR1)) );
       
    /* calculate buffer index */
    tmphead = ( UART1_RxHead + 1) & UART_RX_BUFFER_MASK;
   
    if ( tmphead == UART1_RxTail ) {
        /* error: receive buffer overflow */
        lastRxError = UART_BUFFER_OVERFLOW >> 8;
    }else{
        /* store new index */
        UART1_RxHead = tmphead;
        /* store received data in buffer */
        UART1_RxBuf[tmphead] = data;
    }
    UART1_LastRxError = lastRxError;  
}

SIGNAL(UART1_TRANSMIT_INTERRUPT)
/*************************************************************************
Function: UART1 Data Register Empty interrupt
Purpose:  called when the UART1 is ready to transmit the next byte
**************************************************************************/
{
    unsigned char tmptail;
   
    if ( UART1_TxHead != UART1_TxTail) {
        /* calculate and store new buffer index */
        tmptail = (UART1_TxTail + 1) & UART_TX_BUFFER_MASK;
        UART1_TxTail = tmptail;
        /* get one byte from buffer and write it to UART */
        UART1_DATA = UART1_TxBuf[tmptail];  /* start transmission */
    }else{
        /* tx buffer empty, disable UDRE interrupt */
        UART1_CONTROL &= ~_BV(UART1_UDRIE);
    }
}

/*************************************************************************
Function: uart1_init()
Purpose:  initialize UART1 and set baudrate
Input:    baudrate using macro UART_BAUD_SELECT()
Returns:  none
**************************************************************************/
void uart1_init(unsigned int baudrate)
{
    UART1_TxHead = 0;
    UART1_TxTail = 0;
    UART1_RxHead = 0;
    UART1_RxTail = 0;
   
    /* Set baud rate */
    if ( baudrate & 0x8000 )
    {
     UART1_STATUS = (1<<U2X1);  //Enable 2x speed
      baudrate &= ~0x8000;
    }
    UBRR1H = (unsigned char)(baudrate>>8);
    UBRR1L = (unsigned char) baudrate;
    /* Enable USART receiver and transmitter and receive complete interrupt */
    UART1_CONTROL = _BV(RXCIE1)|(1<<RXEN1)|(1<<TXEN1);
   
    /* Set frame format: asynchronous, 8data, no parity, 1stop bit */  
    #ifdef URSEL1
    UCSR1C = (1<<URSEL1)|(3<<UCSZ10);
    #else
    UCSR1C = (3<<UCSZ10);
    #endif
}/* uart_init */

/*************************************************************************
Function: uart1_getc()
Purpose:  return byte from ringbuffer 
Returns:  lower byte:  received byte from ringbuffer
          higher byte: last receive error
**************************************************************************/
unsigned int uart1_getc(void)
{   
    unsigned char tmptail;
    unsigned char data;

    if ( UART1_RxHead == UART1_RxTail ) {
        return UART_NO_DATA;   /* no data available */
    }
   
    /* calculate /store buffer index */
    tmptail = (UART1_RxTail + 1) & UART_RX_BUFFER_MASK;
    UART1_RxTail = tmptail;
   
    /* get data from receive buffer */
    data = UART1_RxBuf[tmptail];
   
    return (UART1_LastRxError << 8) + data;
}/* uart1_getc */

/*************************************************************************
Function: uart1_putc()
Purpose:  write byte to ringbuffer for transmitting via UART
Input:    byte to be transmitted
Returns:  none         
**************************************************************************/
void uart1_putc(unsigned char data)
{
    unsigned char tmphead;
   
    tmphead  = (UART1_TxHead + 1) & UART_TX_BUFFER_MASK;
   
    while ( tmphead == UART1_TxTail ){
        ;/* wait for free space in buffer */
    }
   
    UART1_TxBuf[tmphead] = data;
    UART1_TxHead = tmphead;
    /* enable UDRE interrupt */
    UART1_CONTROL    |= _BV(UART1_UDRIE);
}/* uart1_putc */

/*************************************************************************
Function: uart1_puts()
Purpose:  transmit string to UART1
Input:    string to be transmitted
Returns:  none         
**************************************************************************/
void uart1_puts(const char *s )
{
    while (*s)
      uart1_putc(*s++);
}/* uart1_puts */

/*************************************************************************
Function: uart1_puts_p()
Purpose:  transmit string from program memory to UART1
Input:    program memory string to be transmitted
Returns:  none
**************************************************************************/
void uart1_puts_p(const char *progmem_s )
{
    register char c;
   
    while ( (c = pgm_read_byte(progmem_s++)) )
      uart1_putc(c);
}/* uart1_puts_p */

#endif

</pre>

Monday, 3 March 2014

Simple Program to interface a motor with Atmega 16/32 :

#include<avr/io.h>
#include<util/delay.h>
#include<compat/deprecated.h> /* some softwares don't run well with newer versions of operating systems. using this header file will automatically resolve conflicts that may arise due to higher versions. */

void main()
{
 DDRD = 0xff; // set D as output port
 sbi(PORTD,4); // set EN1 of motor driver
 while(1)
 {
  sbi(PORTD,2);
  cbi(PORTD,3);
  _delay_ms(1000); // syntax to give delay. (In milli seconds ofcourse).
  cbi(PORTD,2);
  sbi(PORTD,3);
  _delay_ms(1000);
 }
}



Powered by Blogger.