⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 M16C单片机功率控制源码
💻 C
📖 第 1 页 / 共 2 页
字号:
 /*************************************************************************************
  Copyright (c) 2007, EISLAB Lulea University of Technology - Sweden

  All rights reserved.

  Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
  Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

  The purpose of this program is to blink LED's and print data using implemented library functions, via interrupts and timers
  **********************************************************************************************************************************************************************************************/

  #include "hardware.h"
  #include "inthandler.h"
  #include "sema.h"
  #include "hwtimers.h"
  #include "mlibc.h"
  #include<stdarg.h>
 

  #define uchar unsigned char
  #define uint16 unsigned int

  /*************** Functions declarations *****************/
  int main(void);
  void tB2_init(void);
  void tB0_init(void);
  void tA0_init(void);
  void tB0_delay(unsigned int);
  void tA0_start(unsigned int);
  void init_uart1(void);
  void int_putchar(int c);
  uchar _getchar(void);
  int _puts(char *);
  void _echo(void);
  char* _strcpy(char *, char *);
  uint16 _strlen(char *);
  void strrev(char *);
  void print_hex_oct( long int, int, int, int, int, int *);
  void float_print(long double, long double, int, int *);
  int format_val(char *, long, int *, int);
  int _printf(const char * , ...);
  
  int cpu_gear(int gear);
  void wait_for_interrupt(); 
  /*************** Variables declarations *****************/
  sema_t semaphores[7] = {0};
  int left_val,right_val;
  long temp_arr[]={100000,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
  char str1[100] = "Test LibC";
  char str2[sizeof(str1)];
  int from_puts = 0;
  
  int gear;
  
  int to=1; //bool
  int nxt_lps=0; 
  int highCurrent=1;


  /****************************************************************
     Function Main
     ******************************************************************/

int main (void) {

      int lps; // low power state
      uint16 CM=0; // Cascade CM0 and CM1
      CM=((CM|CM1.BYTE)<<8)|CM0.BYTE; 
  
      uint16 PM=0; // Cascade PM0 and PM1
      PM=((PM|PM1.BYTE)<<8)|PM0.BYTE; 

 	  hw_initialise();                  /* hardware initialisation ,chip mode,cpu clock and subclock*/
 	  PD8.BIT.PD8_0 = OUTPUT;           /* setting port P80 as OUTPUT port */
 	  PRCR.BIT.PRC2 = 1;                /* enable writing to PD9 */
 	  PD9.BIT.PD9_1 = OUTPUT;           /* setting port P91 as OUTPUT port */

 	  sema_unset(TIMER_SYSTEM);         /* unset TA0 timer semaphore initially #define TIMER_SYSTEM 1*/
 	  sema_unset(TIMER_DELAY);          /* unset TB0 timer semaphore initially #define TIMER_DELAY 0*/
 	  sema_unset(INT1_SEM);             /* unset INT1 interrupt semaphore initially #define INT1_SEM 2*/
 	  sema_unset(UART1_RECV);           /* unset UART1 receive semaphore initially #define UART1_RECV 3*/

while(1) {
     if (CM0.BIT.CM0_7) { PRCR.BIT.PRC0=1;CM0.BIT.CM0_5=0;CM1.BIT.CM1_5=1;PRCR.BIT.PRC0=0; 
	                  // Start X, high drive, wait ~250 microSec
                      /*TABSR&=~3;TA0MR=0xC0;TA0=1;TA1=8; to=FALSE;TABSR|=3; while(!to);*/
				 	   asm("NOP "); 
					   asm("NOP "); 
					   asm("NOP "); 
					   asm("NOP "); 
					   asm("NOP "); 
					   asm("NOP "); 
					   asm("NOP ");  
					    }
     else { 
		   PRCR.BIT.PRC0=1; CM0.BIT.CM0_4=1;CM0.BIT.CM0_3=1;PRCR.BIT.PRC0=0; 
	       // Start Xc, high drive, wait ~250 MILLI-Sec P		   
            TABSR.BYTE&=~3;
			TA0MR.BYTE=0x80;TA0=5000;TA1=25;
			to=0;
			TABSR.BYTE|=3; 
			while(!to); 
          }
	 
switch(lps) { // Prepare low power request & resources for ~5 second pause
      case 1: gear= 2; nxt_lps=2; break;
      case 2: gear= 4; nxt_lps=3; break;
      case 3: gear= 8; nxt_lps=4; break;
      case 4: gear=16; nxt_lps=5; break;
      case 5: gear=32; nxt_lps=6; TA0MR.BYTE=0xC0;TA0=100; break;
      case 6: gear=32; nxt_lps=7; TA0MR.BYTE=0xC0;TA0=100; semaphores[WAIT]=1; // mode=WAIT;
              highCurrent=~highCurrent; /*Wait mode indication display*/ break; // Push button to release WAIT mode
      case 7: gear= 0; nxt_lps=0; TA0MR.BYTE=0xC0;TA0=100; semaphores[STOP]=1;// mode=STOP;
              /*Stop mode indication display*/; break; // Push button to release STOP mode
      default:gear= 1; nxt_lps=1; P8.BIT.P8_0=0;break;
	        }

CPSRF.BIT.CPSR=1; 
if (gear)cpu_gear(gear);  PRCR.BIT.PRC0=1;// Start shutdown sequence f=X/?, unless STOP mode, UNLOCK(); 
if (highCurrent==1) { PM1.BIT.PM1_7=0;PM0.BIT.PM0_7=0;P1.BIT.P1_0 = 0;P1.BIT.P1_1=1; } 
      // No Global-wait, Output BCLK, display on LED1
else { P1.BIT.P1_0=1; P1.BIT.P1_1 = 0; PM1.BIT.PM1_7=1;PM0.BIT.PM0_7=1; CM1.BIT.CM1_5=0;CM0.BIT.CM0_3=1; } 
      // Global-wait, No BCLK, X,Xc:Both low-drive, display on LED2
if (gear==32) CM0.BIT.CM0_5=1; 
else CM0.BIT.CM0_4=0; // Stop: unused X or unused Xc
if (gear==32) CM=(CM&~2)|1; else CM|=3; PRCR.BIT.PRC0=0;//LOCK(); // P5.7: output f32(f=X) or fc(f=Xc)

to=0;TABSR.BYTE|=3; while(!to) { // Pause in each low power mode
P0.BIT.P0_7=CM0.BIT.CM0_5;P0.BIT.P0_6=~CM0.BIT.CM0_4;
 //P0.BYTE=((P0.BYTE&0x80)|(led_digit&0x7F)); // LEDs: P0=MSA0654, display a digit
if (semaphores[STOP]==SEMA_SET) cpu_gear(0); else // Stop(X,Xc) => RTI
if (semaphores[WAIT]==SEMA_SET) {PRCR.BIT.PRC0=1;
                                 CM0.BIT.CM0_2=1;
								 PRCR.BIT.PRC0=0; 
								 wait_for_interrupt(); 
                                 asm("NOP ");
                                 asm("NOP ");
                                 asm("NOP ");
                                 asm("NOP ");
                                }
// CPU WAIT mode => RTI
     } //WHILE LOOP
	  return (0);
    }  //Main ends













 int cpu_gear(int gear) { // Read or Write CPU clock gear. NB No intelligence, assumes necessary clocks running
   
 
 if (gear==~0000) { // (-1) => Read current setting
 switch(CM & 0xC0C0) { // CM.15.14.main clock fdivision, 7-X,XC selection. 6-low enable 15,14 high f8
 case 0x0000: gear=1; break; // f1
 case 0x4000: gear=2; break; // f2
 case 0x8000: gear=4; break; // f4
 case 0xC000: gear=16; break; // f16
 
 case 0x0040: case 0x4040: case 0x8040: case 0xC040: gear=8; break; // set 1 to MC06 for f8  
 case 0x0080: case 0x4080: case 0x8080: case 0xC080:
 case 0x00C0: case 0x40C0: case 0x80C0: case 0xC0C0: gear=32; break; // Xc
 default: ; }
 } else { // Otherwise assume: Write new setting
 
 IFSR.BYTE=0; // asm("fclr i");  mask all the maskable interrupts   ILVL=000
 PRCR.BIT.PRC0=1; // Unlock protection to system clock
 
 switch(gear) { // concerned with CM.15.14.7.6.8Stmode.4XC
 case 0:  IFSR.BYTE=1; CM1.BIT.CM1_0=1; asm("NOP ");asm("NOP ");asm("NOP ");asm("NOP ");asm("NOP ");asm("NOP "); break; // STOP (X=Off, Xc=Off)
 case 1:  CM=(CM & 0x3FBF)|0x0000; CM0.BIT.CM0_7=0; break; // X/1
 case 2:  CM=(CM & 0x3FBF)|0x4000; CM0.BIT.CM0_7=0; break; // X/2
 case 4:  CM=(CM & 0x3FBF)|0x8000; CM0.BIT.CM0_7=0; break; // X/4
 case 8:  CM=(CM & 0x3FBF)|0x0040; CM0.BIT.CM0_7=0; break; // X/8
 case 16: CM=(CM & 0x3FBF)|0xC000; CM0.BIT.CM0_7=0; break; // X/16
 //case 32: if (mode!=WAIT){led_seg=0xBF; led_digit=0x82;} CM0.BIT.CM0_7=1; break; // Xc/1, display "6" if not WAIT mode.
 default: ; } 
 
 PRCR.BIT.PRC0=0;//protect the CMi
 IFSR.BYTE=1; // relock enable_interrupt()
 } return gear;
 
 }
 
	 
// int main (void) {

// 	  hw_initialise();                  /* hardware initialisation ,chip mode,cpu clock and subclock*/
// 	  PD8.BIT.PD8_0 = OUTPUT;           /* setting port P80 as OUTPUT port */
// 	  PRCR.BIT.PRC2 = 1;                /* enable writing to PD9 */
// 	  PD9.BIT.PD9_1 = OUTPUT;           /* setting port P91 as OUTPUT port */

// 	  sema_unset(TIMER_SYSTEM);         /* unset TA0 timer semaphore initially #define TIMER_SYSTEM 1*/
// 	  sema_unset(TIMER_DELAY);          /* unset TB0 timer semaphore initially #define TIMER_DELAY 0*/
// 	  sema_unset(INT1_SEM);             /* unset INT1 interrupt semaphore initially #define INT1_SEM 2*/
// 	  sema_unset(UART1_RECV);           /* unset UART1 receive semaphore initially #define UART1_RECV 3*/

// 	  PUR2.BIT.PU20 = 1;                /* P80 to P83 pull-up  */
// 	  INT1IC.BYTE = 0x03;               /* enable INT1 interrupt, level 3 */

// 	  tB2_init();                       /* intialise and start main timer */
// 	  tB0_init();                       /* initialise delay timer */
// 	  tA0_init();                       /* initialise system timer */
// 	  init_uart1();                     /* initialise UART1 */
// 
// 	  tA0_start(5000);                  /* start system timer, cycle period 5 secs */
// 	  asm("fset i");                    /* enable interrupts */
// 	  P9.BIT.P9_1 = LOW;                /* set LED's on port P91 OFF initially */
// 	  P8.BIT.P8_0  = HIGH;              /* set LED's on port P80 OFF initially */
// 	  sleep(1000);                      /* start delay timer,  delay for 1 sec */

// 	  _printf("\n You can type any character to echo!!!");
// 	  for (;;) {

// 	    if(sema_status(INT1_SEM) == SEMA_SET){  /* check if INT1 semaphore status is set */
// 	      sema_unset(INT1_SEM);                 /* unset INT1 semaphore */
// 	      sleep(500);                           /* start delay timer, delay for 0.5 sec */
// 	      P8.BIT.P8_0 = LOW;                    /* set LED's on port P80 ON */
// 	      sleep(500);                           /* start delay timer, delay for 0.5 sec */
// 	      P8.BIT.P8_0 = HIGH;                   /* set LED's on port P80 OFF */
// 	    }

// 	    if(sema_status(TIMER_SYSTEM) == SEMA_SET ){ /* check if TA0 semaphore status is set */
// 	      sema_unset(TIMER_SYSTEM);                 /* unset TA0 semaphore */
// 	      P9.BIT.P9_1 = HIGH;                       /* set LED's on port P91 ON */
// 	      sleep(50);                                /* start delay timer, delay for 0.05 sec */
// 	      P9.BIT.P9_1 = LOW;                        /* set LED's on port P91 OFF */

// 	      _printf("\n You entered character:");
// 	      _echo();
// 	      _strcpy(str2, str1);
// 	      _printf("\n Some more _printf() demos---------------------------------------");
// 	      _printf("\n Prints a string with a trailing newline using PUTS for example ");
// 	      from_puts = 1;
// 	      _puts("MYLIBC");
// 	      _printf(" String is copied, Expected Output= Test LibC, Result= %s",str2);
// 	      _printf("\n print_percent %%\n print_string %s\n print_unsignedint %u\n print_float %02f\n printf_char %c\n print_integer_d %d\n print_hex_x %x\n print_hex_X %X\n print_oct %o\n print_int_i %i\n print_withblanks %05d\n", "Hello World",10,10.5f, 'G', 100, 100, 100, 100, 100, 100);
// 	    }

// 	  }
//	  return (0);
//    }


  /****************************************************************
     Hardware Timers (Delay & System)
    *****************************************************************/

  /* initialise and start main timer as count source for TA0 and TB0 */
  void tB2_init(){
    TB2MR.BYTE=0x40;            /* timer mode, f/8 */
    TB2=1250;                   /* preload timer value( CPU_SPEED / 8)  * 1000  millisec ....#define CPU_SPEED	10E6 */
    TABSR.BIT.TB2S=1;           /* start timer B2 */
  }

  /* initialise delay timer */
  void tB0_init(){
    TB0MR.BYTE=0x81;            /* event count mode, overflow TB2 */
  }

  /* initialise system timer */
  void tA0_init(){
    ONSF.BYTE = 0x40;          /* overflow TB2*/
    UDF = 0;                   /* TA0 count downwards */
    TA0MR.BYTE = 0x01;         /* event counter mode */
  }

  /* start delay timer */
  void tB0_delay(uint16 delay_time){
    sema_unset(TIMER_DELAY);                    /* unset TA0 semaphore */
    sema_unset(INT1_SEM);                       /* unset INT1 semaphore */
    TB0IC.BYTE=0x01;                            /* set TB0 interrupt priority level 1 */
    TB0 = delay_time;                           /* reload new timer value */
    TABSR.BIT.TB0S=1;                           /* start timer B0 */
    while(sema_status(TIMER_DELAY)!=SEMA_SET)   /* wait until delay timer semaphore is set  */
      ;
  }

  /*start system timer  */
  void tA0_start(uint16 cycle_period){
    TA0IC.BYTE=0x02;                    /* set TA0 interrupt priority level 2 */
    TA0 = cycle_period;                 /* reload new timer value */
    ONSF.BIT.TA0OS=1;                   /* start TA0 one-shot bit */
    TABSR.BIT.TA0S=1;                   /* start TA0 count bit */
  }

  /****************************************************************
    Library C: Putchar, Getchar, Puts, Echo, Strcpy
    *****************************************************************/

  /*************** Configure  UART1 *****************/
  void init_uart1 (void){
    PD6.BYTE = 0x80;                    /* output port TX */
    U1MR.BYTE = 0x05;                   /* 8 data bits */
    U1C0.BYTE = 0x10;                   /* select f1, CTS/RTS function disabled */
    U1BRG = (((MAIN_CLOCK / (16.0 * SIO_SPEED))+ 0.5) - 1.0);    /* set UART1 bit rate generator */
    U1C1.BIT.TE = 1;                    /* enable transmit */
    U1C1.BIT.RE = 1;                    /* enable receive */
    S1RIC.BYTE = 0x04;                  /* set UART1 receive interrupt priority level 4 */
  }

  /*************** Print Character *****************/
  int _putchar(int c) {
    while (U1C1.BIT.TI == 0)            /* wait if the transmit buffer is full,0 indicates U1TB with data */
      ;
    U1TB.BYTE.U1TBL = (char)c;          /* load character c into transmit buffer */
  }

  /*************** Get Character *****************/
  uchar _getchar(void){
	uchar c = U1RB.BYTE.U1RBL;          /* get data if any from receive buffer */

	if(sema_status(UART1_RECV)==0){     /* check if the receive buffer is empty */
	  return 0;                         /* return nothing */
	}
	else{
	  sema_unset(UART1_RECV);           /* unset UART1 receive semaphore */
	  return c;                         /* return receive buffer data  */
	}
  }

  /*************** Print String *****************/
  int _puts(char *s) {
    while(*s != '\0'){
	  _putchar(*s);
      s++;
    }
    if(from_puts) {
       from_puts = 0;
      _putchar('\n');
      _putchar('\r');
    }
    return 0;
  }

 /*************** Echo Character *****************/
  void _echo(){
    _putchar(_getchar());
  }

  /*************** Copy String *****************/
  char* _strcpy(char *s2, char *s1){
    int i	;

    for(i = 0; s1[i] != '\0'; ++i)
      s2[i] = s1[i];
    s2[i] = s1[i];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -