STM32F103C8 chip water lamp

1, Introduction to STM32F103C8T6

STM32F103C8T6 is a 32-bit microcontroller based on Cortex-M3 core launched by St. the hardware is packaged with LQFP48 and belongs to STM32 series of microcontrollers of ST company. All the information can be downloaded from the wildfire official website Wildfire data download center

2, Light up

To turn on the LED, you need to use the GPIO port.

In order to turn on the LED, three steps are required:

  • Open the clock of GPIO port
  • Initialize GPIO port (select push-pull output)
  • Set low level

(1) Turn on the clock

  • Address of GPIO:
  • Clock address:

    -

    That is 0x40021018, to open the clock of three IO ports, you need to set all three bits to 1:
#define RCC_APB2ENR (*(unsigned int *)0x40021018)

// Turn on the clock
RCC_APB2ENR |= (1<<3);  // Turn on GPIOB clock
RCC_APB2ENR |= (1<<4);  // Turn on GPIOC clock
RCC_APB2ENR |= (1<<2);  // Turn on GPIOA clock

(2) Initialization

The GPIO port has eight modes:

  • Input float
  • Input pull-up
  • Input drop-down
  • Analog input
  • Open drain output
  • push-pull outputs
  • Push pull multiplexing function
  • Open drain multiplexing function

Push pull output is used here

Ports 1-7 are low and ports 8-15 are high. Each pin is controlled by four bits.
Take GPIOB and pin 0 (B0) as an example, set it as push-pull output, and set the maximum speed to 10MHz, then set the four bits of control B0 to 0001:

#define GPIOB_CRL (*(unsigned int *)0x40010c00)

// The last four digits change to 0001
GPIOB_CRL |= (1<<0);  // The last bit changes to 1
GPIOB_CRL &= ~(0xE<<0);  // The reciprocal 2, 3 and 4 bits change to 0

For B0 of GPIOB, C15 of GPIOC and A0 of GPIOA, the settings are as follows:

#define GPIOB_CRL (*(unsigned int *)0x40010C00)
#define GPIOC_CRH (*(unsigned int *)0x40011004)
#define GPIOA_CRL (*(unsigned int *)0x40010800)

// Configure GPIO port as push free output
// GPIOB --- the last four digits are 0001
GPIOB_CRL |= (1<<0);  // The last bit changes to 1
GPIOB_CRL &= ~(0xE<<0);  // The reciprocal 2, 3 and 4 bits change to 0
// GPIOC --- the first four digits are 0001
GPIOC_CRH |= (1<<28);  //  The fourth bit changes to 1
GPIOC_CRH &= ~(0xE0000000);  // The first three digits change to 0
// GPIOA --- the last four digits are 0001
GPIOA_CRL |= (1<<0);  // The last bit changes to 1
GPIOA_CRL &= ~(0xE<<0);  // The reciprocal 2, 3 and 4 bits change to 0

(3) Set low level


The output high level is 1 and the low level is 0

Take GPIOB and pin 0 (B0) as an example, set them to low level

#define GPIOB_ODR (*(unsigned int *)0x40010C0C)
GPIOB_ODR &= ~(1<<0);  // The last bit becomes 0

For B0 of GPIOB, C15 of GPIOC and A0 of GPIOA, the settings are as follows:

#define GPIOB_ODR (*(unsigned int *)0x40010C0C)
#define GPIOC_ODR (*(unsigned int *)0x4001100C)
#define GPIOA_ODR (*(unsigned int *)0x4001080C)

GPIOB_ODR &= ~(1<<0);  //The last bit becomes 0
GPIOC_ODR &= ~(1<<15); //The last 16 bits become 0
GPIOA_ODR &= ~(1<<0);  //The last digit becomes

3, keil create project

1. Create a new uVision project

2. Select an appropriate location to name and save

3. The chip selects STM32F103C8 under STM32F103


4. Copy and paste the startup_stm32f10x_md.s file into the directory of the project file just created, which is generally located in the directory of yehuo [STM32F103C8T6 - core board] data / 3-USART1 receiving and sending / Libraries/CMSIS/startup /


5. Introduce startup_stm32f10x_md.s


6. Create a new main.c file

7.main.c code

#define GPIOB_BASE 0x40010C00
#define GPIOC_BASE 0x40011000
#define GPIOA_BASE 0x40010800

#define RCC_APB2ENR (*(unsigned int *)0x40021018)

#define GPIOB_CRL (*(unsigned int *)0x40010C00)
#define GPIOC_CRH (*(unsigned int *)0x40011004)
#define GPIOA_CRL (*(unsigned int *)0x40010800)

