One of AMR learning notes

STM32F103 minimum system intelligent control (register Implementation)

1, Hardware preparation

1. Preparation before learning: the whole project is developed in C language, so it needs to have a good foundation of C language. Here I will briefly explain that in C language, the three points of general linked list, function pointer and file classification will be much easier in the development process.
2. Hardware preparation: purchase stm32f103ze Learning version online, with resistive screen (capacitive screen is expensive and has no money), code burner (jlink), voice decoding module, SD card, DHT11 and MP3 player module. The hardware connection diagram is as follows

3. Software preparation: keil 4

2, Realize function

1. Functions: clock, snake, music player, dynamic display of temperature and humidity, Notepad, LED light control (the above controls can only be realized by voice control)

Key code analysis

1. Clock: the smallest unit of the chip is the register. How to realize the timer is how to realize the clock. For the display of time, you only need to calculate a timer and then display the number. Here is the RTC clock

void TimeCount_Install(u8 Time_nu,int Count_time,Tm_pHandle PHandle)
{
 switch(Time_nu)
 {
  case TIM2_IRQn:
  case TIM3_IRQn:
  case TIM4_IRQn:
   RCC->APB1ENR |= (1<<(Time_nu-28));
   RCC->CFGR &= ~(7<<8);  //empty
   RCC->CFGR |= (4<<8);   //2 frequency division
   switch(Time_nu)
   {
    case TIM2_IRQn:
     TIM2->ARR = (Count_time-1);  //Determine the value of the reload register 72mhz = 7200 * 10000, and the 1s counter generates an interrupt
     TIM2->PSC = (7200-1);   //Configure prescaler (TIMx_PSC)
     TIM2->DIER |= (1<<0);   //Allow new interrupts
     break;
    case TIM3_IRQn:
     TIM3->ARR = (Count_time-1);  //Determine the value of the reload register 72MHz=7200*10000,1s to generate an interrupt
     TIM3->PSC = (7200-1);   //Configure prescaler (TIMx_PSC)
     TIM3->DIER |= (1<<0);   //Allow new interrupts
     break;
    case TIM4_IRQn:
     TIM4->ARR = (Count_time-1);    
     TIM4->PSC = (7200-1);   
     TIM4->DIER |= (1<<0);   
     break;
   }
   break;
  case TIM5_IRQn:
   RCC->APB1ENR |= (1<<3);
   RCC->CFGR &= ~(7<<8);  
   RCC->CFGR |= (4<<8);   
   TIM5->ARR = (Count_time-1);  
   TIM5->PSC = (7200-1);   
   TIM5->DIER |= (1<<0);   
   break;
 }
 IRQ_Install(Time_nu,PHandle);
 TimeCount_ON(Time_nu);                             //Counter on, hard timer
}

It should be noted that hard timer and soft timer. Generally speaking, we need to use many timers when developing. However, for M3 series chips, the conditions are limited. Therefore, we call the original timer as hard timer. The so-called soft timer is to count again in the hard timer. Assuming that the hard timer is 1 second, when the technology is in it, Then we can get a 10 second soft timer, but here, for accuracy, the general hard timer is in the order of milliseconds and microseconds. (personal understanding)
2. Interrupt encapsulation:
There are 60 external interrupts in total, and each interrupt has an interrupt action function. Therefore, when using interrupts, we can customize them in the corresponding interrupt function (similar to callback). However, this is a little troublesome. We can define all interrupt action functions as one in the startup code, as follows:
How do we know which interrupt is generated? We can traverse the interrupt number through the NVIC register to find the corresponding interrupt signal. The specific code is as follows:

void IRQ_Desacth()
{
 int i,IRQ_NU;
 //Loop through 60 interrupts and find the action interrupt number
 for(i=0;i<60;i++)
 {
  if(i<I2C1_ER_IRQn)
  {
   if((NVIC->IABR[0]>>i)& 1)
   {
    IRQ_NU=i;
    break;
   }
  }
  else if(i>=32)
  {
   if((NVIC->IABR[1]>>(i-I2C1_ER_IRQn))& 1)
   {
    IRQ_NU=i;
    break;
   }
  } 
 }
 switch(IRQ_NU)
 {
  case EXTI0_IRQn: 
  case EXTI2_IRQn: 
  case EXTI3_IRQn:   
  case EXTI4_IRQn:
   //?ж????
   IRQ_Events[IRQ_NU].irqpHandle();
   //After the interrupt, reset 1
   EXTI->PR |= (1<<(IRQ_NU-6));   //Reset 1 
   NVIC->ICPR[0] |= (1<<IRQ_NU);   //Interrupt uncoupling
   break;
  case TIM2_IRQn:
   IRQ_Events[IRQ_NU].irqpHandle();
   TIM2->SR &= ~(1<<0);        //After the interrupt, follow the new interrupt flag
   NVIC->ICPR[0] |= (1<<IRQ_NU);  //Interrupt uncoupling
   break;
  case TIM3_IRQn:
   IRQ_Events[IRQ_NU].irqpHandle();
   TIM3->SR &= ~(1<<0);        
   NVIC->ICPR[0] |= (1<<IRQ_NU);  
   break;
  case TIM4_IRQn:
   IRQ_Events[IRQ_NU].irqpHandle();
   TIM4->SR &= ~(1<<0);        
   NVIC->ICPR[0] |= (1<<IRQ_NU);  
   break;
  case TIM5_IRQn:
   IRQ_Events[IRQ_NU].irqpHandle();
   TIM5->SR &= ~(1<<0);        
   NVIC->ICPR[1] |= (1<<(IRQ_NU-32));  
   break;
  case USART1_IRQn:
   // USART1->SR &= ~(1<<9);
   IRQ_Events[IRQ_NU].irqpHandle();
   NVIC->ICPR[1] |= (1<<(IRQ_NU-32));  
   break;
  case RTC_IRQn:
   RTC->CRL &= ~(1<<0);    
   IRQ_Events[IRQ_NU].irqpHandle();
   NVIC->ICPR[1] |= (1<<IRQ_NU);  
   break;
  case ADC1_IRQn:
   ADC1->SR  &= ~(1<<0);    
   IRQ_Events[IRQ_NU].irqpHandle();
   NVIC->ICPR[1] |= (1<<IRQ_NU);  
   break;
 }
}

Note: not every interrupt needs to be disconnected and set to 1. This needs to see the user manual and the corresponding interrupt explanation. Here, I encapsulate the interrupt time, which is the function pointer and IRQ mentioned earlier_ Events[IRQ_NU]. irqpHandle(); What needs to be done after the interruption. Encapsulates a structure.

3, Harvest and significance

1. Harvest and significance: Generally speaking, the current ARM development is to call library functions. Many times, we don't know how its process is. It's also muddled to use. Register implementation is to learn from the bottom completely. Although it's very troublesome, we still need to look at the flow chart and configure which registers. However, after learning this, we will know more about using library functions, In fact, the internal is implemented in this way. Therefore, it is necessary to learn this, so you can encapsulate it yourself.

Source download

1. Download address: Baidu network disk: extraction code: w0rs

Tags: stm32

Posted by ir4z0r on Mon, 23 May 2022 16:13:15 +0300