Microcontroller reverse engineer
Microcontroller reverse engineer
Everything they make, We can break! 
  HOME COMPANY PCB COPY MCU HACK FAQ CONTACT US
Disassembler Software   
WHY US ?
World first mcu hack company
In business since 1998
Reversed tens of thousands of chips
Copied thousands of pcbs
Foreseen all pertential problems
Integrity with payments
crack ic
 
 
Microcontroller Beginners' Guide

Chapter 4

 

Part 9 - Button Debouncing Through Software

Ok, so now your saying to yourself, we JUST went over debouncing, and it seemed to work fine... Why go deeper into this subject?!? Well, basically, software debouncing, if the program space and microcontroller cycles will allow it, is essentially free. It's just a few lines of code, and you can provide much more control of how the debouncing methods work with the particular button you are using. Debouncing in hardware may add a cost to each board that is developed, and it is more difficult to determine a good debouncing for all the push button switches that will be used. However, if you want to preserve program execution cycles, it's best to go the hardware route.

 

My method of debouncing with software uses only two variables that measure the confidence level of the actual button press. With the help of the Pressed variable introduced in the Button Debouncing, there will be a stream of 1's when the button is pressed, and a stream of 0's when the button is released. If there is bouncing going on, the stream of 1's or 0's will be very short, so we can take advantage of this by introducing two variables that measure the length of these streams. The variables are called, Pressed_Confidence_Level, to measure the button's pressed state, and Released_Confidence_Level to measure the button's released state.

 

So, if the button is pressed, the Pressed_Confidence_Level will rise, and the same with Released_Confidence_Level when the button is released. But, these variables will also become reset to 0 if the opposite condition exists. For instance, say the button was pressed for a time and the Pressed_Confidence_Level became a very large number, like 153,356. If the button was released (or a bouncing happened), the variable would be reset to 0. The trick to these variables is to determine a good threshold to determine a good button press or release state. Say, if the Pressed_Confidence_Level shows that after rising to 500, that this number s a strong indication of a button press, then the LEDs will toggle once. The same goes for the Released_Confidence_Level because bouncing could also happen on a button release. So, let's see how we do this in code:

