Basic Elements of Digital Signal Processing System

Most of the signals encountered in science and engineering are analog in nature. That is the signals are functions of a continuous variable, such as time or space, and usually take on values in a continuous range. Such signals may be processed directly by appropriate analog systems (such as filters or frequency analyzers) or frequency multipliers for the purpose of changing their characteristics or extracting some desired information. In such a case we say that the signal has been processed directly in its analog form, as illustrated in picture below.
 Both the input signal and the output signal are in analog form.

Digital signal processing provides an alternative method for processing the analog signal, as illustrated in figure below.

To perform the processing digitally, there is a need for an interface between the analog signal and the digital processor. This interface is called an analog-to-digital (A/D) converter. The output of the A?D converter is a digital signal that is appropriate as an input to the digital processor.

The digital signal processor may be a large programmable digital computer or a small microprocessor programmed to perform the desired operations on the input signal. It may also be a hardwired digital processor configured to perform a specified set of operations on the input signal. Programmable machines provide the flexibility to change the signal processing operations through a change in the software, whereas hardwired machines are difficult to reconfigure. Consequently, programmable signal processors are in very common use. On the other hand, when signal processing operations are well defined, a hardwired implementation of the operations can be optimized, resulting in a cheaper signal processor and, usually, one that runs faster than its programmable counterpart. In applications where the digital output from the digital signal processor is to be given to the user in analog form, such as in speech communications, we must provide another interface from the digital domain to analog domain. Such an interface is called a digital-to-analog (D/A) converter. Thus the signal is provided to the user in analog form.

However, there are other practical applications involving signal analysis, where the desired information is conveyed in digital form and no D/A converter is required. For example, in the digital processing of radar signals, the information extracted from the radar signal, such as the position of the aircraft and its speed, may simply be printed on paper. There is no need for a D/A converter in this case.

Serial Communication of 2 Processors

This project uses 2 Atmega16 with 16 MHz external clock. The first microcontroller is used to capture inputs from keypad 4 x 4. The second microcontroller is used to show outputs on LCD HD44780 2 x 16. I use asynchronous mode for this project.

This is the schematic:
But if you want to use synchronous mode, PINB.0 of first AVR should be connected to PINB.0 of second AVR.

This is the sample of this project that I have made.

If you want to know how to connect AVR with LCD HD44780, see my other post here.

How to Connect LCD HD44780 with AVR

LCD HD44780 is one of LCD that is commonly used by many students and developers in many countries for learning objectives. If we want to use this LCD, we should connect it with a microcontroller as the control system. The most popular microcontroller for students and developers is AVR, a kind of microcontroller from Atmel.  
There is a simple way to communicate LCD HD44780 with AVR microcontroller. You can use library that have been made by team so it will be easy to set your AVR microcontroller. These are the steps:
1.       You should have the library in your work directory. You can download lcd_lib.h, lcd_lib.c and datasheet of LCD here.
2.       The default output port for LCD that is defined in the library is port D. You can change the port by making some changes on preprocessor in the header file at this part:
#define LDP PORTD
#define LCP PORTD
#define LDDR DDRD
#define LCDR DDRD
3.       There are some basic functions that you can use. You can learn it from demo program that have been made by team. At that demo program you can learn some basic function such as sending a char, sending a string, moving the cursor in LCD, etc. You can download demo program and datasheet here.
4.       This library uses 4 bit data to operate the LCD so you use only 4 LCD data pins. You can see the configuration of the LCD pin below.

If using the library
connect it to GND
connect it to Vcc (put 1k resistor to reduce the current)
connect it to GND (if you don’t want to change contrast)
to PD0
to PD1
to PD2




to PD4
to PD5
to PD6
to PD7
V+ (only if LCD has backlight)
GND (only if LCD has backlight)

5.       Make design of your system and apply it. If you want to be more expert, you can upgrade your system for example by adding a keypad or push button to your system as input device.  This is a basic skill to make more advanced device such as digital clock, digital game, etc.

Introducing to USART in AVR


