Browsing articles tagged with " micro"

Micro and ProgLog CW1: Line-follower

#include <p18F252.h>

int antiTwist = 0;	// Flag for anti-twist code.
int i = 0;			// Counting var.
int turnedAround = 0;

void allStop(void);
void turnRight(void);
void turnLeft(void);
void goStraight(void);
void adcOff(void);
void triggerPulse(void);
void catchInterrupt(void);
void setupInterrupts(void);
void turnAround(void);

#pragma code int_vector=0x08
void ISR (void) {
	_asm
	goto catchInterrupt
	_endasm
}
#pragma code

#pragma interrupt catchInterrupt
void catchInterrupt(void) {
	int p;
	int turningFlag;

	if(PORTBbits.RB0 == 1){		// If it's rising.
		IPR1bits.TMR2IP = 0;	// Tmr 2, low priority.
		PIR1bits.TMR2IF = 0;	// Tmr 2 flag cleared.
		PIE1bits.TMR2IE = 1;	// Enable overflow interrupt.

		//Timer2 Registers Prescaler= 16 - TMR2 PostScaler = 16 - PR2 = 255 - Freq = 91.91 Hz - Period = 0.010880 seconds
		T2CON |= 120;        // bits 6-3 Post scaler 1:1 thru 1:16
		T2CONbits.TMR2ON = 1;  	 // bit 2 turn timer2 on;
		T2CONbits.T2CKPS1 = 1;	 // bits 1-0  Prescaler Rate Select bits
		T2CONbits.T2CKPS0 = 0;
		PR2 = 15;        	 // PR2 (Timer2 Match value)

		INTCONbits.INT0IF = 0; // Clear interrupt flag.
	}else{
		if(PIR1bits.TMR2IF == 0){
			PORTAbits.RA4 = 0; // LED ON.
			T2CONbits.TMR2ON = 0;	// Timer off.

			allStop();
			INTCONbits.GIEH = 0; // Temporarily disable int.

			while(PORTCbits.RC0 > 0 || PORTCbits.RC1 > 0 || PORTCbits.RC2 > 0){
				if(antiTwist == 0){
					turnRight();
				}else{
					turnLeft();
				}
			}
		}else{
			PORTAbits.RA4 = 1;		// LED OFF.
		}

		PIR1bits.TMR2IF = 0;	// Tmr 2 flag cleared.
		INTCON3bits.INT1IF = 0; // Clear interrupt flag.

		for(p = 0; p <= 5000; p++){
			// Kill 12-ish mS.
		}

		triggerPulse();
	}

}

void main (void) {
	adcOff();

	PORTAbits.RA4 = 1;		// LED OFF.

	setupInterrupts();

	TRISC = 0xff;       // Port C = input
	TRISB = 0xff;		// Port B = input
	TRISA = 0x00;       // Port A = output

	allStop();			// Start with motors off.
	triggerPulse();		// Start the ultrasound.

	while(1){
			// Sensors:     RIGHT           	 MIDDLE     	     	 LEFT	

		while(PORTCbits.RC0 == 0 && PORTCbits.RC1 == 0 && PORTCbits.RC2 == 0){
			turnAround();
		}

		if(PORTCbits.RC0 == 1 && PORTCbits.RC1 == 1 && PORTCbits.RC2 == 1){
			allStop();
		}else if(PORTCbits.RC0 == 1 && PORTCbits.RC1 == 0 && PORTCbits.RC2 == 0){
			turnRight();
		}else if(PORTCbits.RC0 == 0 && PORTCbits.RC1 == 1 && PORTCbits.RC2 == 0){
			goStraight();
		}else if(PORTCbits.RC0 == 0 && PORTCbits.RC1 == 0 && PORTCbits.RC2 == 1){
			turnLeft();
		}else if(PORTCbits.RC0 == 1 && PORTCbits.RC1 == 1 && PORTCbits.RC2 == 0){
			turnRight();
		}else if(PORTCbits.RC0 == 0 && PORTCbits.RC1 == 1 && PORTCbits.RC2 == 1){
		   	turnLeft();
	   	}

		for(i = 0; i <= 2500; i++){
			// Kill some time.
		}

		// Reset the motors.
		allStop();
	}
}

