Jump to content

Search the Community

Showing results for tags 'novo FanSpeed PIC16'.



More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • PIC Embedded Programming
    • BoostC and Chameleon compilers programming
    • BoostC porting source code
    • BoostC++ compiler programming
    • BoostBasic compiler programming
    • Assembler programming PIC
    • Novo RTOS Programming
    • Hardware PIC
    • Enhancement Requests
    • Bug Reports

Found 1 result

  1. Hi out there, I'm trying to get familiar with Novo and started therefore with the FanSpeed example of Dave. I got it to work without big problems on a PIC18F2550 and an older PICDEM-2 demo board. Cause I had a 4x4-keypad in my corner I extended the keypad-file. It all worked fine. As next step I wanted to get it worked also on a PIC16 and have chosen a PICkit2 demo board with a PIC16F690. Same setup there but running with an external crystal at 20MHz. Additionally I changed the scheduler-call SysTimerUpdate from main to a timer-driven interrupt that should execute every 10us. I dunno what I did wrong but the code doesn't work. 1st issue: the keypad didn't get read. 2nd issue: after a few seconds the fan gets set to max. speed what is probably caused by a dead-lock or sth. like that. I attached an UART-to-RS232 converter but just got the information so far that the program stucks after several executions in task1... Find the code attached. I hope someone could give me a good hint... Thanks in advance! >> PicConfig.h << // PIC 16F690 with external oscillator (crystal) 20 MHz #pragma DATA _CONFIG, _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & \ _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _HS_OSC >> fanspeed.c << ////////////////////////////////////////////// // Fan Speed Controller // // Author(s): David Hobday // Date: 11 December 2006 // // Target Device: EZ-Controller Turbo (PIC18F2520 with booloader) // // Revision History: // V1.0 11/12/2006 - Initial Release // ////////////////////////////////////////////// // // This code controls the speed of a fan using pulse width modulation, // ie the fan speed is controlled by varying the duty cycle of voltage // waveform applied to the fan - all done without using any PWM hardware. // // The desired speed is set by typing a 1 to 3 digit number (0 to 255) on the // keypad and then pressing the '#' key. Pressing the '*' key switches // between the last two set speeds. // // This code uses Novo RTOS as it makes things so much simpler. // The PWM is implemented in software using Novo RTOS Sys_Sleep functions. // //============================================================================ // My adaptions: //---------------------------------------------------------------------------- // A Keypad matrix is connected to the µC (see keypad.c for details). // A pwm output is genrated from µC-pin in "bit-banging"-style. // // The Novo SysTimerUpdate() function is called at timer0-interrupt of 10µs, so any // time values used with waiting functions, such as Sys_Sleep(), represent the // number of times the run queue is transversed there. // The setup is: // - PICkit2-EvalBoard with PIC16F690 // - external oscillator (crystal) of 20MHz // - used 4x4-keypad and extended "keypad.c" respectively // - attached UART-to-RS232 converter and added some debug-output // #include <system.h> #include <novocfg_pic16t3e5ts1.h> #include <novo.h> // use this configuration when not targeting EZ-COntroller turbo with bootloader, // also remember to remove linker option -rb 0x800 #include "PicConfig.h" #pragma CLOCK_FREQ 20000000 //set to 20MHz at external crystal #include "keypad.h" #define hTask0 0 #define hTask1 1 unsigned char speed = 50; // set initial speed // Delays are measured in run execution counts as we update SysTimerUpdate in the main yeild loop // In this application an update occurs around every 10us #define DEBOUNCE_DELAY_2500us() Sys_Sleep( 250 ) unsigned char WaitForKey() { unsigned char key = 0; unsigned char i; // wait for no key press and keypad stable for a number of loops for( i = 0; i < 10; i++ ) { if( ScanKeyMatrix() != 0xFF ) i = 0; DEBOUNCE_DELAY_2500us(); } // wait for key pressed and stable for a number of loops while( 1 ) { txreg = 'w'; //send to UART for( i = 0; i < 10; i++ ) { unsigned char k = ScanKeyMatrix(); if( key != k ) // key has changed the same { key = k; i = 0; } DEBOUNCE_DELAY_2500us(); // debounce delay txreg = key; //send key to UART } if( key != 0xFF ) // a key has been pressed { txreg = key; //send key to UART return key; } } } void Task0() { ScanKeyMatrixInit(); char key; unsigned char newSpeed = 0, oldSpeed = 0; while( 1 ) { txreg = '0'; //send to UART key = WaitForKey(); if( key >= '0' && key <= '9' ) { newSpeed *= 10; newSpeed += key - '0'; } if( key == '#' ) { oldSpeed = speed; speed = newSpeed; newSpeed = 0; } if( key == '*' ) { newSpeed = speed; speed = oldSpeed; oldSpeed = newSpeed; newSpeed = 0; } if( key == 'A' ) { speed = 255; } if( key == 'B' ) { speed = 200; } if( key == 'C' ) { speed = 120; } if( key == 'D' ) { speed = 50; } } } void Task1() { while( 1 ) { txreg = '1'; //send to UART portc.5 = 0; Sys_Sleep( 255 - speed ); portc.5 = 1; Sys_Sleep( speed ); } } void interrupt(void) { // DISABLE ALL/GLOBAL INTERRUPT SOURCES! intcon.GIE = false; // global interrupt disable // handle all interrupts: // 1) timer0-source: if(intcon.T0IF == true) { tmr0 = 0x32; // reload counting-registers for timer0 intcon.T0IF = false; // reset flag SysTimerUpdate(); // timer0 is used as novo-timebase in timer0-interrupt } // 2) UART-source: if ( pir1.RCIF == true ) // RX via UART occured? { if( (rcsta.OERR == true) || (rcsta.FERR == true) ) // any RX-error occured? { rcsta.CREN = false; nop(); rcsta.CREN = true; // should be better get reset within error-handling !! rcsta.OERR = false; // reset overrun-error flag rcsta.FERR = false; // reset framing-error flag } else { //ToDo: //buffer = rcreg; // read the character from the receive chBuffer //// rcreg = 0x00; // delete RX-register //boRxInterruptFlag = TRUE_d; // set flag for main application } } // (RE-)ENABLE ALL/GLOBAL INTERRUPT SOURCES! intcon.GIE = true; // global interrupt enable } void main() { // disable analog input-channels ansel = 0x00; anselh = 0x00; // disable weak pull-ups of port A & B wpua = 0x00; wpub = 0x00; // set I/O-directions trisa = 0b11111111; trisb = 0b01111111;// only RB7 is output (TX of UART) trisc = 0b11011111;// only RC5 is output // init timer0 option_reg.T0CS = false; // TMR0 Clock Source = Internal instruction cycle clock (FOSC/4) // for prescaler 1:1 =>> need to assign to WDT option_reg.PSA = true; tmr0 = 0x32; // load timer0-value => at Fosc/4 with prescaler 1:1 => value = 50 (0x32) for 10us intcon.T0IE = true; // timer0 interrupt enable // init UART txsta.BRGH = true; // baudrate-generator => high register activated for 16-bit value rcsta.SPEN = true; // enable serial port baudctl.BRG16 = true; // enable 16-bit-mode of baudrate-generator // => value for baudrate 19200 =>> 259 spbrg = 0b00000011; spbrgh = 0b00000001; // enable the asynchronous serial port by clearing bit SYNC, and setting bit SPEN txsta.SYNC = false; rcsta.SPEN = true; pie1.RCIE = true; // enable RX-interrupts txsta.TXEN = true; // enable transmission rcsta.CREN = true; // enable reception // init interrupt-control register intcon.PEIE = true; // enable peripherial interrupts intcon.GIE = true; // global interrupt enable // init Novo SysInit(); SysCreateTask( hTask0, 2, Task0 ); SysCreateTask( hTask1, 2, Task1 ); SysStartTask( hTask0 ); SysStartTask( hTask1 ); while( 1 ) { Sys_Yield(); } } >> keypad.c << ////////////////////////////////////////////// // Matrix Keypad Scanning Routine // // Author(s): David Hobday // Date 11 December 2006 // // Revision History: // V1.0 11/12/2006 - Initial Release // V1.1 130323 - adaption on 4x4 keypad // ////////////////////////////////////////////// //============================================================================ // My adaptions: //---------------------------------------------------------------------------- // - used 4x4-keypad and extended "keypad.c" respectively // // Code written for keypad // with key layout as below: // COL1 COL2 COL3 COL4 // 1 2 3 A ROW 1 // 4 5 6 B ROW 2 // 7 8 9 C ROW 3 // * 0 # D ROW 4 // #include <system.h> // define keypad connections // => ORIGINAL SETTING /*volatile bit row1port @PORTC.1; volatile bit row1tris @TRISC.1; volatile bit row2port @PORTC.6; volatile bit row2tris @TRISC.6; volatile bit row3port @PORTC.5; volatile bit row3tris @TRISC.5; volatile bit row4port @PORTC.3; volatile bit row4tris @TRISC.3; volatile bit col1port @PORTC.2; volatile bit col1tris @TRISC.2; volatile bit col2port @PORTC.0; volatile bit col2tris @TRISC.0; volatile bit col3port @PORTC.4; volatile bit col3tris @TRISC.4;*/ // => SETTING PICkit2 with PIC16F690 AND UART enabled (uses RB5 for RX) volatile bit row1port @PORTC.0; volatile bit row1tris @TRISC.0; volatile bit row2port @PORTA.2; volatile bit row2tris @TRISA.2; volatile bit row3port @PORTA.1; volatile bit row3tris @TRISA.1; volatile bit row4port @PORTC.3; volatile bit row4tris @TRISC.3; volatile bit col1port @PORTB.6; volatile bit col1tris @TRISB.6; volatile bit col2port @PORTB.4; volatile bit col2tris @TRISB.4; volatile bit col3port @PORTC.2; volatile bit col3tris @TRISC.2; volatile bit col4port @PORTC.1; volatile bit col4tris @TRISC.1; rom char* keyPadMatrix = { '1','2','3','A', '4','5','6','B', '7','8','9','C', '*','0','#','D', 0xFF }; void ScanKeyMatrixInit() { // we scan the keypad by turning on the row outputs and // reading the columns row1tris = 0; row2tris = 0; row3tris = 0; row4tris = 0; col1tris = 1; col2tris = 1; col3tris = 1; col4tris = 1; } char ScanKeyMatrix() { // This routine returns the first key found to be // pressed during the scan. char key = 0, row; for( row = 0b00000001; row < 0b00010000; row <<= 1 ) { { // turn on row output row1port = row.0; row2port = row.1; row3port = row.2; row4port = row.3; } // read colums - break when key press detected if( col1port ) break; key++; if( col2port ) break; key++; if( col3port ) break; key++; if( col4port ) break; key++; } row1port = 0; row2port = 0; row3port = 0; row4port = 0; return keyPadMatrix[ key ]; }
×