The Universal Synchronous and Asynchronous serial Receiver and Transmitter (USART) is a highly flexible serial communication device. The main features are:
• Full Duplex Operation (Independent Serial Receive and Transmit Registers)
• Asynchronous or Synchronous Operation
• Master or Slave Clocked Synchronous Operation
• High Resolution Baud Rate Generator
• Supports Serial Frames with 5, 6, 7, 8, or 9 Data Bits and 1 or 2 Stop Bits
• Odd or Even Parity Generation and Parity Check Supported by Hardware
• Data OverRun Detection
• Framing Error Detection
• Noise Filtering Includes False Start Bit Detection and Digital Low Pass Filter
• Three Separate Interrupts on TX Complete, TX Data Register Empty and RX Complete
• Multi-processor Communication Mode
• Double Speed Asynchronous Communication Mode

AVR USART vs. AVR UART – Compatibility

The USART is fully compatible with the AVR UART regarding:
• Bit locations inside all USART Registers
• Baud Rate Generation
• Transmitter Operation
• Transmit Buffer Functionality
• Receiver Operation

However, the receive buffering has two improvements that will affect the compatibility in some special cases:
• A second buffer register has been added. The two buffer registers operate as a circular FIFO buffer. Therefore the UDR must only be read once for each incoming data! More important is the fact that the Error Flags (FE and DOR) and the ninth data bit (RXB8) are buffered with the data in the receive buffer. Therefore the status bits must always be read before the UDR Register is read. Otherwise the error status will be lost since the buffer state is lost.
• The Receiver Shift Register can now act as a third buffer level. This is done by allowing the received data to remain in the serial Shift Register (see Figure 69) if the buffer registers are full, until a new start bit is detected. The USART is therefore more resistant to Data OverRun (DOR) error conditions.

The following control bits have changed name, but have same functionality and register location:
• CHR9 is changed to UCSZ2
• OR is changed to DOR

Clock Generation

The clock generation logic generates the base clock for the Transmitter and Receiver. The USART supports four modes of clock operation: Normal asynchronous, Double Speed asynchronous, Master synchronous and Slave synchronous mode. The UMSEL bit in USART Control and Status Register C (UCSRC) selects between asynchronous and synchronous operation. Double Speed (asynchronous mode only) is controlled by the U2X found in the UCSRA Register. When using Synchronous mode (UMSEL = 1), the Data Direction Register for the XCK pin (DDR_XCK) controls whether the clock source is internal (Master mode) or external (Slave mode). The XCK pin is only active when using synchronous mode.

Internal Clock Generation – The Baud Rate Generator

Internal clock generation is used for the asynchronous and the synchronous master modes of operation. The USART Baud Rate Register (UBRR) and the down-counter connected to it function as a programmable prescaler or baud rate generator. The down-counter, running at system clock (fosc), is loaded with the UBRR value each time the counter has counted down to zero or when the UBRRL Register is written. A clock is generated each time the counter reaches zero. This clock is the baud rate generator clock output (= fosc/(UBRR+1)). The Transmitter divides the baud rate generator clock output by 2, 8, or 16 depending on mode. The baud rate generator output is used directly by the receiver’s clock and data recovery units. However, the recovery units use a state machine that uses 2, 8, or 16 states depending on mode set by the state of the UMSEL, U2X and DDR_XCK bits. Table below contains equations for calculating the baud rate (in bits per second) and for calculating the UBRR value for each mode of operation using an internally generated clock source.

Double Speed Operation (U2X)

The transfer rate can be doubled by setting the U2X bit in UCSRA. Setting this bit only has effect for the asynchronous operation. Set this bit to zero when using synchronous operation. Setting this bit will reduce the divisor of the baud rate divider from 16 to 8, effectively doubling the transfer rate for asynchronous communication. Note however that the Receiver will in this case only use half the number of samples (reduced from 16 to 8) for data sampling and clock recovery, and therefore a more accurate baud rate setting and system clock are required when this mode is used. For the Transmitter, there are no downsides.

