W5500 adjusts the brightness of LED strip by PC control


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:

1 Experimental purpose

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.

2 overall design of the experiment

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.

3 PWM generation principle

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).

4 PWM configuration steps
4.1 Configuring GPIO

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);

}

4.2 Configuring Timers

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);

}

4.3 Configuring PWM

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);

}

4.4 Summary

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.

5 UART configuration steps
5.1 Configuring UART1 and the corresponding GPIO

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);

}

5.2 Configuration Interrupt

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);

}

5.3 Interrupt function

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

}

}

5.4 Summary

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.

6 ASCII code converted to numbers
6.1 Implementation steps:

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;

}

}

}

6.2 10 n power function

Uint8_t Power(uint8_t pow)

{

Uint8_t i;

Uint8_t sum = 1;

For(i=0; i

Return sum;

}

Copper Connecting Terminals

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