void turnRight(void) {
	PORTAbits.RA0 = 0;  // Right reverse.
	PORTAbits.RA2 = 0;  // Enable right.

	PORTAbits.RA1 = 1;  // Left forward.
	PORTAbits.RA3 = 0;  // Enable left.
}

void turnLeft(void) {
	PORTAbits.RA0 = 1;  // Right forward.
	PORTAbits.RA2 = 0;  // Enable right.

	PORTAbits.RA1 = 0;  // Left reverse.
	PORTAbits.RA3 = 0;  // Enable left.
}

void goStraight(void) {
	PORTAbits.RA0 = 1;  // Right forward.
	PORTAbits.RA2 = 0;  // Enable right.

	PORTAbits.RA1 = 1;  // Left forward.
	PORTAbits.RA3 = 0;  // Enable left.
}

void allStop(void) {
	PORTAbits.RA2 = 1; 	// Disable right.
	PORTAbits.RA3 = 1; 	// Disable left.
}

void adcOff(void) {
	// The next three lines set all of PORTA to be digital,
	// disabling the ADC. According to datasheet, 110 is
	// all pins digital.
	ADCON1bits.PCFG1 = 1;
	ADCON1bits.PCFG2 = 1;
	ADCON1bits.PCFG3 = 0;
}

void triggerPulse(void) {
	int q;

	PORTAbits.RA5 = 1;   // Start pulse.
	for(q = 0; q <= 20; q++){
		// Kill 54.2-ish uS.
	}
	PORTAbits.RA5 = 0;   // Stop pulse.
}

void turnAround(void) {
			if(PORTCbits.RC0 == 0 && PORTCbits.RC1 == 0 && PORTCbits.RC2 == 0){
				while(PORTCbits.RC0 == 0 && PORTCbits.RC1 == 0 && PORTCbits.RC2 == 0){
					turnedAround = 1;
					if(antiTwist == 0){
						turnRight();
					}else{
						turnLeft();
					}
				}
			}

			if(turnedAround == 1){
				antiTwist =~ antiTwist;			//Toggle Twist
				turnedAround = 0;
			}

}

void setupInterrupts() {
	RCONbits.IPEN = 1;			// Priorities on.

	INTCONbits.INT0IF = 0;		// Clear IF.
	INTCONbits.INT0IE = 1;		// INT0 on - it's always high priority.
	INTCON2bits.INTEDG0 = 1;	// Catch INT0 on rising edge.

	INTCON3bits.INT1IF = 0;		// Clear IF.
	INTCON3bits.INT1IE = 1;		// INT1 on.
	INTCON3bits.INT1IP = 1;		// High priority.
	INTCON2bits.INTEDG1 = 0;	// Catch INT1 on falling edge.

	INTCONbits.GIEH = 1;		// Enable all high priority interrupts.
}

Digital Systems CW2: Stopwatch

C – micro

#include <reg66x.h>

/////////////////////////
//// PIN DEFINITIONS ////
/////////////////////////

// Port 0 - in - in from CPLD
#define inDigits P0

// Port 1 - all out - out to CPLD
sbit outClock = P1^0;
sbit outReset = P1^1;

// Port 2 - all out - out to display
#define outDisplay P2

// Port 3 - in/out - buttons & speaker & CPLD control
sbit btnStartStop = P3^3;  // in
sbit outAcknowledge = P3^7;// out

/////////////////////////////
//// DECLARE SUBROUTINES ////
/////////////////////////////

void setupTimer();
void setupInputs();
void runningLoop();
void timerCallback();
void digitsCallback();
void controlCallback();
void resetCPLD();