External Clock

External clocking is used by the synchronous slave modes of operation. The description in this section refers to Figure 70 for details. External clock input from the XCK pin is sampled by a synchronization register to minimize the chance of meta-stability. The output from the synchronization register must then pass through an edge detector before it can be used by the Transmitter and Receiver. This process introduces a two CPU clock period delay and therefore the maximum external XCK clock frequency is limited by the following equation:
 Note that fosc depends on the stability of the system clock source. It is therefore recommended to add some margin to avoid possible loss of data due to frequency variations.

Synchronous Clock Operation

When Synchronous mode is used (UMSEL = 1), the XCK pin will be used as either clock input (Slave) or  clock output (Master). The dependency between the clock edges and data sampling or data change is the same. The basic principle is that data input (on RxD) is sampled at the opposite XCK clock edge of the edge the data output (TxD) is changed.

The UCPOL bit UCRSC selects which XCK clock edge is used for data sampling and which is used for data change. As Figure 71 shows, when UCPOL is zero the data will be changed at rising XCK edge and sampled at falling XCK edge. If UCPOL is set, the data will be changed at falling XCK edge and sampled at rising XCK edge.

source: datasheetatmega8535


Latch is a bacis component of memory element. Before you study more such as flip flop, register, counter, etc, you must know about latch.

1.       Basic Latch
We see that latch can be as memory element when its input S=’0’ and R=’0’.

2.       Gated SR Latch
Gated latch is latch which use control signal/clock. Because we use S and R input, we call this latch as Gater SR Latch.

3.       Gated D Latch
It has single data input, called D, and it stores its value on this input, under a control of the clock.

Fuse Setting for the Clock

Using External Clock or Internal Clock ?

If you use WinAVR to program the AVR microcontroller and you want to use internal clock or external clock, You should changes the fuse of microcontroller. Before learn about this, you should know about how to use WinAVR and Makefile. You can see my early article here.

When you has installed WinAVR, you had also installed avrdude in you computer. Avrdude is used to program the AVR.

Now, if you want to check fuse setting on your AVR:
-          you should connect your AVR to your computer using ponyser programmer (RS232 to AVR ISP), or stk500 (usb to AVR ISP), or other kinds of programmer.
-          run command prompt as administrator.
-          type: avrdude –c stk500 –p atmega16 –P com4 –v (in this sample, I use atmega16 and stk500 prgrammer, if you use ponyser, change stk500 to ponyser, the com port is found by trying the command. If com4 don’t work, change to com1, com2, or com3)
-          If it is right, you will see the picture below. 

-          The value of lfuse = 0xE1. By the fuse table from datasheet atmega below, we know that it’s the setting for using internal clock. 

-          If you want to use external clock, set the lfuse to 0xEF by type : avrdude –c stk500 –p atmega16 –P com4 –U hfuse:w:0xD9:m –U lfuse:w:0xEF:m
-          The result is on picture below. 

If you use high frequency, of course the program in your chip is running faster. So, the fuse setting is very important if you want to change the speed of program processing. Another thing, don’t forget to change F_CPU in your source code and Makefile file because the _delay_ms(long int x) function from WinAVR library, using F_CPU variable to calculate the duration of delay and has been adjusted to clock of the chip. F_CPU should be the same as clock of the chip.

For experiment, I make a program:
#include <avr/io.h>
#include <util/delay.h>
#define F_CPU 1000000UL
void main(void)
       DDRC=0xff; //PA and PC as output
       PORTC=0x00; //PC always low voltage
       while (1) //looping forever
              PORTA=0xf0; //PA7-4 high, PA3-0 low
              PORTA=0x0f; //PA7-4 low, PA3-0 high

I try it on my board for:
internalclock 1 Mhz and F_CPU 1 Mhz, internalclock 1 Mhz and F_CPU 16 Mhz, externalclock 16 Mhz and F_CPU 16 Mhz, and externalclock 16 Mhz and F_CPU 1 Mhz. The result is in video below.

 The normal delay is 500 ms, as that have been declared in program.

