SH32F9001 Series User Guide

131
SH32F9001 Series User Guide 1 SH32F9001 Series User Guide - 32-bit MCU Based on ARM® Cortex TM -M3 Core - Version 1.0

Transcript of SH32F9001 Series User Guide

SSH32F9001 Series User Guide

1

SH32F9001 Series User Guide

- 32-bit MCU Based on ARM® CortexTM-M3 Core

- Version 1.0

SH32F9001 Series User Guide

2

Specification change record

Version Record Date

V1.0 Initial version 2020-06

SH32F9001 Series User Guide

3

Document instructions

This user guide is guidance manual for the application of SH32F9001 series microcontroller

products. It mainly contains basic information and special attentions on how to use SH32F9001 series

products, including the configuration and use method of typical working mode of functional modules,

and provides basic operation methods in the form of sample code.

This user guide does not contain a detailed description of product functions and technical features,

including module internal structure, complete function introduction, pin number and distribution,

electrical characteristics, package information, etc., which are provided in the product data manual.

This sample code of user guide uses direct register operation method, and does not use

encapsulated peripheral library function operation method. For product development based on

peripheral library, please refer to sinowealth SH32F9001 series peripheral library development guide.

The structure used in the routine is defined in the header file "SH32F9001.h ".

SH32F9001 Series User Guide

4

Contents

SH32F9001 Series User Guide ............................................................................................................ 1

Specification change record ................................................................................................................. 2

Document instructions ......................................................................................................................... 3

Contents ............................................................................................................................................... 4

1. Power, clock and reset .................................................................................................................. 9

1.1. Overview ......................................................................................................................... 9

1.2. Programming Setting ...................................................................................................... 9

1.2.1. Power ....................................................................................................................... 9

1.2.2. Clock ........................................................................................................................ 9

1.2.3. Reset ....................................................................................................................... 10

1.3. Application examples .................................................................................................... 10

1.3.1. Example 1 .............................................................................................................. 10

2. I/O .............................................................................................................................................. 12

2.1. Overview ....................................................................................................................... 12

2.2. Programming Setting .................................................................................................... 12

2.2.1. GPIO mode ............................................................................................................ 12

2.2.2. Multiplexing for digital peripherals ....................................................................... 13

2.2.3. Multiplexing for analog peripherals ....................................................................... 13

2.2.4. Full close mode ...................................................................................................... 14

2.2.5. Debug interface ...................................................................................................... 14

2.2.6. Other notes ............................................................................................................. 14

2.3. Application examples .................................................................................................... 15

2.3.1. Example 1 .............................................................................................................. 15

2.3.2. Example 2 .............................................................................................................. 16

3. NVIC .......................................................................................................................................... 17

3.1. Overview ....................................................................................................................... 17

3.2. Programming Setting .................................................................................................... 17

3.3. Application examples .................................................................................................... 20

3.3.1. Example 1 .............................................................................................................. 20

3.3.2. Example 2 .............................................................................................................. 20

4. RAM........................................................................................................................................... 26

4.1. Overview ....................................................................................................................... 26

4.2. Programming Setting .................................................................................................... 26

4.3. Application examples .................................................................................................... 26

5. Flash&EEPROM ........................................................................................................................ 28

5.1. Overview ....................................................................................................................... 28

5

5.2. Programming Setting .................................................................................................... 28

5.2.1. Flash Control register unlocking ............................................................................ 28

5.2.2. Flash operation timer function ............................................................................... 29

5.2.3. Flash(E2\OTP) Erasing and Programming ............................................................ 30

5.2.4. Flash control register locking ................................................................................. 31

5.3. Application examples .................................................................................................... 31

5.3.1. Flash(E2\OTP) erase and write flow chart ............................................................. 31

5.3.2. Flash(E2\OTP) example ......................................................................................... 38

5.4. Anti-interference measures for programming/erasing .................................................. 48

6. Code and Data Checking............................................................................................................ 50

6.1. Overview ....................................................................................................................... 50

6.2. CRC ............................................................................................................................... 50

6.2.1. Overview ................................................................................................................ 50

6.2.2. Programming Setting ............................................................................................. 50

6.2.3. Application examples ............................................................................................. 51

6.3. RAMBIST ..................................................................................................................... 53

6.3.1. Overview ................................................................................................................ 53

6.3.2. Programming Setting ............................................................................................. 53

6.3.3. Application examples ............................................................................................. 53

7. WDT........................................................................................................................................... 55

7.1. IWDT overview ............................................................................................................ 55

7.2. IWDT programming Setting ......................................................................................... 55

7.3. IWDT Application examples......................................................................................... 55

7.4. WWDT overview .......................................................................................................... 55

7.5. WWDT programming Setting ....................................................................................... 56

7.6. WWDT application examples ....................................................................................... 56

8. EXTI........................................................................................................................................... 57

8.1. Overview ....................................................................................................................... 57

8.2. Programming Setting .................................................................................................... 57

8.2.1. Edge trigger mode selection ................................................................................... 57

8.2.2. Software triggered interrupt ................................................................................... 57

8.2.3. External interrupt line selection ............................................................................. 57

8.2.4. Attention................................................................................................................. 58

8.3. Application examples .................................................................................................... 58

8.3.1. Example 1 .............................................................................................................. 58

9. System configuration module (SYSCFG).................................................................................. 60

9.1. Overview ....................................................................................................................... 60

9.2. Programming Setting .................................................................................................... 60

9.2.1. BOD ....................................................................................................................... 60

9.2.2. LVR ........................................................................................................................ 60

6

9.2.3. NMI interrupt switch .............................................................................................. 60

9.2.4. Crystal oscillator pins are used as GPIO ................................................................ 60

9.2.5. Simulation pins are used as GPIO.......................................................................... 61

9.2.6. The peripherals run in debug mode ........................................................................ 61

9.2.7. Low-power consumption mode ............................................................................. 61

9.3. Application examples .................................................................................................... 62

9.3.1. Example 1 .............................................................................................................. 62

10. DMA controller .................................................................................................................. 64

10.1. Overview ....................................................................................................................... 64

10.2. Programming Setting .................................................................................................... 64

10.2.1. Relationship between DMA and CPU ............................................................ 64

10.2.2. DMA basic parameter configuration ............................................................... 64

10.2.3. DMA channel configuration and request image table ..................................... 66

10.2.4. DMA interrupt ................................................................................................. 66

10.3. Application examples .................................................................................................... 67

10.3.1. Example 1 ....................................................................................................... 67

10.3.2. Example 2 ....................................................................................................... 68

11. PCA .................................................................................................................................... 70

11.1. Overview ....................................................................................................................... 70

11.2. Programming Setting .................................................................................................... 71

11.2.1. IO setting ......................................................................................................... 71

11.2.2. Clock setting ................................................................................................... 71

11.2.3. PCA count mode setting .................................................................................. 72

11.2.4. PCA mode setting............................................................................................ 72

11.2.5. Attention.......................................................................................................... 72

11.3. Application examples .................................................................................................... 73

11.3.1. Example 1 ....................................................................................................... 73

11.3.2. Example 2 ....................................................................................................... 74

11.3.3. Example 3 ....................................................................................................... 75

11.3.4. Example 4 ....................................................................................................... 76

12. PWM .................................................................................................................................. 78

12.1. Overview ....................................................................................................................... 78

12.2. Programming Setting .................................................................................................... 78

12.2.1. IO setting ......................................................................................................... 78

12.2.2. Protection setting............................................................................................. 78

12.2.3. Module setting................................................................................................. 78

12.2.4. Attention.......................................................................................................... 79

12.3. Application examples .................................................................................................... 79

12.3.1. Example 1 ....................................................................................................... 79

13. ADC ................................................................................................................................... 81

7

13.1. Overview ....................................................................................................................... 81

13.2. Programming Setting .................................................................................................... 81

13.2.1. ADC clock setting ........................................................................................... 81

13.2.2. ADC channel IO port function setting ............................................................ 81

13.2.3. ADC sampling rate configuration ................................................................... 81

13.2.4. ADC conversion mode configuration ............................................................. 82

13.2.5. Obtaining ADC conversion results ................................................................. 83

13.3. Attention........................................................................................................................ 83

14. TIMER ............................................................................................................................... 85

14.1. Overview ....................................................................................................................... 85

14.2. Programming Setting .................................................................................................... 85

14.2.1. Basic timing application.................................................................................. 85

14.2.2. Square wave with adjustable output frequency ............................................... 85

14.2.3. Cascade into 32-bit timer ................................................................................ 85

14.2.4. Attention.......................................................................................................... 85

14.2.5. Example 1 ....................................................................................................... 85

14.2.6. Example 2 ....................................................................................................... 86

14.2.7. Example 3 ....................................................................................................... 87

15. LCD .................................................................................................................................... 89

15.1. Overview ....................................................................................................................... 89

15.2. Programming Setting .................................................................................................... 89

15.3. Application examples .................................................................................................... 89

16. LED .................................................................................................................................... 92

16.1. Overview ....................................................................................................................... 92

16.2. Programming Setting .................................................................................................... 92

16.3. Application examples .................................................................................................... 93

16.3.1. Example 1 ....................................................................................................... 94

16.3.2. Example 2 ....................................................................................................... 94

17. Temperature sensor ............................................................................................................ 96

17.1. Overview ....................................................................................................................... 96

17.2. Application examples .................................................................................................... 96

17.2.1. Application of built-in temperature sensors .................................................... 96

18. UART ................................................................................................................................. 97

18.1. Overview ....................................................................................................................... 97

18.2. Programming Setting .................................................................................................... 97

18.2.1. Sending............................................................................................................ 97

18.2.2. Rreceiving ....................................................................................................... 97

18.2.3. IO setting ......................................................................................................... 97

18.2.4. LIN mode ........................................................................................................ 97

18.2.5. Interrupt ........................................................................................................... 97

8

18.2.6. Parity check ..................................................................................................... 98

18.2.7. Error flag ......................................................................................................... 98

18.2.8. Other notes ...................................................................................................... 98

18.3. Application examples .................................................................................................... 98

18.3.1. Example .......................................................................................................... 98

19. SPI .................................................................................................................................... 100

19.1. Overview ..................................................................................................................... 100

19.2. Programming Setting .................................................................................................. 100

19.2.1. Sending.......................................................................................................... 100

19.2.2. Reveiving ...................................................................................................... 100

19.2.3. IO setting ....................................................................................................... 100

19.2.4. Fast slave mode ............................................................................................. 100

19.2.5. Intterupt ......................................................................................................... 100

19.2.6. Error flag ....................................................................................................... 101

19.3. Application examples .................................................................................................. 101

19.3.1. Example ........................................................................................................ 101

20. TWI (I2C) ........................................................................................................................ 104

20.1. Overview ..................................................................................................................... 104

20.2. Programming Setting .................................................................................................. 104

20.2.1. TWI bus setting ............................................................................................. 104

20.2.2. Four basic communication modes................................................................. 104

20.2.3. TWI Interrupt and timeout ............................................................................ 108

20.3. Application examples .................................................................................................. 108

20.3.1. Example 1 ..................................................................................................... 108

21. Aappendix ........................................................................................................................ 120

21.1. Aappendix 1:Function location and debugging method in KEIL MDK .................. 120

21.1.1. Program running in RAM ............................................................................. 120

21.1.2. Put the critical program into RAM to run ..................................................... 123

21.1.3. Fix a function to a certain position ................................................................ 128

21.1.4. Automatically export similar data to a table ................................................. 129

21.1.5. Fix variables to a location in RAM ............................................................... 131

SH32F9001 Series User Guide

9

1. Power, clock and reset

1.1. Overview

Power, clock and reset circuit are the core of industrial control chip design, and also the guarantee

of reliability and anti-interference ability.

In terms of power, it supports 2.0V-5.5V power supply range, which is a real wide voltage power

supply MCU. Besides, low voltage protection (LVR) and brownout detection (BOD) conventional

protection circuits are added.

In terms of clock, it supports HSI, HSE, PLL, LSI and LSE clock sources. HSI clock can reach 0.2%

accuracy at room temperature, which can replace crystal oscillator as high-precision clock source in

most control applications.

In terms of reset circuit, it supports power on reset, independent pin reset, low voltage reset,

watchdog reset and internal software reset, with various and perfect reset methods.

1.2. Programming Setting

1.2.1. Power

【Note】 VDD and AVDD are two independent power supplies, and the pressure difference

between them should not exceed 0.3V. It is suggested that the same power supply should be used to

supply power to VDD and AVDD respectively, and LC filter should be added in the middle to provide

high quality AVDD power supply.

【Note】There will be a warm-up (stabilization) time for the power supply, so it is recommended to

reserve 15ms (a certain margin on the basis of 11ms). The power supply can be preheated to about

1ms when it wakes up or reset from shutdown mode, because it does not involve power on again.

【Note】BOD is a flexible brownout detection circuit, which supports down detection, rise detection

and bidirectional detection. It can also query the high and low status of current voltage and set voltage.

After BOD is generated, it can apply for BOD interruption or NMI interruption. The latter is set by IEN_

BOD@SYSCFG_ SAFR control bit.

【Note】In order to improve the anti-interference ability, the BOD is designed with return difference

and debouncing functions to prevent BOD error caused by interference and burr on VDD.

【Note】LVR has four gear selection, LVR setting should refer to VDD voltage, and should be

higher than the minimum operating voltage of the chip. For example, if VDD = 5V, LVR = 4.1V, VDD =

3.3V, LVR = 2.8V can be set. LVR is also designed with return difference and debouncing function to

prevent LVR error caused by interference and burr on VDD.

【Note】BOD and LVR are opened and set by internal registers

1.2.2. Clock

【Note】Although there is no mandatory requirement, it is recommended to use HSI as PLL clock

source to open input prescaler (PLLXTPRE=3).

10

【Note】In addition to external crystal oscillator, HSE can also be filled with clock from XTAL1 pin,

which can be filled with square wave or sine wave.

【Note】PLL input clock PLLCLKIN, prescaler clock PRECLK, intermediate frequency doubling

clock VCOCLK and output clock PLLCLK must meet the requirements, otherwise PLL working reliability

cannot be guaranteed.

【Note】All clock sources should be switched after the corresponding READY bit is set.

【Note】HCLK、PCLK0 and PCLK1 have the maximum frequency limit, which should be noted

when configuring the bus clock.

【Note】CSM is normally open after power on and can be turned off by the user code option. After

CSM occurs, the system automatically switches to HSI operation and applies for NMI interrupt (set by

the bit IEN_ [email protected]). In NMI interrupt function, some system protection work can be

done.

【Note】After CSM occurs, some abnormal signs will be generated according to the invalid clock

source, and some status bits and enable bits will be cleared automatically. For simplicity, the

corresponding clock can be turned off, and then the clock can be turned on again according to the steps

(equivalent to calling RCC_Config again).

【Note】SysTick uses HCLK/8 as the clock source by default, and the period constant is fixed at

90000. When HCLK=72MHz, SysTick cycle is 10ms. If HCLK is other basic frequency, the

corresponding period will also change automatically. The calculation method is 90000*8/HCLK.

【Note】HSI trimming function is a special function, which can correct the frequency deviation of

HSI through HSE to further improve the accuracy of HSI or compensate the temperature drift of HSI. It

is generally believed that the accuracy and temperature coefficient of HSE are better than HSI. If there

is a corresponding clock source in the system, the high-accuracy clock source can be used to correct

the system clock source HSI by using the trimming function.

【Note】The reset of each module is set by software. After the reset is completed, the hardware will

clear automatically. After starting the reset, it is required to wait for a HCLK clock to read the reset

parameters.

1.2.3. Reset

【Note】SH32F9001 series has a perfect power on reset circuit. The PIN reset is not necessary.

The PIN reset is reserved for the consideration of flexibility and functionality. For example, after reusing

all SWJ debug interfaces into GPIO ports, the PIN reset intervention is required to restore the debug

function. The details are described in SYSCFG module.

【Note】After power on reset, PIN reset and low voltage reset, there is a warming up time of power

supply, which is calculated as 15ms, while about 1ms is reserved for watchdog reset and software

reset.

1.3. Application examples

1.3.1. Example 1

Function: Standard RCC configuration process example.

11

Note: use external HSE (8MHz) as clock source, turn on PLL, set the main frequency as 72MHz,

HCLK=72M, PCLK0=36M, PCLK1=36M. Note that the flash latency should be set.

Code:

#include <SH32F9001.H>

void RCC_Config(void)

{

FLASH->ACR.V32 = 0x5AA50003; // Set flash lantency=3 in advance

RCC->RCCLOCK = 0x33CC; // unlock

RCC->CR.BIT.HSEON = 1; // HSEON, HSE: 8MHz

while(!RCC->CR.BIT.HSERDY);

/* wait HSE ready. Use while to query to simplify the processing here. Actually, the exit condition should

be set. Or force a delay for a period of time to prevent the failure of HSE to be ready.*/

RCC->CFGR.BIT.PLLXTPRE = 0; // PLL prescaler, 0: 1/1, 1:1/2

RCC->CFGR.BIT.PLLSRC = 1; // PLL clock source, 0: HSI, 1:HSE

RCC->CFGR.BIT.PLLF = 33; // PLLF factor, 15+33=48

RCC->CFGR.BIT.PLLK = 1; // PLLK factor, 1+1=2

// PLL clock: 8M/1*48/2/2=72MHz

RCC->CR.BIT.PLLON = 1; // Open PLL module

while(!RCC->CR.BIT.PLLRDY);

/* wait PLL ready. Use while to query to simplify the processing here. Actually, the exit condition should

be set. Or force a delay for a period of time to prevent the failure of HSE to be ready.*/

RCC->CFGR.BIT.HPRE = 0; // HCLK = SYSCLK/1, 72M

RCC->CFGR.BIT.PPRE0 = 1; // PCLK2 = HCLK /2, 36M

RCC->CFGR.BIT.PPRE1 = 1; // PCLK1 = HCLK /4, 36M

RCC->CR.BIT.SW = 1; // SYSCLK source ~ 00: HSI, 01:PLL, 10:LSE, 11:HSE

while(RCC->CR.BIT.SWS != RCC->CR.BIT.SW);

// Turn on the corresponding clock according to the number of peripheral modules used

RCC->AHBENR.BIT.IOCLKEN = 1; // GPIO clock enable

RCC->APB1ENR.BIT.UART1EN = 1; // UART1 clock enable

RCC->AHBENR.BIT.DMAEN = 1; // DMA clock enable

RCC->AHBENR.BIT.SYSCFGEN = 1; // SYSCFG clock enable

}

SH32F9001 Series User Guide

12

2. I/O

2.1. Overview

The SH32F9001 series provide up to 75 general-purpose I/O ports, which are divided into 5 groups

of ports (A-E), and each group contains up to 16 I/O ports. Each I/O port has its own configuration

register and data register.

Most I/O ports have multiplexing function, either with on-chip digital peripherals, or with on-chip

analog peripherals, or with external interrupt and debug interfaces.

All I/O ports support weak pull-up and pull-down, configurable push-pull and open drain outputs.

The output drive ability can be adjusted in multiple levels. Some I/O ports (PB4 ~ pb15) provide super

current capability (120mA) to meet the requirements of direct drive LED or low-power devices in some

applications.

2.2. Programming Setting

2.2.1. GPIO mode

GPIO mode is the basic working mode of I/O. after power on, all I/O ports are in full close mode (AF

= 0) except for the debug interface (SWJ port). If you need to use the function of GPIO, please set its AF

to 1. It is recommended to set AF to 0 for GPIO ports that is not used.

GPIO mode has three basic working modes: GPIO input, GPIO output (push-pull) and GPIO output

(open drain).

1) GPIO input: MODER=0b,[PLDRx:PHDRx]=00b/01b/10b/11b, the I/O port level state can be

obtained by reading and accessing the input register IDR.

【Note】Read operation only triggers I/O port level sampling, and IDR keeps the last sampling value

at other times.

【Note】[PLDRx:PHDRx]=11b, pull-up and pull-down are fully open. At this time, I/O port level is in

resistance partial voltage state, close to VDD/2 (note that the partial voltage ratio will be affected by VDD,

that is the partial voltage ratio at 5V here).

2)GPIO output (push-pull): MODER=1b,OTYPE=0b,ODRVR[1:0]=00b/01b/10b/11b, the write

operation of the output register ODR will change the I/O port level, write 1 to activate PMOS, output

high level, write 0 to activate NMOS, output low level.

3)GPIO output (open drain): MODER=1b,OTYPE=1b,ODRVR[1:0]=00b/01b/10b/11b, that write

0 to the output register ODR can activate NMOS, output low level. That write 1 can not activate

PMOS, unable to output high level, in high resistance state.

【Note】In the open drain mode, the high level output can be obtained by external pull-up, but the

external pull-up should not exceed the working voltage of the chip and VDD + 0.5V in the extreme case.

【Note】In the output mode, adjusting ODRVR can change the output drive gear, including the

ability of pulling current and sinking current. Among them, only 12 pins have the sinking current ability of

120mA, which is PB4-PB15. The maximum current limit of chip GND is 250mA, and so only one channel

13

of 120mA current can be started each time in application. If there are multiple channels, it can only be

started by scanning mode.

2.2.2. Multiplexing for digital peripherals

Digital peripherals can select mapped I/O ports through AF register. SH32F9001 series support

powerful pin remapping. The same peripheral can be mapped to I/O ports at different positions, which is

convenient for system wiring and function combination.

Digital peripherals will control the I/O port input and output, that is, after an I/O port is mapped to a

digital peripheral, the user does not need to configure the MODER register. In addition, other function

options of I/O port also need user software configuration, such as pull-down, push-pull / open drain,

output drive capability.

【Note】The configuration of digital peripherals and I/O ports have no strict requirements in

sequence. Generally speaking, it is recommended to configure peripherals before I/O ports for output

ports, and I/O ports should be configured before configuring peripherals for input ports or bidirectional

ports. The former is because the output port of some peripherals will present a high resistance state or

a level before it is turned on, and a level will appear after it is turned on. If I/O ports are mapped well in

advance, the level change may have an impact on the external circuit. The latter is for the external input

port, which requires a certain level before opening. Therefore, the I/O port should be configured in

advance to avoid misoperation of peripheral equipment caused by level change.

The configuration sequence can be summarized as follows:

Output peripherals: First configure peripherals, and turn on peripherals. Then configure I/O port pull

up/down and output mode. And finally AF switches to peripherals.

Input peripherals: First configure the I/O port pull-up/down and output mode. Then AF switches to

the peripheral. And finally configure and turn on the peripherals (if the peripheral has an enable switch,

the peripheral can be configured synchronously during I/O configuration, and the last step is to turn on

the peripherals).

When mapping to a digital peripheral, GPIO output will be disconnected (only ODR register output

is actually disconnected). But GPIO input will not be turned off, that is, I/O port level can always be

sampled through IDR.

The mapping between peripherals and I/O ports can be easily determined by "Alternate Function

Mapping Table ".

【Note】SH32F9001 series do not prohibit overlapping mapping. For example, RXD0 can be

mapped to PA4, PB7, PC10 and PD13 at the same time. Once this is done, the received signals of these

four pins will be sent to RXD0, causing signal disorder. This configuration should be avoided in

application. Similarly, TXD0 hardware also allows such overlapping mapping, which should be avoided

by users.

2.2.3. Multiplexing for analog peripherals

When mapping to analog peripherals, both GPIO input and output channels are closed. At this

point, if the user reads the IDR register, it will read 0.

14

It is meaningless to configure the MODER, OTYPE and ODRVR registers for analog peripherals,

but it is allowed to configure the PUPDR register to construct a pull-up, pull-down or intermediate level

on the I/O port.

【Note】Analog peripherals require I/O ports to switch to the relevant AF, and then turn on the

analog peripherals.

Note: This is different from digital peripherals. Digital peripherals are only recommended and

analog peripherals are necessary.

2.2.4. Full close mode

The full close mode will cut off the input and output channels, which can completely eliminate the

leakage problem when I/O ports are configured as input floating. For simplicity, the unused I/O ports

can be configured to be fully closed in application.

During power on reset, all I/O ports except SWJ port are in fully closed state. After reset, it will enter

the default state (GPIO input is suspended).

上电复位期间,除 SWJ 口外的所有 I/O 口都处于全关状态,复位完成后进入默认状态(GPIO 输入悬

空)。

【Note】Pull up and down in full close mode is effective.

2.2.5. Debug interface

Five debug interfaces (SWJ interface, SWD mode): SWDIO, SWCLK and SWO can be multiplexed

as GPIO mode.

After the system is powered on and reset, it is used as the debug interface by default. To multiplex

it into GPIO mode, it needs to be modified by SAFR register in SYSCFG. According to different options,

it can be partially or completely multiplexed as GPIO.

【Note】Here, GPIO mode includes digital peripheral mode, which refers to "non-debug interface"

mode, and can be used as digital peripheral mapping port.

【Note】The SWJ interface has a forced pull-up and pull-down, which cannot be closed. When

multiplexing the SWJ interface as a GPIO port, pay attention to the internal pull-up and pull-down effect.

【Note】For the multiplexing of oscillator interfaces XTAL1/XTAL2 and XTALX1/XTALX2, please

refer to the definition of SAFR register. They are fully closed by default after power on.

【Note】SWJCFG, OSCCFG and OSCXCFGS in SAFR register can only be set once after reset.

Once set in the program, it cannot be changed.

2.2.6. Other notes

【Note】I/O configuration operation has corresponding lock/unlock function, and configuration

information cannot be modified after locking

GPIOB_CFG->LCKR.V32 = 0x5AA5FFFF; // lock PB config

GPIOB_CFG->LCKR.V32 = 0x5AA50000; // unlock PB config

【Note】There are two ways to set and clear the port: BSRR and ODR.The setting and clearing of

ODR are realized by BSRR. When the setting and clearing of a bit by BSRR are effective at the same

time, the setting has high priority.

GPIOB->BSRR.BIT.BS = 0x8000; // set PB15 = 1

15

GPIOB->BSRR.BIT.BR = 0x8000; // set PB15 = 0

GPIOB->ODR |= 0x8000; // set PB15 = 1

GPIOB->ODR &= 0x7FFF; // set PB15 = 0

【Note】TTL level input function. This function mainly aims at the level matching problem when the

external port working at TTL level is connected with the chip. The TTL level input option changes the

input high and low voltage thresholds (VIH3、VIL3).

2.3. Application examples

2.3.1. Example 1

Function: Use PWM0 to output 4KHz square wave on PB8-PB9.

Note: When the configuration is multiplexed, the digital peripheral function is first turned on, and

then mapped to the corresponding I/O port. Generally, the I/O port of this kind of application has

external pull-up/down for protection.

Code:

#include <SH32F9001.H>

void main(void)

{

RCC_Config(); // Configure HSI as the system clock, HCLK=24MHz, PCLK0=HCLK/1

NVIC_Config(); // If you need to configure interrupts, this example does not use interrupts

GPIO_Config(); // If I/O needs to be configured, this example remains closed by default

RCC->RCCLOCK = 0x33CC; // unlock RCC config

RCC->AHBENR.BIT.IOCLKEN = 1; // Turn on the GPIO module clock

RCC->APB0ENR.BIT.PWM0EN = 1; // Turn on the PWM0 module clock

RCC->RCCLOCK = 0x0; // lock RCC config

PWM0->PWMLOCK = 0x5AA5; // unlock PWM0 config

PWM0->PWMPR = 3000; // PWM0 period

PWM0->PWMDR = 1500; // PWM0 duty, 50% duty cycle

PWM0->CR.BIT.PWMEN = 1; //PWM module enable (time base enable)

PWM0->PWMLOCK = 0; // lock PWM0config

GPIOB_CFG->LCKR.V32 = 0x5AA50000; // unlock PB config

GPIOB_CFG->AFRH.BIT.AFR9 = 7; // PB9 is mapped to PWM0B

GPIOB_CFG->AFRH.BIT.AFR8 = 7; // PB8 is mapped to PWM0A

GPIOB_CFG->LCKR.V32 = 0x5AA5FFFF; // lock PB config

while(1) // main loop

{

}

16

}

2.3.2. Example 2

Function: UART0 is used to send and receive on PA3/TXD0 and PA4/RXD0. The host computer

connects SH32F9001 series through UART0, and sends 1 byte. After SH32F9001 series receive the

byte, it adds 0x55 and then feeds back to the host computer. The baud rate is 9600Bps, and the mode

of 8/1/1/ none is adopted.

Note: (1) In the multiplexing configuration, the I/O port is configured first, and then the digital

peripheral function is turned on. If RXD is opened first, it is possible that the change of external I/O level

may lead to the wrong start bit of receiving.

(2) In this example, RXD0 is mapped to PA4 to demonstrate that SWJ interface is multiplexed into

digital peripheral interface function.

(3) RXD0 is initialized as input and internal pull-up, and TXD0 are initialized as output high level.

Code:

#include <SH32F9001.H>

char WaitUartTransmit(UART_TypeDef* Uart, unsigned char ch )

{

while(!Uart->FR.BIT.TI); // Wait for the send to complete

Uart->TDR = ch; // Send data, Ti is auto cleared

return (ch);

}

char WaitUartReceive(UART_TypeDef* Uart)

{

while(!Uart->FR.BIT.RI); // Wait for the reception to complete

Uart->FR.BIT.RIC = 1; // RI is cleared as write 1 by software

return(Uart->RDR); //It is required to clear RI before returning data to avoid blocking reception

}

void main(void)

{

unsigned char rcv_byte;

RCC_Config(); // Configure PLL as system clock, HCLK=72MHz, PCLK0/1=HCLK/2

NVIC_Config(); // If you need to configure interrupts, this example does not use interrupts

GPIO_Config(); // If I/O needs to be configured, this example leaves the default input

RCC->RCCLOCK = 0x33CC; // unlock RCC config

RCC->AHBENR.BIT.IOCLKEN = 1; // Turn on the GPIO module clock

RCC->AHBENR.BIT.SYSCFGEN = 1; // Turn on the SYSCFG module clock (SWJ multiplexing)

RCC->APB1ENR.BIT.UART0EN = 1; // Turn on UART0 clock

RCC->RCCLOCK = 0x0; // lock RCC config

17

GPIOA_CFG->LCKR.V32 = 0x5AA50000; // unlock PA config

GPIOA->MODER |= 0x0008; // set PA3 output

GPIOA->MODER &= 0xFFEF; // set PA4 input (default)

GPIOA_CFG->PUPDR.BIT.PHDR4 = 1; // set PA4 pull-up, 01b: pull-up

GPIOA->ODR |= 0x0008; // set PA3 = 1

SYSCFG->SAFR.V32 = 0x5AA50020; //SWD interface control, release PA4, PA5

GPIOA_CFG->AFRL.BIT.AFR3 = 2; // PA3 is mapped to TXD0

GPIOA_CFG->AFRL.BIT.AFR4 = 2; // PA4 is mapped to RXD0

GPIOA_CFG->LCKR.V32 = 0x5AA5FFFF; // lock PA config

UART0->BRT.BIT.SBRT = 233; // Set baud rate to 9.6KBps, 36M/16/9.6K=234.375, SBRT=233

UART0->BRT.BIT.BFINE = 6; // 0.375*16=6

UART0->CR.BIT.SM = 1; // type 1: 8/1/1/none, variable baud rate

UART0->CR.BIT.SBRTEN = 1; // enable baud rate generation

UART0->CR.BIT.TEN = 1; // enable txd

UART0->CR.BIT.REN = 1; // enable rxd

while(1) // main loop

{

rcv_byte = WaitUartReceive(UART0); // Uart reception

WaitUartTransmit(UART0,rcv_byte+0x55); // Uart sending

}

}

3. NVIC

3.1. Overview

NVIC is the main component of Cortex-M3. It is closely combined with CPU to reduce the interrupt

delay, so that new interrupt can be processed efficiently. In addition to the exceptions provided by

Cortex-M3, the SH32F9001 series also have 41 dynamically configurable priority interrupts. Each

interrupt has 16 priorities.

3.2. Programming Setting

3.2.1.1. Interrupt configuration basis

Each interrupt has an interrupt number, which is the identity of all interrupt operations and is

defined in the chip header file. The starting address of the interrupt vector table is determined by the

register VTOR, which is 0 when reset. The interrupt vector table is defined in startup_SH32F9001_keil.s,

a default processing function is defined for each interrupt. When it is necessary to replace this

processing function, we only need to define an interrupt service function with the same name in the

18

interrupt vector table. There is no need for startup_SH32F9001_keil.s to modify, the compiler will

automatically replace it with a user-defined function.

3.2.1.2. Enable and disable interrupt

In order to enable interrupt, it is necessary to set the interrupt enable bit in the module first, and

then set the interrupt enable bit in NVIC. If any one of them is disabled, the interrupt service program

will not be executed. In addition, special function registers BASEPRI, FAULTMASK, PRIMASK can be

more convenient for masking interrupt. These registers are accessed by MSR, MRS instructions.

BASEPRI: Interrupt mask register, only 8 bits, can set an interrupt priority. All interrupts with a

priority that is no greater than this priority will be masked (the higher the value of interrupt priority, the

lower the priority is, so all interrupts with a priority value greater than or equal to this priority will be

masked). When the value of the register is 0, it means that the register is invalid, that is, it is not used for

interrupt masking. The default value is 0.

PRIMASK: Interrupt mask register, only 1 bit. It is set to mask all maskable interrupts

FAULTMASK: Fault mask register, only 1 bit. When set to 1, all interrupts and faults except NMI

will be masked. This register can only be set to 1 in privileged mode.

3.2.1.3. Interrupt pending and releasing

The interrupt status can be controlled by the interrupt pending register (SETPEND) and interrupt

pending clear register (CLRPEND). The function of triggering an interrupt by program is realized.

【Note】Write interrupt pending register operation has no effect on pended or prohibited interrupts.

【Note】The PEND register in NVIC will be set or cleared automatically, so there is no need to

modify it under non special circumstances.

3.2.1.4. Interrupt priority

The EXTI of SH32F9001 series has a corresponding priority register. Each register has 8 bits, and

the SH32F9001 series occupies the upper 4 bits. The 4-bit priority can be grouped. The grouping mode

is set by the PRIGROUP bit in the interrupt reset register AIRCR. The group priority is preemptive, and

the intra group priority is not preemptive.

3.2.1.5. Interrupt/fault response sequence

Stack: stack 8 registers (xPSR, PC, LR, R12, R3, R2, R1, R0)

Get vector: find the corresponding service program entry address from the vector table

Update register: select stack pointer MSP/PSP, update stack pointer SP, connect register LR,

program counter

SP: stack pointer (PSP/MSP) will be updated to the new position in the stack. After executing

the service routine, MSP is responsible for accessing the stack.

PSR: The IPSR bit segment (located in the lowest part of the PSR) is updated with the

exception number of the new response.

PC: after the vector is taken out, the PC will point to the entry address of the service routine.

LR: The use of LR will be reinterpreted and its value will be updated to a special value called

"EXC_RETURN" and is used when interrupt/fault returns.

19

Update NVIC register: interrupt pending bit is cleared and active bit is set to 1.

【Note】Since the I/D bus is independent, the stack and vector fetching are carried out at the same

time

3.2.1.6. Interrupt /fault return

A return sequence is required after the interrupt/fault service program is executed. There are three

ways to trigger the return sequence

BX <reg> when LR stores EXC_RETURN, use BX LR to return.

POP {PC} / POP {…,PC} EXC_RETURN is stored in the stack when out of the PC stack.

LDR / LDM loads PC as target register into EXC_RETURN.

Return sequence

POP: Restore the register of the previous stack

Update NVIC register: Interrupt active bit is cleared by hardware. For EXTI, if the interrupt input is

set to be valid again, the pending bit will be set again, and a new interrupt response sequence will start

again.

3.2.1.7. Nested interrupts

The NVIC of CM3 core supports interrupt nesting. You need to configure the interrupt priority to

control the nesting of interrupts.

【Note】The capacity of the main stack is to maintain a safe value, and at least eight words per

nested level.

【Note】Reentry is not allowed for the same interrupt.

3.2.1.8. Tail interrupt

If the priority of the pending interrupt is higher than that of all the push stack interrupts, the

processor performs tail chaining. Tail-chaining means that when exiting ISR and entering another

interrupt, the processor skips the push stack and pop stack operations of 8 registers, because it has no

effect on the contents of the stack. Therefore, it is possible to implement back-to-back processing

without redundant state saving and recovery instructions between two interrupts.

3.2.1.9. Late interrupt

If the previous ISR has not entered the execution phase, and the priority of the late interrupt is

higher than that of the previous interrupt, the late interrupt can preempt the previous interrupt. The

response to late interrupt makes it necessary to perform a new vector address and ISR prefetch

operation. Late interrupt does not save the state because the state has been executed by the original

interrupt.

3.2.1.10. Abort model

There are 4 events that can generate abort faults:

Bus error when instruction fetching or vector table loading.

Bus error during data access.

Errors which are detected internally, such as undefined instructions or attempts to change

state with BX instructions

20

The privilege mode or zone for administration is violated due to the fault of MPU

3.2.1.11. Local fault and upgrade

When enabled, the local fault processing program handles all conventional faults. When the

following conditions occur, the local fault will be upgraded to hard fault:

The local fault handling is responding and causes the same type of fault.

Local fault handling procedures cause faults with the same or higher priority.

The exception handler caused a fault with the same or higher priority.

Local fault is not enabled.

3.3. Application examples

3.3.1. Example 1

Function: Use Timer5 to generate a timer interrupt.

Note: Demonstrate the process of using interrupts in programs.

Code:

#include "SH32F9001.h"

uint32_t g_timer_count = 0;

int main()

{

RCC->RCCLOCK = 0x33CC; // Unlock RCC register

RCC->APB0ENR.BIT.TIM5EN = 1; // Turn on the clock switch of timer 5

RCC->RCCLOCK = 0x0; // Lock RCC register to prevent error modification

TIM5->PSQ = 0x8; // Set Timer5 count clock to 9 timer module clocks

TIM5->TPR = 1000; // Set Timer5 count cycle to 1000 clocks

TIM5->TCNT = 0; // Set the initial value to 0

TIM5->CR.BIT.CLKS = 0; // Timer5 clock is APB0 clock

TIM5->CR.BIT.OPM = 0; // Timer5 is set to cycle mode

TIM5->CR.BIT.IE = 1; // Allow timer interrupt generation

NVIC_EnableIRQ(TIM5_IRQn);

// Set NVIC->ISER[] to enable timer interrupt in NVIC, inline function in core_cm3.h file

TIM5->CR.BIT.STR = 1; // Start Timer5

while(1);

}

void TIM5_Handler()

{

TIM5->TIMINTF.BIT.TFC = 1; // Clear interrupt flag

g_timer_count++; // Counter accumulation

}

3.3.2. Example 2

21

Function: Interrupt priority and mask bit demonstration.

Note: Timer5 is used to generate a timer interrupt to demonstrate the use process of interrupt in the

program.

Code:

#include "SH32F9001.h"

#define TIM_SEQ_COUNT 8 // Define the buffer length to save the execution sequence

uint8_t g_timer_seq[TIM_SEQ_COUNT]; // Define the buffer to save the execution sequence

volatile uint8_t g_seq_idx; // Define the buffer index to save the execution sequence

// Delay Function

void delay(int i)

{

while(i > 0)

{

i--;

__NOP();

}

}

// Clear buffer function

void clear_timer_sequence()

{

uint8_t i;

for(i = 0; i < TIM_SEQ_COUNT; i++)

g_timer_seq[i] = 0;

g_seq_idx = 0;

}

// Initialize timer function

void initial_timer(TIM_TypeDef* TIM)

{

TIM->PSQ = 0x1; // Set the timer count clock to 2 timer module clocks

TIM->TPR = 1000; // Set timer count cycle to 1000 clocks

TIM->TCNT = 0; // Set the initial value to 0

TIM->CR.BIT.CLKS = 0; // Timer clock is APB0 clock

TIM->CR.BIT.OPM = 1; // Single mode

TIM->CR.BIT.IE = 1; // Allow timer interrupt generation

}

int main()

{

// Open TIMER, SYSCFG module clock

RCC->RCCLOCK = 0x33CC; // Unlock RCC register

RCC->APB0ENR.BIT.TIM5EN = 1;

22

RCC->APB0ENR.BIT.TIM6EN = 1;

RCC->APB0ENR.BIT.TIM7EN = 1;

RCC->APB0ENR.BIT.TIM8EN = 1;

RCC->AHBENR.BIT.SYSCFGEN = 1;

RCC->RCCLOCK = 0x0; // Lock RCC register to prevent error modification

NVIC_SetPriorityGrouping(5); // Define priority grouping format 5: xx.yyyyyy. For the SH32F9001 series xx.yy0000

// Initialize the timer

initial_timer(TIM5);

initial_timer(TIM6);

initial_timer(TIM7);

initial_timer(TIM8);

// Enable each timer interrupt in NVIC module

NVIC_EnableIRQ(TIM5_IRQn);

NVIC_EnableIRQ(TIM6_IRQn);

NVIC_EnableIRQ(TIM7_IRQn);

NVIC_EnableIRQ(TIM8_IRQn);

/****************************************/

/********* Interrupt preemption ****************/

//Set Priority Timer 5 Lower Than Timer 6

NVIC_SetPriority(TIM5_IRQn,0x4); // Set TIM5 priority to 01:00

NVIC_SetPriority(TIM6_IRQn,0x0); //Set TIM6 priority to 00:00, preemption priority is higher than TIM5

clear_timer_sequence();

TIM5->CR.BIT.STR = 1;

delay(10);

TIM6->CR.BIT.STR = 1;

delay(100000); // Delay to ensure that the interrupt is generated and the execution ends

/***** Sequence of results, g_timer_seq[] : 5,6,16,15 **/

/* Timer5 is preempted by timer6 */

/****************************************/

/****************************************/

/***** Mask interrupt through BASEPRI register priority *****/

//Set the priority of each interrupt: Timer8 > Timer7 > Timer 6 > Timer5

NVIC_SetPriority(TIM5_IRQn,0xC);

NVIC_SetPriority(TIM6_IRQn,0x8);

NVIC_SetPriority(TIM7_IRQn,0x4);

NVIC_SetPriority(TIM8_IRQn,0x0);

__set_BASEPRI(0x4 << __NVIC_PRIO_BITS); // Set masking priority to 4

23

clear_timer_sequence(); //Clear BUFFER of the results

// Start each timer

TIM8->CR.BIT.STR = 1;

TIM7->CR.BIT.STR = 1;

TIM6->CR.BIT.STR = 1;

TIM5->CR.BIT.STR = 1;

delay(100000);

/***** Sequence of results g_timer_seq[] : 8, 18 ****/

/* Interrupts with priority < = 4 are masked */

/****************************************/

__set_BASEPRI(0x8 << __NVIC_PRIO_BITS); // Set mask priority to 8

clear_timer_sequence(); // Clear BUFFER of the results

TIM8->CR.BIT.STR = 1; // Start each timer

TIM7->CR.BIT.STR = 1;

TIM6->CR.BIT.STR = 1;

TIM5->CR.BIT.STR = 1;

delay(100000);

/** Sequence of results g_timer_seq[] : 8,18,7,17 */

/* Interrupts with priority < = 4 are masked */

/****************************************/

/****************************************/

/***** Mask interrupt through BASEPRI *****/

__set_BASEPRI(0x0 << __NVIC_PRIO_BITS); // Disable BASEPRI register

__set_PRIMASK(1); // Enable BASEPRI register

SYSCFG->CRAMLOCK.V32 = (0X5AA5 << 16) | 1; //CRAM write protect

clear_timer_sequence(); //Clear BUFFER of the results

TIM8->CR.BIT.STR = 1; // Start timer

TIM7->CR.BIT.STR = 1;

TIM6->CR.BIT.STR = 1;

TIM5->CR.BIT.STR = 1;

*((volatile uint32_t*)0x10000000) = 0x1122;

// Hardfault is triggered by writing protected cram Illegally.

delay(100000);

/** Sequence of results g_timer_seq[] : 21 */

/* Only hardfault is executed */

/****************************************/

24

/****************************************/

/***** Mask interrupt through FAULTMASK *****/

/****************************************/

__set_PRIMASK(0) //Disable PRIMASK;

__set_FAULTMASK(1); //Enable PRIMASK;

SYSCFG->CRAMLOCK.V32 = (0X5AA5 << 16) | 1; //CRAM write protect

clear_timer_sequence(); // Clear BUFFER of the results

TIM8->CR.BIT.STR = 1; // Start timer

TIM7->CR.BIT.STR = 1;

TIM6->CR.BIT.STR = 1;

TIM5->CR.BIT.STR = 1;

*((volatile uint32_t*)0x10000000) = 0x1122;

// Hardfault is triggered by writing protected cram Illegally.

delay(100000);

/** Sequence of results g_timer_seq[] : 00*/

/* No interrupts and faults are executed */

/****************************************/

while(1);

}

// Timer5 Interrupt service program

void TIM5_Handler()

{

g_timer_seq[g_seq_idx++] = 5; //Write flag

TIM5->TIMINTF.BIT.TFC = 1; // Clear interrupt flag

delay(10); // Delay

g_timer_seq[g_seq_idx++] = 0x15; // Write flag

}

// Timer6 Interrupt service program

void TIM6_Handler()

{

g_timer_seq[g_seq_idx++] = 6; // Write flag

TIM6->TIMINTF.BIT.TFC = 1; // Clear interrupt flag

delay(10); // Delay

g_timer_seq[g_seq_idx++] = 0x16; // Write flag

}

// Timer5 Interrupt service program

void TIM7_Handler()

{

g_timer_seq[g_seq_idx++] = 7; // Write flag

TIM7->TIMINTF.BIT.TFC = 1; // Clear interrupt flag

25

delay(10); // Delay

g_timer_seq[g_seq_idx++] = 0x17; // Write flag

}

// Timer8 Interrupt service program

void TIM8_Handler()

{

g_timer_seq[g_seq_idx++] = 8; // Write flag

TIM8->TIMINTF.BIT.TFC = 1; // Clear interrupt flag

delay(10); // Delay

g_timer_seq[g_seq_idx++] = 0x18; // Write flag

}

// Hardfault Interrupt service program

void HardFault_Handler()

{

SYSCFG->CRAMLOCK.V32 = (0X5AA5 << 16); // Remove write protection

g_timer_seq[g_seq_idx++] = 0x21; // Write flag

}

SH32F9001 Series User Guide

26

4. RAM

4.1. Overview

The SH32F9001 series provides two RAM (SRAM and CRAM). Both can be used as variable areas

of a program. The difference is that CRAM is located in the area of 0x10000000, which belongs to the

code area in Cortex-M3. It can improve the code execution efficiency and has the write protection

function, which can protect the code in CRAM from being tampered with unintentionally. SRAM is

mainly used to store program variables and run program code, but it is not as efficient as CRAM area.

4.2. Programming Setting

The CRAM write protection of SH32F9001 series takes 2K bytes as a sector, and a protection bit

corresponds to a sector, which is controlled by CRAMLCK register in SYSCFG module.

【Note】A bus error will be triggered if a write operation is performed on a write protected CRAM.

【Note】To run a specific program in CRAM, you need to identify the program segment in the

program, and specify the address of the identification segment in the linker's configuration file to CRAM.

Please refer to appendix 2 for further information.

4.3. Application examples

Function: This routine demonstrates how to locate a function to run in CRAM.

Note: After program startup, run_in_cram() will be copied to the CRAM area. Calling this function

will make the PC pointer run to the CRAM area.

Code:

#include "SH32F9001.h"

// Specify this function to ”.cram_code”

uint32_t run_in_cram(void) __attribute__ ((section(".cram_code")));

uint32_t run_in_cram(void)

{

return (uint32_t)run_in_cram; // Return function address

}

int main()

{

volatile uint32_t func_addr;

RCC->RCCLOCK = 0x33CC; // unlock RCC config

RCC->AHBENR.BIT.SYSCFGEN = 1; // Open the SYSCFG module clock

RCC->RCCLOCK = 0x0; // lock RCC config

/* Set the first sector of CRAM to write protection. At this moment, this function body has been copied

to CRAM by C runtime */

SYSCFG->CRAMLOCK.V32 = (0x5AA5<<16)|(1<<0);

27

func_addr = run_in_cram(); // Call the function in CRAM. The return address is 0x10000001

while(1);

}

// Configuration file of linker: cramcode.sct.

// This file needs to be specified in the scatter file option on the linker options page

; *************************************************************

; *** Scatter-Loading Description File generated by uVision ***

; *************************************************************

LR_IROM1 0x00000000 0x00040000 { ; load region size_region

ER_IROM1 0x00000000 0x00040000 { ; load address = execution address

*.o (RESET, +First)

*(InRoot$$Sections)

.ANY (+RO)

}

; Define CRAM area and put specified ".cram_code" in this area

RW_CRAM1 0x10000000 0x00004000 { ; RW data

*(.cram_code)

}

RW_IRAM1 0x20000000 0x00004000 { ; RW data

.ANY (+RW +ZI)

}

}

SH32F9001 Series User Guide

28

5. Flash&EEPROM

5.1. Overview

SH32F9001 series have 256K programmable flash main program memory block. Each sector is

1024 bytes, and 256 sectors can be erased separately. After erasing the main memory area, every 16

bits or 32 bits can be programmed only once.

6KB built-in EEPROM like storage area is used to store user data. Each sector is 1024 bytes, and

each sector can be erased separately.

1KB OTP area is used to store factory initialization data. It should be noted that once the OTP area

data is written, it can not be erased.

The main program area in flash can be protected from illegal reading by setting read protection.

Write protection can also be set for each sector of flash storage area to prevent accidental change in

the case of program running. For 256KB flash storage area, the basic unit of write protection is that 8

sectors are one protection unit.

5.2. Programming Setting

The operation process of Flash、EEPROM、OTP area is basically the same, which can be roughly

divided into the following steps:

Unlock the corresponding operation register

Set flash operation timer

Flash (E2/OTP) erasing and programming configuration

Lock the corresponding operation register

5.2.1. Flash Control register unlocking

After the system reset, the flash memory operation register is locked, so it is necessary to unlock

the flash memory operation register before erasing and programming the flash memory. Different flash

storage areas have different unlocking registers, and corresponding registers need to be unlocked for

different operation areas. To unlock flash, two unlocking values need to be written to the corresponding

unlocking register. The first unlocking value is the initial unlocking value, and the second unlocking

value is the unlocking value of single or multiple operations. If the first key value is written in error or the

second key value is written incorrectly, the corresponding flash area cannot be unlocked, and a bus

error will be generated. If any area is in the unlocking state, then Unlocking the register for unlocking

also generates a bus error. The operation of unlocking flash can also be divided into two situations: one

is that flash can be operated once after unlocking, and the other is that flash can be operated multiple