///////////////////////////
//// DECLARE VARIABLES ////
///////////////////////////

int modeState = 0;
unsigned char hunths, tenths, seconds, tenSecs;

////////////////////////
//// PROGRAMME CODE ////
////////////////////////

void main() {
    setupTimer();
    setupInputs();
    resetCPLD();
   runningLoop();
}

void runningLoop() {
    while(1){
        outDisplay = tenSecs + 64;
        outDisplay = seconds + 128;
        outDisplay = tenths + 192;
        outDisplay = hunths + 0;
    }
}

void resetCPLD(){
    outReset = 1;
    outReset = 0;

    return;
}

void setupTimer() {
    TMOD = 0x01;        // M0 = 1 (Timer mode 1 - 16 bit mode)
    TL0 = 0xFF;         // 400Hz = 2304 delay count, 65535-2304 = 63231
    TH0 = 0xF6;         // TH0 = 0xF6 :: TL0(0xFF) = 0xF6FF = 63231
    ET0 = 1;                // T0 Interrupt enabled.
    EA = 1;             // Interrupts enabled.
    TR0 = 1;                // Begin timer.

    P2 = 0x00000000;

    return;
}

void setupInputs() {
    EA = 1;             // Interrupts enabled.
    IT0 = 1;                // Set on falling edge.
    IT1 = 1;                // Set on falling edge.
    EX0 = 1;            // Enable external interrupt 0.
    EX1 = 1;                // Enable external interrupt 1.

    modeState = 0;
    outAcknowledge = 0;

    return;
}

//////// INTERRUPT CALLBACKS ////////

void timerCallback() interrupt 1 using 2 {
   TR0 = 0;
    TL0 = 0xFF;         // 400Hz = 2304 delay count, 65535-2304 = 63231
    TH0 = 0xF6;         // TH0 = 0xF6 :: TL0(0xFF) = 0xF6FF = 63231
    TF0 = 0;
    TR0 = 1;                // Begin timer.
    outClock =~ outClock;   // Invert the clock output pin.
}

void digitsCallback() interrupt 0 {
    if(modeState == 0){
        seconds = inDigits & 0x0f;
    }else if(modeState == 1){
        tenSecs = inDigits & 0x0f;
    }else if(modeState == 2){
        hunths = inDigits & 0x0f;
    }else if(modeState == 3){
        tenths = inDigits & 0x0f;
    }

    if(modeState < 3){
        modeState++;
    }else{
        modeState = 0;
    }

    outAcknowledge = 1;
    outAcknowledge = 0;
}

void controlCallback() interrupt 2 {
    TR0 =~ TR0;
}

VHDL – CPLD

----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date:    12:25:53 03/18/2009
-- Design Name:
-- Module Name:    clock - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity clock is
    Port ( clockSource : in STD_LOGIC;  -- clock pulse from micro
           reset : in  STD_LOGIC;        -- reset pulse from micro
           microAck : in STD_LOGIC;      -- acknowledgement from micro
              digit : out  STD_LOGIC_VECTOR (3 downto 0);
                                                      -- numbers to micro
              cpldRts : out STD_LOGIC);     -- ready to send to micro (ACTIVE LOW)
end clock;

architecture Behavioral of clock is

signal hunthsCount : std_logic_vector(3 downto 0);
signal tenthsCount : std_logic_vector(3 downto 0);
signal secondCount : std_logic_vector(3 downto 0);
signal tenSecCount : std_logic_vector(3 downto 0);
signal controlFlag : std_logic_vector(1 downto 0);

begin                                                         

process(reset, clockSource)
begin
if reset = '1' then
    hunthsCount

Digital Systems CW1: Calculator

$include (reg66x.inc)

; At the very beginning, jump to 40H...
ORG 0
TIMECOUNT EQU 8h
MBUFFER EQU 10h
KBUFFERA EQU 18h
KBUFFERB EQU 20h
KEY EQU 28h
MODE EQU 30h