Basic of AVR Input Output


In this explanation and next others, I will use Atmega 8535/16/32. It is because this AVR series is commonly used by students and developer. But, sometime I will use Atmega 8 for some simpler case. Beside that, I also use C programming because it is easy to use and many people choose this programming language.
These are some superiority of Atmega 8535:
Advanced RISC Architecture
– 130 Powerful Instructions
– Most Single Clock Cycle Execution
– 32 x 8 General Purpose Working Registers
– Fully Static Operation
– Up to 16 MIPS Throughput at 16 MHz
– On-chip 2-cycle Multiplier
Nonvolatile Program and Data Memories
– 8K Bytes of In-System Self-Programmable Flash
Endurance: 10,000 Write/Erase Cycles
– Optional Boot Code Section with Independent Lock Bits
In-System Programming by On-chip Boot Program
True Read-While-Write Operation
– 512 Bytes EEPROM
Endurance: 100,000 Write/Erase Cycles
– 512 Bytes Internal SRAM
– Programming Lock for Software Security
Peripheral Features
– Two 8-bit Timer/Counters with Separate Prescalers and Compare Modes
– One 16-bit Timer/Counter with Separate Prescaler, Compare Mode, and Capture
– Real Time Counter with Separate Oscillator
– Four PWM Channels
– 8-channel, 10-bit ADC
8 Single-ended Channels
7 Differential Channels for TQFP Package Only
2 Differential Channels with Programmable Gain at 1x, 10x, or 200x for TQFP
Package Only
– Byte-oriented Two-wire Serial Interface
– Programmable Serial USART
– Master/Slave SPI Serial Interface
– Programmable Watchdog Timer with Separate On-chip Oscillator
– On-chip Analog Comparatoror
 And Many More