int main(void)
{
DDRB |= 1 << PINB0; //For Notes on what these actions mean
PORTB ^= 1 << PINB0;
DDRB |= 1 << PINB2;
DDRB &= ~(1 << PINB1);
PORTB |= 1 << PINB1;

int Pressed = 0;
int Pressed_Confidence_Level = 0; //Measure button press cofidence
int Released_Confidence_Level = 0; //Measure button release confidence

while (1)
{
if (bit_is_clear(PINB, 1))
{
Pressed_Confidence_Level ++; //Increase Pressed Conficence
Released_Confidence_Level = 0; //Reset released button confidence since there is a button press
if (Pressed_Confidence_Level >500) //Indicator of good button press
{
if (Pressed == 0)
{
PORTB ^= 1 << PINB0;
PORTB ^= 1 << PINB2;
Pressed = 1;
}
//Zero it so a new pressed condition can be evaluated
Pressed_Confidence_Level = 0;
}
}
else
{
Released_Confidence_Level ++; //This works just like the pressed
Released_Confidence_Level = 0; //Reset pressed button confidence since the button is released
if (Released_Confidence_Level >500
{
Pressed = 0;
Released_Confidence_Level = 0;
}
}
}
}

 

 

Part 10 - The Button Game

It's time to apply a bit of what was learned and create an actual game. This game uses a couple of push buttons, two sets of LEDs (2 rows of 7 LEDs). The object of the game is for two people to try to press their button the most times in the shotest amount of time. As the button is pressed, the LEDs are lit up one after another until the last LED is lit and that side wins. The winner is exposed by their side of LEDs flashing.

 

The circuit consists of two rows of LEDs, 7 LEDs on each row. Since there are 7 LEDs for each side, a single port can be used for maker together club each set, and there is still room for a push button on each port. One push button and 7 LEDs can be wired to 8 pins, or one port worth of pins. In the video, I use port B for one player's button and LEDs and port D for the other player's button and LEDs.

 

Three other programming fundamentals were also demonstrated in the video: arrays, encapsulation and a bit more information on variables. The arrays are used to simplify the variables used for each player. Instead of creating unique varibles for the button debouncing, button press and LEDs to be lit, a single variable was used for each containing an array of "2", one for each player. This also made encapsulation and repetitive code use much easier. If code is to be re-used in the program more than once, it makes sense to put that code in a special area called a function, or a method so it can be called whenever it is needed. since there were two players, we had identical code that was going to be used twice when the button press and release is tested and the code that is used to light up the LEDs.

 

Specifically, in the program, you will see a few new things. With the creation of new functions, we can essentially create what looks like new commands that the program will undestand. These functions are called ProcessPressedButton and ProcessReleasedbutton. With the help of the arrays, all that needs to be done is the array number (player number) be passed into these fnctions. In the program, the first thing you will notice is that there are a couple of statements with "void" at the beginning. eeprom recovery These are called function prototypes. The language of C, or C++ requires these function prototypes to inform the compiler that these are used in the program before they are actuall defined. Notice that the functions are used in the program (within the main function) before the actual functions and code (after the main function). An alternative to this would be to actually put the main function at the end of the program, and remove the prototypes, but I personally like keeping the main function at the beginning for clarity. There is even a better alternative: to create a couple of library files that contain these new functions, but we have not gotten to this level of programming yet at this poing in the tutorial series.

 

You will also notice that there are integers (variables) outside of the main function (ignore the brackets and number 2 for now). This will force these variables to have a global scope. Ok, I know... I haven't discussed scope yet (not even in the video). Scope is where the declared variables will be used. If a variable is declared within a specific code block, like in a function, then the variable will live and die in this code block, and any code blocks within this block. For instance, if the variables are declared within the main function, these variables cannot be used within another function that resides outside the main function. If the variables are defined at the bottom most level (outside of any block), they become global, and any code block can use them.

 

Now the arrays... notice the [2] at the end of the global variables. This allows for two of these same variables to be created and differentiated by using a [0] or [1]. Why "0"? The numbers are indexed from 0, not 1. So, take the Pressed[2] as an example. This creates a variable called Pressed[0] and a Pressed[1]. Notice in the functions that I have a variable within the brackets. Encapsulation and arrays can provide some really cool features in programming.

#include <avr/io.h>
#include <util/delay.h>

void ProcessPressedButton(int ButtonPressed);
void ProcessReleasedButton(int ButtonReleased);
int Pressed_Confidence_Level[2];
int Released_Confidence_Level[2];
int Pressed[2];
int LEDNumber[2];
int main(void)
{
DDRB = 0b01111111;
DDRD = 0b01111111;
PORTB = 0b10000000;
PORTD = 0b10000000;

while (1)
{
if (bit_is_clear(PINB, 7))
{
ProcessPressedButton(0);
}
else
{
ProcessReleasedButton(0);
}
if (bit_is_clear(PIND, 7))
{
ProcessPressedButton(1);
}
else
{
ProcessReleasedButton(1);
}
}
}

void ProcessPressedButton(int ButtonPressed)
{
Pressed_Confidence_Level[ButtonPressed] ++;
if (Pressed_Confidence_Level[ButtonPressed] > 500)
{
if (Pressed[ButtonPressed] == 0)
{
Pressed[ButtonPressed] = 1;
if (ButtonPressed == 0) PORTB |= 1 << LEDNumber[ButtonPressed];
if (ButtonPressed == 1) PORTD |= 1 << LEDNumber[ButtonPressed];
LEDNumber[ButtonPressed] ++;
if (LEDNumber[ButtonPressed] >6)
{
for(int i=0;i < 10;i++)
{
if (ButtonPressed == 0) PORTB = 0b11111111;
if (ButtonPressed == 1) PORTD = 0b11111111;
_delay_ms(10);
if (ButtonPressed == 0) PORTB = 0b10000000;
if (ButtonPressed == 1) PORTD = 0b10000000;
_delay_ms(10);
}
LEDNumber[0] = 0;
LEDNumber[1] = 0;
PORTB = 0b10000000;
PORTD = 0b10000000;
}
}
Pressed_Confidence_Level[ButtonPressed] = 0;
}
}

void ProcessReleasedButton(int ButtonReleased)
{
Released_Confidence_Level[ButtonReleased] ++;
if (Released_Confidence_Level[ButtonReleased] > 500)
{
Pressed[ButtonReleased] = 0;
Released_Confidence_Level[ButtonReleased] = 0;
}
}

 

 

Part 11 - Basic and Default Usage of a Timer and Counter and The Microcontroller Clock

Timers and counters are so important that you will find many examples throughout this tutorial series. As the name implies, timers can tell the time and count. Counting and timing allows for some really cool things, like controlling the brightness of LEDs, controlling the angle of servo shafts, receiving sensor data that transmit in PWM (Pulse Width Modulation - more on that in another tuorial), making a timer (like on the stove), or just simply adding a time variable to your microcontroller project.

 

But first, it's important to know that there is a clock inside (or outside) the AVR microcontrollers. In fact, all microcontrollers have clocks in them (or use one that resides outside of a microcontroller). Microcontrollers need clocks so the our programs can be executed in rythm with the clock. This is the basic function of microcontrollers. A basic instruction is processed when a tick from the clock passes. Just like these programs we are writing, as clock ticks pass, instructions are processed in time with the ticks of the clock.

 

The timer and counter functions in the microcontroller simply count in sync with the microcontroller clock. However, the counter can only count up to either 256 (8-bit counter), or 65535 (16-bit counter). That's far from the 1,000,000 ticks per second that the standard AVR microcontroller provides. The microcontroller provides a very useful feature called prescaling. Prescaling is simply a way for the counter to skip a certain number of microcontroller clock ticks. The AVR microcontrollers allow prescaling (skipping) numbers of: 8, 64, 256 and 1024. That is, if 64 is set as the prescaler, then the counter will only count every time the clock ticks 64 times. That means, in one second (where the microcontroller ticks one million times) the counter would only count up to 15,625. you could see that if the counter counts up to that number, then you would be able to blink an LED every second.

 

Mainly, timers have a register for control, and a register that holds the count number. The control register contains some switches to turn on and off features. And you guessed it... one of the features is which prescaling to select. The control register is called TCCR0 or TCCR1 (Timer/Counter Control Register). The TCCR0 is the 8-bit control register and only has an 8-bit control register, so there is only 8 switches to turn on and off. TCCR1 is 16-bit, so it has 16 switches to turn on and off, but it comes in two 8-bit registers labeled A and B (TCCR1A and TCCR1B). The switches are as follows: FOC (force Output Compare), WGM (Waveform Generation Mode), COM (Compare Match Output Mode) and CS (Clock Select).

 

The register that holds the count is called the TCNT register. And there is an 8-bit version (TCNT0) and a 16-bit version (TCNT1). The TCNT1 register actually gets its number from two other 8-bit registers to create a complete 16-bit number, but that is all done behind the scenes (abstracted) so you don't need to worry about how the TCNT1 gets this ability to have 16-bit, just think it's magic.

 

In the video, two programs were shown: one that just shows a single LED blinking at approximately 1 second, and another program that has one row of 7 LEDs chasing every second, and another row of 7 LEDs chasing each at 1 second. The latter program is shown here since it has the most features used with the 16-bit timer.

 

Without being repetitive from previous posts, the program initializes the ports for the LEDs and sets the timer/counter #1 (the 16-bit timer). The TCCR1B control register is used to set the prescaling factor of 64 with the CS10 and CS11 switches.

 

Since we want one of the 7 LEDs to chase 1/7th of a second each, we take the number 15,625 (1000000/64 - remember the 1000000 is the 1 mhz clock of the micrcontroller) and divide it by 7 to get ~2,232.143. Now, you're saying, but you use only 2232 in the pogram!! that's because TCNT1 will only accept integer (no decimals). Now you're saying, the timing will be off by the amount of the decimal!! True, but the AVR internal clock is +/- 10% inaccurate anyway. If an external crystal is used, you sould use a perfect number that represents the appropriate count.

 

You will notice that the TCNT1 is also reset to zero manually. This is needed otherwise the TCNT1 will keep counting past the 2232 condition that was set. There are other control features that has an automatic zeroing of this number, but we will get to that in another tutorial. The remaining parts of the program is using stuff we learned i previous tutorials (LED turning on and off and arrays).

#include <avr/io.h>
int main(void)
{
DDRB = 0b01111111;
PORTB = 0b00000000;
DDRD = 0b01111111;
PORTD = 0b00000000;
TCCR1B |= 1<<CS10 | 1<<CS11;
int LEDNumber[2];
while(1)
{
if (TCNT1 > 2232)
{
TCNT1 = 0;
PORTB = 1<<LEDNumber[0];
LEDNumber[0] ++;
if (LEDNumber[0] > 6)
{
LEDNumber[0] = 0;
PORTD = 1<<LEDNumber[1];
LEDNumber[1] ++;
if (LEDNumber[1] > 6)
LEDNumber[1] = 0;
}
}
}
}

 

 

Part 12 - Introduction to Interrupts - Using the Timer/Counter as an Example

Since our brains are still warm on the subject of timers and counters, we will investigate how interrupts work using the counter as an example. Interrupts really enhance the use of microcontrollers ina big way. Interrupts make your programs react to the hardware of the microcontrollers, which may be a reaction from the circuit/evironment outside of the microcontoller.

 

Basically, an interrupt is exactly defined by it's title... it interrupts the normal program flow to do something else (other code block that you program). Imagine your program is doing its normal blinking LEDs or something and you want it to react to, say, a PIR (Passive Infra Red) sensor (connected to an interrupt pin), and goes to a special code block to, say, make a beep from a buzzer connected to another pin. If you tell the microcontroller to do this, it will stop the program in its tracks and go to the code that belongs to that interrupt (make a beep). After the interrupt code is executed, the program continues exactly where it left off. In some cases, interrupts would be an alternative to polling something, which requires program cycles. For example, say your program is wanting to only beep when a person passes the PIR sensor. Your program could keep testing that pin to see if it has a high reading over and over within the never ending loop (while(1)). Instead, remove all of the polling program code to test the pn for a high reading and let the interrupt automatically go to the beep code when the micocontroller senses the high reading.

 

So, what types of interrupts are available for the AVR Microcontroller? Interrupts can be established for events such as a counter's number, a pin changing state (from low to high or high to low), serial communication receiving of information, or the Analog to Digital having established a conversion. Here is a full list of interrupt vectors that you can use. Other tutorials will make use of many of these interrupt vectors.

 

We are going to use the timer/counter as an example. We will inform the timer/counter of a number that the TCNT1 (the couter) will need to match. The number to match will go into a register called OCR1A (Output Compare Register). The "1" represents the specific counter we are using which is the 16-bit version. We have two OCRs, the A and the B. We will use A for this example. However, do we know if the counter will reset to zero when th match is made? We definitely want the TCNT1 to go back to zero so the count will start over and we get another match at our intended number, but this isn't done in code like we did last time (remember the TCNT1 = 0;). This time, we will want to turn on another switch in the TCCR1B control register called WGM12 (waveform Generation Mode for timer 1). The #2 in that switch just represents which WGM it is, since there are a few. We will also be using the CS10 and CS11 again to set the prescaling to 64 as in the intro to timers video.

 

Then the timer/counter will need to know that we intend to use the interrupt feature. This is done through the TIMSK (Timer/Counter Interrupt Mask Register). We only need to turn on one switch in this register: the OCIE1A (Output Compare A Match Interrupt Enable) switch. Once the snaileye number put into the OCR1A is matched by the counter, the program will be interrupted to toggle the LED. For an interrupt to happen, we will need to enable the global interrupts "sei()", then we will need to enable the interrupt for the timer/counter, and finally the interrupt service routine (ISR) will need to be created. The interrupt service routine is just like the functions that were made in the button game example. The interrupt service routine is just a code block outside of the main routine and begins with ISR with the vector within parenthesis "(vector)", ollowed by the block of code within brackets"{Code}". For the timer/counter (16-bit version), and the fact that we are using the A version of the OCR1, the vector name is: TIMER1_COMPA_vect. So the routine would be: ISR(TIMER1_COMPA_vect) { code to execute fib聚焦离子束刻蚀}.

 

We used a number in the intro to timers video that represented one second: 15625, so we will use this one for the OCR1A. But, the number should consider indexing from 0, so we will need to use the number 15624 instead.

 

Let's put all of this information together in a program:

#include <avr/io.h>
#include <avr/interrupt.h>

int main(void)
{
sei();

DDRB |= 1<<PINB0;

TCCR1B |= 1<<CS10 | 1<<CS11 | 1<<WGM12;
TIMSK |= 1<<OCIE1A; //If using atmega324, this regester is TIMSK1
OCR1A = 15624;

while(1)
{
}
}

ISR(TIMER1_COMPA_vect)
{
PORTB ^= 1<<PINB0;
}

Here is the pseudocode version:

  • Include some basic information to properly configure our microcontroller.
  • Include the interrupt library that has all the interrupt functions we need.
  • Start the main routine (do the indented stuff)
    • Enable the global interrups
    • Since we are using an LED, fib focused ion beam attack enable that pin to be output
    • Turn on the timer and use 64 prescaling (skip 64 clock ticks)
    • Enable the output compare register and set a number to represent one second
    • Loop Forever
    • No code needed in the forever loop this time
  • End main routine
  • Start Interrupt routine (for the correct vector)
    • Toggle the pin to which the LED is connected
  • End Interrupt routine (go back to where the program left off)

 

 

Chapter 1 | Chapter 2 | Chapter 3 | Chapter 4 | Chapter 5 | Chapter 6 | Chapter 7 | Chapter 8 | Chapter 9

 

 

 
 
     
 
PCB Copying Service
PCB Projects Overview
PCB Clone
PCB Reverse Engineering
PCB Prototype
PCB Assembly Production
 
 
 
Mcu Hacking Service
Atmel / Analog Mcu Hack
Actel Mcu Attack
Altera Microcontroller Crack
Cygnal Mcu Unlock
Cypress IC Reverse Engineer
Dallas / Elan Mcu Code Extract
Fujitsu Microprocessor Decryption
Freescale IC Code Extraction
Giga Device circuit Hack
Hitachi Mcu Code Extract
Holtek Chip Reverse Engineer
Infineon Microcontroller Dump
Intel Mcu Read Code Protection
ICT Microcontroller Duplication
Lattice Microcontroller Clone
Microchip Source Code Recovery
Motorola Microcontroller Crack
Maxim Mcu Attack
MDT Controller Hack
Megawin Microcontroller Unlock
NEC Mcu Reverse Engineer
NTK Microcontroller Code Extract
Nuvoton Chip Decryption
NXP Semiconductor Code Extraction
Philips integrated circuit Crack
Renesas Microcontroller Dump
ST Processor Reverse Engineer
Silicon Labs Mcu Read Protection
Samsung Mcu Duplication
SST Mcu Clone
Sinowealth Source Code Recovery
SyncMOS Mcu Unlock
Sonix Mcu Read Source Code
STC Microprocessor Code Extract
Tenx Microcontroller Decryption
Texas Instruments MCU Hack
Winbond MCU Code Extraction
Xilinx integrated circuit Crack
Zilog MCU Reverse Engineer
 
     
 
 
More MCU brands we can reverse engineer below, please contact us if yours not listed here:
AMD Feeling LG / Hyundai Myson STK
ChipON Hynix Mitsubishi National Semi Temic
Coreriver ICSI Mosel Vitelic Portek Toshiba
Dallas ISSI MXIC SSSC Gal / Pal / Palce
Copyright © 2013 Mikatech. All rights reserved. Full dedicated reverse engineering company