DISPLAYA EQU 38H
DISPLAYB EQU 40H
DISPLAYC EQU 48H
DISPLAYD EQU 50H

DISPLAYR EQU 58H
CLEARCALLED EQU 60H
LJMP CLEAR

; ...which is where our code begins.
ORG 40H

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MAIN:             ; Defines the MAIN loop.
ACALL INPUT       ; INPUT subroutine.
ACALL CALCULATE   ; CALCULATE subroutine.
ACALL OUTPUT      ; OUTPUT subroutine.
SJMP MAIN         ; Jump back to the beginning.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;; Subroutine: CALCULATE
;;;;; Purpose: Prepares calculations for output.
;;;;; MODE: 1 = ADD, 2 = SUB, 3 = MULT
;;;;;       4 = DIV, 9 = RESULT
CALCULATE:
MOV A, MODE
CJNE A, #0, STOREMODE
SJMP NONEOFTHEABOVE

STOREMODE:
CJNE A, #9, DOSTOREMODE
SJMP RESULT
DOSTOREMODE:
MOV MBUFFER, MODE
LJMP CALCULATEDONE

RESULT:
MOV A, MBUFFER
ADDITION:
CJNE A, #1, SUBTRACT
MOV A, KBUFFERA
ADD A, KBUFFERB
MOV R0, A
MOV B, #10
DIV AB
CJNE A, #0, ADDTWODIGITS
MOV DISPLAYA, R0
SJMP CLEANUP
ADDTWODIGITS:
MOV DISPLAYB, A
MOV DISPLAYA, B
SJMP CLEANUP

SUBTRACT:
CJNE A, #2, MULTIPLY
MOV A, KBUFFERA
SUBB A, KBUFFERB
MOV DISPLAYA, A
SJMP CLEANUP

MULTIPLY:
CJNE A, #3, DIVIDE
MOV A, KBUFFERA
MOV B, KBUFFERB
MUL AB
MOV R0, A
MOV B, #10
DIV AB
CJNE A, #0, MULTWODIGITS
MOV DISPLAYA, R0
SJMP CLEANUP
MULTWODIGITS:
MOV DISPLAYB, A
MOV DISPLAYA, B
SJMP CLEANUP

DIVIDE:
CJNE A, #4, CALCULATEDONE
MOV A, KBUFFERA
MOV B, KBUFFERB
DIV AB
MOV DISPLAYA, B
MOV DISPLAYR, #1
MOV DISPLAYC, A
SJMP CLEANUP

NONEOFTHEABOVE:
MOV A, MBUFFER
CJNE A, #0, STOREB
STOREA:
MOV KBUFFERA, KEY
SJMP STOREDONE
STOREB:
MOV KBUFFERB, KEY
STOREDONE:
MOV A, KEY
CJNE A, #0, DISPLAYKEY
SJMP CALCULATEDONE
DISPLAYKEY:
MOV DISPLAYA, KEY
SJMP CALCULATEDONE

CLEANUP:
MOV KBUFFERA, #0
MOV KBUFFERB, #0
MOV MBUFFER, #0
MOV KEY, #0
MOV MODE, #0
MOV A, #0
MOV B, #0
CALCULATEDONE:
RET

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;; Subroutine: OUTPUT
;;;;; Purpose: Updates the display.
OUTPUT:
MOV P2, #3
MOV P1, DISPLAYD
ACALL TIMER

MOV P2, #2
MOV P1, DISPLAYC
ACALL TIMER

MOV P2, #1
MOV A, DISPLAYR
CJNE A, #1, DISPLAYBNOW
MOV P1, #0FFh
CPL P2.4
CPL P2.5
SJMP DISPLAYANOW
DISPLAYBNOW:
MOV P1, DISPLAYB

