Hello guys,
I was asked to design a phase sequence detector, which utilizes low end uC (pic10f200). Below is my code:
But I can't quite find where's my mistake. The code compiles and the logic seems right to me, but failed on the proteus test. Can you help me out with some suggestions on where the problem is or how to improve the algorith? Thank you!
I was asked to design a phase sequence detector, which utilizes low end uC (pic10f200). Below is my code:
Code:
/*#############################################################################
* Phase Sequence Detector
############################################################################ */
#include <xc.h>
#include <stdint.h>
/***** CONFIGURATION *****/
#pragma config MCLRE=OFF
#pragma config CP=OFF
#pragma config WDTE=OFF
/*#############################################################################
* Functions
############################################################################ */
/*#############################################################################
* timer0_init ()
* Usage - Initializes the TMR0 module for future use.
############################################################################ */
void timer0_init (void){
OPTION = 0b11010110; // Timer mode with Prescaler 64
// Timer period = 4MHz/(4*128) = 7812Hz
// Period = 128us
// 20ms/128ms = 156,25 for 1 period
// 156,25/20 = 7,8125 ticks for 1ms
}
/*#############################################################################
* timer0_start ()
* Usage - Clears and starts the timer.
############################################################################ */
void timer0_start (void){
TMR0 = 0b00000000; // Reset and start the Timer
}
/*#############################################################################
* Debounce ()
* Usage - Filters the edge detections.
############################################################################ */
uint8_t debounce (uint8_t PortMask){
uint8_t counter = 0;
while( PortMask == (GPIO & PortMask) && counter<15 )
{
counter++;
}
return (counter > 10)?(1):(0);
}
/*#############################################################################
* div_uint_by5 ()
* Usage - Optimized division by constant for the particular task. (max divident
* is expected to be less than 80)
############################################################################ */
uint8_t udiv (uint8_t divider){
uint8_t divident = TMR0;
uint8_t counter = 0;
while(divident)
{
divident -= divider;
counter++;
}
return counter;
}
void main(){
volatile uint8_t Margin = 0; // varriable to store the duration of the pulse on GP1
// and the 20% margin
volatile uint8_t PortCurrentState = 0;
volatile uint8_t PortPreviousState = 0;
volatile uint8_t Flag = 0;
const uint8_t Phase2 = 51;
const uint8_t Phase3 = 102;
const uint8_t Phase1 = 153;
volatile uint8_t temp2 = 0;
OPTION = 0b11010110;
TRISGPIO = 0b11111011;// Initialize GPIO port
GPIO = _GPIO_GP2_MASK;// Turn the LED on for error;
// Get the pulse width for initial calculations
do{
PortCurrentState = GPIO;
if( (PortPreviousState & _GPIO_GP0_MASK)==0x00 && (PortCurrentState & _GPIO_GP0_MASK)!=(PortPreviousState & _GPIO_GP0_MASK) )
{
if( debounce(_GPIO_GP0_MASK) )
{
TMR0 = 0b00000000;
if(Margin)
{
break;
}
}
}
if( (PortPreviousState & _GPIO_GP0_MASK)==_GPIO_GP0_MASK && (PortCurrentState & _GPIO_GP0_MASK)!=(PortPreviousState&_GPIO_GP0_MASK) )
{
if( debounce(_GPIO_GP0_MASK) )
{
Margin = udiv(5); // calculate the 20% margin
}
}
PortPreviousState = PortCurrentState;
}while(1);
while(1)
{
switch( udiv(Phase2)+1 )
{
case 1 :
{
temp2 = Phase2 + Margin;
while( TMR0<temp2 )
{
if( debounce(_GPIO_GP1_MASK) )
{
Flag |= _GPIO_GP1_MASK;
break;
}
}
}
break;
case 2 :
{
temp2 = Phase3 + Margin;
while( TMR0<temp2 )
{
if( debounce(_GPIO_GP3_MASK) )
{
Flag |= _GPIO_GP3_MASK;
break;
}
}
}
break;
case 3 :
{
temp2 = Phase1 + Margin;
while( TMR0<temp2 )
{
if( debounce(_GPIO_GP0_MASK) )
{
Flag |= _GPIO_GP0_MASK;
if( Flag == 0x0B )
{
TMR0 = 0b00000000;
Flag = 0x00;
GPIO = ~_GPIO_GP2_MASK;
}
break;
}
}
}
break;
case 4 :
{
temp2 = Phase1 + Margin;
if(TMR0>temp2)
{
GPIO = _GPIO_GP2_MASK;
Flag = 0x00;
TMR0 = 0b00000000;
}
}
break;
}
}
}