#define GPIOB_ODR (*(unsigned int *)0x40010C0C)
#define GPIOC_ODR (*(unsigned int *)0x4001100C)
#define GPIOA_ODR (*(unsigned int *)0x4001080C)
	


void SystemInit(void);
void Delay_ms(volatile  unsigned  int);

void Delay_ms( volatile  unsigned  int  t)
{
     unsigned  int  i;
     while(t--)
         for (i=0;i<800;i++);
}


int main(){
	// ????
	RCC_APB2ENR |= (1<<3); // ?? GPIOB ??
	RCC_APB2ENR |= (1<<4); // ?? GPIOC ??
	RCC_APB2ENR |= (1<<2); // ?? GPIOA ??
	
	
	// ?? GPIO ?????
	// ?? GPIOB ????? 0001 (B0)
	GPIOB_CRL |= (1<<0);  // ???????1
	GPIOB_CRL &= ~(0xE);  // ???????????0
	// ?? GPIOC ???? 0001  (C15)
	GPIOC_CRH |= (1<<28); // ??????1
	GPIOC_CRH &= ~(0xE0000000);  // ??????0
	// ?? GPIOA ????? 0001 (A0)
	GPIOA_CRL |= (1<<0);  // ???????1
	GPIOA_CRL &= ~(0xE);  // ???????????0

	
	// 3?LED??????(????)
	GPIOB_ODR |= (1<<0);  // ???????1
	GPIOC_ODR |= (1<<15); // ???15????1
	GPIOA_ODR |= (1<<0);  // ???????1
	
	
	while(1){
		GPIOB_ODR &= ~(1<<0); // ??1
		Delay_ms(1000000);
		GPIOB_ODR |= (1<<0);  // ??1
		Delay_ms(1000000);
		
		GPIOC_ODR &= ~(1<<15); // ??2
		Delay_ms(1000000);
		GPIOC_ODR |= (1<<15);  // ??2
		Delay_ms(1000000);
		
		GPIOA_ODR &= ~(1<<0); // ??3
		Delay_ms(1000000);
		GPIOA_ODR |= (1<<0);  // ??3
		Delay_ms(1000000);
		
	}
	
}


void SystemInit(){
	
}

4, Connecting circuit

For USB to TTL module and stm32f103c8t6 connection

GND — GND
3v3 — 3v3
TXD — A10
RXD — A9


5, Compiling and burning code

(1) Compile

1. Select Create hex file

2.bulid generates. hex files

3. Generate Object/test4.hex successfully (test5 is changed to test4 because the project has been rebuilt)

(2) Preparation for burning

1. Download CH341SerSetup.exe, install it with administrator privileges, and load the USB serial port driver

2. Download one of FlyMcu.exe or mcuisp.exe to facilitate burning

(3) Burning program

Burn with FlyMcu


(4) Results

6, Assembler implementation

RCC_APB2ENR EQU 0x40021018;to configure RCC register,Clock,0x40021018 Is the clock address

GPIOB_BASE EQU 0x40010C00
GPIOC_BASE EQU 0x40011000
GPIOA_BASE EQU 0x40010800
	
GPIOB_CRL EQU 0x40010C00
GPIOC_CRH EQU 0x40011004
GPIOA_CRL EQU 0x40010800
	
GPIOB_ODR EQU 0x40010C0C
GPIOC_ODR EQU 0x4001100C
GPIOA_ODR EQU 0x4001080C

Stack_Size EQU  0x00000400;Stack size
	
                AREA    STACK, NOINIT, READWRITE, ALIGN=3 ;NOINIT:  = NO Init,Not initialized. READWRITE : Readable and writable. ALIGN =3 : 2^3 Alignment, i.e. 8-byte alignment.
Stack_Mem       SPACE   Stack_Size
__initial_sp




                AREA    RESET, DATA, READONLY

__Vectors       DCD     __initial_sp               ; Top of Stack
                DCD     Reset_Handler              ; Reset Handler
                    
                    
                AREA    |.text|, CODE, READONLY
                    
                THUMB
                REQUIRE8
                PRESERVE8
                    
                ENTRY
Reset_Handler 
				bl LED_Init;bl: A linked jump instruction. When using this instruction to jump, the current address(PC)It will be sent automatically LR register
MainLoop        BL LED_ON_C
                BL Delay
                BL LED_OFF_C
                BL Delay
				BL LED_ON_A
                BL Delay
                BL LED_OFF_A
                BL Delay
				BL LED_ON_B
                BL Delay
                BL LED_OFF_B
                BL Delay
                
                B MainLoop;B:Unconditional jump.