DISPLAYANOW:
ACALL TIMER
MOV P2, #0
MOV P1, DISPLAYA
RET

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;; Subroutine: INPUT
;;;;; Purpose: Read buttons pressed on keypad.
INPUT:
MOV MODE, #0
MOV P0, #0FFH
CLR P0.4
ACALL TIMER
MOV A,P0
ANL A, #0FH
CJNE A, #0FH, ROWONECOLONE

SETB P0.4
CLR P0.5
ACALL TIMER
MOV A, P0
ANL A, #0FH
CJNE A, #0FH, ROWTWOCOLONE

SETB P0.5
CLR P0.6
ACALL TIMER
MOV A, P0
ANL A, #0FH
CJNE A, #0FH, ROWTHREECOLONE

SETB P0.6
CLR P0.7
ACALL TIMER
MOV A, P0
ANL A, #0FH
CJNE A, #0FH, ROWFOURCOLONE
RET

ROWONECOLONE:
CJNE A, #14, ROWONECOLTWO
MOV KEY, #1h
RET
ROWONECOLTWO:
CJNE A, #13, ROWONECOLTHREE
MOV KEY, #2h
RET
ROWONECOLTHREE:
CJNE A, #11, ROWONECOLFOUR
MOV KEY, #3h
RET
ROWONECOLFOUR:
MOV MODE, #1 ; mode 1 = ADD
RET

ROWTWOCOLONE:
CJNE A, #14, ROWTWOCOLTWO
MOV KEY, #4h
RET
ROWTWOCOLTWO:
CJNE A, #13, ROWTWOCOLTHREE
MOV KEY, #5h
RET
ROWTWOCOLTHREE:
CJNE A, #11, ROWTWOCOLFOUR
MOV KEY, #6h
RET
ROWTWOCOLFOUR:
MOV MODE, #2 ; mode 1 = SUB
RET

ROWTHREECOLONE:
CJNE A, #14, ROWTHREECOLTWO
MOV KEY, #7h
RET
ROWTHREECOLTWO:
CJNE A, #13, ROWTHREECOLTHREE
MOV KEY, #8h
RET
ROWTHREECOLTHREE:
CJNE A, #11, ROWTHREECOLFOUR
MOV KEY, #9h
RET
ROWTHREECOLFOUR:
MOV MODE, #3 ; mode 1 = MULT
RET

ROWFOURCOLONE:
CJNE A, #14, ROWFOURCOLTWO
MOV CLEARCALLED, #1
ACALL CLEAR
RET
ROWFOURCOLTWO:
CJNE A, #13, ROWFOURCOLTHREE
MOV KEY, #0h
RET
ROWFOURCOLTHREE:
CJNE A, #11, ROWFOURCOLFOUR
MOV MODE, #9 ; mode 9 = EQUALS
RET
ROWFOURCOLFOUR:
CJNE A, #7, NOKEYSCAN
MOV MODE, #4 ; mode 4 = DIVIDE
RET

NOKEYSCAN:
RET

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;; Subroutine: CLEAR
;;;;; Purpose: Reset the shit out of it.
CLEAR:
MOV KBUFFERA, #0
MOV KBUFFERB, #0
MOV MBUFFER, #0
MOV DISPLAYA, #0
MOV DISPLAYB, #0
MOV DISPLAYC, #0
MOV DISPLAYD, #0
MOV DISPLAYR, #0
MOV KEY, #0
MOV MODE, #0
MOV A, #0
MOV B, #0
MOV A, CLEARCALLED
CJNE A, #0, CLEARRET
LJMP MAIN
CLEARRET:
MOV A, #0
MOV CLEARCALLED, #0
RET

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;; Subroutine: TIMER
;;;;; Purpose: Produce a 58ms-ish delay on ACALL.
TIMER:
MOV R0, #255
TIMELOOPA:
DJNZ R0, TIMELOOPA
TIMEDONE:
RET

END