You are on page 1of 9

/*

* Project name:
LED_Blinking (Simple 'Hello World' project)
* Copyright:
(c) Mikroelektronika, 2011.
* Revision History:
20110929:
- initial release (FJ);
* Description:
This is a simple 'Hello World' project. It turns on/off LEDs connected to
PORTA, PORTB, PORTC, PORTD and PORTE.
* Test configuration:
MCU:
PIC18F45K22
http://ww1.microchip.com/downloads/en/DeviceDoc/41412D.pdf
Dev.Board:
EasyPIC7 - ac:LEDs
http://www.mikroe.com/easypic/
Oscillator:
HS-PLL 32.0000 MHz, 8.0000 MHz Crystal
Ext. Modules:
None.
SW:
mikroC PRO for PIC
http://www.mikroe.com/mikroc/pic/
* NOTES:
- Turn ON the PORT LEDs at SW3.
*/
sbit
sbit
sbit
sbit
sbit
sbit
sbit
sbit

Em1
Sm1
Em2
Sm2
Em3
Sm3
Em4
Sm4

at
at
at
at
at
at
at
at

RD0_bit;
RD1_bit;
RD2_bit;
RD3_bit;
RD4_bit;
RD5_bit;
RD6_bit;
RD7_bit;

sbit
sbit
sbit
sbit
sbit
sbit
sbit
sbit

Em1_Direction
Sm1_Direction
Em2_Direction
Sm2_Direction
Em3_Direction
Sm3_Direction
Em4_Direction
Sm4_direction

at
at
at
at
at
at
at
at

sbit
sbit
sbit
sbit
sbit

pin_lift_en
pin_lift_up
pin_lift_down
pin_senzor
port_servo

at
at
at
at
at

sbit
sbit
sbit
sbit
sbit

pin_lift_en_direction
pin_lift_up_direction
pin_lift_down_direction
pin_senzor_direction
port_servo_direction

TRISD0_bit;
TRISD1_bit;
TRISD2_bit;
TRISD3_bit;
TRISD4_bit;
TRISD5_bit;
TRISD6_bit;
TRISD7_bit;
rc2_bit;
rc0_bit;
rc1_bit;
rc6_bit;
rc7_bit;

/*sbit LCD_RS at RB2_bit;


sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;

at
at
at
at
at

TRISC0_bit;
TRISC1_bit;
TRISC2_bit;
TRISC6_bit;
TRISc7_bit;

sbit LCD_D7 at RB7_bit;


sbit
sbit
sbit
sbit
sbit
sbit

LCD_RS_Direction
LCD_EN_Direction
LCD_D4_Direction
LCD_D5_Direction
LCD_D6_Direction
LCD_D7_Direction

sbit
sbit
sbit
sbit
sbit
sbit

LCD_RS
LCD_EN
LCD_D4
LCD_D5
LCD_D6
LCD_D7

sbit
sbit
sbit
sbit
sbit
sbit

LCD_RS_Direction
LCD_EN_Direction
LCD_D4_Direction
LCD_D5_Direction
LCD_D6_Direction
LCD_D7_Direction

const
const
const
const
const
const

at
at
at
at
at
at

at
at
at
at
at
at

TRISB2_bit;
TRISB3_bit;
TRISB4_bit;
TRISB5_bit;
TRISB6_bit;
TRISB7_bit;

*/

RB4_bit;
RB5_bit;
RB0_bit;
RB1_bit;
RB2_bit;
RB3_bit;
at
at
at
at
at
at

TRISB4_bit;
TRISB5_bit;
TRISB0_bit;
TRISB1_bit;
TRISB2_bit;
TRISB3_bit;

unsigned long LUNGIME_MINIMA = 2000;


unsigned long LUNGIME_MAXIMA = 3000;
short CAPACITATE_LIFT = 4;
unsigned long LIFT_START_DELAY = 1000;
unsigned long LIFT_UP_TIME = 5000;
unsigned long CONVEIOR_TIMER_TOTAL = 20000;

const int CONV_STEP_HIGH = 3;


const int CONV_STEP_LOW = 1;
const short SERVO_PERIOD = 66;
= 20ms perioada pentru servo (50hz)
enum directieServ { STANGA = 4, CENTRU = 5, DREAPTA = 6 }
directieServo;

// 200 /// 0.3 *66

enum conveioare {C_PRINCIPAL, C_STANGA, C_CENTRU, C_DREAPTA };


enum sLift { INACTIV, ACTIV, ON_START_DELAY }
stareLift;

// 11, 15, 19

char cnt
unsigned
unsigned
unsigned

= 0;
long counter;
short servoCounter;
long lastcount;

static short bufferLift;


char liftActiv;
unsigned long liftCounter;
short conveiorActiv[4];
long int conveiorTimerActual[4];
//char resolution = 1;
//sbit tempBit;
short lowbyte;
//timer low
short highbyte;
//timer high
int word;
//timer acc
int Step_x1(int xx)

{
xx = 0;
Delay_ms(5);
xx = 1;
Delay_ms(5);
return xx;

// 1.3/sec

}
void Interrupt() {
if (tmr1if_bit) {
TMR1IF_bit = 0;
TMR1H = 0xF1;
TMR1L = 0xF0;
servoCounter++;
if (servoCounter > SERVO_PERIOD)
servoCounter = 0;
if (servoCounter < directieServo)
port_servo = 1;
else
port_servo = 0;
}
if (tmr0if_bit) {
tmr0h = 0xD1;
tmr0l = 0x20;
TMR0IF_bit = 0;
counter++;
}
}
short caramida_start = 0;
unsigned long caramida_start_count;
//
//
//
//

functia aceasta intoarce lungimea caramizii


in cazul in care caramida nu a ajuns inca la senzor sau
caramida este in curs de citire, functia intoarce valoarea 0
altfel, intoarce lungimea caramizii (o variabila de tip long)

