- CODE: SELECT_ALL_CODE
/*
* File: main.c
* Author: user
*
* Created on July 18, 2016, 5:55 PM
*/
#include <xc.h>
//#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)
//#pragma config LVP = ON // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
//#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
//#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
//#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
//#pragma config WDTE = OFF
//#pragma config FOSC = XT
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = ON // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
#if defined(WDTE_OFF)
__CONFIG(WDTE_OFF & LVP_OFF);
#elif defined (WDTDIS)
__CONFIG(WDTDIS & LVPDIS);
#endif
#define MOTOR_R1 RC0 //Control pin for motor, going through motor driver L293D, right motor
#define MOTOR_R2 RC3 //Control pin for motor, going through motor driver L293D, right motor
#define MOTOR_L1 RC4 //Control pin for motor, going through motor driver L293D, left motor
#define MOTOR_L2 RC5 //Control pin for motor, going through motor driver L293D, left motor
#define p_select 0
#define p_joyl 1
#define p_joyr 2
#define p_start 3
#define p_up 4
#define p_right 5
#define p_down 6
#define p_left 7
#define p_l2 8
#define p_r2 9
#define p_l1 10
#define p_r1 11
#define p_triangle 12
#define p_circle 13
#define p_cross 14
#define p_square 15
#define p_con_status 28
#define p_motor1 29
#define p_motor2 30
#define SPEEDL CCPR1L //PWM register for left motor, to control speed
#define SPEEDR CCPR2L //PWM register for right motor, to control speed
void init(void);
void SKPS_PScon(void); //function for PS2 control with SKPS
void forward(void);
void stop (void);
void backward (void);
void reverse (void);
void left(void);
void right(void);
void uart_init(void); //initialize UART module, 9600 baud
void uart_send(unsigned char data); //send data out via UART
unsigned char uart_rec(void); //uart receive, 1 byte
unsigned char skps(unsigned char data); //transmit command out to SKPS using UART and wait for response
void disable_global_int(void); //disable global interrupt
int main()
{
init();
SKPS_PScon(); // mode 5 : PS2 Controller Mode
}
void uart_init(void)
{
BRGH = 1; //baud rate high speed option
TXEN = 0; //enable transmission
SPBRG = 0x40; //set baud rate to 9600 at 10Mhz
TX9 = 0;
CREN = 1; //enable continuous reception
SPEN = 1; //enable serial port
RX9 = 0;
if(OERR == 1) //check if there is overrun error.
{
CREN = 0;
CREN = 1; //reset the OERR
}
if(RCREG); //simple read of receive buffer to clear it
if(RCREG);
RCIE = 0; //disable receiver interrupt initially
}
//function to send out a byte via uart
void uart_send(unsigned char data)
{
while(TXIF == 0); //wait for previous data to finish send out
TXREG = data; //send new data
}
unsigned char uart_rec(void) //function to wait for a byte receive from uart
{
if(OERR == 1) //check if there is overrun error.
{
CREN = 0;
CREN = 1; //reset the OERR
if(RCREG); //simple read of receive buffer to clear it
if(RCREG);
RCIE = 0; //disable receiver interrupt initially
}
while(RCIF==0); //wait for data to received
return RCREG; //return the received data
}
unsigned char skps(unsigned char data) //function to read button and joystick
{ //information on ps controller
uart_send(data);
return uart_rec();
}
void disable_global_int(void)
{
GIE = 0; //disable global interrupt
PEIE = 0; //disable peripheral interrupt
}
void init()
{
PORTA = 0;
PORTB = 0;
PORTC = 0;
PORTD = 0;
PORTE = 0;
// Tris configuration (input or output)
TRISA = 0b00110011; //set RA0 and RA2 pin as input,other as output
//PR23 Rev2.0 has RA4 and RA5 as input for IR01A
TRISB = 0b00011111; //set RB0-RB4 pin as input, other as output
TRISC = 0b10000000; //set PORTC pin as output, RC7 is UART Receive pin (input)
TRISD = 0b00000000; //set all PORTD pin as output
TRISE = 0b00000011; //RE0 and RE1 as input (Switches) RE2 as output (LED)
// motor PWM configuration
PR2 = 255; // set period register for PWM
T2CON = 0b00000100; // Timer Control register, timer 2 ON, prescaler = 1:1
CCP1CON = 0b00001100; // config for RC1 to generate PWM( for more detail refer datasheet section 'capture/compare/pwm')
CCP2CON = 0b00001100; // config for RC2 to generate PWM
SPEEDL = 0; //initial PWM is zero
SPEEDR = 0; //initial PWM is zero
stop(); //motors are off
}
void SKPS_PScon()
{
stop(); //stop mobile robot
uart_init(); //initialize UART
while(1)
{
//button control for mobilility
if(skps(p_up)==0) //check "up" button
{
forward(); //move forward
SPEEDL=230;
SPEEDR=230;
}
else if(skps(p_down)==0) //check "down" button
{
backward(); //move backward
SPEEDL=230;
SPEEDR=230;
}
else if(skps(p_left)==0) //check "left" button
{
left(); //rotate left
SPEEDL=230;
SPEEDR=230;
}
else if(skps(p_right)==0) //check "right" button
{
right(); //rotate right
SPEEDL=230;
SPEEDR=230;
}
else
{
stop();
SPEEDL = 0;
SPEEDR = 0;
}
}//while(1)
}
void forward () //function to enable robot to move forward, do not change the speed
{
MOTOR_R1 = 0;
MOTOR_R2 = 1;
MOTOR_L1 = 0;
MOTOR_L2 = 1;
}
void backward () //function to enable robot to move backward, do not change the speed
{
MOTOR_R1 = 1;
MOTOR_R2 = 0;
MOTOR_L1 = 1;
MOTOR_L2 = 0;
}
void left() //function to enable robot to turn left, do not change the speed
{
MOTOR_R1 = 0;
MOTOR_R2 = 1;
MOTOR_L1 = 1;
MOTOR_L2 = 0;
}
void right() //function to enable robot to turn right, do not change the speed
{
MOTOR_R1 = 1;
MOTOR_R2 = 0;
MOTOR_L1 = 0;
MOTOR_L2 = 1;
}
void stop() //function to enable robot to stop, do not change the speed
{
MOTOR_R1 = 0;
MOTOR_R2 = 0;
MOTOR_L1 = 0;
MOTOR_L2 = 0;
}
My code as shown had downloaded into PIC16F877A. This code mostly copy from the sample code provide by cytron website. Yet, the MOTOR_R1, MOTOR_R2, MOTOR_L1 and MOTOR_L2 do not respond to the button pressed on the joystick. The oscillator i used is 10Mhz with 9600 baud rate. MOTOR_R1, MOTOR_R2, MOTOR_L1 and MOTOR_L2 connected to LED to test whether the pin is set.