power_sample.c
来自「最新版IAR FOR ARM(EWARM)5.11中的代码例子」· C语言 代码 · 共 523 行 · 第 1/2 页
C
523 行
/**********************************************************************************/
/* */
/* Copyright (C) 2005 Oki Electric Industry Co., LTD. */
/* */
/* System Name : ML67Q4051/ML67Q4061 */
/* Module Name : Power control sample program */
/* File Name : power_sample.c */
/* Revision : 01.00 */
/* Date : 2005/02/16 initial version */
/* */
/**********************************************************************************/
#include "ML674061.h"
#include "common.h"
#include "irq.h"
#include "pm674061_lib.h"
#ifdef __IAR__
#include "intrinsics.h"
#endif
/* Constants */
#define MHz (1000000L)
#define TMRCYC (30) /* interval of timer interrupt (ms) */
#define SYSCLK (33) /* SYSCLK (MHz)*/
#define VALUE_OF_TMRLR /* reload value of timer */\
(65536 - (TMRCYC * SYSCLK * 1000) / 16)
#if ((VALUE_OF_TMRLR) < 0 || 0x10000 <= (VALUE_OF_TMRLR))
#error "Invalid value : VALUE_OF_TMRLR"
#endif
/* constants */
#define TRIGGER_LEVEL 14
#define BUFF_SIZE 256
#define FIFO_SIZE 16
/* please note, the test at slower rate here is due to the
fact that, in the APB clock test, if the APBCLK is down
to 8Mhz, UART may not work at baudrate 115,200. See User's Manual
17.4.10. The deviation will be too big to compensate.
The test conducted below is, 32Mhz, 16Mhz, 8Mhz at the same
baudrate 57,600. When the APB clock is divided by half, to keep
the same baudrate, the divisor latch value needs to be divided too. */
#define DLM_BAUD 0x00 /* baud = 9,600 */
#define DLL_BAUD 0xD7 /* baud = 9,600 */
/* === setting baud rate value === */
/* baud | DLM_BAUD | DLL_BAUD */
/* 1,200 | 0x06 | 0xB7 */
/* 2,400 | 0x03 | 0x5B */
/* 4,800 | 0x01 | 0xAE */
/* 9,600 | 0x00 | 0xD7 */
/* 19,200 | 0x00 | 0x6B */
/* 38,400 | 0x00 | 0x36 */
/* 57,600 | 0x00 | 0x24 */
/* 115,200 | 0x00 | 0x12 */
#define LED_H 0x0076
#define LED_S 0x006D
/* Functions */
int main(void); /* Main routine */
static void setup_exint(void); /* setup exint */
static void set_timer(void); /* setup of timer */
static void Blink_LED( int blink_count ); /* Blink LED */
static void reg_irq_handler(void); /* registration of IRQ handler */
static void timer_handler(void); /* timer handler */
void init_uart(void); /* initialize UART */
void uart_handler(void); /* UART interrupt handler */
void reg_uart_irq_handler(void); /* registration of IRQ handler */
/* LED lighting pattern table */
UHWORD LED_TABLE [18] = {LED_0,LED_1,LED_2,LED_3, /* "0","1","2","3" */
LED_4,LED_5,LED_6,LED_7, /* "4","5","6","7" */
LED_8,LED_9,LED_A,LED_b, /* "8","9","A","b" */
LED_C,LED_d,LED_E,LED_F, /* "C","d","E","F" */
LED_all,LED_off}; /* all on ,all off */
/* global variables */
volatile unsigned char rw_buff[BUFF_SIZE]; /* ring buffer */
int write_pointer = 0; /* the current char point from UART to execute the command */
volatile int cmd_flag = 0;
volatile int rec_data_counter = 0;
volatile int error_flag = 0; /* 0:no error, 1:overrun error, 2:parity error,
3:framing error, 4:overflow error */
static volatile int counter;
static volatile int led_count;
/****************************************************************************/
/* Entry point */
/* Function : main */
/* Parameters */
/* Input : Nothing */
/* Output : 0 */
/****************************************************************************/
int main(void)
{
UBYTE input;
UBYTE diva_clk_gear = 0;
UBYTE apb_clk_gear = 0;
UHWORD diva_clk_led_pattern[5] = {0x0020,0x0001,0x0021,0x0002,0x0022};
UHWORD apb_clk_led_pattern[3] = {0x0010,0x0008,0x0018};
/* Initialization of IRQ */
init_irq();
/* initialize clock gear for both CCLK and APB CLK */
pm_diva_clkgear(0, 1);
pm_apb_clkgear(0, 0);
/* registration of IRQ handler */
reg_irq_handler();
/* setting of timer */
set_timer() ;
/* setup UART 0 instead of SIO as for the OKI-J board */
init_uart();
/* register of UART IRQ handler */
reg_uart_irq_handler();
/* setup of extint1*/
setup_exint();
/* initialize led */
init_led();
led_on(LED_START_PATTERN);
/* IRQ enable */
#ifdef __IAR__
__enable_interrupt();
#else
irq_en();
#endif
for(;;)
{
/* receive ready? */
/* cmd_flag 1 is received on the UART, 0 is processed or not received. */
if ( write_pointer != 0 && error_flag == 0 && cmd_flag != 0 )
{
/* Get UART data from buffer */
/* get previous data */
input = rw_buff[write_pointer-1];
switch(input)
{
case 'h':
case 'H':
led_on(LED_H);
put_wvalue(TMEN, 0x01); /* timer start */
/* HALT mode */
cmd_flag = 0;
pm_halt(0x00000001,0x00000004); /* external INT and timer */
/* even in the HALT mode, the SIO and SYSCLK interrupt can be used to
set the CPU to RUN mode, that's why, after calling pm_halt() to
HALT the MCU, the enabling of the timer will wake the CPU right after.
SIO can not be used for wakeup as it's not connected on AME_51 board. */
Blink_LED( 5 );
put_wvalue(TMEN, 0x00); /* timer stop */
led_on(LED_START_PATTERN);
/* change to SYSCLK */
put_wvalue(CLKCNT, (get_wvalue(CLKCNT)&0xFFFFFCFF)) ;
break;
case 's':
case 'S':
led_on(LED_S);
cmd_flag = 0;
/* change to ringosc */
put_wvalue(CLKCNT, (get_wvalue(CLKCNT)&0xFFFFFCFF) | 0x00000100) ;
/* STOP mode */
pm_stop(0x00000000,0x00000004);
/* At this point, the CPU is stopped, an external interrupt EXTINT1
can be used to wake up the CPU. So, once LED display is S, it stops,
press the EXTINT1 button, will wake up CPU, in turn, the LED will
blink 5 times, then back to START_PATTERN. */
/* change to SYSCLK */
put_wvalue(CLKCNT, (get_wvalue(CLKCNT)&0xFFFFFCFF));
put_wvalue(TMEN, 0x01); /* timer start */
Blink_LED( 5 );
put_wvalue(TMEN, 0x00); /* timer stop */
led_on(LED_START_PATTERN);
break;
case 'o':
case 'O':
if(diva_clk_gear > 0)
{
diva_clk_gear--;
set_bit(UARTLCR0,UARTLCR_DLAB);
if ( diva_clk_gear == 0 )
put_value(UARTDLL0, DLL_BAUD); /* DLL of divider latch register */
else
put_value(UARTDLL0, DLL_BAUD / (0x01 << diva_clk_gear));
put_value(UARTDLM0, DLM_BAUD); /* DLM of divider latch register */
clr_bit(UARTLCR0,UARTLCR_DLAB);
}
/* DIVA_CLK gear */
pm_diva_clkgear(diva_clk_gear, 0);
led_on((UBYTE)(diva_clk_led_pattern[diva_clk_gear]));
break;
case 'p':
case 'P':
/* skip 1/32 divider on the SYSCLK because of the baurate deviation problem */
if(diva_clk_gear < 4) /* diva_clk_gear is 0~4 */
{
diva_clk_gear++;
set_bit(UARTLCR0,UARTLCR_DLAB);
put_value(UARTDLL0, DLL_BAUD / (0x01 << diva_clk_gear)); /* DLL of divider latch register */
put_value(UARTDLM0, DLM_BAUD); /* DLM of divider latch register */
clr_bit(UARTLCR0,UARTLCR_DLAB);
}
/* DIVA_CLK gear */
pm_diva_clkgear(diva_clk_gear, 1);
led_on((UBYTE)(diva_clk_led_pattern[diva_clk_gear]));
break;
case '[':
if(apb_clk_gear > 0)
{
apb_clk_gear--;
set_bit(UARTLCR0,UARTLCR_DLAB);
if ( apb_clk_gear == 0 )
put_value(UARTDLL0, DLL_BAUD); /* DLL of divider latch register */
else
put_value(UARTDLL0, DLL_BAUD / (0x01 << apb_clk_gear));
put_value(UARTDLM0, DLM_BAUD); /* DLM of divider latch register */
clr_bit(UARTLCR0,UARTLCR_DLAB);
}
/* APB_CLK gear */
pm_apb_clkgear(apb_clk_gear, 0);
led_on(LED_off);
led_on((UBYTE)(apb_clk_led_pattern[apb_clk_gear]));
break;
case ']':
if(apb_clk_gear < 2)
{
apb_clk_gear++;
set_bit(UARTLCR0,UARTLCR_DLAB);
put_value(UARTDLL0, DLL_BAUD / (0x01 << apb_clk_gear)); /* DLL of divider latch register */
put_value(UARTDLM0, DLM_BAUD); /* DLM of divider latch register */
clr_bit(UARTLCR0,UARTLCR_DLAB);
}
/* APB_CLK gear */
pm_apb_clkgear(apb_clk_gear, 1);
led_on((UBYTE)(apb_clk_led_pattern[apb_clk_gear]));
break;
default:
continue;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?