The experiment uses the W5500 development board to send commands to the development board through the host computer to control the brightness of the external light strip; the main process is as follows: The host computer sends a string of the format "redbrightness, greenbrightness, bluebrightness" to the MCU through the serial port. The MCU converts the numbers to the corresponding brightness. The experiment is mainly divided into two parts: PWM configuration and serial communication configuration. The difficulty of the whole experiment is the process of converting ASCII code into numbers. The general-purpose timer can use the GPIO pin for pulse output. To make the STM32's general-purpose timer TIMx generate a PWM output, three registers are required. These are: capture/compare mode register (TIMx_CCMR1/2), capture/compare enable register (TIMx_CCER), and capture/compare registers (TIMx_CCR1~4). (Note that there is also a TIMx ARR register that is used to control the output frequency of pwm). For the capture/compare mode register (TIMx_CCMR1/2), there are a total of two registers, TIMx _CCMR1 and TIMx _CCMR2. TIMx_CCMR1 controls CH1 and 2, while TIMx_CCMR2 controls CH3 and 4. This is followed by the Capture/Compare Enable Register (TIMx_CCER), which controls the switching of each input and output channel. Finally, the capture/compare registers (TIMx_CCR1~4) have a total of four registers corresponding to four output channels CH1~4. The four registers function similarly to set the duty cycle of pwm. For example, if the configuration pulse counter TIMx_CNT is counted up, and the reload register TIMx_ARR is configured as N, that is, the current count value X of the TIMx_CNT is continuously accumulated under the driving of the TIMxCLK clock source, when the value X of the TIMx_CNT is greater than N, it will be heavy. Set the TIMx_CNT value to 0 to recount. While the TIMxCNT counts, the count value X of the TIMxCNT is compared with the value A pre-stored by the comparison register TIMx_CCR. When the value X of the pulse counter TIMx_CNT is smaller than the value A of the comparison register TIMx_CCR, the output is high (or low). Flat) Conversely, when the value X of the pulse counter is greater than or equal to the value A of the comparison register, a low level (or a high level) is output. In this cycle, the obtained output pulse period is the value (N+1) stored in the reload register TIMx_ARR multiplied by the clock period of the trigger pulse, and the pulse width is the value A of the comparison register TIMx_CCR multiplied by the clock period of the trigger pulse, that is, The duty cycle of the output PWM is A/(N+1). Void LED_Co nfig(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE);//Enable multiplexed clock GPIO_InitStructure.GPIO_Pin = LED_RED| LED_BLUE | LED_GREEN; GPIO_InitStructure.GPIO_Speed ​​= GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_SetBits(GPIOC, LED_RED | LED_BLUE | LED_GREEN); } Void TIMER_Co nfig(void) { TIM_Timeba seInitTypeDef TIM_ba seInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); GPIO_PinRemapCo nfig(GPIO_FullRemap_TIM3, ENABLE); TIM_ba seInitStructure.TIM_Period = 255; TIM_ba seInitStructure.TIM_Prescaler = 0; TIM_ba seInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_ba seInitStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_Timeba seInit(TIM3, &TIM_ba seInitStructure); TIM_ARRPreloadCo nfig(TIM3, ENABLE); TIM_Cmd(TIM3, ENABLE); } Void PWM_Co nfig(void) { TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCStructInit(&TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = 0; TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1; //Select mode 1 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low //The polarity is active high TIM_OC2Init(TIM3, &TIM_OCInitStructure); TIM_OC3Init(TIM3, &TIM_OCInitStructure); TIM_OC4Init(TIM3, &TIM_OCInitStructure); TIM_OC2PreloadCo nfig(TIM3, TIM_OCPreload_Enable); TIM_OC3PreloadCo nfig(TIM3, TIM_OCPreload_Enable); TIM_OC4PreloadCo nfig (TIM3, TIM_OCPreload_Enable); TIM_CtrlPWMOutputs(TIM3,ENABLE); } PWM mode 1: When counting up, channel 1 is inactive (T1REF = 0) once TIMx_CNTTIMx_CCR1, otherwise it is active (OC1REF = 1). PWM mode 2: When counting up, channel 1 is active once TIMx_CNTTIMx_CCR1, otherwise it is inactive. The valid comments for the simultaneous output are also related to the polarity configuration: TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; This configuration is high to an active level and vice versa. Void Usart_Co nfig(uint32_t BaudRate) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed ​​= GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = BaudRate; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowCo ntrol = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART_PC, &USART_InitStructure); USART_ITCo nfig (USART_PC, USART_IT_RXNE, ENABLE); //Open serial port receive interrupt USART_ITCo nfig (USART_PC, USART_IT_IDLE, ENABLE); //Open serial port receive interrupt USART_Cmd (USART_PC, ENABLE); } Void NVIC_Co nfiguration(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupCo nfig(NVIC_PriorityGroup_0); NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelPreemptio nPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } Void USART1_IRQHandler(void) { Uint8_t clear = clear; If(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { USART_ClearITPendingBit(USART1, USART_IT_RXNE); RxBuffer[RxCounter++] = USART_ReceiveData(USART1); } Else if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) { Clear = USART1->SR; Clear = USART1->DR; //Read SR first and then read DR, in order to clear IDLE interrupt RxNumber = RxCounter; RxCounter = 0; //count clear IDLE_Flag = 1; / / mark the receipt of a frame of data } } The STM32 microcontroller can receive byte data of indefinite length. Since the STM32 MCU has an IDLE interrupt, this interrupt can be used to receive data of indefinite long bytes. Since STM32 belongs to ARM microcontroller, the method of this article is also suitable for other ARM microcontrollers. IDLE is the interrupt that occurs after the serial port receives a frame of data. For example, to send a single byte to a single-chip microcomputer, or send 8 bytes at a time, these once sent data, called a frame of data, can also be called a packet of data. After the end of one frame of data, an IDLE interrupt will be generated. This interruption is very useful and can save a lot of trouble. While(RxBuffer[i] != ','){ i++; len++;}//If not ',' length plus 1 For(j=i-len; j Value = RxBuffer[j]&0 x0f; //convert the ascii code to a number Pwm_red += value * Power(len-1); Len--; } i++; Len = 0; While(RxBuffer[i] != ','){ i++; len++;} For(j=i-len; j Value = RxBuffer[j]&0 x0f; //convert the ascii code to a number Pwm_green += value * Power(len-1); Len--; } i++; Len = 0; While(RxBuffer[i] != '\0'){ i++; len++;} For(j=i-len; j Value = RxBuffer[j]&0 x0f; //convert the ascii code to a number Pwm_blue += value * Power(len-1); Len--; } RedOutput(pwm_red); GreenOutput(pwm_green); BlueOutput(pwm_blue); Pwm_red = 0; Pwm_green = 0; Pwm_blue = 0; For(i=0; i<11; i++) RxBuffer[i] = NULL;//Clear the array i = 0; Len = 0; } } } Uint8_t Power(uint8_t pow) { Uint8_t i; Uint8_t sum = 1; For(i=0; i Return sum; } Our company specializes in the production and sales of all kinds of terminals, copper terminals, nose wire ears, cold pressed terminals, copper joints, but also according to customer requirements for customization and production, our raw materials are produced and sold by ourselves, we have their own raw materials processing plant, high purity T2 copper, quality and quantity, come to me to order it! Copper Connecting Terminals,Cable Lugs Insulated Cord End Terminals,Pvc Insulated Cord End Terminal,Cable Connector Insulated Cord End Terminal Taixing Longyi Terminals Co.,Ltd. , https://www.longyiterminals.com 1 Experimental purpose
2 overall design of the experiment
3 PWM generation principle
4 PWM configuration steps
4.1 Configuring GPIO
4.2 Configuring Timers
4.3 Configuring PWM
4.4 Summary
5 UART configuration steps
5.1 Configuring UART1 and the corresponding GPIO
5.2 Configuration Interrupt
5.3 Interrupt function
5.4 Summary
6 ASCII code converted to numbers
6.1 Implementation steps:
6.2 10 n power function