times after unlocking. If the flash memory operation register is in the unlocking state, the flash can be

controlled by FLASH_CR which is used to erase and program each storage area of flash.

29

Table: unlock value of each unlocking register and description

Register Function

Flash Initial

unlock

value

Single

operation

unlock value

Multiple

operations

unlock value

Instructions

FLASH_

MKYR

Unlock main

program area

0x8ACE

0246

0xC3C3

C3C3 0xB4B4 B4B4

Through the program

running in RAM, the

program in the main

program area

FLASH_

E2KYR

Unlock EEPROM

like area of special

information area

0x9BDF

1357

0xC3C3

C3C3 0xB4B4 B4B4

Through the program

running in RAM, the

program in the main

program area

FLASH_

IKYR

Unlock the code

protection block,

customer block,

and OTP area of

the special

information area

0xABCD

5678

0xC3C3

C3C3 0xB4B4 B4B4

Code protection area,

customer information

area and OTP area can

be realized by program

running in RAM and

program in main

program area

5.2.2. Flash operation timer function

The flash control module has an operation timer. The count value of the flash operation timer takes

the system clock as the clock source. The count value of the flash operation timer must be less than the

upper limit value of the flash operation timer and greater than zero. Only then can the flash storage area

be operated, or a 32bit / 16bit data can be written to the destination address. If you start a flash

operation, it means bit STRT@FLASH_ When Cr is set to 1 or the write operation to flash is started, the

count value of flash operation timer is not in the valid time window, and the flash operation is not

executed, and PGWERR@FLASH_ SR is set to 1. The specific usage of flash operation timer can refer

to the figure below.

The flash control module has an operation timer. The count value of the flash operation timer uses

the system clock as its clock source. The count value of the flash operation timer must be less than the

upper limit of the flash operation timer, and is greater than zero, then operations can be performed on

flash memory, or a 32-bit/16-bit data can be written to target address. If a flash operation is initiated,

which means when STRT@FLASH_CR bit is set to 1 or write operation to flash is initiated, the flash

operation timer count value is not in the valid time window, then the flash operation cannot be

performed and PGWERR@FLASH_SR bit is set to 1. For detailed usage of flash operation timer, see

the figure below.

It should be noted that, CNTEN@FLASH_CNTCR bit controls whether the operation timer starts to

count down. When CNTEN@FLASH_CNTCR bit is set to 1, start timer count down. When CNTEN@

FLASH_CNTCR bit is set to 0, the flash operation timer count remains unchanged. Therefore, as long

30

as the flash operation timer count value is not greater than the flash operation timer upper limit value,

the flash operation can be performed normally.

Is the FLASH_CNT window counter within the valid range of the time window?

(IC hardware implementation)

Is BSY@FLASH_SR bit set to 0?

Yes

No

Set the initial value of the FLASH_CNT window counter,

set the FLASH_UPCNT counter upper limit bit

CNTEN@CNTCR to 1, and start the timer

Start

……

FLASH erase/program operation setting

STRT@FLASH_CR bit is set to 1

or

a 32bit/16bit data is written to target address.

Yes

End

No

OPERR@FLASH_SR bit is set to 1

(IC hardware implementation)

Is the FLASH_CNT window counter within the valid

range of the time window?

(IC hardware implementation)

Figure 1 Flash Operation Timer Flowchart

5.2.3. Flash(E2\OTP) Erasing and Programming

After the Flash、EEPROM、OTP area are operated, and then the flash controller is unlocked and the

flash operation timer is set, the flash control register needs to be configured. The options to be

configured include:

Flash operation command word: CMD@FLASH_CR

0xE619: main block sector erase (MSE)

0x6E91: main block programming (MPG)

0xB44B: E2Prom block programming (IPG)

0x4BB4: E2Prom block sector erase (E2Prom-like) (E2SE)

0xF00F: OTP block programming (OPG)

31

Program operation bit width selection:PSIZE@FLASH_CR

0: 32-bit programming simultaneously

1: 16-bit programming simultaneously

Sector erase selection: SNB@FLASH_CR

00000000: Sector 0

00000001: Sector 1

00000010: Sector 2

……..

11111110: Sector 254

11111111: Sector 255

Note: This bit is effective only when the CMD[15:0] is MSE or E2SE. When the main program

block is erased by sector, each sector size is 1024 bytes. When the EEPROM-like block is erased by

sector, each sector size is 1024 bytes.

Starting flag bit: STRT@FLASH_CR

When the operation command word is erase, an operation will be triggered when the bit is' 1 '.

When the operation command word is programming, an operation will be triggered when a 32-bit word

/16 bit half word is written to the destination address. This bit can only be set to '1' by the software and

cleared to '0' when BSY@FLASH_SR changing to '1'. When BSY@FLASH_SR is cleared to '0', it

means that the operation is finished. At this time, you need to query the status bits in FLASH_SR

register to determine whether the operation is executed normally. If there is an error, the corresponding

error flag bit will be set to 1

5.2.4. Flash control register locking

If the unlocking mode of flash control register allows multiple operations, the corresponding flash

control register must be relocked to prevent the flash from being misoperated.

5.3. Application examples

5.3.1. Flash(E2\OTP) erase and write flow chart

5.3.1.1. Overall erase of main program area

Flash operation provides the overall erase function, which can erase the contents of the main block.

The specific steps are as follows:

(1) FLASH_MKYR is written into flash unlock value and single operation unlock value in order to

ensure that the flash main program area is not locked;

(2) Check BSY@FLASH_SR bit to determine whether flash memory is running.

(3) When the BSY@FLASH_SR bit is 0, write the flash main program area total erasure

instruction word to the FLASH_CR register.

(4) Full-chip erasure operation is initiated via setting STRT@FLASH_CR bit to 1.

(5) Check BSY@FLASH_SR bit to determine whether the erasure instruction has been

executed.

(6) The operation is done when BSY@FLASH_SR bit is 0.

32

EOP@FLASH_SR bit indicates the end of the operation. This bit being set to 1 indicates that

the operation has been completed. All flash data is reset to 0x0000 0000 after being erased.

The flowchart is as follows:

Unlock target flash

(single operation)

Is BSY@FLASH_SR bit set to 0?

Write the main flash program area total erasure

instruction word to the FLASH_CR register

Yes No

Is MNLCK@FLASH_CR bit set to 0?

Is BSY@FLASH_SR bit set to 0?

Yes

STRT@FLASH_CR bit is set to 1

No

Yes

No

End

Start

Figure 3 Main Program Area Total Erasure

Note: before the running program of flash main program area performs overall erasure, it is

necessary to write the overall erase protection byte (Addr: 0x0FFFE020) of the main program

area to 0x01 before erasing.

5.3.1.2. Main Program Area Sector Erasure

Each sector of flash memory can be erased independently without affecting the contents of other

sectors. The flash operation steps to erase sectors are as follows:

(A) Erase a sector separately

(1) FLASH_MKYR sequentially writes the flash unlock value and the single operation unlock value

to ensure that the main flash program area is not locked.

(2) Check BSY@FLASH_SR bit to determine if flash memory is running.

(3) When the BSY@FLASH_SR bit is 0, write the flash main program area sector erasure

instruction word and the number of sector which is going to be erased to the FLASH_CR register.

(4) Sector erasure operation is initiated via setting STRT@FLASH_CR bit to 1.

(5) Check BSY@FLASH_SR bit to determine whether the erasure instruction has been executed.

33

(6) The operation is done when BSY@FLASH_SR bit is 0.

The flowchart is as follows:

Unlock target flash

(single operation)

Is BSY@FLASH_SR bit set to 0?

Write the main flash program area sector erasure instruction word and sector

number to the FLASH_CR register

YesNo

Is MNLCK@FLASH_CR bit set to 0?

Is BSY@FLASH_SR bit set to 0?

Yes

STRT@FLASH_CR bit is set to 1

No

Yes

No

End

Start

Figure4 Main Program Area Sector Erasure (Single Sector)

34

(b) Erase multiple sectors

(1) FLASH_MKYR sequentially writes the flash unlock value and the multiple operation unlock

value to ensure that the main flash program area is not locked.

(2) Check BSY@FLASH_SR bit to determine if flash memory is running.

(3) When the BSY@FLASH_SR bit is 0, write the flash main program area sector erasure

instruction word and sector numbers to the FLASH_CR register.

(4) Sector erasure operation is initiated via setting STRT@FLASH_CR bit to 1.

(5) Check BSY@FLASH_SR bit to determine whether the erasure instruction has been executed.

(6) Repeat steps 3 to 5 to erase other sectors.

(7) Set MNLCK@FLASH_CR bit to 1 to complete the operation.

The flowchart is as follows:

Unlock target flash

(multiple operation)

Is BSY@FLASH_SR bit set to 0?

Write the main flash program area sector erasure instruction word and sector

number to the FLASH_CR register

Yes No

Is MNLCK@FLASH_CR bit set to 0?

Is BSY@FLASH_SR bit set to 0?

Yes

STRT@FLASH_CR bit is set to 1

No

Yes

No

MNLCK@FLASH_CR bit is set to 1

End

Start

Whether there are other sectors that need to be erased

Yes

No

Figure5 Main Program Area Sector Erasure (Multiple Sector)

35

When target erasure sector is used to fetch instructions or access data, the corresponding

erasure operation is invalid, but the flash operation will not provide any notification, so it is

necessary to ensure that the target erasure sector address is correct. EOP@FLASH_SR bit

indicates the end of the operation.

5.3.1.3. Main Program Area Programming

The Flash operation provides a 32-bit word/16-bit half-word programming function to modify

the contents of the flash main memory block. To program on main flash program area, 32 bits/16

bits can be written each time. The addresses must be aligned by 32 bits/16 bits. If they are not

aligned, the corresponding operation is invalid and the relevant error flag is set to 1. When the

FLASH_CR register operation instruction word is set to main program area programming, writing

a word or half word at a flash address will initiate a programming. During the programming

process (bit BSY@FLASH_SR bit is '1'), any operation that reads or writes to flash will cause

CPU to pause until the end of this flash programming.

The following steps show the procedure of word programming operation register.

(a) Single word or half-word programming

(1) FLASH_MKYR sequentially writes the flash unlock value and the single operation unlock

value to ensure that the main flash program area is not locked.

(2) Check BSY@FLASH_SR bit to determine if flash memory is running.

(3) When the BSY@FLASH_SR bit is 0, write the flash main program area programming

instruction word and program operation bit width to the FLASH_CR register.

(4) Write a 32-bit word/16-bit half-word into target address.

(5) Check BSY@FLASH_SR bit to determine whether the programming instruction has been

executed.

(6) The operation is done when BSY@FLASH_SR bit is 0.

The operation flowchart is as follows:

36

Unlock target flash

(single operation)

Is BSY@FLASH_SR bit set to 0?

Write main flash program area programming operation instruction word to

FLASH_CR register

Yes No

Is MNLCK@FLASH_CR bit set to 0?

Is BSY@FLASH_SR bit set to 0?

Yes

No

Yes

No

End

Start

Write a 32-bit word/16-bit half-word into target address

Figure6 Main Program Area Programming (Single word or half word)

37

(b) Continuous multi-word writing programming

(1) FLASH_MKYR sequentially writes the flash unlock value and the multiple operation unlock

value to ensure that the main flash program area is not locked.

(2) Check BSY@FLASH_SR bit to determine if flash memory is running.

(3) Write the flash main program area programming instruction word and program operation bit

width to the FLASH_CR register.

(4) Write a 32-bit word/16-bit half-word into target address.

(5) Check BSY@FLASH_SR bit to determine whether the programming instruction has been

executed.

(6) Repeat steps 4 to 5 until all programmings are done on multiple addresses.

(7) Set MNLCK@FLASH_CR bit to 1 to complete the operation.

Unlock target flash

(multiple operation)

Is BSY@FLASH_SR bit set to 0?

Write main flash program area programming operation instruction word to

FLASH_CR register

Yes No

Is MNLCK@FLASH_CR bit set to 0?

Is BSY@FLASH_SR bit set to 0?

Yes

No

Yes

No

End

Start

Write a 32-bit word/16-bit half-word into target address

Yes

Whether all programmings are done on multiple

addresses

No

MNLCK@FLASH_CR bit is set to 1

Figure7 Main Program Area Programming (Continuous multi-word)

For flash memory, 16-bit or 32-bit data can be written each time. After the main memory erasure operation, of the 16-bit or 32-bit data which are going to be programmed, if any one bit of them is not 0, it cannot be programmed again, otherwise the programming error flag PGERR@FLASH_SR bit is set to 1.

38

If a certain sector of the main flash program area has been protected by any write protection

bit, but this sector is still being written, then the write protection error flag WRPRTERR

@FLASH_SR bit is set to 1.

5.3.1.4. EEPROM-like Memory Area Erasure Programming

EEPROM-like memory area erasure programming is similar to main program area sector

erasure and programming. The difference lies in flash unlock registers. The operation instruction

words written to FLASH_CR register are different, and the flag bits of the lock memory area are

different.

5.3.1.5. OTP Area Programming

OTP area can only be programmed once, and it cannot be erased after programming. The

programming of the OTP area is similar to the programming of the main program area. The

difference lies in flash unlock registers. The operation instruction words written to FLASH_CR

register are different, and the flag bits of the lock memory area are different.

5.3.2. Flash(E2\OTP) example

#include <SH32F9001series.H>

// Setting the flash operation window timer

void FLASH_Set_PGMWindow(uint32_t CounterInitValue, uint32_t UpperCounterValue)

{

/* Sets the initial value of counter */

FLASH->CNTR = CounterInitValue;

/* Sets the upper limit value of counter */

FLASH->UPCNTR = UpperCounterValue;

/* Enable the downcounter */

FLASH_CNTCR_CNTEN_BIT = SET;

}

// Clear disable flash operation window timer

void FLASH_Clear_PGMWindow(void)

{

/* Clears the window counters */

FLASH->CNTR = 0x0;

FLASH->UPCNTR = 0x0;

FLASH_CNTCR_CNTEN_BIT = RESET;

}

// Unlock flash main program storage area

void FLASH_Main_Lock(void)

39

{

/* Set the LOCK Bit to lock the FLASH Registers access */

FLASH_CR_MNLCK_BIT = SET;

}

// Lock flash main program storage area

void FLASH_Main_Unlock(uint8_t OperationType)

{

if(FLASH_CR_E2LCK_BIT == RESET)

{

FLASH_CR_E2LCK_BIT = SET;

}

if(FLASH_CR_INFLCK_BIT == RESET)

{

FLASH_CR_INFLCK_BIT = SET;

}

if(FLASH_CR_MNLCK_BIT != RESET)

{

/* Authorize the FLASH Registers access */

FLASH->MKYR = FLASH_MAIN_KEY;

/* The single unlock key unlocks the flash interface for one write or erase operation. */

if(OperationType == SINGLE_OPERATION)

FLASH->MKYR = FLASH_SINGLE_OP_KEY;

/* The multiple unlock key unlocks the flash interface for write or erase operations

until the block is locked. */

else if(OperationType == MULTI_OPERATION)

FLASH->MKYR = FLASH_MULTI_OP_KEY;

}

}

// Lock E2PROM area

void FLASH_E2_Lock(void)

{

/* Set the E2LCK Bit to lock the EEPRom block control Registers access */

FLASH_CR_E2LCK_BIT = SET;

}

40

// Unlock E2PROM area

void FLASH_E2_Unlock(uint8_t OperationType)

{

if(FLASH_CR_MNLCK_BIT == RESET)

{

FLASH_CR_MNLCK_BIT = SET;

}

if(FLASH_CR_INFLCK_BIT == RESET)

{

FLASH_CR_INFLCK_BIT = SET;

}

if(FLASH_CR_E2LCK_BIT != RESET)

{

/* Authorize the FLASH Registers access */

FLASH->E2KYR = FLASH_E2_KEY;

/* The single unlock key unlocks the flash interface for one write or erase operation. */

if(OperationType == SINGLE_OPERATION)

FLASH->E2KYR = FLASH_SINGLE_OP_KEY;

/* The multiple unlock key unlocks the flash interface for write or erase operations

until the block is locked. */

else if(OperationType == MULTI_OPERATION)

FLASH->E2KYR = FLASH_MULTI_OP_KEY;

}

}

// Clear the status bits of flash status register

void FLASH_ClearFlag(uint32_t FLASH_FLAG)

{

/*Check the parameters */

assert_param(IS_FLASH_CLEAR_FLAG(FLASH_FLAG));

/*Clear the flags */

FLASH->SR.V32 = (FLASH_FLAG<<16);

}

// Query status bits of flash status register

41

FLASH_Status FLASH_GetStatus(void)

{

FLASH_Status flashstatus = FLASH_COMPLETE;

if((FLASH->SR.V32 & FLASH_FLAG_BSY) == FLASH_FLAG_BSY)

{

flashstatus = FLASH_BUSY;

}

else

{

if((FLASH->SR.V32 & FLASH_FLAG_WRPERR) != (uint32_t)0x00)

{

flashstatus = FLASH_ERROR_WRP;

}

else

{

if((FLASH->SR.V32 & FLASH_FLAG_FLSERR) != (uint32_t)0x00)

{

flashstatus = FLASH_ERROR_FLS;

}

else

{

if((FLASH->SR.V32 & FLASH_FLAG_PGPERR) != (uint32_t)0x00)

{

flashstatus = FLASH_ERROR_PGP;

}

else

{

if((FLASH->SR.V32 & FLASH_FLAG_PGWERR) != (uint32_t)0x00)

{

flashstatus = FLASH_ERROR_PGW;

}

else

{

if((FLASH->SR.V32 & FLASH_FLAG_STAERR) !=

(uint32_t)0x00)

{

flashstatus = FLASH_ERROR_STA;

}

else

42

{

if((FLASH->SR.V32 & FLASH_FLAG_OPERR) !=

(uint32_t)0x00)

{

flashstatus = FLASH_ERROR_OPERATION;

}

else

{

flashstatus = FLASH_COMPLETE;

FLASH_ClearFlag(FLASH_FLAG_EOP);

}

}

}

}

}

}

}

/* Return the FLASH Status */

return flashstatus;

}

// Wait for the flash operation to complete

FLASH_Status FLASH_WaitForLastOperation(void)

{

__IO FLASH_Status status = FLASH_COMPLETE;

/* Check for the FLASH Status */

status = FLASH_GetStatus();

/* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.

Even if the FLASH operation fails, the BUSY flag will be reset and an error

flag will be set */

while(status == FLASH_BUSY)

{

status = FLASH_GetStatus();

}

/* Return the operation status */

return status;

}

// Erase main program area memory by Sector

43

FLASH_Status FLASH_Main_EraseSector(uint32_t FLASH_Sector)

{

FLASH_Status status = FLASH_COMPLETE;

/* Check the parameters */

assert_param(IS_FLASH_SECTOR(FLASH_Sector));

/* Wait for last operation to be completed */

status = FLASH_WaitForLastOperation();

if(status == FLASH_COMPLETE)

{

/* Unlock the Flash to enable the flash control register access */

FLASH_Main_Unlock(SINGLE_OPERATION);

/* Sets the programming window timer values */

FLASH_Set_PGMWindow(SE_ERS_TIME,SE_ERS_TIME);

/* if the previous operation is completed, proceed to erase the sector */

FLASH->CR.V32 = FLASH_Sector | (FLASH_CR_CMD_MSE <<

FLASH_CR_CMD_Pos) |(SET << FLASH_CR_STRT_Pos);

/* Wait for last operation to be completed */

status = FLASH_WaitForLastOperation();

if(status == FLASH_COMPLETE)

{

/* if the erase operation is completed, disable the operation command */

FLASH->CR.V32 = 0;

}

/* Clears the programming window timer values */

FLASH_Clear_PGMWindow();

}

/* Return the Erase Status */

return status;

}

// Write a word to an address in the main program area

FLASH_Status FLASH_Main_ProgramWord(uint32_t Address, uint32_t Data)

{

FLASH_Status status = FLASH_COMPLETE;

44

/* Check the parameters */

assert_param(IS_FLASH_MAIN_BLOCK_ADDRESS(Address));

/* Wait for last operation to be completed */

status = FLASH_WaitForLastOperation();

if(status == FLASH_COMPLETE)

{

FLASH_Set_PGMWindow(PGM_WORD_TIME,PGM_WORD_TIME);

/* if the previous operation is completed, proceed to program the new data */

FLASH->CR.V32 = ((FLASH_CR_PSIZE_WD << FLASH_CR_PSIZE_Pos)

| (FLASH_CR_CMD_MPG << FLASH_CR_CMD_Pos)

| (SET << FLASH_CR_STRT_Pos));

*(__IO uint32_t*)Address = Data;

/* Wait for last operation to be completed */

status = FLASH_WaitForLastOperation();

/* if the program operation is completed, disable the operation command */

FLASH->CR.V32 = 0;

FLASH_Clear_PGMWindow();

}

/* Return the Program Status */

return status;

}

// Erase one sector of E2PROM area by sector

FLASH_Status FLASH_E2_EraseSector(uint32_t E2_Sector)

{

FLASH_Status status = FLASH_COMPLETE;

/* Check the parameters */

assert_param(IS_E2_BLOCK_SECTOR(E2_Sector));

/* Wait for last operation to be completed */

status = FLASH_WaitForLastOperation();

if(status == FLASH_COMPLETE)

{

45

/* Unlock the Flash to enable the flash control register access */

FLASH_E2_Unlock(SINGLE_OPERATION);

/* Sets the programming window timer values */

FLASH_Set_PGMWindow(SE_ERS_TIME,SE_ERS_TIME);

/* if the previous operation is completed, proceed to erase the sector */

FLASH->CR.V32 = (E2_Sector

| (FLASH_CR_CMD_E2SE << FLASH_CR_CMD_Pos)

| (SET << FLASH_CR_STRT_Pos));

/* Wait for last operation to be completed */

status = FLASH_WaitForLastOperation();

/* if the erase operation is completed, disable the operation command */

FLASH->CR.V32 = 0;

/* Clears the programming window timer values */

FLASH_Clear_PGMWindow();

}

/* Return the Erase Status */

return status;

}

// Write a word to an address in E2PROM area

FLASH_Status FLASH_E2_ProgramWord(uint32_t Address, uint32_t Data)

{

FLASH_Status status = FLASH_COMPLETE;

/* Check the parameters */

assert_param(IS_E2_BLOCK_ADDRESS(Address));

/* Wait for last operation to be completed */

status = FLASH_WaitForLastOperation();

if(status == FLASH_COMPLETE)

{

FLASH_Set_PGMWindow(PGM_WORD_TIME,PGM_WORD_TIME);

/* if the previous operation is completed, proceed to program the new data */

FLASH->CR.V32 = ((FLASH_CR_PSIZE_WD << FLASH_CR_PSIZE_Pos)

46

| (FLASH_CR_CMD_E2PG << FLASH_CR_CMD_Pos)

| (SET << FLASH_CR_STRT_Pos));

*(__IO uint32_t*)Address = Data;

/* Wait for last operation to be completed */

status = FLASH_WaitForLastOperation();

/* if the program operation is completed, disable the operation command */

FLASH->CR.V32 = 0;

FLASH_Clear_PGMWindow();

}

/* Return the Program Status */

return status;

}

#define START_ADDR 0x20000 // Starting address

#define START_SECTOR 64 // Sector corresponding to starting address

#define SECTOR_SIZE 0x800 // Sector Size

#define START_ADDR_E2 0x0FFF0000 // Starting address

#define START_SECTOR_E2 0 // Sector corresponding to starting address

int main(void)

{

uint32_t tmp_len = 0;

uint32_t tmp_addr = 0;

FLASH_Status status = FLASH_COMPLETE;

// Erase a sector

status = FLASH_Main_EraseSector(START_SECTOR);

if(status != FLASH_COMPLETE)

{

while(1);

}

// Unlock main program area

FLASH_Main_Unlock(MULTI_OPERATION);

// Write the sector

for(tmp_len=0; tmp_len<SECTOR_SIZE; tmp_len=tmp_len+4)

47

{

status = FLASH_Main_ProgramWord(START_ADDR + tmp_len, 0x12345678+

tmp_len);// Written by word

if(status != FLASH_COMPLETE)

{

while(1);

}

}

if(status != FLASH_COMPLETE)

{

while(1);

}

FLASH_Main_Lock();

// Verify the written data

tmp_addr = START_ADDR;

tmp_len = 0;

while (tmp_len < SECTOR_SIZE)

{

if (*(__IO uint32_t*)tmp_addr != (0x12345678 + tmp_len) )

{

status = FLASH_ERROR_VERIFY;

while(1);

}

tmp_addr += 4;

tmp_len += 4;

}

// Erase one sector of E2PROM area

status = FLASH_E2_EraseSector(START_SECTOR_E2);

if(status != FLASH_COMPLETE)

{

while(1);

}

// Unlock E2PROM area

FLASH_E2_Unlock(MULTI_OPERATION);

// Write the sector

for(tmp_len=0; tmp_len<SECTOR_SIZE; tmp_len=tmp_len+4)

{

48

status = FLASH_E2_ProgramWord(START_ADDR_E2 + tmp_len, 0x98765432+

tmp_len);// Written by word

if(status != FLASH_COMPLETE)

{

while(1);

}

}

if(status != FLASH_COMPLETE)

{

while(1);

}

FLASH_E2_Lock();

// Verify the written data

tmp_addr = START_ADDR_E2;

tmp_len = 0;

while (tmp_len < SECTOR_SIZE)

{

if (*(__IO uint32_t*)tmp_addr != (0x98765432+ tmp_len) )

{

status = FLASH_ERROR_VERIFY;

while(1);

}

tmp_addr += 4;

tmp_len += 4;

}

if(status == FLASH_COMPLETE)

{

while(1);

}

}

5.4. Anti-interference measures for programming/erasing

Because the program code contains the main program area or E2PROM area and other areas of

erasing, programming functions, when the system is strongly disturbed, erasing/programming operation

has a certain risk. For example, in the ESD/EFT test, the program may run away. If it flies directly from

the outside to the place where the code is written, it may rewrite or erase the non-program intention and

cause the system to run abnormally.

49

In view of this reason, it is suggested to add anti-interference measures to flash main program area,

EEPROM area or other areas:

(1) Because only when the start flag bit STRT@FLASH_CR is set to 1, it will start or wait for flash

erasing/programming. Therefore, add a software flag at the beginning of the operation, and then set the

start flag STRT@FLASH_CR, check whether the software flag matches. If the flag bit does not match,

the operation will exit directly, so the programming or erasing action will not be started.

(2) To make full use of the function of the flash operation timer, you can start the flash operation

timer at the beginning of the operation, calculate and configure the window time allowed for the

operation, so that the program runs normally until the execution of erasing or writing operation, the

value of the flash operation timer is just within the executable window range, so as to avoid the

misoperation caused by the program running.

(3) Try to avoid programming and erasing subfunction calls in main program area or EEPROM

area with parameters. Because the parameters are random when the program is running, it is easy to

misoperate. Therefore, it is suggested that the main program area or EEPROM area erase the sub

function, without parameters, and assign a constant value to the address in the function to erase a fixed

sector.

SH32F9001 Series User Guide

50

6. Code and Data Checking

6.1. Overview

In order to facilitate the detection of program code and RAM area when the program is running, and

meet the requirements of IEC60730 software program, SH32F9001 series provide CRC module and

RAMBIST module. CRC module is used to detect whether the program code has been tampered with,

and RAMBIST module is used to detect the effectiveness of RAM function (read-write).

6.2. CRC

6.2.1. Overview

The SH32F9001 series provide CRC module to calculate the cyclic redundancy code. This module

provides four kinds of generating polynomials and a variety of data pre-processing and post-processing

to meet the different requirements of CRC algorithm.

6.2.2. Programming Setting

6.2.2.1. Generating polynomials

Four kinds of general generating polynomials are supported: CRC-32 bit (0x04C11DB7), CRC-16

bit (0x8005), CRC-CCITT (0x1021), CRC-8 (0x7). Generate 32-bit, 16 bit, 8-bit CRC code respectively.

6.2.2.2. Input data processing

Support the input data format conversion before CRC operation. The supported conversion

methods include reverse bit order, reverse byte order and reverse bit order within byte.

6.2.2.3. Result processing

Support the format conversion of CRC operation results. The supported conversion methods

include reverse bit order, reverse byte order and reverse bit order within byte.

6.2.2.4. Operation trigger

After the initial value is imported into the internal operation register through the reload control bit, as

long as the value is written to the DR register, a CRC operation will be triggered (CRC operation will be

triggered if the program directly writes the DR register or writes the calculated data to the DR register

through DMA).

6.2.2.5. Result obtaining

Read the DR register and get the CRC operation result without special waiting. If the operation is

not finished, the read instruction does not end.

【Note】You need to reload the initial value before starting a continuous operation. Otherwise, the

initial value of the internal register is unknown, which will affect the calculation result. Similarly, in the

process of continuous operation, the initial value cannot be reloaded, otherwise the intermediate result

will be changed and the heaviest result will be affected.

51

【Note】The reload function is to load the initial register directly into the internal register without any

format conversion. When the CRC value of an area is calculated by block or time division, if the output

result is format converted, the result is not the value of internal register. Therefore, in the next block

operation, we can not directly load the last result into the internal register, but we need to get the correct

intermediate result through the inverse operation of format conversion and then load it into the internal

register. The simple way is: the first few blocks do not set the result format processing, and then set the

result format processing when the operation reaches the last block.

【Note】When writing data to DR register for calculation, it supports 8-bit, 16 bit and 32-bit writing.

However, when writing/reading, the register address must be word aligned (4-byte alignment, that is, it

must be the first address of DR register). Otherwise, the result is uncertain.

【Note】When the generating polynomial is 32-bit, the result of writing 32-bit data at one time is the

same as writing 8-bit data in four times (the low byte is first) without format conversion of input data.

【Note】When the generating polynomial is 8 bits, if one word is written at a time, only one byte is

calculated, and the high bit is ignored. Similarly, when the generating polynomial is 16 bits, if one word

is written at a time, only a half words are calculated, and the high order is ignored.

6.2.3. Application examples

Function: Calculate the CRC value of an array

Note: The CRC value of a given array is calculated in two ways. One is continuous calculation, and

the other is block calculation. Because this kind of operation needs format conversion of output results,

special processing is carried out in segmented processing.

Code:

#include "SH32F9001.h"

//Define the array to be calculated

const uint32_t g_array[32] = {

0x12345678, 0x32345678,0x89323333,0x11111111,0x22222222,0x33333333,0x44444444,0x55555555,

0x22345678, 0x42345678,0x99323333,0x21111111,0x32222222,0x43333333,0x54444444,0x55555555,

0x32345678, 0x52345678,0x09323333,0x31111111,0x42222222,0x53333333,0x64444444,0x65555555,

0x42345678, 0x62345678,0x19323333,0x41111111,0x52222222,0x63333333,0x74444444,0x75555555,

};

int main()

{

volatile uint32_t result1;

volatile uint32_t result2;

int i;

RCC->RCCLOCK = 0x33CC; // unlock RCC config

RCC->AHBENR.BIT.CRCEN = 1; // Turn on the module clock

RCC->RCCLOCK = 0x0; // lock RCC config

CRC->INIT = 0xFFFFFFFF; // Set initial value

CRC->CR.BIT.RBITW = 1; //Set input format conversion: reverse byte order

CRC->CR.BIT.MODE = 0; //Set generation polynomial CRC-32

52

CRC->CR.BIT.RBITR = 1; // Set result format conversion: reverse byte order

CRC->CR.BIT.RELOAD = 1; //Load initial value to internal register

// Continuous operation

for(i = 0; i < 32; i++)

{

CRC->DR = g_array[i];

}

result1 = CRC->DR; // Read CRC results

// Block operation

//The first block 0~7

CRC->CR.BIT.RBITR = 0; // Clear result format processing

CRC->CR.BIT.RELOAD = 1; // Reload initial values to internal registers

for(i = 0; i < 8; i++)

CRC->DR = g_array[i];

result2 = CRC->DR; // Temporary storage intermediate result

CRC->DR = 0xA5A5A5A5; //Deliberately scrambling internal calculation registers

//The second block 8~15

CRC->INIT = result2; // Change initial value register

CRC->CR.BIT.RELOAD = 1; //Reload the saved intermediate results to the internal register

for(; i < 16; i++)

CRC->DR = g_array[i];

result2 = CRC->DR; // Temporary storage intermediate result

CRC->DR = 0xA5A5A5A5; //Deliberately scrambling internal calculation registers

//The third block 17~32, last block

CRC->INIT = result2; // Change initial value register

CRC->CR.BIT.RBITR = 1; // Restore result format conversion settings

CRC->CR.BIT.RELOAD = 1; //Deliberately scrambling internal calculation registers

for(; i < 32; i++)

CRC->DR = g_array[i];

result2 = CRC->DR; // Read the final result

//Comparing the two results, they are equal

if(result1 == result2)

{

//CRC OK.

}

while(1);

}

53

6.3. RAMBIST

6.3.1. Overview

To meet the requirements of the IEC60730 standard for RAM, SH32F9001 series provide a

hardware-implemented RAM detection module. This module supports March-C and March-X algorithms,

and you can choose one of them when you use it. The detection module is allowed to be interrupted

during the program running. Compared with the traditional RAM detection software implementation, it

greatly improves the detection efficiency and reduces the complexity of the software.

6.3.2. Programming Setting

6.3.2.1. Select detection area

Because the march-c algorithm and the march-x algorithm are destructive detection, it is necessary

to backup the data in the detected area and restore it after the detection. The backup area is fixed as

the high address area of RAM area, and the size is determined by the size of detection block. The

backup area can also be used as ordinary RAM when no detection is made. The detection of

SH32F9001 series is divided into DRAM working area, CRAM working area, DRAM backup area and

CRAM backup area, which are set by registers ADDR and CSR.

6.3.2.2. Selection algorithm and detection block size

The SH32F9001 series supports march-c and march-x algorithms, which are set by the register

CFG. The detection block size supports 16bytes, 32bytes to 2048bytes, which is set by the register

CFG.

6.3.2.3. Start detection

Writing 0X59A6 to the lower 16 bits of the CSR register will start the detection. At this time, the

busy bit of CSR register is automatically set to 1, and is automatically cleared to 0 after the detection is

finished.

【Note】In the detection process, it is allowed to read and write the detected work area, but not to

the backup area.

【Note】Detection of write protected areas is not allowed.

【Note】That write to module register is invalid during detection.

【Note】When starting detection, the error bit should be cleared at the same time, and the module

will not automatically be cleared.

【Note】This module has no clock switch and can be used directly.

【Note】During the detection, the backup block is detected first, and then the working block is

detected after passing the detection.

【Note】The address of the detection block must be aligned with the size of the detection block.

6.3.3. Application examples

Function: March-c is detected in DRAM area.

Note: First, the backup area is detected, and then the working area is detected. The size of the

block is 64 bytes.

Code:

54

#include "SH32F9001.h"

#define RAM_ADDRESS (0x20000000) // Define DRAM starting address

#define RAM_SIZE (0x2000) // Define DRAM size: 8K bytes

#define CHK_BLK_SIZE (2) // Define the detection block size value 0:16Byte 1:32Byte...

#define RAM_BLK_SIZE (1<<(CHK_BLK_SIZE+4)) // Calculate the size of detection block: 64 Bytes

int main()

{

uint32_t addr;

addr = RAM_ADDRESS;

RAMBIST->ADDR.V32 = addr; // Set detection area

RAMBIST->CFG.BIT.BLKSZ = CHK_BLK_SIZE; // Set detection block size

RAMBIST->CFG.BIT.SEL = 0; // Select the march-c algorithm

RAMBIST->CSR.BIT.ERR = 0; // Clear error flag

RAMBIST->CSR.BIT.MOD = 1; // Set detection backup block

RAMBIST->CSR.BIT.RUN = 0x59A6; // Start detection

while(RAMBIST->CSR.BIT.BSY); // Wait for the end of the test

if(RAMBIST->CSR.BIT.ERR) // Check error flag

{

//Error

}

while(addr < (RAM_ADDRESS + RAM_SIZE - RAM_BLK_SIZE))

{

RAMBIST->ADDR.V32 = addr; // Modify detection block address

RAMBIST->CSR.BIT.ERR = 0; // Clear error flag

RAMBIST->CSR.BIT.MOD = 0; // Set detection work block

RAMBIST->CSR.BIT.RUN = 0x59A6; // Start detection

while(RAMBIST->CSR.BIT.BSY); // Wait for the end of the test

if(RAMBIST->CSR.BIT.ERR) // Check error flag

{

//Error

break;

}

addr += RAM_BLK_SIZE; // Next detection block address

}

while(1);

}

SH32F9001 Series User Guide

55

7. WDT

7.1. IWDT overview

The SH32F9001 series independent watchdog has a 12 bit decrement counter, using 128K LSI as

the clock source.

The independent watchdog cannot be turned off after power on

IWDT can work in shutdown mode, so it can be used as wake-up timer by setting

IWDTPD@IWDT_CR. It is used to select whether to turn on or off the watchdog during shutdown (off in

default shutdown mode). This position cannot be changed after 1, but can only be changed after reset.

When power on, the watchdog works for a long time, and the overflow time is about 4096 * 32 / 128

= 1024ms.

7.2. IWDT programming Setting

Before the timer overflows, write 0xAAAA to update counter to restart the count to avoid overflow

through the feed dog register IWDT_CLR. It should be noted that after modifying the independent

watchdog overload value or clock frequency division, a dog feeding instruction is required to update the

new setting. Since the clock of the independent watchdog is not synchronized with the system clock,

please do not modify the configuration of the independent watchdog immediately after feeding the dog.

When the timer overflows, the chip will be reset and set IWDTRSTF@RCC_ CSR.

DBG_IWDT can control whether the watchdog stops working during debugging. When the core

enters the debug state, IWDT stops working by default.

7.3. IWDT Application examples

// Configure independent watchdog overflow time,T= 4096/(128K/64) = 2.048s

IWDT->CR.V32 = ((0x5AA5 << IWDT_CR_LOCK_Pos) |

(1 << IWDT_CR_IWDTON_Pos ) |

((IWDT_Prescaler_64) << IWDT_CR_IWDTPR_Pos) |

(0xFFF << IWDT_CR_IWDTRLR_Pos) );

// feed the dog

IWDT->CLR =0xAAAA;

7.4. WWDT overview

The watchdog is usually used to monitor software fault caused by external disturbances or

unforeseen logical conditions that deviate from the normal running sequence of applications. WWDT is

an 8-bit down counter, and the dog feeding interval is a window area. Feeding the dog earlier than the

window dog feeding area will generate an advanced abnormal event, and later than the window dog

feeding area will produce a delay abnormal event. Both of them will cause reset. In addition, when the

56

counter reaches the lower boundary of the window dog feeding area, the latest dog feeding time can be

applied for WWDT interrupt, which can be used as the last remedial time of window dog feeding.

7.5. WWDT programming Setting

If RL is the overload value of the window watchdog, WT is the upper feeding limit of the watchdog.

If RL>= WT is set, it is a normal window monitoring function with advanced abnormal monitoring, that is,

the watchdog can feed the dog only when the counter is down to below the upper limit of dog feeding,

otherwise it will reset. If RL<WT is set, there is no advanced exception monitoring, only delay exception

monitoring. If the delay dog feeding interrupt is enabled, when the counter reaches the lower boundary

of the window dog feeding area, the latest dog feeding time can be applied for WWDT interrupt, which

can be used as the last remedial time of window dog feeding; if the delay dog feeding interrupt is

disabled, it will be reset directly when the counter reaches the lower boundary of the window dog

feeding area. Therefore, the time of feeding dog and the setting of window watchdog must be calculated

accurately according to the program.

Note: if RL=WT=0xFF is set, the window is the largest and there is no advanced monitoring. The

function is similar to the ordinary watchdog.

7.6. WWDT application examples

// Configure window watchdog overflow time

WWDT->CR.V32 = ((0x5AA5 << WWDT_CR_LOCK_Pos) | // Register unlock bit

(1 << WWDT_CR_WWDTON_Pos ) | //Start WWDT

(1 << WWDT_CR_WWDTIE_Pos ) | // Enable WWDT interrupt

(WWDT_Prescaler_32 << WWDT_CR_WWDTPR_Pos) | // Clock division

(0xFF<< WWDT_CR_WWDTRLR_Pos) ); // Overload value

// Configuration window watchdog upper limit

WWDT->WTR.V32 = ((0x5AA5 << WWDT_WTR_LOCK_Pos) | // Register unlock value

(0x7F<< WWDT_WTR_WWDTWTR_Pos) );// Upper limit of dog feeding window

……(user code)

// feed the dog

WWDT->CLR =0x5555;

SH32F9001 Series User Guide

57

8. EXTI

8.1. Overview

EXTI consists of 16 edge detectors that generate event/interrupt requests, which can be used

to detect the edge signal and level signal of external input. All GPIO pins on the chip can be

configured as external interrupt lines, and each interrupt line can be configured with input type

independently or can be shielded independently.

8.2. Programming Setting

8.2.1. Edge trigger mode selection

FTSR and RTSR registers select whether the corresponding external interrupt line can be triggered

by external signals. For example, if bit0 of FTSR is 1, it means that external interrupt line EXTI0 can be

triggered by external high level / rising edge. Other bits are similar to this. Once the corresponding bits

of FTSR and RTSR are set to 1, as long as there is an external trigger signal, the corresponding bit of

PR register will be set to 1, even if the enable bits such as IMR/EMR/DMR are 0.

8.2.2. Software triggered interrupt

Register SWIER is a software trigger register. Writing 1 to the corresponding bit of SWIER is

equivalent to an external signal triggering on the corresponding external interrupt line. It is often used in

the program that there is no external trigger signal, but the program needs to enter the external interrupt

function to execute. This bit will be cleared automatically after writing 1, and the software does not need

to operate.

8.2.3. External interrupt line selection

Each GPIO pin can be configured as an external interrupt line, so multiple GPIO pins must share

an external interrupt line. For example, PIN0 of GPIOA/GPIOB/GPIOC/GPIOD/GPIOE is connected to

e EXTI0, and so on. EXTI0~15 is connected with PIN0~15 of different ports respectively, and the

specific GPIO port selected by EXTI line is determined by CFGL and CFGH registers in EXTI module.

The following figure lists the values of the EXTI0 bit segment.

EXTI0[2:0] Describe

000 PA0 to EXTI0

001 PB0 to EXTI0

010 PC0 to EXTI0

011 PD0 to EXTI0

100 PE0 to EXTI0

Therefore, we should avoid using PA0/PB0…PE0 of the same external interrupt line at the same

time in practical application. If there are three buttons that need to be connected to the external interrupt

line, it is recommended to connect them to PA1, PB2, PA3 and other pins that occupy different EXTI

ports, instead of PA0, PB0, and PC0. Otherwise, it is necessary to be screened again in the program.

58

8.2.4. Attention

(1) Since the registers controlling triggering interrupt, triggering event and triggering DMA are

independent of each other, the same external pulse can trigger the above three situations at

the same time

(2) Because Cortex-M3 core uses three-level pipeline, we need to pay attention to the local

execution timing. In the interrupt service program, there will be such a requirement. Specifically,

do not put the clearing interrupt flag on the last instruction before the interrupt returns.

Otherwise, it may cause the second response of the interrupt. A pipeline partition instruction

(such as "DSB") can be used to ensure that the clearing interrupt flag is executed before the

interrupt returns. See "example" for details.

8.3. Application examples

8.3.1. Example 1

Function: External interrupt triggered by rising edge

Note: Configure PA0 to connect to EXTI0, external input a rising edge to trigger the entry of

external interrupt.

Code:

#include “SH32F9001.h”

int main(void)

{

RCC->RCCLOCK = 0x33CC;

RCC->AHBENR.BIT.IOCLKEN = 1;

GPIOA_CFG->PUPDR.BIT.PHDR0 = 1;

EXTI->FTSR = 0x0001;

EXTI->IMR = 0x0001;

NVIC_EnableIRQ(EXTI0_IRQn);

while(1)

{

}

}

void EXTI0_Handler(void)

{

if ((EXTI->PR.V32 & 0x0001) == 0x0001)

{

EXTI->PR.V32 = 0x00010000;

// First, clear the interrupt flag, and then execute the user code

59

//add user code // At least one statement (any)

}

}

void EXTI0_Handler(void)

{

if ((EXTI->PR.V32 & 0x0001) == 0x0001)

{

//add user code

EXTI->PR.V32 = 0x00010000;

__DSB();

//After the interrupt flag is cleared, a "DSB" instruction is executed to isolate the pipeline

}

}

SH32F9001 Series User Guide

60

9. System configuration module (SYSCFG)

9.1. Overview

The system configuration module is mainly used to set some systematic parameters, such as

CRAM lock, DEBUG environment, etc.

9.2. Programming Setting

9.2.1. BOD

The mode of VDD detection can be set by BODMD bit. When BODMD=10B, the rising and falling of

VDD can be detected. When VDD rises, BODF bit is 0, and when VDD falls, BODF is 1.

9.2.2. LVR

VLVR[1:0] can select four kinds of LVR voltage, and the value of this LVR related register remains

unchanged after reset.

9.2.3. NMI interrupt switch

The NMI interrupt belongs to unshielded interrupt and has the highest priority in the whole chip. By

enabling the corresponding bit of SAFR register, CSM, EXTI0 and BOD can be connected to NMI

interrupt.

Once the above three interrupts are connected to the NMI interrupt, it will directly enter the NMI

interrupt service function when an interrupt occurs. Although the original interrupt can also be triggered,

the service function of the original interrupt will not be executed due to its lower priority than the NMI

interrupt. This should be paid special attention to in the application design process.

9.2.4. Crystal oscillator pins are used as GPIO

Crystal oscillator pins XTAL1/XTAL2 and XTALX1/XTALX2 are used as ordinary GPIO by default.

If you want to use external crystal oscillator, you need to set OSCCFG and OSCXCFG bit of SAFR

register, and they can not be modified until the next reset.

OSCCFG[1:0] Describe

00 XTAL1 and XTAL2 are used as GPIO (default)

01 XTAL1 and XTAL2 are used as external

oscillator interfaces

10 XTAL1 is used as external clock source input

and XTAL2 as GPIO

11 reserved

OSCCCFG Describe

0 XTALX1/XTALX2 are used as GPIO (default)

1 XTALX1 and XTALX2 are used as external oscillator interfaces

61

9.2.5. Simulation pins are used as GPIO

When a large number of IO pins are needed in application, the simulation pins can be used as

GPIO by setting the SWJCFG bit of SAFR. According to the different values of the SWJCFG bit, which

pins can be used as GPIO function can be determined. For details, please refer to the chapter "27

debug interface" of the spec.

When SWJCFG=1b, SW-DP is closed, but SWDIO and SWCLK have special conditions. That is,

when the chip is in normal operation mode, the program sets the SWJCFG to 1b, then all simulation

pins are treated as GPIO pins, which cannot be modified or entered into simulation mode until the next

reset. When the chip is running in the simulation mode step by step, even if it runs to the statement of

setting SWJCFG=1b, other simulation pins are regarded as GPIO, but SWDIO and SWCLK are still

used as simulation pins, and simulation mode will not be forced to exit.

9.2.6. The peripherals run in debug mode

When the chip is in the simulation mode, the peripherals will be in the stop state under normal

conditions, such as the timer counter will not continue to count. By setting the corresponding bit of

DBGCR register, the peripheral can continue to run. For example, if BIT9 of the register is set to 1, the

timer can run normally.

The upper 16 bits of DBGCR register are unlocking bits, which must be 0x5AA5. When DBGCR is

set, 32-bit data should be written to the register at the same time to take effect.

9.2.7. Low-power consumption mode

There are two low power consumption modes, sleep mode and stop mode. The difference is that

the latter not only stops the kernel, but also stops the clock of peripheral devices, which is equivalent to

deep sleep.

In software processing, stop mode needs to set the bit SLEEPDEEP of the core system control

register (0XE000ED10) to 1, and then execute WFE or WFI instruction.

An example of configuration for sleep mode is as follows:

1) Turn off peripherals that do not need to run in sleep mode.

2) Configure wake-up sources, such as external interrupts or other interrupts that can run in sleep

mode.

3) Use the instruction WFI or WFE to enter sleep mode (if WFE is used and there is an

interruption before, it is recommended to call two).

4) Wait for MCU to wake up.

An example of configuration to stop mode is as follows:

1) Configure wake-up sources, such as EXTI (most peripheral interrupts cannot wake up MCU in

stop mode).

2) Turn off the clock source that does not use peripherals. The analog module also needs to turn

off the enable bit of the module.

3) GPIO pins that are not used can be configured as analog inputs to save power.

4) Set the bit SLEEPDEEP of the system control register to 1.

62

5) Call instruction WFI or WFE into stop mode (if WFE is used and there is an interrupt before, call

twice).

6) Wait for MCU to wake up.

In the above two modes, stop mode has the lowest power consumption. After entering this mode,

all peripheral clocks are turned off, so ordinary peripheral interrupts cannot wake up MCU. For example,

when using the Tim of APB0 clock, because the clock is turned off, the counter cannot overflow and

cannot generate interrupt, so it can't be used as interrupt source.

WFE and WFI are two ways to enter low power consumption. WFE is event wake-up and WFI is

interrupt wake-up. Generally, interrupts that can wake up WFI can wake up WFE, otherwise it is not.

9.3. Application examples

9.3.1. Example 1

Function: Set BOD to detect the rising and falling of VDD at the same time

Note: The BOD detection threshold value is set to 3.0V to enable BOD interruption. Firstly, the

VDD is lowered downward, and then the VDD is increased

Code:

#include “SH32F9001.h”

int main(void)

{

RCC->RCCLOCK = 0x33CC; // Unlock RCC register protection

RCC->AHBENR.BIT.SYSCFGEN = 1; // Enable system configuration module clock

SYSCFG->PWRCR.BIT.BODMD = 2;

// Set the BOD detection mode to rise and fall simultaneously

SYSCFG->PWRCR.BIT.VBOD = 6; // Set BOD detection voltage threshold to 3.0V

SYSCFG->PWRCR.BIT.BODIE = 1; // Enable BOD interrupt allowed bit

SYSCFG->PWRCR.BIT.BODEN =1; // Enable BOD module

NVIC_EnableIRQ(BOD_IRQn); // Enable NVIC allowed bit

while(1)

{

}

}

void BOD_Handler(void)

{

SYSCFG->PWRSR.BIT.BODIF = 0;

//After entering the interrupt, clear the interrupt flag bit first

63

// When VDD is greater than 3.4V, VDD is in the rising process

if (SYSCFG->PWRSR.BIT.BODF == 0)

{

//add user code

}

else // When VDD is less than 3.4V, VDD is in the falling process

{

//add user code

}

}

SH32F9001 Series User Guide

64

10. DMA controller

10.1. Overview

Direct memory access (DMA) is used to provide high-speed data transfer between peripherals

and memory or between memory and memory. Without CPU intervention, data can be moved

quickly through DMA, which saves CPU resources to do other operations. The DMA controller has

eight channels, each of which is used to manage requests for memory access from one or more

peripherals. There is also an arbiter to coordinate the priority of CPU and DMA requests.

10.2. Programming Setting

10.2.1. Relationship between DMA and CPU

DMA controller can operate data receiving and sending independently, without the

participation of CPU. However, DMA also occupies the system bus and conflicts with CPU, so

DMA and CPU usually occupy bus control power alternately. The bus strength of DMA can be

adjusted by using the BURSTIDLE parameter.The larger the value, and the lower the strength.

Since the minimum value of BURSTIDLE is 1, DMA occupies the highest bus strength, that is, it is

used alternately with CPU in 1:1 mode. However, DMA occupies the bus in BURST mode. If the

BURSTLEN is set too large, the bus time will be occupied for a single transmission, which may

affect the CPU efficiency in some cases.

Generally speaking, if the DMA frequency is lower than 10%, the impact on CPU can be

considered slightly, and if it is lower than 1%, the impact on CPU can be ignored.

For example, the main frequency of the system is 72 MHz, several peripherals are driven by

DMA, and UART is running at 115.2KBps baud rate, so the impact on CPU efficiency can be

ignored. When ADC runs at 1MSPS sampling rate and transmits 8 channels of data at a time,

attention should be paid to the impact on CPU efficiency.

10.2.2. DMA basic parameter configuration

The basic parameters of DMA include transmission data NPKT and automatic overload

RELOAD, source and destination address configuration, data bit width SIZE, pointer modification

mode SPTYP/DPTYP, trigger mode ONE-SHOT/TO-END, burst length BURSTLEN and release

length BURSTIDLE.

【Note】NPKT is configured according to the n-1 mode. If you want to transmit 100 times,

configure NPKT=99. In addition, NPKT=0 is a special case, which is meaningless when DMA

enable = 0, and it means one transmission when enable=1.

【Note】There are three meanings of DMA data quantity: NPKT defines the burst number

transmitted, BURSTLEN defines burst length (DMA data number), and SIZE defines DMA data bit

width, which is divided into 1, 2 and 4 bytes.

65

【Note】RELOAD sets DMA enable again and clears the CPKTcounter. However, the source

and target pointers are still modified in the original way and will not be cleared. At the same time, if

DMA is triggered by software, RELOAD will not automatically turn on triggering.

【Note】In hardware triggered transmission, RELOAD can be transmitted without CPU

intervention. In software triggered transmission, because the overload counter RELOAD still needs

software intervention to turn on the software trigger control bit.

【Note】DMA source and target are not limited, that is, they can be configured to flash storage

area, RAM storage area, APB1 peripheral area, APB2 peripheral area and AHB peripheral area. It

supports the mutual transmission between storage area and peripheral area.

【Note】If the DMA target transfer area is flash area, the DMA controller will automatically

shield the write operation to flash. The flash controller will not send the write error information, and

the DMA controller will not send DMA error information. DMA will complete all data transmission,

but no data will be written to flash.

【Note】DMA supports direct transmission from peripheral devices to peripheral devices. At

this time, DMA source device is generally used as trigger source, while DMA destination device is

used as a general peripheral address. For example, the sending and receiving process of UART1

in example 2 of this chapter.

【Note】If DMA target address is configured to GPIO address, the data stored in SRAM can be

sent to I/O port by DMA mode, and some special waveform can be generated without CPU

intervention.

【Note】There are three types of data bit width: 1byte, 2byte and 4byte. When the source and

target bit width are different, there will be interception and zero padding operations. Please refer to

table 16-2 of the data manual for details.

【Note】There are four kinds of pointer modification methods: accumulation, decrement, fixed

and cycle. The cycle mode should be considered together with burst transmission, and its cycle

period is equal to the burst length. In the infinite transmission, the cycle pointer mode is particularly

meaningful, which can avoid the CPU intervention to modify the pointer.

【Note】The trigger mode is also very intuitive. One-shot transfers a burst every time when it is

triggered, and to-end means that all bursts are transmitted once every trigger.

【Note】Burst length is the number of DMA data contained in burst. Burst is the basic unit of

DMA transmission. Every burst transmission cannot be interrupted by CPU. The larger the burst

length, the higher the DMA transmission efficiency, but the longer the interruption time to CPU.

【Note】The release length is the time that DMA releases bus to CPU, and the minimum value

of BURSTIDLE is 1 cycle, that is to say, after DMA execution, at least one cycle is released to CPU

for execution. The larger the release bus value, the higher the CPU getting execution proportion.

【Note】The burstidle time is also included in the burst transfer time, so the DMA is still in the

busy state, but in fact, the DMA controller has released the bus to allow the CPU to execute. DMA

cannot be switched to the next DMA channel due to DMA busy setting.

66

10.2.3. DMA channel configuration and request

image table

The 8 channels of DMA are completely independent, with priority control among them,

including hardware priority and software priority (software first and then hardware). After each burst

transmission, priority rotation will be performed. When the two trigger sources are queued, the

priority of the channel that has been transmitted is lower than that of the channel that has not been

transmitted. The purpose of priority rotation is to avoid high priority channel clock preempting low

priority channel. After the introduction of priority rotation, the difference between high and low

priority is only transmitted in burst level, while the overall DMA total transmission opportunity is

equal.

【Note】Priority rotation is only carried out in the middle of the same priority, and different

priorities still follow the principle of high priority over low priority.

For example, channels 1, 3, 5 are high priority, 2, 4, and 6 are low priority, all of which are

triggered by one-shot.

(1) The burst of channel 1 is transmitted first, and then the burst of channel 3 is transmitted

because of the same priority;

(2) And then, when channel 3 and 5 happen at the same time, since channel 3 has been

transmitted once, burst of channel 5 is transmitted first, and then burst of 3 is transmitted;

(3) And then, when channel 1, 3 and 5 happen at the same time, according to rotation,

1>>5>>3.

(4) And then, when channel 1, 2, 3 and 4 happen at the same time, 1>>3>>2>>4, that is, low

priority channel 4 is executed last. If 1, 2 and 6 happen again before channel 4 starts, the high

priority of channel 1 will be inserted before channel 4. While channel 2, 4 and 6 will be processed

according to hardware priority and priority rotation, 4 > > 6 > > 2, and the complete transmission

sequence is 1 > > 3 > > 2 > > 1 > > 4 > > 6 > > 2.

Refer to table 16-4 for DMA request image. To enable DMA trigger, in addition to configuring

STRMSEL to select trigger source in DMA module, it is also necessary to configure DMA trigger

function in corresponding module. For example, PWM module is PWMDMA control bit and ADC

module is ADDE control bit.

10.2.4. DMA interrupt

Four kinds of events in DMA can cause interrupt. There are three interrupt entries in eight DMA

channels, which are DMA_CH0, DMA_CH1, DMA_CH2_7.

Among the four events, DMA transfer completion and more than half of DMA transfer are often

used in DMA process control. Load some "ping pong" operations to maintain the continuity of data flow,

as shown in the figure:

67

Buffer 1

Buffer 2

DMA HT Interrupt

Pointer 1

Pointer 2

DMA TC Interrupt

Source Destination

CPU processDMA process

DMA transfers external data to SRAM. The latter is divided into two buffers. The CPU fetches

data from buffer according to ping-pong operation. When HT interrupt occurs, CPU fetches data

from buffer 1. When TC interrupt occurs, CPU fetches data from buffer 2. This is very meaningful in

some high-speed continuous data stream operations.

10.3. Application examples

10.3.1. Example 1

Function: The data in SRAM is sent to host computer through UART1 by DMA.

Note: Transfer 256 bytes of data, UART1 baud rate of 9.6Bps, the main process uses TC flag

query mode to wait for the transmission to complete.

Code:

#include <SH32F9001.H>

void UART1_Config(void)

{

GPIOA_CFG->LCKR.V32 = 0x5AA50000; // PA0~PA15 unlock (only CFG)

GPIOB_CFG->AFRH.BIT.AFR9 = 2; // PB9 = AF2 ~ RXD1

GPIOB_CFG->AFRH.BIT.AFR8 = 2; // PB8 = AF2 ~ TXD1

GPIOB_CFG->PUPDR.BIT.PHDR9 = 0; // PB9 input no pull

UART1->BRT.BIT.SBRT = 233; // 9.6KBpas, 36000/16/9.6=234.375

UART1->BRT.BIT.BFINE = 6; // SBRT = 234-1=233, fine=0.375*16=6

UART1->CR.BIT.SM = 1; // type 1: 8/1/1/none, variable baud rate

UART1->CR.BIT.SBRTEN = 1; // enable baud rate generation

UART1->CR.BIT.TEN = 1; // enable txd

UART1->CR.BIT.REN = 1; // enable rxd

}

void main(void)

{

RCC_Config(); // PLL as system clock,HCLK=72MHz,PCLK0/1=HCLK/2S

68

NVIC_Config(); // If you need to configure interrupts, this example does not use interrupts

GPIO_Config(); // If I/O needs to be configured, this example leaves the default input

UART1_Config(); // UART1 is configured as 9.6KBps, PCLK1=36MHz

RCC->RCCLOCK = 0x33CC; // unlock RCC config

RCC->AHBENR.BIT.DMAEN = 1; // DMA clock enable

RCC->AHBENR.BIT.IOCLKEN = 1; // GPIO clock enable

RCC->APB1ENR.BIT.UART1EN = 1; // UART1 clock enable

RCC->RCCLOCK = 0x0; // lock RCC config

UART1->CR.BIT.DMAT = 1; // Enable DMA trigger function of UART1

DMA->SAR2 = Addr1_Sram_Data; // SRAM buffer address

DMA->DAR2 = Addr1_Uart1_TDR; // UART1 TDR address

DMA->NPKT2 = 255; // 256 bursts

DMA->CCR2.BIT.TRGMODE = 0; // one-shot

DMA->CCR2.BIT.SPTYP = 0; // point modify, 00~inc, 01~dec, 10~fix, 11~round

DMA->CCR2.BIT.DPTYP = 2; // point modify, 00~inc, 01~dec, 10~fix, 11~round

DMA->CCR2.BIT.EN = 1; // channel1 enable

DMA->CSR.BIT.SWTRG = 1<<2; // SWTRG_2

while(!((DMA->IFSR.BIT.TCIF)&(1<<2))); // wait TCIF_2 flag

DMA->IFCR.BIT.CTCIF = 1<<2; // clear TCIF_2 flag

while(1) // main loop

{

}

}

10.3.2. Example 2

Function: DMA unlimited transmission with UART1

Note: Set RELOAD=1, UART1 receives data from the host computer, and then sends it back to the

host computer. The host computer sets automatic transmission, which will realize unlimited

transmission. Note that DMA is triggered by the RDR of UART1.

Code:

#include <SH32F9001 series.H>

void main(void)

{

RCC_Config(); // PLL as system clock,HCLK=72MHz,PCLK0/1=HCLK/2

NVIC_Config(); // If you need to configure interrupts, this example does not use interrupts

GPIO_Config(); // If I/O needs to be configured, this example leaves the default input

69

UART1_Config(); // UART1 is configured as 9.6KBps, PCLK1=30MHz

RCC->RCCLOCK = 0x33CC; // unlock RCC config

RCC->AHBENR.BIT.DMAEN = 1; // DMA clock enable

RCC->AHBENR.BIT.IOCLKEN = 1; // GPIO clock enable

RCC->APB1ENR.BIT.UART1EN = 1; // UART1 clock enable

RCC->RCCLOCK = 0x0; // lock RCC config

UART1->CR.BIT.DMAR = 1; // UART1 RDR is used as trigger source

DMA->SAR3 = Addr1_Uart1_RDR; // UART1 RDR, trigger source

DMA->DAR3 = Addr1_Uart1_TDR; // UART1 TDR

DMA->NPKT3 = 255;

DMA->CCR3.BIT.TRGMODE = 0; // one-shot

DMA->CCR3.BIT.SPTYP = 2; // point modify, 00~inc, 01~dec, 10~fix, 11~round

DMA->CCR3.BIT.DPTYP = 2; // point modify, 00~inc, 01~dec, 10~fix, 11~round

DMA->CSR.BIT.RELOAD = 1<<3; // auto-reload

DMA->CCR3.BIT.EN = 1; // channel1 enable

while(1) // main loop

{

}

}

SH32F9001 Series User Guide

70

11. PCA

11.1. Overview

SH32F9001 series has 8 advanced 16-bit programmable counter arrays built in. PCA0/1 counters

can run at AHB (HCLK) and PCA2 ~ PCA7 counters can run at APB0 clock (PCLK0). The programmable

counter array PCAx provides enhanced timer function that requires less CPU intervention.

The PCA characteristics of SH32F9001 series are as follows:

PCAx (x = 0 ~ 7) has two independent comparison capture modules.

Support input capture, compare match (output).

Support square wave output with adjustable frequency.

Support PWM modulated output, and Optional 8/16 bit PWM modulator.

16-bit PWM modulator supports phase correction function and phase frequency correction

function.

PCA0/1, PCA2/3, PCA4/5, or PCA6/7 can be cascaded into 32-bit PCA module.

Note: ①The small subscript x is the serial number of PCA. For example, PCAx (x=0~7). PCAx will be

used uniformly in the belowing, and the value of x will not be described any more.

②The small subscript n is the serial number of the compare/capture modules. For example,

P0CEXn (n=0, 1), PxCEXn will be used uniformly in the belowing, and the value of n will not be

described any more.

PCAx consists of a dedicated 16 bit counter/timer and two 16 bit capture/compare modules. Each

capture/compare module has its own I/O line (PxCEXn). The schematic diagram of PCAx is shown in

figure.

16 Bit Counter

Capture/

Compare Cell 0

PxC

EX

0

PxC

EX

1

Overflow

Flag

InterruptRequest

CF

PCAx->TOPR

16Bit Compare

Clear

Clo

ck S

ele

ct

Sysclk

Sysclk/12

Sysclk/4

TIMER5

ECIxCrystal/8

PCAx->CMD->CPS[2:0]

PR

128kHz/32kHz Cry

Sysclk/32

Capture/

Compare Cell 1

Overflow

The 16-bit PCAx counter/timer has a 16-bit counting unit and a 16-bit counter overflow value

register PxTOPR. Users can freely configure the PxTOPR (x = 0 ~ 7) register to define the overflow

value of the counter. The initial value of the PxTOPR register is 0xFFFF.

16-bit timer/counter is the most basic unit of PCAx, and it is also an essential unit for the normal

operation of each module. Through the PR bit of PCAx->CR register, the timer/counter can be

turned on/off. When PR is set to logic "0", the 16-bit counter is forced to be cleared to 0. When the

timer overflows from 0x0000 to PxTOPR (In the same system clock from PxTOPR to 0x0000, that is.

71

single ramp mode) or the counter counts down from PxTOPR to 0x0000 (When PCAx counter works

in dual ramp mode), the overflow flag (CF) in PCAx->PCAINTF register is set to logic '1' and an

interrupt request is generated (if ECF bit in PCAx->CMD is set to logic '1', the CF flag can generate

interrupt request). When CPU turns to interrupt service program, CF bit cannot be cleared

automatically by hardware, but must be cleared by software. It should be noted here that when

multiple PCAx modules work in different working modes (but the counting ramp mode is the same),

CF may be set to logic "1" when PCA counter reaches PxTOPR and 0x0000.

11.2. Programming Setting

11.2.1. IO setting

When the related input and output functions of PCA are used, the IO multiplexing (AF) function

must be set first, that is, the corresponding IO multiplexing register (GPIOx->CFG_AFRH/L) must be set

to AF5.

11.2.2. Clock setting

The counter/timer of PCAx has a programmable clock source which is bus clock, bus clock divided

by 4, bus clock divided by 12, bus clock divided by 32, the external oscillator divided by 8, overflow of

timer 5, an external clock signal on the ECIx input pin, or 32.768kHz crystal / built-in128kHz RC /

32.768KHz crystal. Select clock source of the counter/timer by CPS[2:0] bit in PCAx->CMD register, as

shown in following table.

PxCPS2 PxCPS1 PxCPS0 时钟源

0 0 0 Bus clock

0 0 1 Bus clock divided by 4

0 1 0 Bus clock divided by 12

0 1 1 Bus clock divided by 32

1 0 0 Overflow of timer 5

1 0 1 The external oscillator divided by 8

1 1 0 Falling edge of ECIx (max rate = bus clock divided by 4)

1 1 1 32.768KHz crystal / built-in 128kHz RC

Note: 1.External oscillator source divided by 8 is synchronized with the bus clock.

2.The bus clock period must not be less than 4 times of the count clock period (except bus clock

as basetime). Otherwise PCAx counter will not count correctly.

3.When PxCPS[2:0] is 111, LSE (32kHz crystal) and LSI (built-in 128khz RC) exist at the same

time, and then the clock source of PCAx is LSE (32kHz crystal).

4.When LSERDY is 1, the external 32.768KHz crystal oscillator is used as the count clock source.

When LSERDY is 0: if CSMLSEF is 1, the clock switched by CSM (built-in 32kHz RC) is used as the

count clock source, and if CSMLSEF is 0, built-in 128khz RC is used as the count clock source.

72

11.2.3. PCA count mode setting

The counter/timer of PCAx has a control bit with optional counting mode. Clearing SDEN in

PCAx->CMD register indicates single ramp and setting SDEN indicates double ramp. The time series

waveforms of single slope and dual slope are as follows:

PCAx

When CFx=1,new TOP

reload,new TOP will take

effect after the next interrupt

period

The timing diagram of single slope

period

PCAx

CFx set 1

The timing diagram of dual slope

11.2.4. PCA mode setting

2-way capture/compare module of PCAx counter can achieve enhanced function. Each capture/

compare module can be configured to work independently (Note: one capture/compare module

corresponds to one channel). Each module has its own control registers in the system controller, which

are used to configure the working mode of the module and exchange data with the module. The module

can work in one of the following four working modes by configuring two bits of SMPn and SMNn in

PCAx->CPMn register of each module: edge trigger capture, comparison match output, frequency

output and PWM output mode. For details, please refer to chapter PCA of the specification.

11.2.5. Attention

1. Changing the PCAx->TOP value must ensure that the new PCAx->TOP value is not less than

the value of all comparison registers.

2. When the compare/capture module is used as PWM output function, if PCAx->CPRn is equal

to 0x0000, the output is always kept at low level; if PCAx->CPRn is equal to PCAx->TOP,

the output is kept at high level. If the pin is reversed, the output is opposite.

3. All compare/capture modules of PCAx can only work in the same ramp mode (for example:

PCA0 compare/capture module 0 and compare/capture module 1 can only work in the same

ramp mode).

73

4. After cascading, the TOP value of PCA1 and CP0/CP1 are automatically

mapped to the upper 16 bits of corresponding registers of PCA0. Therefore, only 32-bit

registers of PCA0 need to be read, and the other PCA cascade is the same.

11.3. Application examples

11.3.1. Example 1

Function: Use P0CEX0 of PCA0 to capture an external pulse signal and test the width of its high

level and low level.

Code:

#include <SH32F9001.H>

uint32_t val_h; //High level time

uint32_t val_l; //low level time

void PCA0_Config(void)

{

GPIOC_CFG->LCKR.V32 = 0x5AA50000; // PC0~PC15 unlock (only CFG)

GPIOC_CFG->AFRL.BIT.AFR7 = 5; // PC7 = AF5 ~ P0CEX0

PCA0->CMD.BIT.CPS = 0; // PCA clocksourceis HCLK

PCA0->CPM0.BIT.SM0 = 0; // MODE0 capture

PCA0->CPM0.BIT.FS0 = 3; // raisingandfallingedgecapture

PCA0->CPM0.BIT.ECOM0 = 1; // enablepca0channel0

PCA0->CPM0.BIT.ECCF0 = 1; // enable interrupt

}

void main(void)

{

RCC_Config(); // PLL as system clock, HCLK=72MHz,PCLK0/1=HCLK/2

RCC->RCCLOCK = 0x33CC; // unlock RCC config

RCC->AHBENR.BIT.PCA0EN = 1; // PCA0 clock enable

RCC->AHBENR.BIT.IOCLKEN = 1; // GPIO clock enable

RCC->RCCLOCK = 0x0; // lock RCC config

GPIO_Config(); // If I/O needs to be configured, this example leaves the default input

PCA0_Config(); // PCA0 configuration

PCA0->CR.PR = 1; // Start count

NVIC_EnableIRQ(PCA0_IRQn); //allow PCA0 interrupt

while(1) // main loop

74

{

IWDT->CLR = 0Xaaaa; // feed WDT

}

}

Void PCA0_Handler(void)

{

if(PCA0->CPM0.BIT.TCP0 == 1)

{

Val_l = PCA0->CPR0.V32;

}

else

{

Val_h = PCA0->CPR0.V32;

}

PCA0->PCAINTF.BIT.CCF0C = 1; //clear CCF0

__DSB(); //wait CCF0 clear

}

11.3.2. Example 2

Function: Use PCA0 to generate an interrupt with 5ms

Code:

#include <SH32F9001.H>

void PCA0_Config(void)

{

GPIOC_CFG->LCKR.V32 = 0x5AA50000; // PC0~PC15 unlock (only CFG)

PCA0->CMD.BIT.CPS = 2; // PCA clocksourceis HCLK/12

PCA0->CPM0.BIT.SM0 = 1; // MODE1count

PCA0->CPM0.BIT.FS0 = 0; // autoreload

PCA0->CPM0.BIT.MAT0 = 1; // allow match

PCA0->CPM0.BIT.ECOM0 = 1; // enablepca0channel0

PCA0->CPR0.V32 = 30000; // 6M*5MS = 30000

PCA0->TOPR.V32 = 30000;

PCA0->CPM0.BIT.ECCF0 = 1; // enable interrupt

}

void main(void)

{

75

RCC_Config(); // PLL as system clock, HCLK=72MHz,PCLK0/1=HCLK/2

RCC->RCCLOCK = 0x33CC; // unlock RCC config

RCC->AHBENR.BIT.PCA0EN = 1; // PCA0 clock enable

RCC->AHBENR.BIT.IOCLKEN = 1; // GPIO clock enable

RCC->RCCLOCK = 0x0; // lock RCC config

GPIO_Config(); // If I/O needs to be configured, this example leaves the default input

PCA0_Config(); // PCA0 configuration

PCA0->CR.PR = 1; // Start count

NVIC_EnableIRQ(PCA0_IRQn); //allow PCA0 interrupt

while(1) // main loop

{

IWDT->CLR = 0Xaaaa; // feed WDT

}

}

Void PCA0_Handler(void)

{

PCA0->PCAINTF.BIT.CCF0C = 1; //clear CCF0

__DSB(); //wait CCF0 clear

}

11.3.3. Example 3

Function: A 500KHz square wave is generated using P0CEX0 of PCA0

Code:

#include <SH32F9001.H>

void PCA0_Config(void)

{

GPIOC_CFG->LCKR.V32 = 0x5AA50000; // PC0~PC15 unlock (only CFG)

GPIOC_CFG->AFRL.BIT.AFR7 = 5; // PC7 = AF5 ~ P0CEX0

PCA0->CMD.BIT.CPS = 0; // PCA clocksourceis HCLK

PCA0->CPM0.BIT.SM0 = 2; // MODE2output

PCA0->CPM0.BIT.FS0 = 0; // autoreload

PCA0->CPM0.BIT.ECOM0 = 1; // enablepca0channel0

PCA0->CPR0.CPH0= 71; // 72M/(71+1)/2=500k

}

void main(void)

{

RCC_Config(); // PLL as system clock, HCLK=72MHz,PCLK0/1=HCLK/2

RCC->RCCLOCK = 0x33CC; // unlock RCC config

RCC->AHBENR.BIT.PCA0EN = 1; // PCA0 clock enable

76

RCC->AHBENR.BIT.IOCLKEN = 1; // GPIO clock enable

RCC->RCCLOCK = 0x0; // lock RCC config

GPIO_Config(); // If I/O needs to be configured, this example leaves the default input

PCA0_Config(); // PCA0 configuration

PCA0->CR.PR = 1; // Start count

while(1) // main loop

{

IWDT->CLR = 0Xaaaa; // feed WDT

}

}

11.3.4. Example 4

Function: Use P0CEX0 of PCA0 to output PWM wave with duty ratio of 40% and frequency of

12khz.

Code:

#include <SH32F9001.H>

void PCA0_Config(void)

{

GPIOC_CFG->LCKR.V32 = 0x5AA50000; // PC0~PC15 unlock (only CFG)

GPIOC_CFG->AFRL.BIT.AFR7 = 5; // PC7 = AF5 ~ P0CEX0

PCA0->CMD.BIT.CPS = 0; // PCA clocksourceis HCLK

PCA0->CPM0.BIT.SM0 = 3; // MODE2PWM

PCA0->CPM0.BIT.FS0 = 1; // 16 bit PWM

PCA0->CPM0.BIT.ECOM0 = 1; // enablepca0channel0

PCA0->TOPR.V32 = 6000-1; // 72M/12K=6000

PCA0->CPR0.V32 = 2400-1; // 6000*0.4 = 2400

}

void main(void)

{

RCC_Config(); // PLL as system clock, HCLK=72MHz,PCLK0/1=HCLK/2

RCC->RCCLOCK = 0x33CC; // unlock RCC config

RCC->AHBENR.BIT.PCA0EN = 1; // PCA0 clock enable

RCC->AHBENR.BIT.IOCLKEN = 1; // GPIO clock enable

RCC->RCCLOCK = 0x0; // lock RCC config

GPIO_Config(); // If I/O needs to be configured, this example leaves the default input

PCA0_Config(); // PCA0 configuration

PCA0->CR.PR = 1; // Start count

while(1) // main loop

77

{

IWDT->CLR = 0Xaaaa; // feed WDT

}

}

SH32F9001 Series User Guide

78

12. PWM

12.1. Overview

SH32F9001 series integrates four 16 bit PWM modules. PWM module can generate PWM

waveform with adjustable cycle and duty cycle respectively.

If EFLT is set, the output of PWMx (x = 0,1,2,3) can be automatically turned off by the change of

input signal of FLT pin.

The PWM timer also provides four interrupt sources for PWMx (x = 0,1,2,3), and interrupts are

generated in each PWM cycle. In this way, the user can change the cycle or duty cycle of the next cycle

in each PWM cycle.

It has the following characteristics:

4×2 complementary outputs with dead zone control

Provide overflow interrupt per pwmx (x = 0,1,2,3) cycle

Two output polarities can be selected independently

Provide error detection function to turn off PWM output in an emergency

Provide protection register to protect important registers from interference and errors

12.2. Programming Setting

12.2.1. IO setting

When using the PWM related output function, the IO alternate function (AF) must be set first, that is,

the corresponding IO alternate register (GPIOx->CFG_AFRH/L) must be set to AF7.

12.2.2. Protection setting

The PWM module is equipped with protection registers. When setting PWM related registers, it is

necessary to be unlocked by writing 0x5AA5 to PWMx->PWMLOCK, and then operate other registers.

When writing values other than 0x5AA5 to PWMx->PWMLOCK, the operation of other registers is

invalid, that can effectively protect the output anti-interference of PWM.

12.2.3. Module setting

PWM programming is divided into the following steps:

(1) Unlock the PWM module.

(2) Select the clock source of PWM module.

(3) Set PWM cycle / duty cycle by writing appropriate value to PWM cycle control register (PWMPR)

or PWM duty cycle register (PWMDR).

(4) Select the PWMx output mode (active at high level or active at low level) by setting the PWMSx

bit of PWMx->CR register.

(5) Set the EPWMx of PWMx->CR register to allow channel output.

(6) Set PWMEN of PWMx->CR register enable module output.

79

(7) If the PWM cycle or duty cycle needs to be changed, the operation process is as described in

step 2 or step 3. The value of the modified overload counter is valid for the next cycle.

12.2.4. Attention

(1) When PWMx output is off (including PWME off and FLT occurrence), PWMxA and PWMxB (x =

0,1,2,3) output fixed low level (PWMSA = 0, PWMSB = 1) or high level (PWMSA = 1, PWMSB = 0).

(2) Once the high/low level of FLTx pin is detected, the internal state will remain and the PWMx

output will be turned off.

(3) When the FLTx input signal is valid, the FLTS bit cannot be cleared. The FLTS status bit can

only be cleared after the FLTx input signal disappears.

(4) When [pp.15, pp.0] = 000h, if PWMSA = 0, PWMxA (x = 0,1,2,3) outputs low level regardless of

PWMx duty cycle.

When [pp.15, pp.0] = 000h, if PWMSA = 1, PWMxA (x = 0,1,2,3) outputs high level regardless of

PWMx duty cycle.

(5) When [PP.15, PP.0] ≤ [PD.15, PD.0], if PWMSA = 0, PWMxA (x = 0,1,2,3) outputs high level.

When [PP.15, PP.0] ≤ [PD.15, PD.0], if PWMSA = 1, PWMxA (x = 0,1,2,3) outputs low level.

12.3. Application examples

12.3.1. Example 1

Function: Configure PWM0 and then PWM0B port outputs a 12kHZ PWM wave with duty cycle

60%.

Code:

#include <SH32F9001.H>

void PWM0_Config(void)

{

GPIOB_CFG->LCKR.V32 = 0x5AA50000; // PB0~PB15 unlock (only CFG)

GPIOB_CFG->AFRH.BIT.AFR8 = 7; // PB8 = AF7 ~ PWM0B

PWM0->PWMLOCK = 0x5AA5; //unlock PWM0

PWM0->CR.BIT.TCK = 4; //pwm clock source is pclk0

PWM0->CR.BIT.PWMSB = 1; // duty positive level is high

PWM0->PWMPR = 3000-1; // 36M/12K = 3000

PWM0->PWMDR = 1800-1; //3000*0.6 = 1800

PWM0->CR.BIT.EPWMB = 1; // allow PWM0B output

PWM0->CR.BIT.PWMEN = 1; // enable PWM0 MODULE

}

void main(void)

{

RCC_Config(); // PLL as system clock, HCLK=72MHz,PCLK0/1=HCLK/2

80

RCC->RCCLOCK = 0x33CC; // unlock RCC config

RCC->APB0ENR.BIT.PWM0EN = 1; // PWM0 clock enable

RCC->AHBENR.BIT.IOCLKEN = 1; // GPIO clock enable

RCC->RCCLOCK = 0x0; // lock RCC config

GPIO_Config(); // If I/O needs to be configured, this example leaves the default input

PWM0_Config(); // PCA0 configuration

while(1) // main loop

{

IWDT->CLR = 0Xaaaa; // feed WDT

}

}

SH32F9001 Series User Guide

81

13. ADC

13.1. Overview

The SH32F9001 series have a 12 bit A/D converter with successive approximation. The maximum

single channel conversion rate can reach 1 MSPS. Built in VREF, external VREF or AVDD three

reference voltage sources can be selected, a total of 26 ADC analog input channels, support sequence

conversion mode, intermittent conversion mode and continuous conversion mode, with comparison

function, support DMA. It not only supports software triggering AD conversion, but also supports PWM,

TIM7 and external pin hardware triggering AD conversion.

13.2. Programming Setting

13.2.1. ADC clock setting

After the system clock is set, the ADC module clock control bit is enabled.

/* enable module clock */

RCC->RCCLOCK = 0x33CC;

RCC->AHBENR.BIT.IOCLKEN = 1;

RCC->APB1ENR.BIT.ADCEN = 1;

RCC->RCCLOCK = 0x0;

13.2.2. ADC channel IO port function setting

Enable analog alternate function of ADC channel corresponding IO port.

GPIOD_CFG->AFRL.BIT.AFR2 = 0x8; // PD2 is mapped to AN8

GPIOD_CFG->AFRL.BIT.AFR3 = 0x8; // PD3 is mapped to AN9

GPIOD_CFG->AFRL.BIT.AFR4 = 0x8; // PD4 is mapped to AN10

GPIOD_CFG->AFRL.BIT.AFR5 = 0x8; // PD5 is mapped to AN11

13.2.3. ADC sampling rate configuration

ADC clock and sampling time can be set by register ADCON2. Set the clock of ADC through

TADC[3:0]@ADCON2. Through registers TS[3:0]@ADCON2, TGAP[2:0]@ADCON2 and

GAPENx@ADGAPON, set the sampling time tSAMP of each channel, tSAMP = (TS[3:0]+ TGAP[2:0]*

GAPEN+1) * tAD, where TGAP[2:0] GAPEN is the time interval between adjacent channels in the

sequence, GAPEN is the gap time enable control bit of ADC channel y.

For 12-bit mode AD conversion, the AD conversion time of each channel is fixed at 15 * tAD.

Therefore, the total sample conversion time per channel = tSAMP + 15 * tAD. For 10-bit mode AD

conversion, the AD conversion time of each channel is fixed at 13 * tAD. Therefore, the total sample

conversion time per channel = tSAMP + 13 * tAD.

For 12-bit mode ADC, if the system clock is 72M (maximum), the ADC sampling rate is set to 1M,

and there is no channel interval time. The configuration is as follows:

82

/* set ADC clock */

ADC->ADCON2.BIT.TADC = 1; //2 frequency division, The ADC clock is set to 18M

/* set ADC Interval time */

ADC->ADCON2.BIT.TS = 2; //The sampling rate of ADC is 18M/(2+1+15) = 1M

ADC->ADCON2.BIT.TGAP = 0; // Channel interval time is 0

ADC->ADGAPON = 0; // Channel interval function disable

13.2.4. ADC conversion mode configuration

13.2.4.1. Software triggered single sequence conversion mode

For example, if the ADC has four channels to be converted, and the order of priority is AN0, AN2,

AN4, AN7, then ADMAXCH [2:0] = 3, SEQCH0 = 0, SEQCH1 = 2, SEQCH2 = 4, SEQCH3 = 7, then

each time AD conversion (ADSOC = 1) is started, the four channels starting from channel 0 will be

converted in turn, and the results will be stored in ADDR0, ADDR1, ADDR2, ADDR3. The software

configuration is as follows:

ADC->ADCON1.BIT.ADON = ENABLE; //Enable ADC

ADC->ADCON1.BIT.ADSTRS = 0; // Software trigger

ADC->ADCON1.BIT.REFC = 0; //AVDD is reference voltage source

ADC->ADCON1.BIT.ADCTU = 0; // Single sequence conversion mode

ADC->ADCON2.BIT.ADMAXCH = 3; // Convert 4 channels in turn

ADC->SEQCHSEL.BIT.SEQCH0 = 0x0; //Analog channel 0 selects AN0

ADC->SEQCHSEL.BIT.SEQCH1 = 0x2; // Analog channel 1 selects AN2

ADC->SEQCHSEL.BIT.SEQCH2 = 0x4; // Analog channel 2 selects AN4

ADC->SEQCHSEL.BIT.SEQCH3 = 0x7; // Analog channel 3 selects AN7

ADC->ADINTF.V32 = 0x00070000; // Clear each flag bit

ADC->ADCON1.BIT.ADSOC = 1; // Start conversion

13.2.4.1. Hardware triggered single sequence conversion mode

For example, if TIM7 overflow triggers ADC, there are two channels that need to be converted. If

the order of priority is AN0 and AN2, it is set to ADMAXCH[2:0] = 1, SEQCH0 = 0, SEQCH1 = 2. Then

each time tim7 overflows, AD conversion will be started. Then the two channels starting from channel 0

will be converted in turn, and the results will be stored in ADDR0 and ADDR1 in turn. The software

configuration is as follows:

//On the basis of 13.2.1 ADC clock configuration, enable TIM7 clock control bit

RCC->APB1ENR.BIT.TIM7EN = 1; // Enable TIM7 module clock control bit

ADC->ADCON1.BIT.ADON = ENABLE; // Enable ADC

ADC->ADCON1.BIT.ADSTRS = 0x08; //TIM7 hardware trigger

ADC->ADCON1.BIT.REFC = 0; //AVDD reference voltage source

ADC->ADCON1.BIT.ADCTU = 0; // Single sequence conversion mode

ADC->ADCON2.BIT.ADMAXCH = 2; // Convert 2 channels in turn

83

ADC->SEQCHSEL.BIT.SEQCH0 = 0x0; // Analog channel 0 selects AN0

ADC->SEQCHSEL.BIT.SEQCH1 = 0x2; // Analog channel 1 selects AN2

ADC->ADINTF.V32 = 0x00070000; // Clear each flag bit

TIM7->TPR = 10000; // Timer 7 auto-reload register

TIM7->CR.BIT.TRIGEN = 1; // Timer 7 overflow triggers external module enable

while(1)

{

TIM7->TCNT = 9998; // Timer 7 count value

TIM7->CR.BIT.STR = 1; // Timer 7 enable count

/* start ADC sample */

while(!ADC->ADINTF.BIT.ADIF);

ADC->ADINTF.BIT.ADIFC = 1;

tmp1 = ADC->ADDR0;

TIM7->CR.BIT.STR = 0; // Timer 7 stops counting

}

13.2.5. Obtaining ADC conversion results

while(!ADC->ADINTF.BIT.ADIF); // Query whether ADC conversion is complete

ADC->ADINTF.BIT.ADIFC = 1; // Clear conversion end interrupt flag bit

buffer[0] = ADC->ADDR0; // Get data from ADC result register 0

buffer[1] = ADC->ADDR1; // Get data from ADC result register 1

buffer[2] = ADC->ADDR2; // Get data from ADC result register 2

buffer[3] = ADC->ADDR3; // Get data from ADC result register 3

13.3. Attention

In order to reduce the influence of external environment on ADC conversion results, chip capacitor

must be connected to AVDD pin and CVREF pin, and 4.7uf (475) capacitance is recommended.

In order to ensure that the AD conversion can convert accurate AD results at a certain conversion

rate, it is necessary to calculate whether the equivalent input impedance matches according to the

actual application, otherwise the conversion result with accuracy error within 0.1 LSB will not be

obtained.

Before ADC conversion, the ADON@ADCON1 is on with 10us, and then ADSOC@ADCON1 is set

to 1, because it takes a period of warm-up after the ADC module is turned on.

For the channel used for AD conversion, the IO port function must be reused as the analog function

(GPIOx_CFG_AFRH/L is set to AF14), otherwise the correct conversion result cannot be obtained.

84

After the ADC conversion is started, the channel parameters, including TGAP, GAPENx, TS,

ADMAXCH, TADC, ADPCH, SEQCHx and other core channel parameters, can not be changed. Any

modification will be considered invalid.

The same channel number can also be set in SEQCHx. For example, if all the values in SEQCHx

are set to AN3, the result register will store the sampling values of AN3 in different time periods.

If the gain amplification channel needs to be converted, the OP function needs to be opened first.

The OP needs to establish a time (about 100us) to stabilize the output. Then AD conversion is

performed. During the conversion, OPUT1, OPOUT2 and OPOUT3 channels are selected.

When ADIE, ADLIE, DGIE are all on, any set of ADIF, ADLIF, ADGIF can cause interrupt, and

share an interrupt vector. By determining which of ADIF, ADLIF and ADGIF is 1, the specific interrupt

source is determined and the specific operation is customized.

The time interval between adjacent channels in AD conversion sequence can be used to increase

the sampling time of ADC. The gap time of each channel can be set separately, so the gap time can

also be used as the sampling time of each channel. The gap time of all channels can only be set to one

value, but each channel can be set to enable gap time independently. The first channel can also set the

gap time, which can also be used as the sampling time.

In any hardware triggered single sequence, intermittent conversion and continuous conversion

process, if another hardware trigger occurs, the previous conversion will be terminated and a new

conversion will be started.

When the comparison function is applied, the values written by ADDGT and ADDLT take effect

immediately, and the latest updated values of ADDGT and ADDLT will be used in the comparison.

SH32F9001 Series User Guide

85

14. TIMER

14.1. Overview

There are four basic 16-bit timers in SH32F9001 series. Two 32-bit timers can be set by setting

registers. Each timer can run at APB0 clock, and they can also run at internal low frequency RC (128

kHz LSI).

Each timer can output square wave whose frequency can be set through actual GPIO pin, and can

also drive counting unit of timer through GPIO pin from external input clock source.

14.2. Programming Setting

14.2.1. Basic timing application

The basic timer can be configured as a simple timing function, which is mostly used in system time

base or software timing in practical application.

14.2.2. Square wave with adjustable output

frequency

By setting GPIO pin as TIM function and enabling TC bit of CR register, GPIO pin can be flipped

according to overflow time of timer to generate a square wave. To change frequency, only need to

modify overflow time of timer.

14.2.3. Cascade into 32-bit timer

In this example, TIM5 and TIM6 are cascaded as a 32-bit timer, in which TIM5 is a high-level timer

and TIM6 is a low-level timer.

In cascade operation, only the CASCEN bit of TIM5 is valid. Once the CASCEN bit of TIM5 is set to

1, the TCNT, PSQ, TPR registers of TIM6 will become read-only attributes, and the 32 bits of TCNT,

PSQ and TPR registers of TIM5 are readable and writable.

Therefore, when two 16 bit timers are cascaded into a 32-bit timer, only the CASCEN bit of TIM5 is

1, and then TIM5 can be used as a 32-bit timer.

14.2.4. Attention

1) The overflow flag bit is generated when the counter changes from the value in the period register

(TPR) to 0. Therefore, in fact, the actual number of clocks in a cycle is TPR + 1, that is, when the period

is 100 in the application, TPR should be set to 99.

2) If the initial value of the counter TCNT is greater than the value of the cycle TPR, after enabling

the timer, the counter will run up to 0xFFFF, and then overflow to 0, and then it will cycle between 0 and

TPR in the next cycle.

3) The counter register, prescaler register and cycle register can be modified at runtime, but note

that the counter register will not be cleared when the software sets STR to 0.

14.2.5. Example 1

Function: Configure timer to generate interrupt every 1ms

86

Note: Set the timer register to generate time interval of 1ms, and enable the interrupt switch of

NVIC

Code:

#include “SH32F9001.h”

int main(void)

{

RCC->RCCLOCK = 0x33CC;

RCC->APB0ENR.BIT.TIM5EN = 1;

TIM5->TCNT = 0;

TIM5->PSQ = 7;

TIM5->TPR = 999;

TIM5->CR.BIT.IE = 1;

TIM5->CR.BIT.STR = 1;

NVIC_EnableIRQ(TIM5_IRQn);

while(1)

{

}

}

void TIM5_Handler(void)

{

TIM5->TIMINTF.BIT.TFC = 1;

}

14.2.6. Example 2

Function: Output a square wave with frequency of 1 kHz.

Note: Set the overflow time of the timer to 500us, so the corresponding GPIO will flip once

every 500 us, and the square wave with frequency of 1 kHz can be output.

Code:

#include “SH32F9001.h”

int main(void)

{

RCC->RCCLOCK = 0x33CC;

RCC->APB0ENR.BIT.TIM5EN = 1;

87

RCC->AHBENR.BIT.IOCLKEN = 1;

GPIOA_CFG->AFRL.BIT.AFR0 = 6;

TIM5->TCNT = 0;

TIM5->PSQ = 7;

TIM5->TPR = 499;

TIM5->CR.BIT.TC = 1;

TIM5->CR.BIT.STR = 1;

while(1)

{

}

}

14.2.7. Example 3

Function: Two 16 bit timers are cascaded into a 32-bit timer, and the timer is configured as 100

ms for one interrupt.

Note: APB0 clock runs at 36MHz, the prescaler of timer is 0, and TPR register is set to make

the time interval be 100ms to enter an overflow interrupt.

Code:

#include “SH32F9001.h”

int main(void)

{

RCC->RCCLOCK = 0x33CC;

RCC->APB0ENR.BIT.TIM5EN = 1;

RCC->APB0ENR.BIT.TIM6EN = 1;

RCC->AHBENR.BIT.IOCLKEN = 1;

GPIOA_CFG->AFRL.BIT.AFR0 = 6;

TIM5->CR.BIT.CASCEN = 1;

TIM5->TCNT = 0;

TIM5->TPR = 100000;

TIM5->PSQ = 35;

88

TIM5->CR.BIT.TC = 1;

TIM5->CR.BIT.STR = 1;

while(1)

{

}

}

SH32F9001 Series User Guide

89

15. LCD

15.1. Overview

The LCD driver characteristics of SH32F9001 series are as follows:

Support 4*40, 5*39, 6*38, 8*36

Support 1/3bias and 1/4bias

Support 1/4, 1/5, 1/6, 1/8 duty

Support fast charge mode to reduce power consumption

The COM port that is not enabled can be shared as SEG port

LCD is turned off during power on reset, pin reset, low voltage reset or watchdog reset.

When LCD is turned off, Common and

Segment both output low level

Support internal resistance series voltage division to realize bias voltage

Support operation in shutdown mode

SH32F9001 series provides traditional resistive LCD display mode, supports contrast

adjustment, 1/4 duty cycle 1/3 bias voltage, 1/5 duty cycle 1/3 bias voltage and 1/6 duty cycle 1/4

bias voltage drive mode. When ELCC bit of LCD->CR register is set to 1, LCD driving voltage

VLCD is determined by contrast control bit. When ELCC bit is cleared to 0, VLCD is equal to VDD.

When MCU enters power down mode, if 32.768kHz oscillator / 128kHz RC works, LCD works. The

LCD is turned off during power on reset, pin reset, low voltage reset or watchdog reset. When the

LCD is turned off, COM and SEG are multiplexed as IO.

15.2. Programming Setting

【Note】LCD clock source selection is determined by LCLK bit of LCD->CR register. When LCLK

bit is 1, LCD clock source is LSE (32.768k crystal). At this time, LCD fixed frame rate is 64Hz. When

LCLK bit is 0, LCD clock source is LSI (128K RC). At this time, LCD frame rate is determined by DCK

[1:0] bit of LCD->CR register.

【Note】When LSI or LSE is enabled, LCD module can work in deepsleep mode.

【Note】Select 1/4 duty cycle 1/3 bias, 1/5 duty cycle 1/3 bias voltage, 1/6 duty cycle 1/3 bias

voltage, 1/8 duty cycle, 1/4 bias voltage according to the DUTY [2:0] bit of LCD->CR register.

【Note】The 16 level contrast adjustment is controlled by the VOL[3:0] bit of LCD->CR register.

【Note】It is controlled by the MOD[1:0] bit of LCD->CR register, which can be selected as

traditional resistance LCD or fast charge mode to reduce power consumption.

【Note】The charging time is 1/8, 1/16, 1/32 or 1/64 of the LCD COM cycle selected by the FCCTL

[1:0] bit of the LCD->CR register.

15.3. Application examples

Function: Select COM1-4, SEG5-6 to generate the following display waveform: (frame = 64Hz)

90

SEGn

Vcc

COM4 - SEGn

SEGn+1

0

COM4

COM3

COM2

COM1

COM4

COM3

COM2

COM1

V2

V1

Vcc

0

V2

V1

Vcc

0

V2

V1

Vcc

0

V2

V1

Vcc

0

V2

V1

Vcc

0

V2

V1

Vcc

0

V

V1

-Vcc

-V2

-V1

SEGn+1

SEGn

one frame

Code:

#include <SH32F9001.H>

void main(void)

{

RCC_Config(); // PLL as system clock, HCLK=72MHz

NVIC_Config(); // If you need to configure interrupts, this example does not use interrupts

GPIO_Config(); // If I/O needs to be configured, this example leaves the default input

RCC->RCCLOCK = 0x33CC;

RCC->APB1ENR.BIT.LCDEN = 1; // Enable LCD module clock

RCC->AHBENR.BIT.IOCLKEN = 1; // Enable GPIO clock

91

RCC->CR.BIT.LSEON = 1; // Turn on LSI

while(RCC->CR.BIT.LSERDY == 0){WDT_FEED();}

RCC->RCCLOCK = 0x33CC;

GPIOB_CFG->AFRL.V32 = 0x99990000; //PB4~PB7 asCOM1~COM4

GPIOC_CFG->AFRL.V32 = 0x00000099; //PC0~PC1 as SEG1~SEG2

LCD->LCDSHARE.V32 = 0x0000030F; //Enable COM&SEG

LCD->LCD_BUFS1.LCDBUF4 = 0x0D;

LCD->LCD_BUFS1.LCDBUF4 = 0x0B; // SET data

LCD->CR.BIT.EN = 1; // LCD GO

while(1) // main loop

{

}

}

SH32F9001 Series User Guide

92

16. LED

16.1. Overview

The LED driver contains a controller, with 12 Common signal pins and 16 segment driver pins.

And support 1/1~1/12 duty voltage driving mode.

The LED driver has two kind of operation mode.

Mode 1: Light LED mode

When LED driver working in the light LED mode, each LEDCOM controls a LED light. When

LEDCOMx [15:0] bit is 0, LED lights out. And when LEDCOMx [15:0] bit is 1, LED lights are on. After

each LED frame or each scan of COM, the interrupt flag (LEDIF or COMIF) of LED driver is set to 1.

Mode 2: Dimming LED mode

When LED driver working in the Dimming LED mode, each of LEDSEGx [7:0] controls the duty

of SEG in the scanning COM period. The duty has 256 levels to select. When LEDSEGx [7:0] byte is

0xff, SEG outputs maximum duty, When LEDSEGx [7:0] byte is 0x00, SEG outputs minimum duty.

When LEDSEGx [7:0] byte is a value between 0x00 and 0xff, SEG outputs corresponding duty. The

change of LEDSEGx [7:0] byte, will be actived in the next COM scan period.

After each scan of COM period, next scan begins immediately, and the interrupt flag (FR_COMIF) of

LED driver will set to 1. Because the LED driver working in the mode 2, after LED driver enabled,

the interrupt flag (FR_COMIF) will set to 1, which makes the user change the value of LEDSEGx[7:0]

conveniently. After scanning a frame, LED driver interrupt flag (FR_COMIF) will set to 1.

Whether the LED driver working in Mode1 or Mode2, the unselected level of COM and SEG is

floating, the active output level of COM is low, and the active output level of SEG is high.

LEDSHARE_LEDCOM [11:0] registers decide the number of COM port of the LED driver.

LEDSHARE_LEDSEG1 [7:0] and LEDSHARE_LEDSGE2 [7:0] registers decide the number of SEG

port of the LED driver. CR_DISCOM [7:0] register can select the width of each COM period. In order

to prevent the uncertain state from occurring between two COM display switches, the LED driver

adds a dead-time between two COM. In the dead-time, the COM port outputs floating level. The

width of dead-time is a system clock width, which can be set by CR_LEDZZ [7:0] register.

During Power on Reset, Pin Reset, LVR or Watch Dog Reset, LED will be turned off. When LED is

turned off, COM and SEG will output floating level.

16.2. Programming Setting

Example of mode 1:

TB is LED single COM scanning width, Tpclk1 is system clock width, and TLED is LED scanning

time width.

TB = Tpclk1*256* LED_CR_DISCOM

TLED = TB *S

93

S is the quantity of scan LED COM: scan 4COM, that is, S=4, scan 5COM, that is, S=5, and so on.

For example, the LED frame rate which is needed to display is 200HZ(5ms), when LED is 5COM

and the system clock selected is internal RC 24MHz:

TB= Tpclk1*256* LED_CR_DISCOM

=41.66ns*256*94(5EH)

=1002506ns=1002.506u s=1.002ms

Need to set TLED =5ms

TLED= TB*S =1.002ms*5=5.010ms

Configurate the interrupt function(ELED=1) which need to be enabled, the frame interrupt (LEDFY=1)

(must) or COM interrupt (LEDCY=1) (selectable) can be selected. Enable the LED model and start LED

scaning, once a frame/COM waveform scans over, the selected frame interrupt (LEDIF=1)/COM

interrupt (COMIF=1) flag will set to 1. (the unselected level of COM and SEG is floating, the active output

level of COM is low, and the active output level of SEG is high.)

Example of mode 1:

TB is the width of single LED COM scan, TSYS is the width of system clock, TLED is the width of

LED scan time.

TB = Tpclk1*256* LED_CR_DISCOM

TLED = TB *S

S is the quantity of scan LED COM: scan 4COM, that is, S=4, scan 5COM, that is, S=5, and so

on.

For example, the LED frame rate which is needed to display is 200HZ(5ms), when LED is

5COM and the system clock selected is internal RC 24MHz:

TB= Tpclk1*256* DISCOM

=41.66ns*256*94(5EH)

=1002506ns=1002.506u s=1.002ms

Need to set TLED =5ms

TLED= TB*S =1.002ms*5=5.010ms

1. SEGXduty(X=0~16), the waveform of first COM and SEG(if output rail-to-rail configurated as 0XFF,

that is the first COM period displays 100% duty high, if not display, configurated as 0x00, that is display

floating; if configurated as 0x7F, the SEG output 50% duty high). Configurate the interrupt function

(ELED=1) which need to be enabled, the COM interrupt (LEDCY=1) (must) or frame interrupt (LEDFY=1)

(selectable) can be selected. Enable the LED interrupt and the LED module.

2. Configurate the first COM waveform before enabling the LED function, and enable the LED function.

when LED interrupt generated (COMIF=1), configurate SEG waveform register SEGXduty(X=0~16) of

the second COM period. If not changed, then display the last period waveform. By parity of reasoning,

one frame scan over (LEDIF=1). Before the second COM interrupt comes, configurate SEG waveform of

th the first COM of the next frame.

16.3. Application examples

94

16.3.1. Example 1

Function: COM1-4 and SEG1-8 are selected to display four common negative eight seg LED with

display contents of 1, 2, 3, 4 and eight segment code LED. The definition of LED SEG is shown in the

following figure:

SEG3

SEG2

SEG1

SEG8

SEG4

SEG5

SEG7

SEG6

Note: Use on/off mode (MODE1)

Code:

#include "SH32F9001.h"

int main()

{

RCC->RCCLOCK = 0x33CC; // unlock RCC config

RCC->AHBENR.BIT.IOCLKEN = 1; // GPIO clock enable

RCC->APB1ENR.BIT.LEDEN = 1; // LED clock enable

RCC->RCCLOCK = 0x0; // lock RCC config

GPIOB_CFG->AFRL.V32 = 0x88880000; //PB4~PB7 asCOM1~COM4

GPIOC_CFG->AFRL.V32 = 0x88888888; //PC0~PC7as SEG1~SEG8

LED->CR.BIT.DISCOM = 0x3F; //Setscan time

LED->CR.BIT.LEDDZ = 0x10; //Set dead duty time

LED->LEDSHARE.V32 = 0x00FF000F; //Enable COM&SEG

LED->LCE_BUFS0.LEDCOM1 = 0x06; //show 1

LED->LED_BUFS0.LEDCOM2 = 0x5B; //show 2

LED->LED_BUFS0.LEDCOM1 = 0x4F; //show 3

LED->LED_BUFS0.LEDCOM2 = 0x66; //show 4

LED->CR.BIT.EN = 1; // LED GO

while(1);

}

16.3.2. Example 2

Function: Select COM1-2 and SEG1-4 to realize the output duty cycle of each SEG port at COM1

95

and 1 / 2 at COM2 in the first cycle; in the second cycle, the duty cycle of each SEG port is 1 / 4 at COM1

and 1 / 8 at COM2 in the second cycle;

Note: Use dimming mode (MODE2)

Code:

#include "SH32F9001.h"

int main()

{

RCC->RCCLOCK = 0x33CC; // unlock RCC config

RCC->AHBENR.BIT.IOCLKEN = 1; // GPIO clock enable

RCC->APB1ENR.BIT.LEDEN = 1; // LED clock enable

RCC->RCCLOCK = 0x0; // lock RCC config

GPIOB_CFG->AFRL.V32 = 0x00880000; //PB4~PB5asCOM1~COM2

GPIOC_CFG->AFRL.V32 = 0x00008888; //PC0~PC3as SEG1~SEG4

LED->CR.BIT.DISCOM = 0x3F; //Set scan time

LED->CR.BIT.LEDDZ = 0x10; //Set dead duty time

LED->CR.BIT.MODE = 1; //Mode 2

LED->LEDSHARE.V32 = 0x000F0003; //Enable COM&SEG

LED->CR.BIT.IE = 1; // allow LED interrupt

LED->CR.BIT.LDECY = 1; // allow LED COM interrupt

LED->LED_BUFS6.V32 = 0xFFFFFFFF; // initial duty 100%

NVIC_EnableIRQ(LED_IRQn); // enable LED interrupt

LED->CR.BIT.EN = 1; // LED GO

while(1);

}

VoidLED_Handler(void)

{

LED->FR.BIT.COMIFC = 1; // clear flag

LED->LED_BUFS6.BIT.LEDSEG1 = LED->LED_BUFS6.BIT.LEDSEG1 – 0x40;

LED->LED_BUFS6.BIT.LEDSEG2 = LED->LED_BUFS6.BIT.LEDSEG1 – 0x40;

LED->LED_BUFS6.BIT.LEDSEG3 = LED->LED_BUFS6.BIT.LEDSEG1 – 0x40;

LED->LED_BUFS6.BIT.LEDSEG4 = LED->LED_BUFS6.BIT.LEDSEG1 – 0x40;

}

SH32F9001 Series User Guide

96

17. Temperature sensor

17.1. Overview

SH32F9001 series have a temperature sensor. The built-in temperature sensor can be calculated

by ADC sampling value.

17.2. Application examples

17.2.1. Application of built-in temperature sensors

The built-in temperature sensor has a calibrated temperature and is stored at a fixed address as

follows:

unsigned short Temp, TempAD0, TempAD1, TempAD_Test0, TempAD_Test1;

unsigned intTempErr, TempTest;

/* Read the temperature sensor reference value */

Temp = ReadAddr[0x0FFFF070]; // Temperature value during calibration, 16bits, Q4 format

TempAD0 = ReadAddr[0x0FFFF072];

// During calibration, the stored AD value CHOP=0, 16bits, 12 bit AD sampling value

TempAD1 = ReadAddr[0x0FFFF074];

// During calibration, the stored AD value CHOP=1, 16bits, 12 bit AD sampling value

/* Channel 0 sampling temperature sensor of ADC */

TempAD_Test0 = ADC->ADDR0; // When testing, the AD value CHOP=0

TempAD_Test1 = ADC->ADDR0; // When testing, the AD value CHOP=1

/* Calculate the measured temperature, if the reference voltage of ADC is 5V */

TempErr = ((TempAD_Test0+TempAD_Test1)- (TempAD0+TempAD1))/2;

// Average difference between two samples

TempErr <<= 16;

// In order to improve the calculation accuracy, the difference is changed into 32-bit data

TempTest = (TempErr/0x438B) + Temp;

//0x438B = (5.153/5000*4096<<12), Output Q4 format temperature

Note: V25 in the spec is 1.5V, which is a typical value. There will be some deviation during

production. It is recommended to calculate the test temperature by the above method.

SH32F9001 Series User Guide

97

18. UART

18.1. Overview

The SH32F9001 series provide 6 UARTs. Support flexible IO function mapping.

Each UART has four working modes, with its own baud-rate generator, supporting hardware parity

check and DMA communication.

In addition, it also supports 1/2-bit stop bit setting, and supports hardware generation and detection

of LIN bus synchronization interruption. Enhanced functions include frame error detection and

automatic address recognition.

18.2. Programming Setting

18.2.1. Sending

UART sending logic has two levels of registers: TDR and TXD shift, so the user can write 2-byte

sending data continuously for the first time. When UART is turned on, the sending interrupt flag bit TI is

valid by default. It will not be cleared automatically until TDR and shift are filled with data. Then, the

interrupt TI will be generated when the data of TDR is loaded into the shift register and becomes empty.

TC flag bit occurs in TDR and shift registers, when the data is sent empty, the flag bit will be

automatically cleared with data writing.

18.2.2. Rreceiving

In UART receiving circuit, there are two registers of RDR and RDR shift. Users need to take away

the data in time after receiving the data. Otherwise, when there is data in RDR, the data in shift will be

flushed after receiving. Therefore, the user needs to take the RDR data before the shift data reception is

completed at the latest. The RI flag is generated after receiving a complete byte of data. After the data

in RDR is read empty, RI will automatically be cleared to 0.

18.2.3. IO setting

Because TXDx/RXDx pins are multiplexed with I / O functions. If UART is selected for AF function,

RXDx pin is automatically set as UART input, but the internal pull-up resistor needs to be opened

manually in advance; TXDx pin is automatically set as UART output, but the open drain output or

push-pull output needs to be initialized in advance. Note that if it is reused with the simulation port, the

simulation port must be closed in SYSCFG, otherwise AF configuration will not take effect.

18.2.4. LIN mode

In LIN mode, detecting intermittent frame and receiving data cannot be carried out at the same time.

The correct use process is to detect synchronization interruption first, then to switch to receiving data

mode under LBD interrupt, and then to switch back to synchronous intermittent detection mode after

receiving.

18.2.5. Interrupt

98

When using interrupt mode, it is recommended that TIE be started before sending data after UART

initialization. Otherwise, TIE is started before enabling TEN. Interrupt service program will transport

2byte data to TDR and shift, and send it when TEN is enabled.

18.2.6. Parity check

When parity check function is used, its priority is the highest. Multi machine communication and

custom ninth bit function will not be used.

18.2.7. Error flag

When the error flag bits such as sending conflict, receiving overflow, parity error and frame error

occur again, they will be set, but the interrupt will not be triggered. If the user wants to use it, they need

to query and process it in UART interrupt.

18.2.8. Other notes

In order to avoid misjudgment at the receiver, it is recommended to set the I/O status of the

corresponding TXD to the output high level in the UART transmission initialization program.

18.3. Application examples

18.3.1. Example

Function: UART0 is used to send and receive serial port on PA3/TXD0, PA4/RXD0. The host

computer connects SH32F9001 series through UART0, and the host computer sends 1 byte. After

SH32F9001 series receive the byte, it adds 0x55 and then returns back to the host computer. The baud

rate is 9600bps, and the mode of 8/1/1/none is adopted.

Note: (1) In the alternate configuration, the I/O port is configured first, and then the digital peripheral

function is turned on. If RXD is opened first, it is possible that the change of external I/O level may lead

to the wrong start bit of receiving. (2) In this example, RXD0 is mapped to PA4 to demonstrate that SWJ

interface is alternated into digital peripheral interface function. (3) RXD0 is initialized as input and

internal pull-up and TXD0 are initialized as output high level.

Code:

#include <SH32F9001.H>

char WaitUartTransmit(UART_TypeDef* Uart, unsigned char ch )

{

while(!Uart->FR.BIT.TI); // Wait for the send to complete

Uart->TDR = ch; // Send data, TI is auto clear

return (ch);

}

char WaitUartReceive(UART_TypeDef* Uart)

{

while(!Uart->FR.BIT.RI); // Wait for the reception to complete

Uart->FR.BIT.RIC = 1; // RI manual clearing, defined as write 1 to clear

return(Uart->RDR);

99

// It is required to clear RI before returning data to avoid blocking reception

}

void main(void)

{

unsigned char rcv_byte;

RCC_Config(); // PLL as system clock, HCLK=72MHz,PCLK0/1=HCLK/2

NVIC_Config(); // If you need to configure interrupts, this example does not use interrupts

GPIO_Config(); // If I/O needs to be configured, this example leaves the default input

RCC->RCCLOCK = 0x33CC; // unlock RCC config

RCC->AHBENR.BIT.IOCLKEN = 1; // Turn on the GPIO module clock

RCC->AHBENR.BIT.SYSCFGEN = 1; // Turn on the SYSCFG module clock (SWJ multiplexing)

RCC->APB1ENR.BIT.UART0EN = 1; // Turn on uart1 clock

RCC->RCCLOCK = 0x0; // lock RCC config

GPIOA_CFG->LCKR.V32 = 0x5AA50000; // unlock PA config

GPIOA->MODER |= 0x0008; // set PA3 output

GPIOA->MODER &= 0xFFEF; // set PA4 input (default)

GPIOA_CFG->PUPDR.BIT.PHDR4 = 1; // set PA4 pull-up, 01b: pull-up

GPIOA->ODR |= 0x0008; // set PA3 = 1

SYSCFG->SAFR.V32 = 0x5AA50020; // SWD interface control, release PA4, PA5 port

GPIOA_CFG->AFRL.BIT.AFR3 = 2; // PA2 is mapped to RXD1

GPIOA_CFG->AFRL.BIT.AFR4 = 2; // PE7 is mapped to TXD1

GPIOA_CFG->LCKR.V32 = 0x5AA5FFFF; // lock PA config

UART0->BRT.BIT.SBRT = 233; // Set baud rate to 9.6KBps,36M/16/9.6K=324.375

UART0->BRT.BIT.BFINE = 6; // 0.375*16=6

UART0->CR.BIT.SM = 1; // type 1: 8/1/1/none, variable baud rate

UART0->CR.BIT.SBRTEN = 1; // enable baud rate generation

UART0->CR.BIT.TEN = 1; // enable txd

UART0->CR.BIT.REN = 1; // enable rxd

while(1) // main loop

{

rcv_byte = WaitUartReceive(UART0); // Uart receives

WaitUartTransmit(UART0,rcv_byte+0x55); // Uart sends

}

}

SH32F9001 Series User Guide

100

19. SPI

19.1. Overview

SH32F9001 series provides two SPIs. Support flexible IO function mapping.

Each SPI supports working in full duplex mode, master/slave mode, programmable master

clock frequency (Maximum support bus frequency 2 division), programmable polarity and phase of

serial clock, each bit width transmitted data word is 8, 16 bits, and large/small end mode to be

optional. Support DMA communication.

19.2. Programming Setting

19.2.1. Sending

The sending circuit of SPI contains three registers: TDR, TDR buffer and TDR shift; therefore, the

user can write three data for the first time. When SPI is turned on, the sending interrupt flag bit SPTI is

valid by default. It will not be cleared automatically until TDR, buffer and shift are filled with data. Then

the interrupt TI will be generated when the data of TDR is loaded into the buffer register and becomes

empty.

19.2.2. Reveiving

There are three levels of registers in SPI receiving circuit: RDR, RDR buffer and RDR shift. Users

need to take away the data in time after receiving the data. Otherwise, when there is data in RDR and

RDR buffer, the data in shift will be flushed when receiving data after receiving. Therefore, users need

to take RDR data after receiving shift data and before new data arrives at the latest. The flag of SPRI is

generated after receiving a complete byte of data. After the data in RDR is read empty, SPRI will

automatically be cleared to 0. If there is data in the lower buffer, the data will be automatically pushed to

RDR register, and SPRI will be reset.

19.2.3. IO setting

Because SPI pin is multiplexed with I/O function. If SPI is selected for AF function, the signal input

pin is automatically set as SPI input, but the internal pull-up resistance needs to be manually opened in

advance; the signal output pin is automatically set to SPI output, but the open drain output or push-pull

output needs to be initialized in advance.

19.2.4. Fast slave mode

When the SPI module selects the slave mode with CPHA = 0, the SS pin must be used as a chip

selection signal, and it must be pulled up after sending 1 byte, and it must be pulled down again before

sending 1 byte. If the SPSFF slave fast mode is used, the first data sent is loaded by the SS pin pulling

down the signal, and the subsequent data is automatically loaded by the last CLK edge of the previous

data. Therefore, when using this mode, the next data should be filled into the TDR cache before the

previous data transmission is completed.

19.2.5. Intterupt

101

When using interrupt mode, SPTIE needs to be turned on after initializing SPI and before sending

data. When MODF error occurs, it is necessary to use software to switch to slave and close SPI in

interrupt. If SPI needs to be switched to slave to receive data, SPI needs to be enabled again. If SPI

needs to send and receive data as host, it needs to detect that SS level is high before setting SPI

communication to host again.

19.2.6. Error flag

Send conflict, receive overflow error flag will not trigger interrupt. If necessary, user needs to check

and handle in the program.

19.3. Application examples

19.3.1. Example

Function: Use SPI1 to send and receive the data in the array TXDATA, and save the received data

in RXDATA. The clock frequency is 1125k (36M 32 division), select the host mode, SCK default level is

high, the second edge sampling; Data word length is 8bit, LSB mode. PA10 is used as the control signal

source selected by the slave.

Note: (1) Initialize IO before initializing SPI. Main settings: turn on MISO pin pull-up resistor and

switch AF function to SPI function. (2) In the main loop, the first 8-byte data in TXDATA array is sent,

and the received 8-byte data is saved in RXDATA data. (3) After receiving the 8th byte data, close SPI.

(4) This example can be used to read and write SPI device, and adjust the content of TXDATA. It can

not only realize the purpose of reading and writing peripherals, but also can directly short-circuit MO

and MI to observe the sending and receiving of data.

Code:

#include <SH32F9001.H>

unsigned char Taddr,Raddr;

unsigned char

TXDATA[16]={0xAA,0xA1,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0xFF};

unsigned char RXDATA[16];

void main(void)

{

RCC->RCCLOCK = 0x33CC; // unlock RCC config

RCC->AHBENR.BIT.IOCLKEN = 1; // Turn on the GPIO module clock

RCC->APB1RSTR.BIT.SPI1RST = 1; //RESET SPI1

RCC->APB1ENR.BIT.SPI1EN = 1; // Turn on SPI1 clock

RCC->RCCLOCK = 0x0; // lock RCC config

GPIOA_CFG->LCKR.V32 = 0x5AA50000; // unlock PA config

GPIOA_CFG->PUPDR.BIT.PHDR1 = 1; // MASTER INPUT PULL UP

GPIOA_CFG->AFRH.BOT.AFR10 = 1;

102

GPIOA->MODER |= 0X0400;

GPIOA->ODR |= 0X0400; //USE PA10 TO SELECT SLAVE

GPIOA->AFRL.BIT.AFR3 = 0X04; //SCK1 OUT

GPIOA->AFRL.BIT.AFR2 = 0X04; //MOSI1 OUT

GPIOA->AFRL.BIT.AFR1 = 0X04; //MISO1 IN MASTER MODE

GPIOA_CFG->LCKR.V32 = 0x5AA5FFFF; // lock PA config

SPI1->CR.BIT.SPR = 4; //SPI_SPR_32

SPI1->CR.BIT.SSDIS = 1; //SPI_SSDIS_DISABLE

SPI1->CR.BIT.CPOL = 1; //SPI_CPOL_HIGH

SPI1->CR.BIT.CPHA = 1; //SPI_CPHA_SECOND

SPI1->CR.BIT.MSTR = 1; //SPI_MSTR_MASTER

SPI1->CR.BIT.DIR = 1; //SPI_DIR_LSB

SPI1->CR.BIT.SPDATL = 0; //SPI_SPDATL_8BIT

SPI1->CR.BIT.SPIEN = 1; //SPI_SPIEN_ENABLE

GPIOA->ODR &= ~0X0400; //USE PA10 TO SELECT SLAVE

while(1) // main loop

{

//SEND DATA IN TXDATA[]

if(SPI1->FR.BIT.SPTI) //CHECK SPTI FLAG

{

if(Taddr > 7)

{

}

else

{

SPI1->TDR = TXDATA[Taddr]; //SEND DATA

Taddr++;

}

}

//RECEIVE DATA AND SAVE IN RXDATA[]

if(SPI1->FR.BIT.SPRI) //CHECK SPRI FLAG

{

RXDATA[Raddr] = SPI1->RDR; //RECEIVE AND SAVE DATA

Raddr++;

}

//CLOSE SPI1

if(Raddr >=7)

103

{

GPIOA_IOD->ODR &= ~0X0400; //USE PA10 TO SELECT SLAVE

SPI1->CR.BIT.SPIEN = 1;

}

}

}

SH32F9001 Series User Guide

104

20. TWI (I2C)

20.1. Overview

TWI (two wire serial interface) interface is the inheritance and development of I^2C bus

interface, which is fully compatible with I^2C bus.

TWI consists of a clock line and a data line. It is transmitted in bytes. It is compatible with

SMBus bus specification. It can automatically process byte transmission and track serial

communication.

SCL/SDA is the signal line of TWI bus. SDA is a bidirectional data line and SCL is a clock line.

When data is transmitted on TWI bus, first send the highest bit (MSB), and then the host sends the

start signal, and then the host sends one or more bytes of data. After data transmission, the host

sends a stop signal to complete the simplest TWI transmission.

20.2. Programming Setting

20.2.1. TWI bus setting

20.2.1.1. I/O setting

TWI bus is required to be configured as open drain output. And pay attention that the external

pull-up limit is VDD or slightly higher than VDD.

GPIOA_CFG->AFRH.BIT.AFR13 = 3; // PA13 = AF3 ~ SCL

GPIOA_CFG->AFRH.BIT.AFR14 = 3; // PA14 = AF3 ~ SDA

GPIOA_CFG->OTYPER = 0x6000; // PA13/14: OD output

GPIOA_CFG->PUPDR.V32 = 0x14000000; // PA13/14: pull high, internal pull-up

20.2.1.2. Baud rate configuration

// prescale, 0:64, 1:16, 2:4, 3:1

TWI1->CR.BIT.CR = 3;

/* Baud rate formula:Ftwi / (16+2*CR*BRT), when setting baud rate to be 100KBps, Ftwi=30MHz,

require CR*BRT=142, get CR=1, BRT=142 */

TWI1->BRT = 142;

20.2.1.3. Communication address configuration

// AMR=0, Do not turn on the shield. ADDR[6:0]=0111011b, Local address. GC=0b, disable response

TWI1->ADDR.V32 = 0x0076;

20.2.2. Four basic communication modes

105

The communication between SH32F9001 series TWI is based on the underlying driver circuit

and interrupt based application software. All bus events, such as receiving a byte or sending a

starting condition, produce an interrupt. So during byte transmission, the application software can do

other operations.

Four basic operation modes of TWI:

Host sending mode: the host machine sends data as the host

Host sending mode: the host machine receives data as the host

The slave sending mode: the local machine sends data as a slave

The slave receiving mode: the local machine receives data as a slave

All operations are combined from these four basic operation modes. The following is an example of

the program. In order to simplify the program, only query mode is used, and interrupt is not used. For

some macro definitions, please refer to the following "application examples". Here, only one of the

multiple process branches of each mode is provided.

【Note】During TWINT setting, TWI bus does not receive and send operations, and the status will

not be updated. The status can only be updated after clearing the flag.

【Note】TWINT setting is only related to the local state change. It may be that the local machine

completes a certain transmission or the local machine completes a certain reception, which will lead to

the state change.

【Note】In the initialization phase, AA = 1 indicates that the slave mode is set, and in the

communication process, AA = 1 indicates that the ACK signal is returned.

【Note】In TWI bus, start condition and stop condition are sent by host computer.

20.2.2.1. Host sending mode

Open_TWI; // Open the module

Send_STA; // Start condition of host sending

CLR_STA; // Stop start condition (close repeat start condition)

WAIT_TWINT; // Waiting for state change (send start condition)

if (TWI1->STAT.V32!=STATE_08) // If the status is not 08H, it will go to error handling

Go_State_Error (STATE_08); // Status error

Send_SLA_W; // Master sends slave address + write command

CLR_TWINT; // Clear status information (08H)

WAIT_TWINT; // Waiting for state change (send SLA_W, receive ACK)

if (TWI1->STAT.V32!=STATE_18) // If the status is not 18H, it will go to error handling

Go_State_Error (STATE_18); // Status error

Send_DAT; // Host sends the first byte data

CLR_TWINT; // Clear status information (18H)

WAIT_TWINT; //Waiting for state change (send DR, receive ACK)

106

if (TWI1->STAT.V32!=STATE_28) // If the status is not 28H, it will go to error handling

Go_State_Error (STATE_28); // Status error

Send_DAT2; //The host sends the second byte data

CLR_TWINT; // Clear status information (28H)

WAIT_TWINT; // Waiting for state change (send DR, receive ACK)

if (TWI1->STAT.V32!=STATE_28) // If the status is not 28H, it will go to error handling

Go_State_Error (STATE_28); // Status error

Send_STO; // Host sends stop condition (pay attention to send STO before clearing state)

