📄 cerebv41.c
字号:
servo_curr = servo_curr + 1;
servo_curr = servo_curr & 0x07; // increment to next servo, mod 8 //
servo_switch = servo_switch << 1;
if (servo_switch == 0) servo_switch = 1; // increment to next servo port bit //
servo_state = 1;
}
clear_bit(INTCON, 2); // clear T0IF = 0;
}
// end of servo control
// Analog-digital converter code //////////////////
char ADCON0@0x1f;
char ADRESH@0x1e;
char ADCON1@0x9f;
// this is called with a character 0 through 7 and returns
// an analog-digital reading
char adc_read(char ch) {
ADCON0 = (ch << 3) & 56; // shift ch to correct bit position
ADCON0 |= 0x81; // Tad = Fosc/32, ADC on.
delay_us(12); // wait for Tacq
ADCON0 |= 4; // acquire go!
while (ADCON0 & 4); // wait for AD to complete
delay_us(4); // wait for 2Tad
return ADRESH; // return captured value
}
// End of Analog-Digital conversion code //////////////
// PWM Motor code //////////////
//globals for motor PWM control//
char ccpcon;
char CCP1CON@0x17;
char CCP2CON@0x1d;
char TMR2@0x11;
char PR2@0x92;
char CCPR1L@0x15;
char CCPR2L@0x1b;
char T2CON@0x12;
char PORTC@0x07;
void pwm_init(void) {
// init hardware PWM
CCP1CON = 0; // CCP off
CCP2CON = 0;
TMR2 = 0;
PR2 = 0xff; // 0x3f: 78kHz, 0xff: 19.5kHz
CCPR1L = 0; // actually, I don't think the output is inverted! 0 = stop.
CCPR2L = 0;
TRISC = TRISC & 11011000b; // set DC motor pins to output
clear_bit(TRISB,1); // clear for motor direction output lines - chnged 0 to 1 illah 1/16/03
clear_bit(TRISA,4); // clear for motor direction output lines
ccpcon = 00111100b; // setup reg mask
CCP1CON = ccpcon; // CCP module to PWM mode
CCP2CON = ccpcon;
set_bit(T2CON,TMR2ON);
}
// parameters are motor number (0 or 1), direction (0 or 1) and speed //
// presumes that port c, bits 5 and 0 are being used for this.
void pwm_setvel8(char n, char d, char c) {
if (n == 0) {
if (d == 0) { //set_bit(PORTC,5);
set_bit(PORTC,5);
clear_bit(PORTB,1); // changed 0 to 1 illah 1/16/2003
}
else { //clear_bit(PORTC,5);
clear_bit(PORTC,5);
set_bit(PORTB,1); // changed 0 to 1 illah 1/16/2003
}
CCPR1L = c;
}
else if (n==1) {
if (d == 0) { //set_bit(PORTC,0);
set_bit(PORTC,0);
clear_bit(PORTA,4);
}
else { //clear_bit(PORTC,0);
clear_bit(PORTC,0);
set_bit(PORTA,4);
}
CCPR2L = c;
}
}
// END of PWM Motor Code ///////////////////////
// Code for I2C Master communication implementation
// Author: Rashmi Patel
// Credits: J. Winpenny for original C2C I2C file
// Date: 7/12/2003
// Bits of SSPSTAT
#define SMP 7
#define CKE 6
#define D_A 5
#define P 4
#define S 3
#define R_W 2
#define R_W_MASK 0x04
#define UA 1
#define BF 0
// Bits of SSPCON2
#define GCEN 7
#define ACKSTAT 6
#define ACKDT 5
#define ACKEN 4
#define RCEN 3
#define PEN 2
#define RSEN 1
#define SEN 0
// Bits of PIR1
#define PSPIF 7
#define ADIF 6
#define RCIF 5
#define TXIF 4
#define SSPIF 3
#define SSPIF_MASK 0x08
#define CCP1IF 2
#define TMR2IF 1
#define TMR1IF 0
// Bits of SSPCON
#define WCOL 7
#define SSPOV 6
#define SSPEN 5
#define CKP 4
#define SSPM3 3
#define SSPM2 2
#define SSPM1 1
#define SSPM0 0
/************************* I2C Routines ************************************/
/**************************************/
/* Configure the MSSP as an I2C Port */
/* For PIC16F877 */
/* */
/* Relevant port pins configured as */
/* Inputs */
/**************************************/
void i2c_init(void)
{
set_bit( SSPCON, SSPEN ); // Enable I2C mode
set_bit( SSPCON, SSPM3 ); // Setup I2C
clear_bit( SSPCON, SSPM2 );
clear_bit( SSPCON, SSPM1 );
clear_bit( SSPCON, SSPM0 );
set_bit( STATUS, RP0 ); // *** Register page 1 ***
SSPCON2 = 0;
clear_bit( SSPSTAT, SMP );
clear_bit( SSPSTAT, CKE ); // Set I2C Levels
// Set I2C Speed
SSPADD = 49; // 100k at 20Mhz clock
clear_bit( STATUS, RP0 ); // *** Register page 0 ***
}
/**************************************/
/* Waits for I2C process to complete */
/**************************************/
void i2c_wait(void)
{
while ( !( PIR1 & SSPIF_MASK ) ); // Wait for Interrupt
clear_bit( PIR1, SSPIF ); // Clear Interrupt flag
}
/***********************/
/* Send a char via I2C */
/***********************/
void i2c_send( char ch )
{
SSPBUF = ch; // Load DATA to send
i2c_wait(); // Wait for completion
}
/**************************/
/* Receive a char via I2C */
/**************************/
char i2c_receive(void)
{
set_bit( STATUS, RP0 ); // *** Register page 1 ***
while ( SSPSTAT & R_W_MASK ); // Wait for Transmit to end
set_bit( SSPCON2, RCEN ); // Enable I2C receiver
clear_bit( STATUS, RP0 ); // *** Register page 0 ***
i2c_wait(); // Wait for data to arrive.
return SSPBUF; // Return the data
}
/**************************/
/* Send an I2C ACK */
/**************************/
void i2c_ack(void)
{
set_bit( STATUS, RP0 ); // *** Register page 1 ***
clear_bit( SSPCON2, ACKDT ); // Setup for ACK
set_bit( SSPCON2, ACKEN ); // Send ACK
clear_bit( STATUS, RP0 ); // *** Register page 0 ***
i2c_wait(); // Wait for completion
}
/**************************/
/* Send an I2C ACK */
/**************************/
void i2c_nak(void)
{
set_bit( STATUS, RP0 ); // *** Register page 1 ***
set_bit( SSPCON2, ACKDT ); // Setup for NAK
set_bit( SSPCON2, ACKEN ); // Send NAK
clear_bit( STATUS, RP0 ); // *** Register page 0 ***
i2c_wait(); // Wait for completion
}
/**************************/
/* Generate an I2C START */
/**************************/
void i2c_start(void)
{
set_bit( STATUS, RP0 ); // *** Register page 1 ***
set_bit( SSPCON2, SEN ); // Initiate START condition
clear_bit( STATUS, RP0 ); // *** Register page 0 ***
i2c_wait(); // Wait for completion
}
/***************************/
/* Generate an I2C RESTART */
/***************************/
void i2c_restart(void)
{
set_bit( STATUS, RP0 ); // *** Register page 1 ***
set_bit( SSPCON2, RSEN ); // Initiate START condition
clear_bit( STATUS, RP0 ); // *** Register page 0 ***
i2c_wait(); // Wait for completion
}
/**************************/
/* Generate an I2C STOP */
/**************************/
void i2c_stop(void)
{
set_bit( STATUS, RP0 ); // *** Register page 1 ***
set_bit( SSPCON2, PEN ); // Generate STOP condition
clear_bit( STATUS, RP0 ); // *** Register page 0 ***
i2c_wait(); // Wait for completion
}
// interrupt handler code
// variables for saving state during interrupt handling
int save_w;
int save_status;
//the actual interrupt handler function itself.
void interrupt(void) {
//store current state of processor
asm {
movwf _save_w
swapf STATUS,W
bcf STATUS,5
bcf STATUS,6
movwf _save_status
} // end asm
if (INTCON & 36) do_servo();
// in other words if (TOIE & TOIF) then do_servo() //
// restore processor state
asm {
swapf _save_status,W
movwf STATUS
swapf _save_w,F
swapf _save_w,W
} // end asm
}
// this initializes the buttons and leds on cerebellum //
// this also initializes PortD digital as outputs, for servoes and digital outs //
void init_cerebellum(void)
{
TRISB &= 207; // make port B pins 4 and 5 write-out able for LED's by setting
// tristate bits 4 and 5 to zero
PORTB &= 207; // turn off yellow and green LED's
TRISD = 0; // port D as outputs for Servo cmds and digital output settings
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -