sh32f9001 series user guide
TRANSCRIPT
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
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;
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)
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.
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