LED_Init;LED initialization
                PUSH {R0,R1, LR};R0,R1,LR Put the values in the stack
                ;Control clock
                LDR R0,=RCC_APB2ENR;LDR Is to load the address into the register(such as R0). 
                ORR R0,R0,#0x1c
                LDR R1,=RCC_APB2ENR
                STR R0,[R1]
				
				
                ;initialization GPIOA_CRL
                LDR R0,=GPIOA_CRL
                BIC R0,R0,#0x0fffffff;BIC reverses the immediate number first, and then compares it by bit
                LDR R1,=GPIOA_CRL
                STR R0,[R1]
				
                LDR R0,=GPIOA_CRL
                ORR R0,#0x00000001
                LDR R1,=GPIOA_CRL
                STR R0,[R1]
                ;take PA0 Set 1
                MOV R0,#0x01
                LDR R1,=GPIOA_ORD
                STR R0,[R1]
				
				
                ;initialization GPIOB_CRL
                LDR R0,=GPIOB_CRL
                BIC R0,R0,#0x0fffffff;BIC reverses the immediate number first, and then compares it by bit
                LDR R1,=GPIOB_CRL
                STR R0,[R1]
				
                LDR R0,=GPIOB_CRL
                ORR R0,#0x00000001
                LDR R1,=GPIOB_CRL
                STR R0,[R1]
                ;take PB0 Set 1
                MOV R0,#0x01
                LDR R1,=GPIOA_ORD
                STR R0,[R1]
				
				
				 ;initialization GPIOC
                LDR R0,=GPIOC_CRH
                BIC R0,R0,#0x0fffffff
                LDR R1,=GPIOC_CRH
                STR R0,[R1]
				
                LDR R0,=GPIOC_CRH
                ORR R0,#0x01000000
                LDR R1,=GPIOC_CRH
                STR R0,[R1]
                ;take PC15 Set 1
                MOV R0,#0x8000
                LDR R1,=GPIOC_ORD
                STR R0,[R1]
             
                POP {R0,R1,PC};Store the previously stored in the stack R0,R1,LR Value returned to R0,R1,PC
LED_ON_A
                PUSH {R0,R1, LR}    
                
                MOV R0,#0x00
                LDR R1,=GPIOA_ORD 
                STR R0,[R1]
             
                POP {R0,R1,PC}
             
LED_OFF_A
                PUSH {R0,R1, LR}    
                
                MOV R0,#0x01
                LDR R1,=GPIOA_ORD 
                STR R0,[R1]
             
                POP {R0,R1,PC}  
LED_ON_B;Light up
                PUSH {R0,R1, LR}    
                
                MOV R0,#0x00
                LDR R1,=GPIOB_ORD
                STR R0,[R1]
             
                POP {R0,R1,PC}
             
LED_OFF_B;Turn off the light
                PUSH {R0,R1, LR}    
                
                MOV R0,#0x01
                LDR R1,=GPIOB_ORD
                STR R0,[R1]
             
                POP {R0,R1,PC}  
LED_ON_C;Light up
                PUSH {R0,R1, LR}    
                
                MOV R0,#0x00
                LDR R1,=GPIOC_ORD
                STR R0,[R1]
             
                POP {R0,R1,PC}
             
LED_OFF_C;Turn off the light
                PUSH {R0,R1, LR}    
                
                MOV R0,#0x0100
                LDR R1,=GPIOC_ORD
                STR R0,[R1]
             
                POP {R0,R1,PC}             
             
Delay
                PUSH {R0,R1, LR}
                
                MOVS R0,#0
                MOVS R1,#0
                MOVS R2,#0
                
DelayLoop0        
                ADDS R0,R0,#1

                CMP R0,#330
                BCC DelayLoop0
                
                MOVS R0,#0
                ADDS R1,R1,#1
                CMP R1,#330
                BCC DelayLoop0

                MOVS R0,#0
                MOVS R1,#0
                ADDS R2,R2,#1
                CMP R2,#15
                BCC DelayLoop0
                
                
                POP {R0,R1,PC}    
                NOP
				END


7, Summary

The running water lamp experiment of stm32 chip takes into account the practical ability and other aspects. The code burning fails and the serial port cannot be opened. It may be that there is no download driver, the USB driver fails, or the circuit problem. This experiment has a certain understanding of the input and output, working principle and register address of each serial port of stm32 chip. If the personal mastery is not deep enough, there will be failure in all links There is no end to learning. Through continuous learning, we will better understand these contents and find appropriate methods.

8, References

STM32F103C8 chip water lamp

Tags: IoT stm32

Posted on Tue, 19 Oct 2021 00:38:29 -0400 by cristiano