void AfisareLCD(long int valoare ) {


static char temp[12];
longtostr(valoare, temp);
Lcd_Out(1, 1, temp);
}
unsigned long CitireLungimeCaramida() {
if (!caramida_start)
// nicio caramida in senzor
{
if (!pin_senzor)
// caramida tocmai a intrat in senzor
// a se inlocui porta.b0 cu portul pe care este cone
ctat senzorul
{
caramida_start = 1;
caramida_start_count = counter;
return 0;
// tocmai incepem sa citim o caramida => intoarcem v
aloarea 0
}
else
return 0;
// nicio caramida in senzor => intoarcem valoarea 0
}
else
// caramida probabil in senzor
{

if (!pin_senzor)
// caramida este inca in senzor
return 0;
// intoarcem 0
else
// caramida a iesit din senzor
{
// intoarcem lungimea caramizii
caramida_start = 0; // resetam caramida_start pentru ca functia sa nu se
mai apeleze pana nu se detecteaza o caramida noua
if (counter > caramida_start_count) // citire OK
return (counter - caramida_start_count); // intoarcem lungimea caramizi
i
else
// counter-ul s-a dat peste cap in timpul citirii (a
ajuns la maxim si a luat-o de la inceput)
// intoarcem lungimea maxima a unui long minus caram
ida_start_count plus counter
{
// dar te las pe tine sa cauti care este lungimea m
axima a unui long
unsigned long max_long = 4294967295;
return (max_long - caramida_start_count + counter);
}
}
}
return 0;
}
void liftUp() {
if (stareLift == INACTIV) {
// primire comanda pornire (ace
asta conditie este adevarata o singura data la fiecare pornire)
bufferLift++;
// incrementam numarul de piese
aflate in buffer
stareLift = ON_START_DELAY;
// schimbam starea liftului in
"on start delay"
liftCounter = 0;
// resetam counterul
}
else if (stareLift == ON_START_DELAY) {
// s-a pornit deja comanda de p
ornire; se asteapta un timp pentru ca piesa sa ajunga pe lift
// inainte sa inceapa sa urce
if (liftCounter < LIFT_START_DELAY) {
// inca nu s-a depasit timpul d
e asteptare inainte de start
liftCounter++;
// incrementam counterul
}
else {
// s-a depasit timpul de astept
are => incepem urcarea
liftCounter = 0;
// resetam counterul
stareLift = ACTIV;
// schimbam stare in "lift acti
v"
}
}
else {
// liftul este ACTIV (in urcare
)
pin_lift_en = 1;
portc.b2 = 1;
pin_lift_up = 1;
// pornire lift
portc.b0 = 1;
if (liftCounter < LIFT_UP_TIME)
// nu s-a atins inca timpul de
urcare
{
liftCounter++;
// incrementare counter lift
//AfisareLCD(liftCounter);
}
else {
// s-a terminat urcarea
stareLift = INACTIV;
// resetam sarea liftului la ce

a initiala (INACTIV)
liftActiv = 0;
// resetam flag-ul de lift acti
v ca sa nu mai intre in aceasta functie pana la urmatoarea piesa
pin_lift_up = 0;
// oprire lift
pin_lift_en = 0;
portc.b0 = 0;
portc.b1 = 0;
portc.b2 = 0;
}
}
}
void TimersInit() {
//t0 - 1ms
t0con = 0x88;
TMR0IF_bit = 0;
tmr0h = 0xd1;
tmr0l = 0x20;
T0IE_bit = 1;
//t1 - 0.3ms
T1CON = 0X01;
TMR1IF_bit = 0;
TMR1H = 0xF1;
TMR1L = 0xF0;
TMR1IE_bit = 1;
INTCON = 0xC0;
}
/* Instructiuni pentru initializarea microcontrollerului */
void InitMCU() {
adcon0 = 0;
adcon1=0x0F;
cmcon=0b00000111;
TRISC = 0x00;
// Set PortC as output
PORTC = 0x00;
// tmr0h=0;
// t0con=0b11000010;
// t0con.TMR0ON = 1;
// t0con.TMR0IE = 1;
//INTCON.GIE = 0b10100000;
// intcon = 0;
// t1con = 0;
GIE_bit = 1; //intreruperi activate
// TMR0ON_bit = 1;
// while(1) {
// lowbyte = tmr0l;
// highbyte = tmr0h;
//word = highbyte << 8 + lowbyte;
//}
Em1_Direction = 0;
Sm1_Direction = 0;
Em2_Direction = 0;
Sm2_Direction = 0;
Em3_Direction = 0;
Sm3_Direction = 0;
Em4_Direction = 0;
Sm4_Direction = 0;

Em1 = 1;
Sm1 = 0;
Em2 = 1;
Sm2 = 0;
Em3 = 1;
Sm3 = 0;
Em4 = 1;
portd.b6 = 1;
Sm4 = 0;
pin_senzor_direction = 1;
pin_lift_en_direction = 0;
pin_lift_down_direction = 0;
pin_lift_up_direction = 0;
port_servo_direction = 0;
TRISA = 0xFF;
trisb = 0x00;
trisb = 0x00;

// Keypad inputs

//t0con = 0x88;
//tmr0h = 0xfD;
//tmr0l = 0xA8;
}
void main() {
unsigned long lungimeCaramida = 0;
short cycle = 0;
int i;
InitMCU();
TimersInit();
/* Initializare variabile */
bufferLift = 0; // numarul de caramizi existente in bufferul liftului
liftActiv = 0; // starea initiala a liftului (inactiv)
lastcount = 0; // utilizat pentru executarea cu periada fixa a programului
(1ms)
counter = 7;
// utilizat pentru executarea cu periada fixa a programului
(1ms)
directieServo = CENTRU; // pozitia initiala a servo-ului
for (i = 0; i < 4; i++) {
conveiorActiv[i] = 0;
// conveioarele sunt initial oprite
conveiorTimerActual[i] = 0; // initializare timere conveioare
}
/* Initializare LCD */
Lcd_Init();
Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_CURSOR_OFF);
LCD_OUT(2, 1, "while");

// Clear display
// Cursor off

Em1 = 0; /* Activare motor conveior 1 */


