Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
en:projects:can_windscreen_wiper [2010/03/14 18:46] mikk.leinien:projects:can_windscreen_wiper [2020/07/20 12:00] (current) – external edit 127.0.0.1
Line 1: Line 1:
 +====== CAN windscreen wiper ======
 +
 +//Requirements: [HW] 2 x [[en:hardware:arm-can:controller]], [HW] Servo-motor//
 +
 +[{{  :images:projects:can_windscreen_wiper:windscreen_wiper.gif|Windscreen wiper in different modes}}]
 +
 +This project demonstrates how to use CAN interface to transfer commands from one device to other. Two ARM-CAN contollers are need of which one acts as a lever on the steering wheel of a car and another one as a windscreen wiper controller. When buttons is pressed on lever controller, next wiping mode is selected and wiper is notified. Servo-motor is used for simulating the wiper. There are three modes:
 +
 +  * Stop mode. Wiper is not moving. Red LED's are on.
 +  * Slow mode. Wiper is moving slowly from side to side. Green LED's are on.
 +  * Fast mode. Wiper is moving rapidly from side to side. Blue LED's are on.
 +
 +~~CL~~
 +
 +===== windscreen_wiper_control.c =====
 +
 +<code c>
 +//*****************************************************************************
 +//
 +// Windscreen wiper control
 +//
 +// Program is entirely interrupts based.
 +//
 +// Copyright (c) 2009 TUT Department of Mechatronics
 +//
 +//*****************************************************************************
 +
 +#include <inc/hw_ints.h>
 +#include <inc/hw_memmap.h>
 +#include <inc/hw_types.h>
 +#include <driverlib/sysctl.h>
 +#include <driverlib/interrupt.h>
 +#include <driverlib/gpio.h>
 +#include <driverlib/timer.h>
 +#include <driverlib/can.h>
 +#include <drivers/general.h>
 +#include <drivers/rgb_led.h>
 +
 +//*****************************************************************************
 +//
 +// Configuration.
 +//
 +//*****************************************************************************
 +#define CAN_BITRATE           250000
 +#define CAN_ACTUATOR_MSG_ID   0x01
 +#define CAN_ACTUATOR_MSG_BOX  1
 +
 +//*****************************************************************************
 +//
 +// Global variables.
 +//
 +//*****************************************************************************
 +unsigned char g_ucMode = 0;
 +
 +//*****************************************************************************
 +//
 +// The interrupt handler for the port B interrupt.
 +//
 +//*****************************************************************************
 +void PortBIntHandler(void)
 +{
 + tCANMsgObject psCommandMsg;
 +
 + //
 + // Clear the port interrupt.
 + //
 + GPIOPinIntClear(GPIO_PORTB_BASE, GPIO_PIN_7);
 +
 + //
 + // Next wiper mode of 3 modes.
 + //
 + g_ucMode = (g_ucMode + 1) % 3;
 +
 + //
 + // Create message.
 + //
 + psCommandMsg.ulMsgID    = CAN_ACTUATOR_MSG_ID;
 + psCommandMsg.ulFlags    = MSG_OBJ_NO_FLAGS;
 + psCommandMsg.ulMsgLen   = 1;
 + psCommandMsg.pucMsgData = &g_ucMode;
 +
 + //
 + // Set message.
 + //
 + CANMessageSet(CAN0_BASE, CAN_ACTUATOR_MSG_BOX,
 +               &psCommandMsg, MSG_OBJ_TYPE_TX);
 +
 + //
 + // Turn on the appropriate LED.
 + //
 + RGBLEDSetRGB((g_ucMode == 0 ? 255 : 0),
 +              (g_ucMode == 1 ? 255 : 0),
 +              (g_ucMode == 2 ? 255 : 0));
 +}
 +
 +//*****************************************************************************
 +//
 +// Main function.
 +//
 +//*****************************************************************************
 +int main(void)
 +{
 + //
 + // Set the clocking to run from the PLL at 50MHz
 + //
 + SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
 + SYSCTL_XTAL_8MHZ);
 +
 + //
 + // Enable peripherals.
 + //
 + SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
 + SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
 + SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
 + SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
 + SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);
 +
 + //
 + // Enable the peripherals that should continue to run when the processor
 + // is sleeping.
 + //
 + SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_GPIOB);
 + SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_GPIOC);    
 + SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_GPIOD);
 + SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_GPIOE);
 + SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_CAN0);
 +
 + //
 + // Drivers configuring.
 + //
 + DeviceConfigure();
 + RGBLEDConfigure();
 +
 + // 
 + // Configure button to generate interrupt on press.
 + //
 + GPIOIntTypeSet(GPIO_PORTB_BASE, GPIO_PIN_7, GPIO_FALLING_EDGE);
 + GPIOPinIntEnable(GPIO_PORTB_BASE, GPIO_PIN_7);
 + IntEnable(INT_GPIOB);
 +
 + //
 + // Configure CAN pins.
 + //    
 + GPIOPinTypeCAN(GPIO_PORTD_BASE, GPIO_PIN_0 | GPIO_PIN_1);
 +
 + //
 + // Enable the CAN controller.
 + //     
 + CANInit(CAN0_BASE);
 + CANBitRateSet(CAN0_BASE, SysCtlClockGet(), CAN_BITRATE);
 + CANEnable(CAN0_BASE);
 +
 + //
 + // Enable processor interrupts.
 + //
 + IntMasterEnable();
 +
 + //
 + // Loop forever.
 + //
 + while (1)
 + {
 + //
 + // Save power - turn off CPU.
 + //
 + SysCtlSleep();
 + }
 +}
 +</code>
 +
 +===== windscreen_wiper_actuator.c =====
 +
 +<code c>
 +//*****************************************************************************
 +//
 +// Windscreen wiper actuator
 +//
 +// Program is entirely interrupts based.
 +//
 +// Copyright (c) 2009 TUT Department of Mechatronics
 +//
 +//*****************************************************************************
 +
 +#include <inc/hw_ints.h>
 +#include <inc/hw_memmap.h>
 +#include <inc/hw_types.h>
 +#include <driverlib/sysctl.h>
 +#include <driverlib/interrupt.h>
 +#include <driverlib/gpio.h>
 +#include <driverlib/timer.h>
 +#include <driverlib/can.h>
 +#include <drivers/general.h>
 +#include <drivers/rgb_led.h>
 +#include <drivers/servo_motor.h>
 +
 +//*****************************************************************************
 +//
 +// Configuration.
 +//
 +//*****************************************************************************
 +#define SERVO_INDEX                0
 +#define CAN_BITRATE                250000
 +#define CAN_ACTUATOR_MSG_ID        0x01
 +#define CAN_ACTUATOR_MSG_BOX       1
 +#define CAN_ACTUATOR_MSG_BOX_FLAG  (1 << (CAN_ACTUATOR_MSG_BOX - 1))
 +
 +//*****************************************************************************
 +//
 +// Global variables.
 +//
 +//*****************************************************************************
 +signed long g_slWiperDirection = 1;
 +
 +//*****************************************************************************
 +//
 +// The interrupt handler for the timer2 interrupt.
 +//
 +//*****************************************************************************
 +void Timer2IntHandler(void)
 +{
 + //
 + // Clear the timer interrupt.
 + //
 + TimerIntClear(TIMER2_BASE, TIMER_TIMA_TIMEOUT);
 +
 + //
 + // Set servo position.
 + //
 + ServoSetPulseWidth(SERVO_INDEX, 100 * g_slWiperDirection);
 +
 + //
 + // Reverse wiper direction.
 + //
 + g_slWiperDirection = -g_slWiperDirection;
 +}
 +
 +//*****************************************************************************
 +//
 +// Wiper mode setting.
 +//
 +//*****************************************************************************
 +void WiperModeSet(unsigned char ucMode)
 +{
 + unsigned long ulPeriod = 0;
 +
 + //
 + // Turn on the appropriate LED.
 + //
 + RGBLEDSetRGB((ucMode == 0 ? 255 : 0),
 +              (ucMode == 1 ? 255 : 0),
 +              (ucMode == 2 ? 255 : 0));
 +
 + //
 + // Mode 0 ?
 + //
 + if (ucMode == 0)
 + {
 + //
 + // Disable wiper timer.
 + //
 + TimerDisable(TIMER2_BASE, TIMER_A);
 +
 + //
 + // Stop servo motor.
 + //
 + ServoSetPulseWidth(SERVO_INDEX, 0);
 + }
 + //
 + // Mode 1 or 2 ?
 + //
 + else if (ucMode <= 2)
 + {
 + //
 + // Set period according to the mode.
 + //
 + switch (ucMode)
 + {
 + case 1:
 + ulPeriod = SysCtlClockGet() * 2; // 2 s
 + break;
 +
 + case 2:
 + ulPeriod = SysCtlClockGet() / 2; // 500 ms
 + break;
 + }
 +
 + //
 + // Configure periodic timer to generate interrupt.
 + //
 + TimerLoadSet(TIMER2_BASE, TIMER_A, ulPeriod);
 + TimerEnable(TIMER2_BASE, TIMER_A);
 + }
 +}
 +
 +//*****************************************************************************
 +//
 +// The interrupt handler for the CAN interrupt.
 +//
 +//*****************************************************************************
 +void CAN0IntHandler(void)
 +{
 + tCANMsgObject psCommandMsg;
 + unsigned char pucRxData[8];
 + unsigned char ucMode = 0;
 +
 + //
 + // Set pointer to data.
 + //
 + psCommandMsg.pucMsgData = pucRxData;
 +
 + //
 + // New CAN message received ?
 + //
 + if (CANStatusGet(CAN0_BASE, CAN_STS_NEWDAT) & CAN_ACTUATOR_MSG_BOX_FLAG)
 + {
 + //
 + // Get the message.
 + //
 + CANMessageGet(CAN0_BASE, CAN_ACTUATOR_MSG_BOX_FLAG, &psCommandMsg, true);
 +
 + //
 + // Check message length.
 + //
 + if (psCommandMsg.ulMsgLen == 1)
 + {
 + //
 + // Get mode from data.
 + //
 + ucMode = *psCommandMsg.pucMsgData;
 +
 + //
 + // Set wiper mode.
 + //
 + WiperModeSet(ucMode);
 + }
 + }
 +}
 +
 +//*****************************************************************************
 +//
 +// Main function.
 +//
 +//*****************************************************************************
 +int main(void)
 +{
 + tCANMsgObject psCommandMsg;
 +
 + //
 + // Set the clocking to run from the PLL at 50MHz
 + //
 + SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
 +    SYSCTL_XTAL_8MHZ);
 +
 + //
 + // Enable peripherals.
 + //
 + SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
 + SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
 + SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
 + SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
 + SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
 + SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER2);
 + SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);
 +
 + //
 + // Enable the peripherals that should continue to run when the processor
 + // is sleeping.
 + //
 + SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_GPIOB);
 + SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_GPIOC);    
 + SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_GPIOD);
 + SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_GPIOE);    
 + SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_TIMER0);
 + SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_TIMER2);
 + SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_CAN0);
 +
 + //
 + // Drivers configuring.
 + //
 + DeviceConfigure();
 + RGBLEDConfigure();
 + ServoConfigure(SERVO_INDEX);
 +
 + //
 + // Configure timer 2 as periodic wiper timer.
 + //
 + TimerConfigure(TIMER2_BASE, TIMER_CFG_32_BIT_PER);
 +
 + //
 + // Enable timer 2 interrupt.
 + //
 + TimerIntEnable(TIMER2_BASE, TIMER_TIMA_TIMEOUT);
 + IntEnable(INT_TIMER2A);
 +
 + //
 + // Configure CAN pins.
 + //    
 + GPIOPinTypeCAN(GPIO_PORTD_BASE, GPIO_PIN_0 | GPIO_PIN_1);
 +
 + //
 + // Enable the CAN controller.
 + //     
 + CANInit(CAN0_BASE);
 + CANBitRateSet(CAN0_BASE, SysCtlClockGet(), CAN_BITRATE);
 + CANEnable(CAN0_BASE);
 +
 + //
 + // Enable CAN interrupts.
 + //
 + CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_STATUS);
 + IntEnable(INT_CAN0);    
 +
 + //
 + // Create receive command message object.
 + //
 + psCommandMsg.ulMsgID     = CAN_ACTUATOR_MSG_ID;
 + psCommandMsg.ulMsgIDMask = CAN_ACTUATOR_MSG_ID;
 + psCommandMsg.ulFlags     = MSG_OBJ_RX_INT_ENABLE;
 +
 + //
 + // Set message object.
 + //
 + CANMessageSet(CAN0_BASE, CAN_ACTUATOR_MSG_BOX, &psCommandMsg, MSG_OBJ_TYPE_RX);
 +
 + //
 + // Enable processor interrupts.
 + //
 + IntMasterEnable();
 +
 + //
 + // Loop forever.
 + //
 + while (1)
 + {
 + //
 + // Save power - turn off CPU.
 + //
 + SysCtlSleep();
 + }
 +}
 +</code>
  
CC Attribution-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0