Let's Learn
Atmega 8535 has 32 I/O register. Port A, B, C, and D have 8 bit, so the total is 32 bit. If we want to make a pin working as an input pin, we set its DDR to ‘0’. But if we want to make a pin working as an output pin, we set its DDR to ‘1’.
When a port works as input, there are two options, making it as input with internal pull-up or making it as floating input. To activate the pull-up internal we set its PORT to ‘1’ but if we want make it as floating input we set its PORT to ‘0’.
When a port works as output, there are also two option, making it to have high voltage or to have low voltage. PORT is set to ‘1’ for high voltage and PORT is set to ‘0’ for low voltage.
Ok, let’s make a sample program for basic input output.
In programmer notepad or other source  editors and based on WinAVR. Please check this for explanation how to use WinAVR and AVR Studio.
Let’s make a C code:
#include <avr/io.h>
void main (void)
{ DDRA=0b00000000;
The explanation:

DDRA = 0b00000000, it makes 8 pin in PORTA to work as input.
PORTA=0b00001111, it makes PORTA.0 – PORTA.3 to use internal pull-up and PORTA.4 – PORTA.7 to be floating input.

DDRB= 0b00001111, it makes PORTB.0 – 3 to work as output and PORTA.4 –7 to work as input.
PORTB=0b00110011, it makes PORTA.0 –1 to have high voltage, PORTA.2 – 3 to have low voltage, PORTA.4 – 5 to use internal pull-up and PORTA.6 – 7 to be floating input.

DDRC=0b11111111, it makes 8 pin in PORTC to work as output.
PORTC=0b11110000, it makes PORTC0 –3 to have low voltage and PORTA4 –7 to have high voltage.

output of PORTD will be same as input to PORTA. To access the value of an input register we should use PIN not PORT. If PORTA0 – 3 are connected to Vcc and PORTA4 – 7 are connected to Ground, the output of PORTD0 – 3 are high and PORTD4 – 7 are low.

All bit in a I/O register can be access one by one for example: DDRA1, PORTC3, PIND5, etc. We can make PORTD3 = PINA5, DDRB1 = 0, etc.

Internal pull-up is usually activated when the input port is connected to switch. Floating input is usually used when the input port is connected with sensor.

In the program above, I use a macro, io.h. Why I use this macro? I use this because definition of PORT, PIN, and DDR are there. Beside that there are some function in this header file that will be usefull for our program in the next. Such as:

·         _BV(n); to set the n-th bit of a registert. e.g: DDRC = _BV(5) means DDRC5 = 1.
·         bit_is_clear(sfr, n); return value = 1, if the n-th bit of sfr (register) is clear. Clear means 0, Set means 1.
·         bit_is_set(sfr, n); return value = 0, if the n-th bit of sfr (register) is clear.
·         loop_until_bit_is_clear(sfr,n); do nothing until the n-th bit of register equal to ‘0’.
·         loop_until_bit_is_set(sfr,n); do nothing while the n-th bit of register equal to ‘0’.

Note: To be more expert, you can use AVR Studio to simulate a progarm. You can see characteristic and every changes in every register in AVR.

Fibonacci Sequence Program

This program will read user input to give the number of fibonacci sequence that want to be showed. by user Then, the program will show the Fibonacci Sequence. This program is consists of 4 files. If you don’t have known about compilation using makefile, see my other posting about Make Makefile File and C Compilation using GCC.
Make inputn.c
#include "fibo.h"
#include <stdio.h>
int main()
    int nf;
    printf("Fibonacci Sequence Program\n");
    printf("Number of Sequence (>=1) = "); scanf("%d",&nf);
    printf("Sequence = ");
    return 0;

Make fibo.c
#include "fibo.h"
#include <stdio.h>
int fibonacci(int m)
    int t=0;
    if          (m == 1) {return 1;}
    else if     (m == 2) {return 1;}
    else if (m >= 3) {t = fibonacci(m-1)+fibonacci(m-2); return t;};

void showfibonacci(int n)
    int i;
    for (i=1;i<=n;i++)
          if (i==1)
          {printf(", %d",fibonacci(i));};

File fibo.h
#ifndef FIBO_H
#define FIBO_H
int fibonacci(int m);
void showfibonacci(int n);

File makefile to make fiboprog.exe
fiboprog : inputn.o fibo.o
    gcc inputn.o fibo.o -o fiboprog

inputn.o : inputn.c
    gcc -c inputn.c

fibo.o : fibo.c
    gcc -c fibo.c

You can see the result below.

How to Make Makefile File for Compilation

Makefile is a file where we can type some instructions on it  to compile a program automatically. We just use “make” instruction in command prompt.
The basic makefile is composed of:

target: dependencies
[tab] system command

Target is the output that we want. Dependencies is the related file to make the output that we want. System command is the rule to produce the output. Don’t  forget to press tab on keyboard before you type the system command.
Let’s we learn from example. The steps are:
1.       Make a work directory for all of our code.
2.       Make the first source code and save as main_text.c in your work directory.
#include "text.h"
void main()
3.       Make the second source code and save as text.c in your work directory.
#include <stdio.h>
#include "text.h"
void test()
      printf("Arsitektur Komputer I");
4.       Make the third source and save as text.h in your work directory.
#ifndef TES_H
#define TES_H
void test();
5.       Make the fourth source and save as makefile in your work directory.
all: coba

coba: main2.o coba.o
     gcc main_text.o text.o -o coba

main2.o: main_text.c
     gcc -c main_text.c

coba.o: text.c
     gcc -c text.c

-          main2.o will execute gcc c main_text.c and the result is main_text.o
-          coba.o will execute gcc c text.c and the result is text.o
-          coba will execute gcc main_text.o text.o o coba and result is coba.exe
-          in this case, we learn that the name of target and dependencies is up to us. But we still should use the name of the result of the target in the system command, not the name of the target. We still type:
gcc main_text.o text.o o coba  
NOT gcc main2.o coba.o o coba

6.       Open command prompt, Enter your work directory and type "make", Enter, Then type "coba", Enter. The result is :

Now, you can use makefile file to compile and bulid a program just by type "make" in command prompt.