CLR_TWINT; // Clear status information (28H)

20.2.2.2. Host receiving mode

Send_STA; // Start condition of host sending

CLR_STA; // Stop start condition (close repeat start condition)

WAIT_TWINT; // Waiting for state change (send start condition)

if (TWI1->STAT.V32!=STATE_08) // If the status is not 08H, it will go to error handling

Go_State_Error (STATE_08); // Status error

Send_SLA_R; // Host sends slave address + read command

CLR_TWINT; // Clear status information (08H)

WAIT_TWINT; // Waiting for state change (send SLA_R, receive ACK)

if (TWI1->STAT.V32!=STATE_40) // If the status is not 40H, it will go to error handling

Go_State_Error (STATE_40); // Status error

Send_ACK;

// Set the host return ACK (because sent by the slave, the host sets the return information in advance)

CLR_TWINT; // Clear status information (40H)

WAIT_TWINT; // Waiting for state change (receive data, respond ACK)

if (TWI1->STAT.V32!=STATE_50) // If the status is not 50H, it will go to error handling

Go_State_Error (STATE_50); // Status error

if (TWI1->DR!=0x85) // Is the first data received by the host as 0x85?

Go_State_Error (STATE_INIT); // Data receiving error

Send_NAK; // Setting NACK for host feedback

CLR_TWINT; // Clear status information (50H)

WAIT_TWINT; // Waiting for state change (receive data, respond NACK)

107

if (TWI1->STAT.V32!=STATE_58) // If the status is not 58H, it will go to error handling

Go_State_Error(STATE_58); // Status error

if (TWI1->DR!=0x58) // Is the host receiving the second data 0x58?

Go_State_Error(STATE_INIT); //Data receiving error

Send_STO; // Host sends stop condition (pay attention to send STO before clearing state)

CLR_TWINT; // Clear status information (58H)

20.2.2.3. Slave transmission mode

Open_TWI;

Send_ACK; // Set to slave mode

WAIT_TWINT; // Wait for state change (receive SLA + R, respond ACK)

if (TWI1->STAT.V32!=STATE_A8) // If the status is not A8H, it will go to error handling

Go_State_Error(STATE_A8); // Status error

Send_DAT; // Send the first byte data

CLR_TWINT; // Clear status information (A8H)

WAIT_TWINT; // Wait for state change (receive data, receive ACK response)

if (TWI1->STAT.V32!=STATE_B8) // If the status is not B8H, it will go to error handling

Go_State_Error(STATE_B8); // Status error

Send_DAT2; // Send 2nd byte data

CLR_TWINT; // Clear status information (B8H)

WAIT_TWINT; // Wait for state change (receive data, receive NACK response)

if (TWI1->STAT.V32!=STATE_C0) // If the status is not C0H, it will go to error handling

Go_State_Error(STATE_C0); // Status error

CLR_TWINT; // Clear status information (C0H)

20.2.2.4. Slave receiving mode

Open_TWI;

Send_ACK; // slave mode is set

WAIT_TWINT; // Wait for state change (receive SLA + W, respond ACK)

if (TWI1->STAT.V32!=STATE_60) // If the status is not 60H, it will go to error handling

Go_State_Error (STATE_60); // Status error

CLR_TWINT; // Clear status information (60H)

WAIT_TWINT; // Waiting for state change (addressable, data received, ACK responded)

if (TWI1->STAT.V32!=STATE_80) // If the status is not 80H, it will go to error handling

108

Go_State_Error (STATE_80); // Status error

if (TWI1->DR!=0x85) // Is the first data received 0x85?

Go_State_Error (STATE_INIT); // Data receiving error

Send_NAK; // Set slave to return to NACK

CLR_TWINT; // Clear status information (80H)

WAIT_TWINT; // Waiting for state change (addressable, data received, NACK responded)

if (TWI1->STAT.V32!=STATE_88) // If the status is not 88H, it will go to error handling

Go_State_Error (STATE_88); // Status error

if (TWI1->DR!=0x58) // Is the second data received 0x58?

Go_State_Error (STATE_INIT); // Data receiving error

CLR_TWINT; // Clear status information (88H)

20.2.3. TWI Interrupt and timeout

The TWI of SH32F9001 series has three interrupt sources: communication interruption, bus

timeout and SCL high level timeout. The corresponding three interrupt flags are TWINT, TOUT and

TFREE.

The bus timeout (TOUT) function and SCL high level timeout (TFREE) function of the SH32F9001

series are always on and cannot be turned off.

TOUT occurs when the low level of SCL exceeds a certain period of time, which indicates that a

master or slave can pull down the bus clock. If this time is exceeded, a bus timeout event will be

generated. The hardware will release the bus automatically and send the corresponding flag (if

enabled).

TFREE occurs after the high level of SCL exceeds a certain period of time, indicating that the bus is

in the "idle" state. After the TFREE event occurs, the hardware automatically releases the bus and

sends the corresponding flag (if enabled).

【Note】The two enable bits ETOT and EFREE control whether the corresponding flag bit is set

when TOUT and TFREE occur. Only when the flag bit is set, the subsequent TWI interrupt be

generated. If ETOT and EFREE are closed, the flag will not be generated and the interrupt will not occur

naturally.

【Note】TWINT is a communication interrupt flag. When the state of TWI changes, it will cause

setting, but entering the F8 state from other states will not cause setting.

【Note】TWINTE is the total interrupt enable bit.

20.3. Application examples

20.3.1. Example 1

Function: Use TWI interface to read and write EEPROM at 400KBps, model AT24C02.

Note: The core functions of TWI interface are I2C_EE_BufferWrite() and I2C_EE_BufferRead(),

which are buffer write and buffer read respectively. PB0 is mapped to SDA and PB1 is mapped to SCL.

109

Code:

#include <SH32F9001.H>

#define EEP_Firstpage 0x00

/* EEPROM Addresses defines */

#define EEPROM_Block0_ADDRESS 0xA0 /* E2 = 0 */

//#define EEPROM_Block1_ADDRESS 0xA2 /* E2 = 0 */

//#define EEPROM_Block2_ADDRESS 0xA4 /* E2 = 0 */

//#define EEPROM_Block3_ADDRESS 0xA6 /* E2 = 0 */

#define I2C_Direction_Transmitter ((uint8_t)0x00)

#define I2C_Direction_Receiver ((uint8_t)0x01)

#define IS_I2C_DIRECTION(DIRECTION) (((DIRECTION) == I2C_Direction_Transmitter) || \

((DIRECTION) == I2C_Direction_Receiver))

#define Send_STA (TWI1->CR.BIT.STA = 1)

#define CLR_STA (TWI1->CR.BIT.STA = 0)

#define Send_STO (TWI1->CR.BIT.STO = 1)

#define Send_ACK (TWI1->CR.BIT.AA = 1)

#define Send_NAK (TWI1->CR.BIT.AA = 0)

#define CLR_TWINT (TWI1->FR.BIT.TWINTC = 1)

#define WAIT_TWINT while(!TWI1->FR.BIT.TWINT)

#define Open_TWI (TWI1->CR.BIT.TWIEN = 1)

#define Close_TWI (TWI1->CR.BIT.TWIEN = 0)

#define STATE_INIT 0xff

#define STATE_OK 0xee

#define STATE_00 (0x0)

#define STATE_08 (0x08)

#define STATE_10 (0x10)

#define STATE_18 (0x18)

#define STATE_20 (0x20)

#define STATE_28 (0x28)

#define STATE_30 (0x30)

#define STATE_38 (0x38)

#define STATE_40 (0x40)

#define STATE_48 (0x48)

#define STATE_50 (0x50)

#define STATE_58 (0x58)

#define STATE_60 (0x60)

110

#define STATE_68 (0x68)

#define STATE_70 (0x70)

#define STATE_78 (0x78)

#define STATE_80 (0x80)

#define STATE_88 (0x88)

#define STATE_90 (0x90)

#define STATE_98 (0x98)

#define STATE_A0 (0xa0)

#define STATE_A8 (0xa8)

#define STATE_B0 (0xb0)

#define STATE_B8 (0xb8)

#define STATE_C0 (0xc0)

#define STATE_C8 (0xc8)

#define STATE_F8 (0xf8)

#define I2C1_OWN_ADDRESS7 0x0A

#define I2C_PageSize 8 /* AT24C02 has 8 bytes per page */

u16 EEPROM_ADDRESS;

u16 rxREP,txREP;

u8 I2c_Buf_Write[256];

u8 I2c_Buf_Read[256];

void I2C_Test(void);

void I2C_EE_Init(void);

void I2C_EE_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 NumByteToWrite);

void I2C_EE_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead);

void I2C_EE_PageWrite(u8* pBuffer, u8 WriteAddr, u8 NumByteToWrite);

void I2C_EE_WaitEepromStandbyState(void);

void main(void)

{

RCC_Config(); // PLL as the system clock,HCLK=120MHz,PCLK1=HCLK/4

I2C_EE_Init(); // Configure I/O port as PB0/PB1 and TWI baud rate as 400kbps

I2C_Test(); //Main function

while(1) // main loop

{

}

}

void I2C_Test(void)

{

111

u8 i;

for ( i=0; i<=255; i++ ) // Fill buffer

{

I2c_Buf_Write[i] = i;

}

// The data in I2c_Buf_Write is written to EERPOM sequentially and incrementally

I2C_EE_BufferWrite( I2c_Buf_Write, EEP_Firstpage, 256);

// Keep the reading data of EEPROM to I2c_Buf_Read sequentially

I2C_EE_BufferRead(I2c_Buf_Read, EEP_Firstpage, 256);

//The data in I2c_Buf_Read is printed through serial port

for (i=0; i<=255; i++)

{

if(I2c_Buf_Read[i] != I2c_Buf_Write[i])

{

printf("0x%x ", I2c_Buf_Read[i]);

printf("error:I2C EEPROM writing and reading not match \n\r");

while(1);

}

}

printf("result ok:I2C EEPROM writing and reading all match \r\n");

printf("I2C(AT24C02) test ok\n\r")

}

/*

* Function name: I2C_EE_BufferWrite

* Description: write data in buffer to I2C EEPROM

* Input: - Pbuffer, buffer pointer

* - WriteAddr, the address of the EEPROM that receives the data

* - NumByteToWrite, the number of bytes to write to EEPROM

* Output: None

* Output: None

* Call: external calls

*/

void I2C_EE_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 NumByteToWrite)

{

u8 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0;

112

Addr = WriteAddr % I2C_PageSize;

count = I2C_PageSize - Addr;

NumOfPage = NumByteToWrite / I2C_PageSize;

NumOfSingle = NumByteToWrite % I2C_PageSize;

/* If WriteAddr is I2C_PageSize aligned */

if(Addr == 0)

{

/* If NumByteToWrite < I2C_PageSize */

if(NumOfPage == 0)

{

I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);

I2C_EE_WaitEepromStandbyState();

}

/* If NumByteToWrite > I2C_PageSize */

else

{

while(NumOfPage--)

{

I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);

I2C_EE_WaitEepromStandbyState();

WriteAddr += I2C_PageSize;

pBuffer += I2C_PageSize;

}

if(NumOfSingle!=0)

{

I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);

I2C_EE_WaitEepromStandbyState();

}

}

}

/* If WriteAddr is not I2C_PageSize aligned */

else

{

/* If NumByteToWrite < I2C_PageSize */

if(NumOfPage== 0)

{

I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);

I2C_EE_WaitEepromStandbyState();

113

}

/* If NumByteToWrite > I2C_PageSize */

else

{

NumByteToWrite -= count;

NumOfPage = NumByteToWrite / I2C_PageSize;

NumOfSingle = NumByteToWrite % I2C_PageSize;

if(count != 0)

{

I2C_EE_PageWrite(pBuffer, WriteAddr, count);

I2C_EE_WaitEepromStandbyState();

WriteAddr += count;

pBuffer += count;

}

while(NumOfPage--)

{

I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);

I2C_EE_WaitEepromStandbyState();

WriteAddr += I2C_PageSize;

pBuffer += I2C_PageSize;

}

if(NumOfSingle != 0)

{

I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);

I2C_EE_WaitEepromStandbyState();

}

}

}

}

/*

* Function name: I2C_EE_BufferRead

* Description: Read a piece of data from EEPROM.

* Input: - pBuffer, buffer pointer to store the data read from EEPROM.

* - WriteAddr, the EEPROM address that receives the data

* - NumByteToWrite, the number of bytes to read from EEPROM

* Output: None

* Return: None

114

* Call: external calls

*/

void I2C_EE_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead)

{

uint8 ErrorFlag=0;

u16 tCnt=0;

uint8* tpBuffer;

rxREP=0;

do

{

rxREP++;

ErrorFlag=0;

tCnt = NumByteToRead;

tpBuffer = pBuffer;

Send_STA;

CLR_TWINT;

WAIT_TWINT;

CLR_STA;

if (TWI1->STAT.V32!=STATE_08) ErrorFlag++;

TWI1->DR = EEPROM_ADDRESS | I2C_Direction_Transmitter;

CLR_TWINT;

WAIT_TWINT;

if (TWI1->STAT.V32!=STATE_18) ErrorFlag++;

TWI1->DR = ReadAddr;

CLR_TWINT;

WAIT_TWINT;

if (TWI1->STAT.V32!=STATE_28) ErrorFlag++;

Send_STA;

CLR_TWINT;

WAIT_TWINT;

CLR_STA;

if (TWI1->STAT.V32!=STATE_10) ErrorFlag++;

TWI1->DR = EEPROM_ADDRESS | I2C_Direction_Receiver;

CLR_TWINT;

115

WAIT_TWINT;

if (TWI1->STAT.V32!=STATE_40) ErrorFlag++;

Send_ACK;

CLR_TWINT;

while(tCnt>1)

{

WAIT_TWINT;

if (TWI1->STAT.V32!=STATE_50) ErrorFlag++;

*tpBuffer = TWI1->DR;

tpBuffer++;

tCnt--;

Send_ACK;

CLR_TWINT;

}

Send_NAK;

WAIT_TWINT;

if (TWI1->STAT.V32!=STATE_58) ErrorFlag++;

*tpBuffer = TWI1->DR;

tpBuffer++;

}while(ErrorFlag);

Send_STO;

CLR_TWINT;

}

/*

* Function name: I2C_EE_PageWrite

* Description: Multiple bytes can be written in one write loop of EEPROM, but the number of bytes written

* at a time cannot exceed the size of the EEPROM page. AT24C02 has 8 bytes per page.

* Input: - pBuffer, buffer pointer to store the data read from EEPROM.

* -WriteAddr WriteAddr, the EEPROM address that receives the data

* -NumByteToWrite, the number of bytes to read from EEPROM

* Output: None

* Return: None

* Call: external calls

*/

void I2C_EE_PageWrite(u8* pBuffer, u8 WriteAddr, u8 NumByteToWrite)

{

uint8 ErrorFlag=0;

116

uint8 tCnt=0;

uint8* tpBuffer;

txREP = 0;

do

{

txREP++;

ErrorFlag=0;

tCnt = NumByteToWrite;

tpBuffer = pBuffer;

Send_STA;

CLR_TWINT; // clear for going

WAIT_TWINT;

CLR_STA;

if (TWI1->STAT.V32!=STATE_08) ErrorFlag++;

TWI1->DR = EEPROM_ADDRESS | I2C_Direction_Transmitter;

CLR_TWINT;

WAIT_TWINT;

if (TWI1->STAT.V32!=STATE_18) ErrorFlag++;

TWI1->DR = WriteAddr;

CLR_TWINT;

/* While there is data to be written */

while(tCnt--)

{

WAIT_TWINT;

if (TWI1->STAT.V32!=STATE_28) ErrorFlag++;

/* Send the current byte */

TWI1->DR = *tpBuffer;

/* Point to the next byte to be written */

tpBuffer++;

CLR_TWINT;

}

}while(ErrorFlag);

Send_STO;

CLR_TWINT;

}

117

/*

* Function name: I2C_GPIO_Config

* Description: I2C1 I/O configuration

* Input: none

* Output: None

* Call: internal calls

*/

static void I2C_GPIO_Config(void)

{

// PC0:SCL1

// PC1:SDA1

GPIOC_CFG->LCKR.V32 = 0x5AA50000; // PC0~PC15 unlock (only CFG)

GPIOC_CFG->AFRL.BIT.AFR0 = 4; // PC0 = AF4 ~ SCL

GPIOC_CFG->AFRL.BIT.AFR1 = 4; // PC1 = AF4 ~ SDA

GPIOC_CFG->OTYPER = 0x03; // PB0/1: OD output

GPIOC_CFG->PUPDR.V32 = 0x05; // PB0/PB1 = 0101b, pull high

}

/*

* Function name: I2C_Configuration

* Description: I2C working mode configuration

* Input: none

* Output: None

* Call: internal calls

*/

static void I2C_Mode_Configu(void)

{

TWI1->CR.BIT.CR = 3; // 0:64, 1:16, 2:4, 3:1

TWI1->BRT = 29; // 30000/400 = 16+2*CR*BRT ==> 29.5

TWI1->ADDR.BIT.TWIAMR = 0; // No Address Mask

TWI1->ADDR.BIT.ADDR = I2C1_OWN_ADDRESS7; // Set local address

TWI1->ADDR.BIT.GC = 0; // No GC Address

TWI1->DR = 0;

TWI1->CR.BIT.TWIEN = 1; // enable TWI

TWI1->CR.BIT.TWINTE = 0; // disable TWI interrupt, using the query method

Send_ACK; // AA=1

}

118

/*

* Function name: I2C_EE_Init

* Description: I2C peripheral (EEPROM) initialization

* Input: none

* Output: None

* Call: internal calls

*/

void I2C_EE_Init(void)

{

I2C_GPIO_Config();

I2C_Mode_Configu();

/* Select the address to write to EEPROM */

#ifdef EEPROM_Block0_ADDRESS

/* Select EEPROM block0 to write */

EEPROM_ADDRESS = EEPROM_Block0_ADDRESS;

#endif

#ifdef EEPROM_Block1_ADDRESS

/* Select EEPROM block1 to write */

EEPROM_ADDRESS = EEPROM_Block1_ADDRESS;

#endif

#ifdef EEPROM_Block2_ADDRESS

/* Select EEPROM block2 to write */

EEPROM_ADDRESS = EEPROM_Block2_ADDRESS;

#endif

#ifdef EEPROM_Block3_ADDRESS

/* Select EEPROM block3 to write */

EEPROM_ADDRESS = EEPROM_Block3_ADDRESS;

#endif

}

void Delay(u32 nCount) // Simple delay function

{

for(; nCount != 0; nCount--);

}

/*

119

* Function name: I2C_EE_WaitEepromStandbyState

* Description: Wait for EEPROM Standby state(E2 device does not respond to I2C interface reading and writing

during internal writing. This feature can be used to query whether E2 writing is completed. In this example,

the processing is simplified and the delay is forced for a period of time according to the EEPROM timing

sequence)

* Input: none

* Output: None

* Return: None

* Call:

*/void I2C_EE_WaitEepromStandbyState(void)

{

Delay(100000);

}

SH32F9001 Series User Guide

120

21. Aappendix

21.1. Aappendix 1:Function location and debugging method in KEIL MDK

Take SH32F9001 series as an example:

Code Area: 0x0000 0000~0x0004 0000

RAM1:0x1000 0000 ~0x1000 4000

RAM2:0x2000 0000~ 0x20004000

21.1.1. Program running in RAM

Requirement: the debug program must be smaller than the size of RAM.

Objective: run the whole program in RAM1 and variable in RAM2

Steps:

1. Add debug initialization file in the project directory and save it as "run_in_ram.ini”. The file is in

plain ASCII text format and the content is as fllowing:

FUNC void Setup (void) {

SP = _RDWORD(0x10000000);

PC = _RDWORD(0x10000004); _WDWORD(0xE000ED08, 0x10000000);

}

FUNC void OnResetExec (void) {

Setup();

}

load %L incremental

Setup();

g, main

Statement Description:

SP=_RDWORD(0x10000000): Read 1 word from 0x10000000 and send it to SP

PC=_RDWORD(0x10000004): Read 1 word from 0x10000004 and send it to PC

_WDWORD(0xE000ED08,0x10000000): Set start address of interrupt vector table

OnResetExec(); This function is called when the reset button is pressed

Load %L incremental : Add debug information of the file, and %L represents the output file of the

link

g, main represents execution to the main function

** Statements outside the function are called when entering debug

121

2. Modify the IROM settings and adjust the RAM settings as follows

3. Modify the debug option as follows: add the previously saved run_in_ram.ini to the initialization

file

122

4. Modify the Utilities options as follows: remove Update Target before Debugging

5.Modify the Flash Download settings as follows

6.After Rebuild the project, press the Debug button directly. There will be a warning "no flash

operation", click OK.

123

7.It is running in RAM normally. As shown in the figure below.

Matters needing attention:

You cannot use the RESET button to reset. You must exit Debug and re-enter. Because after reset,

SP will be taken from the position of code area position 0, and PC will be taken from position 4

The program must reset the position of the interrupt vector table to 0x10000000, otherwise the

interrupt or exception cannot be located correctly.

21.1.2. Put the critical program into RAM to run

Requirement: programs that need to run in RAM must be smaller than the size of RAM.

Objective: Put some functions into RAM1 and variables into RAM2

Steps:

124

1.Put the functions that need to be run in RAM into a file, and add the compiler instructions that

define the section at the top. (The section name can be defined by yourself) as shown in the figure

below:

2. 增加 Link 控制文件 ramcode.sct.如图 Add Link control file “ramcode.sct”. As shown in the figure.

3. Set the link option, as shown in the figure.

125

4. Modify “Flash Download” settings as follows.

5.After rebuilding the project, press “Download” button to download the program, and then press

the enter debug button to enter the debug interface. When you run to the place where the function is

called, you can see that it is running in flash.

126

6. After running step into, you can see that you have already jumped to RAM1.

127

7. Run step out again, and you can see that you jump back to the flash area again

128

21.1.3. Fix a function to a certain position

1. Give the function a section name

You can also use #pragma arm section code=”XNTEST1” to define a section with the same name

for all functions in the whole file.

2. Specify the address in the scatter file

129

As shown in the figure, the function “OutputInfo1” is fixed at the position of 0x20000

As shown in the figure, the function “OutputInfo2” is fixed at the position of 0x30000

21.1.4. Automatically export similar data to a table

21.1.4.1. Define an output macro

For example:

#define SECTION(x) __attribute__((section(x)))

#define RT_USED __attribute__((used))

typedef int (*drv_func) (void* param);

struct func_item{

drv_func func;

const char* desc;

};

#define EXPORT_FUNC_TABLE(name,desc) const char _drv_##name##_desc[] = #desc; \

const struct func_item _drv_##name##_cmd SECTION("MySymTab") =

\

{ \

(drv_func)&name, \

_drv_##name##_desc \

};

21.1.4.2. Export call function

Call this macro where you need to export

For example:

static int func1 (void* param)

{

130

return 3;

}

EXPORT_FUNC_TABLE(func1, func desp1);

static int func2 (void* param)

{

return 1;

}

EXPORT_FUNC_TABLE(func2, func desp2);

static int func3 (void* param)

{

return 0;

}

EXPORT_FUNC_TABLE(func3, func desp3);

static int func4(void* param)

{

return 5;

}

EXPORT_FUNC_TABLE(func4, func desp3);

21.1.4.3. Table lookup method

**Note, the header identifier MySymTab$$Base and the tail identifier MySymTab$$Limit will be

automatically added in keil MDK.

void my_func(void)

{

struct func_item *ps;

struct func_item *pe;

extern const int MySymTab$$Base;

extern const int MySymTab$$Limit;

ps = (struct func_item*) MySymTab$$Base;

pe = (struct func_item*) MySymTab$$Limit;

while(ps != pe)

{

ps->func(0);

ps++;

}

}

131

21.1.5. Fix variables to a location in RAM

21.1.5.1. Specify the address directly at the variable definition

uint32_t g_var1 __attribute__((at(0x20000000))) = 0x33445566;

uint32_t g_var2 __attribute__((at(0x20000004)));

21.1.5.2. Specify the section directly in the variable definition

Specify the section in the variable definition, and then fix the section to a certain position with

linker's scatter file:

uint32_t g_fvar1 __attribute__((section(".fixed1"))) = 0x12345678; /* RW */

uint32_t g_fvar2 __attribute__((section(".fixed1"))) = 0x87654321; /* RW */

uint32_t g_fvar3 __attribute__((section(".fixed1"))) = 0x87654321; /* RW */

uint32_t g_fixed1 __attribute__ ((section(".fixed_var")));

Define variable g_fvar1, g_fvar2,g_fvar3 belong to section ".fixed1", variable g_fixed1 belongs to

section“.fixed_var”.

Then, it is defined as follows in the scatter file:

RAM_IRAM_1 0X20000400 0x0000400{

*(.fixed_var);

}

RAM_IRAM_2 0X20000800 0x0000400{

*(.fixed1);

}

Variable in section “.fixed_var” is defined to the starting position of 0x20000400

Variable in section “.fixed1” is defined to the starting position of 0x20000800

21.1.5.3. Specify all variables in the file to a fixed location

In the source file header, define the section. Attribute as rwdata

#pragma arm section rwdata=".fixed_var"

#pragma arm section zidata=".fixed_var"

uint32_t g_fixed1;

uint32_t g_fixed2;

Then define it in scatter file as follows

RAM_IRAM_1 0X20000400 0x0000400{

*(.fixed_var);

}

Section “.fixed_var” is defined at the beginning of 0x20000400