while (1)
{
while (lastcount == counter) portb.b3 = 1;
lastcount = counter;
portb.b3 = 0;

//cycle = counter % 100;


/// CITIRE LUNGIME CARAMIDA //////////////
//if (counter % 2 == 0)
ii din 2 in 2 ms
lungimeCaramida = CitireLungimeCaramida();
if (lungimeCaramida > 100)
senzor
{

// citim lungimea caramiz


//o caramida a trecut de

//actionam in functie de lu
ngimea caramizii
AfisareLCD(lungimeCaramida);
if (lungimeCaramida < LUNGIME_MINIMA)
// caramida scurta detectat
a
{
// a se schimba valoarea LU
NGIME_MINIMA cu cea corecta care reiese din teste (o valoare intre 0 si 999999)
directieServo = STANGA;
// orientare servo catre ba
nda cu caramizi scurte
conveiorActiv[C_STANGA] = 1;
// activam conveiorul STANG
A
conveiorTimerActual[C_STANGA] = 0;
// resetam timerul conveior
ului
}
else if (lungimeCaramida < LUNGIME_MAXIMA) // caramida buna (intre LUN
GIME_MINIMA si LUNGIME_MAXIMA)
{
// a se schimba valoarea LU
NGIME_MAXIMA cu cea corecta
directieServo = CENTRU;
// orientare servo catre ba
nda cu caramizi bune
conveiorActiv[C_CENTRU] = 1;
conveiorTimerActual[C_CENTRU] = 0; // activam conveiorul CENTR
U
if (bufferLift < CAPACITATE_LIFT) // resetam timerul conveior
ului
liftActiv = 1;
}
else
// caramida mare
{
directieServo = DREAPTA;
// orientre servo catre ban
da cu caramizi mari
conveiorActiv[C_DREAPTA] = 1;
// activam conveioru
l DREAPTA
conveiorTimerActual[C_DREAPTA] = 0;
// resetam timerul c
onveiorului
}
}
///////////////////////////////
/// SETARE DIRECTIE SERVO//////
// SE FACE DIRECT IN INTRERUPERE //
///////////////////////////////
/// INCARCARE BUFFER //////////
if (liftActiv) {
// daca liftul este ACTIV (o caramida a tre
cut de senzor)
liftUp();
// se apeleaza functia pentru lift
}
///////////////////////////////
/*
// portb = 0xf0;

if (Button(&PORTA, 0, 50, 1))


{
Em1 = 0;
Em2 = 0;
}
if ((Em2 == 0) && (counter % 1 == 0))
{
Sm1=!Sm1;
Sm2=!Sm2;
if (porta.B1 == 1) {Em2 = 1; Em1=1;}
}
*/
//miscare conveioare////////////
if (counter % CONV_STEP_HIGH == 0) {
Sm1 = !Sm1;
//
}
//
//

if (counter % CONV_STEP_LOW == 0)
{
if (conveiorActiv[C_STANGA])
{
Em2 = 0;

// step conveior 1
// step celelalte conveioare
// conveior stanga
// ne asiguram ca conveiorul este

pornit
Sm2 = !Sm2;
conveiorTimerActual[C_STANGA]++;

// generam stepul
// incrementam timpul cat a mers

conveiourl
if (conveiorTimerActual[C_STANGA] > CONVEIOR_TIMER_TOTAL) { // conve
iorul a depasit timpul total cat trebuie sa fie ACTIV; oprire conveior
Em2 = 1;
// oprim conveiorul hardware
Sm2 = 0;
conveiorActiv[C_STANGA] = 0;
// oprim conveiorul software
}
}
if (conveiorActiv[C_CENTRU])
// conveior centru
{
Em3 = 0;
Sm3 = !Sm3;
// AfisareLCD(conveiorTimerActual[C_CENTRU]);
conveiorTimerActual[C_CENTRU]++;
if (conveiorTimerActual[C_CENTRU] > CONVEIOR_TIMER_TOTAL) { // oprir
e conveior
Em3 = 1;
Sm3 = 0;
conveiorActiv[C_CENTRU] = 0;
}
}
if (conveiorActiv[C_DREAPTA])
// conveior dreapta
{
Em4 = 0;
portd.b6 = 0;
Sm4 = !Sm4;
conveiorTimerActual[C_DREAPTA]++;
if (conveiorTimerActual[C_DREAPTA] > CONVEIOR_TIMER_TOTAL) { // opri
re conveior
Em4 = 1;
portd.B6 = 1;
Sm4 = 0;
conveiorActiv[C_DREAPTA] = 0;
}

}
}
////////////////////////////////
}
}
[DEVICE]
Name=UNKNOWN
Clock=10000000
[FILES]
Count=0
[BINARIES]
Count=0
[IMAGES]
Count=0
ActiveImageIndex=-1
[OPENED_FILES]
Count=0
[EEPROM]
Count=0
[ACTIVE_COMMENTS_FILES]
Count=0
[OTHER_FILES]
Count=0
[SEARCH_PATH]
Count=3
Path0=C:\Users\Public\Documents\Mikroelektronika\mikroC PRO for PIC\defs\
Path1=C:\Users\Public\Documents\Mikroelektronika\mikroC PRO for PIC\Uses\P18\
Path2=C:\Users\SEBA\Downloads\
[HEADER_PATH]
Count=0
[HEADERS]
Count=0
[PLDS]
Count=0
[Useses]
Count=0
[MEMORY_MODEL]
Value=0
[BUILD_TYPE]
Value=0
[ACTIVE_TAB]
Value=
[USE_EEPROM]
Value=0
[USE_HEAP]
Value=0
[HEAP_SIZE]
Value=2000
[EEPROM_DEFINITION]
Value=
[EXPANDED NODES]
Count=0

You might also like