stm32-led-serial-port-PWM

Publisher:心怀梦想Latest update time:2019-04-09 Source: eefocusKeywords:stm32 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Because of the project needs, I learned about the GPIO, serial port, PWM, and interrupt parts of stm32. Here is a summary for us to learn together. All programs have been tested in practice and the output is correct.


Paste the configuration program of GPIO, serial port, PWM (timer) as follows


1. Enable the peripheral clock: APB1ENR, APB2ENR


2. Configuration register or control register. When configuring the stm32 peripheral, you must enable the clock of the peripheral at any time! And each control register is likely to include 1 mode register, 2 enable register, and 3 may be what we think of as data register or content register.


3. Enable peripherals. Even if configured, if you don't enable the peripherals, they will never work, which is easy to forget.


Register configuration, please see


http://wenku.baidu.com/link?url=NE4LMJFepztwPxYEb0n72SMNZLTruz32JsEJNPAtcV9AcS9OpA6CoLrJGllXzW5relKtY2c8MBKWURnBdYZG_sNj7yg_JFo7cpdut4k1mzS


Since many pins of stm32 are multiplexed, they must be set to multiplex when configuring registers. Remember that multiplexing is the default multiplexing function. For reference documents, please check


http://download.csdn.net/detail/bolvtin/8867933


1. Peripheral clock register


RCC_APB1ENR (APB1 peripheral clock enable register)


RCC_APB2ENR (APB2 peripheral clock enable register)


RCC_APB2RSTR (APB2 peripheral reset register)


RCC_APB1RSTR (APB1 peripheral reset register)


There is a corresponding relationship between the peripheral enable register and the peripheral reset register, and the corresponding position corresponds to the clock enable and reset of the corresponding peripheral.


Note the following peripherals


1. GPIO--GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG clocks are all in the RCC_APB2ENR register


2. Serial port--USART1 clock is in the RCC_APB2ENR register


3. Timer-TIM1, TIM8 clocks are in RCC_APB2ENR register


1. Serial port - USART2, USART3, USART4, USART5 clocks are all in the RCC_APB1ENR register


2. Timer-TIM2, TIM3, TIM4, TIM5, TIM6, TIM7 clocks are all in the RCC_APB1ENR register, TIM2-TIM5 can generate PWM 


   Pay attention to the source of the timer's internal clock signal


       When the clock division number of APB1 is set to 1, the clock of the general timer is the clock of APB1; when the clock division number of APB1 is set to 2, the clock of the general timer TIMx is twice that of APB1, that is, 72Mhz. The clock of advanced timer 1 and 8 comes from APB2, not APB1.


Procedure:


led.h

 

#ifndef __LED_H

#define __LED_H  

#include "sys.h"

//Mini STM32 development board

//LED driver code  

//Atom on point @ALIENTEK

//2010/5/27

 

//LED port definition

#define LED0 PAout(8) // PA8

#define LED1 PDout(2) // PD2

 

void LED_Init(void); //initialization     

#endif

 

 

led.c

 

#include

#include "led.h"

///////////////////////////////////////////////////// ////////////////////////////////////  

//This program is for learning purposes only and may not be used for any other purpose without the author's permission.

//Mini STM32 development board

//LED driver code    

//Atom on point @ALIENTEK

//Technical forum: www.openedv.com

//Modification date: 2010/5/27

//Version: V1.0

//All rights reserved. Piracy will be prosecuted.

//Copyright(C) Zhengdian Atom 2009-2019

//All rights reserved   

///////////////////////////////////////////////////// ////////////////////////////////////    

 

//Initialize PA8 and PD2 as output ports and enable the clocks of these two ports     

//LED IO initialization

 

/****************************************************** *******************************/

void LED_Init(void)

{

//The overall is 3 parts

//1. Enable the GPIO clock. Here, it is assumed that the 4 GPIO peripherals A, B, C, and D are enabled.

//2. Configure the register, whether it is input or output, the default definition, or the default multiplexing function

//3. Fill in the default data parameters. Here, the default output is high level.

RCC->APB2ENR|=1<<2; //Enable PORTA clock

RCC->APB2ENR|=1<<3; //Enable PORTB clock

RCC->APB2ENR|=1<<4; //Enable PORTC clock      

RCC->APB2ENR|=1<<5; //Enable PORTD clock

     

GPIOA->CRH&=0XFFFFFFF0; //Clear the original setting of PA8 without affecting the settings of other bits. PA8 is connected to DS0 light on mini stm32

GPIOA->CRH|=0X00000003; //PA8 push-pull output     

    GPIOA->ODR|=1<<8; //PA8 output high


GPIOC->CRH&=0XFFF00FFF; 

GPIOA->CRH|=0X00038000; //PC11 input PC12 output     

    GPIOA->ODR=1<<11; //PC11 pull-up

GPIOA->ODR|=1<<12; //PC.12 output high

 

  

GPIOD->CRL&=0XFFFFF0FF; //PD2 is connected to DS1 light on mini stm32

GPIOD->CRL|=0X00000300; //PD.2 push-pull output

GPIOD->ODR|=1<<2; //PD.2 output high 

}


timer.h

 

#ifndef __TIMER_H

#define __TIMER_H

#include "sys.h"

///////////////////////////////////////////////////// ////////////////////////////////////  

//This program is for learning purposes only and may not be used for any other purpose without the author's permission.

//Mini STM32 development board

//General timer driver code    

//Atom on point @ALIENTEK

//Technical forum: www.openedv.com

//Modification date: 2010/12/03

//Version: V1.0

//All rights reserved. Piracy will be prosecuted.

//Copyright(C) Zhengdian Atom 2009-2019

//All rights reserved

///////////////////////////////////////////////////// ////////////////////////////////////   

 

//Change the duty cycle by changing the value of TIM3->CCR2 to control the brightness of LED0

#define LED0_PWM_VAL TIM3->CCR2 

 

void Timerx_Init(u16 arr,u16 psc);

void PWM_Init(u16 arr,u16 psc);

#endif

 

 

usart.h

 

#ifndef __USART_H

#define __USART_H

#include

#include "stdio.h"  

///////////////////////////////////////////////////// ////////////////////////////////////  

//This program is for learning purposes only and may not be used for any other purpose without the author's permission.

//Mini STM32 development board

//Serial port 1 initialization    

//Atom on point @ALIENTEK

//Technical forum: www.openedv.com

//Modification date: 2010/5/27

//Version: V1.3

//All rights reserved. Piracy will be prosecuted.

//Copyright(C) Zhengdian Atom 2009-2019

//All rights reserved

//************************************************ *********************************

//V1.3 modification instructions 

//Support serial port baud rate settings at different frequencies.

//Added support for printf

//Added the serial port receiving command function.

//Fixed the bug that the first character of printf was lost

///////////////////////////////////////////////////// ////////////////////////////////////   

 

 

extern u8 USART_RX_BUF[64]; //Receive buffer, maximum 63 bytes. The last byte is a line break character 

extern u8 USART_RX_STA; //Receive status mark

 

 

extern char imgCenterX[5];

extern char imgCenterY[5];

 

extern int imgCenterX0,imgCenterX1;

extern int imgCenterY0,imgCenterY1;

 

//If you want the serial port to interrupt reception, please do not comment the following macro definition

#define EN_USART1_RX //Enable serial port 1 receiving

#define EN_USART2_RX //Enable serial port 2 receiving

#define EN_USART3_RX //Enable serial port 3 receiving

void uart_init(u32 pclk2,u32 bound);

 

#endif    

 

 

usart.c

 

#include "sys.h"

#include "usart.h"

///////////////////////////////////////////////////// ////////////////////////////////////  

//This program is for learning purposes only and may not be used for any other purpose without the author's permission.

//Mini STM32 development board

//Serial port 1 initialization    

//Atom on point @ALIENTEK

//Technical forum: www.openedv.com

//Modification date: 2010/5/27

//Version: V1.3

//All rights reserved. Piracy will be prosecuted.

//Copyright(C) Zhengdian Atom 2009-2019

//All rights reserved

//************************************************ *********************************

//V1.3 modification instructions 

//Support serial port baud rate settings at different frequencies.

//Added support for printf

//Added the serial port receiving command function.

//Fixed the bug that the first character of printf was lost

///////////////////////////////////////////////////// ////////////////////////////////////   

 

 

///////////////////////////////////////////////////// /////////////////

//Add the following code to support the printf function without selecting use MicroLIB   

#if 1

#pragma import(__use_no_semihosting)             

//Support functions required by the standard library                 

struct __FILE 

int handle; 

/* Whatever you require here. If the only file you are using is */ 

/* standard output using printf() for debugging, no file handling */ 

/* is required. */ 

}; 

/* FILE is typedef' d in stdio.h. */ 

FILE __stdout;       

// define _sys_exit() to avoid using semihost mode    

_sys_exit(int x) 

x = x; 

//Redefine fputc function, because this serial port is defined as PA9 and PA10 on minisTM32 and connected to the USB-to-serial port chip, it is convenient to communicate with the PC and debug through the serial port assistant, so it is not redefined to other serial port output

int fputc(int ch, FILE *f)

{      

while((USART1->SR&0X40)==0);//Send in a loop until the sending is completed   

USART1->DR = (u8)ch;      

return ch;

}

////Own redefinition of fputc function 

//We still define USART1 as the redefinition output serial port of the printf function, but use USART3 for Linux serial port input 

//int fputc(int ch, FILE *f)

//{      

// while((USART3->SR&0X40)==0); // Loop sending until the sending is completed   

// USART3->DR = (u8) ch;      

// return ch;

//}

#endif

 

//In stm32, the multiplexing function output of the serial port, i.e. GPIO, can be seen from the following link,

//http://download.csdn.net/detail/bolvtin/8867933

//PA9--USART1_TX output PA10--USART1_RX input

//PA2--USART2_TX output PA3--USART2_RX input  

//PB10--USART3_TX output; PB11--USART3_RX input

 

/****************************************************** *******************************/

//Here, serial port 1 is used to continuously receive serial port data from another PC B, and then continuously send data to PC A in the program (there is a serial port debugging assistant on it to observe the data)

//But I found that if serial port 1 keeps sending data while receiving data, a lot of data will be lost, resulting in program errors.

//Therefore, it is set to receive data from PC B from serial port 3 and send it from serial port 1 to PC A's serial debugging assistant to observe the data

 

//#ifdef EN_USART1_RX //If reception is enabled

////Serial port 1 interrupt service routine

////Note that reading USARTx->SR can avoid inexplicable errors   

//u8 USART_RX_BUF[64]; //Receive buffer, maximum 64 bytes.

////Receiving status

////bit7, receiving completion flag

////bit6, received 0x0d

////bit5~0, the number of valid bytes received

//u8 USART_RX_STA=0; //Receive status flag   

//

//char imgCenterX[5];

//char imgCenterY[5];

//

//int imgCenterX0=320,imgCenterX1; //The corresponding image is width*height=640*480

//int imgCenterY0=240,imgCenterY1;

//

//void USART1_IRQHandler(void)

//{

// u8 res;     

// if(USART1->SR&(1<<5))//Receive data

// {  

//res=USART1->DR; 

// if((USART_RX_STA&0x80)==0)//receiving is not completed

// {

// //if(USART_RX_STA&0x40) //Received 0x0d, set USART_RX_STA to 0100 0000

// if(USART_RX_STA&0x40) //Received the $US dollar symbol Wang Bo

// {

// //if(res!=0x0a)USART_RX_STA=0;//Receive error, restart

// if(res!=0x24)USART_RX_STA=0; //Receive error, restart

// else 

// {

//

// USART_RX_STA|=0x80; //Receiving completed

// imgCenterX[0]=USART_RX_BUF[14]; //15th byte

// imgCenterX[1]=USART_RX_BUF[15];

// imgCenterX[2]=USART_RX_BUF[16];

// imgCenterX[3]=USART_RX_BUF[17];

//

// imgCenterY[0]=USART_RX_BUF[36];

// imgCenterY[1]=USART_RX_BUF[37];

// imgCenterY[2]=USART_RX_BUF[38];

// imgCenterY[3]=USART_RX_BUF[39];

//

// imgCenterX1=atoi(imgCenterX);

// //printf("%dn",imgCenterX1);

//

// imgCenterY1=atoi(imgCenterY);

// //printf("%dn",imgCenterY1);

//

// }

// }else //Has not received 0X0D

// {

// //if(res==0x0d)USART_RX_STA|=0x40;

// if(res==0x24)USART_RX_STA|=0x40;

// else

// {

// USART_RX_BUF[USART_RX_STA&0X3F]=res;

// USART_RX_STA++;

// if(USART_RX_STA>63)USART_RX_STA=0; //Receive data error, restart receiving   

// }  

// }

// }       

// }  

//}

//#endif 

/****************************************************** *******************************/

//mini stm32 serial port 2

 

#ifdef EN_USART2_RX //If reception is enabled

//Serial port 1 interrupt service routine

//Note that reading USARTx->SR can avoid inexplicable errors   

u8 USART_RX_BUF[64]; //Receive buffer, maximum 64 bytes.

//Receive status

//bit7, receiving completion flag

//bit6, received 0x0d

//bit5~0, the number of valid bytes received

u8 USART_RX_STA=0; //Receive status mark   

 

char imgCenterX[5];

char imgCenterY[5];

 

int imgCenterX0=320,imgCenterX1=320; //The corresponding image is width*height=640*480

int imgCenterY0=240,imgCenterY1=240;

 

void USART2_IRQHandler(void)

{

u8 res;     

if(USART2->SR&(1<<5))//Receive data

{  

res=USART2->DR; 

if((USART_RX_STA&0x80)==0)//receiving is not completed

{

//if(USART_RX_STA&0x40) //Received 0x0d, set USART_RX_STA to 0100 0000

if(USART_RX_STA&0x40) //Received $dollar symbol tinbo

{

//if(res!=0x0a)USART_RX_STA=0;//Receive error, restart

if(res!=0x24)USART_RX_STA=0; //Receive error, restart

else 

{


USART_RX_STA|=0x80; //Receiving completed

imgCenterX[0]=USART_RX_BUF[14]; //15th byte

imgCenterX[1]=USART_RX_BUF[15];

imgCenterX[2]=USART_RX_BUF[16];

imgCenterX[3]=USART_RX_BUF[17];


imgCenterY[0]=USART_RX_BUF[36];

imgCenterY[1]=USART_RX_BUF[37];

imgCenterY[2]=USART_RX_BUF[38];

imgCenterY[3]=USART_RX_BUF[39];

 

imgCenterX1=atoi(imgCenterX);

//printf("%dn",imgCenterX1);

 

imgCenterY1=atoi(imgCenterY);

//printf("%dn",imgCenterY1);


}

}else //Has not received 0X0D

{

//if(res==0x0d)USART_RX_STA|=0x40;

if(res==0x24)USART_RX_STA|=0x40;

else

{

USART_RX_BUF[USART_RX_STA&0X3F]=res;

USART_RX_STA++;

if(USART_RX_STA>63)USART_RX_STA=0; //Receive data error, restart receiving   

}  

}

}       

}

else

{


}  

#endif

/****************************************************** *******************************/

//mini stm32 serial port 3

 

//#ifdef EN_USART3_RX //If reception is enabled

////Serial port 1 interrupt service routine

////Note that reading USARTx->SR can avoid inexplicable errors   

//u8 USART_RX_BUF[64]; //Receive buffer, maximum 64 bytes.

////Receiving status

////bit7, receiving completion flag

////bit6, received 0x0d

////bit5~0, the number of valid bytes received

//u8 USART_RX_STA=0; //Receive status flag   

//

//char imgCenterX[5];

//char imgCenterY[5];

//

//int imgCenterX0=320,imgCenterX1=320; //The corresponding image is width*height=640*480

//int imgCenterY0=240,imgCenterY1=240;

//

//void USART3_IRQHandler(void)

//{

// u8 res;     

// if(USART3->SR&(1<<5))//Receive data

// {  

//res=USART3->DR; 

// if((USART_RX_STA&0x80)==0)//receiving is not completed

// {

// //if(USART_RX_STA&0x40) //Received 0x0d, set USART_RX_STA to 0100 0000

// if(USART_RX_STA&0x40) //Received the $US dollar symbol Wang Bo

// {

// //if(res!=0x0a)USART_RX_STA=0;//Receive error, restart

// if(res!=0x24)USART_RX_STA=0; //Receive error, restart

// else 

// {

//

// USART_RX_STA|=0x80; //Receiving completed

// imgCenterX[0]=USART_RX_BUF[14]; //15th byte

// imgCenterX[1]=USART_RX_BUF[15];

// imgCenterX[2]=USART_RX_BUF[16];

// imgCenterX[3]=USART_RX_BUF[17];

//

// imgCenterY[0]=USART_RX_BUF[36];

// imgCenterY[1]=USART_RX_BUF[37];

// imgCenterY[2]=USART_RX_BUF[38];

// imgCenterY[3]=USART_RX_BUF[39];

//

// imgCenterX1=atoi(imgCenterX);

// //printf("%dn",imgCenterX1);

//

// imgCenterY1=atoi(imgCenterY);

// //printf("%dn",imgCenterY1);

//

// }

// }else //Has not received 0X0D

// {

// //if(res==0x0d)USART_RX_STA|=0x40;

// if(res==0x24)USART_RX_STA|=0x40;

// else

// {

// USART_RX_BUF[USART_RX_STA&0X3F]=res;

// USART_RX_STA++;

// if(USART_RX_STA>63)USART_RX_STA=0; //Receive data error, restart receiving   

// }  

// }

// }       

// }

// else

// {

//

// }  

//} 

//#endif

 

/****************************************************** *******************************/  

// Initialize IO serial port

//pclk2: PCLK2 clock frequency (Mhz)

//bound: baud rate

//CHECK OK

//091209

void uart_init(u32 pclk2,u32 bound)

{   

float temp;

u16 mantissa;

u16 fraction;

 

float temp2;

u16 mantissa2;

u16 fraction2;


float temp3;

u16 mantissa3;

u16 fraction3;

 

//The overall is 3 parts

//1. Enable the serial port 1 clock. However, because the GPIO port is used, the GPIO clock needs to be enabled. Here, it is assumed that the 4 GPIO peripherals A, B, C, and D are enabled, including the 3 steps of the GPIO port

//2. Configure registers, configure baud rate, stop bit, check bit, etc.

//3. Enable the serial port and enable the receive buffer non-empty interrupt

 

/****************************************************** *******************************/

//Initialization of serial port 1    

temp=(float)(pclk2*1000000)/(bound*16);//get USARTDIV

mantissa=temp; //get the integer part

fraction=(temp-mantissa)*16; //get the decimal part  

    mantissa<<=4;

mantissa+=fraction;

 

RCC->APB2ENR|=1<<2; //Enable PORTA clock  

RCC->APB2ENR|=1<<14; //Enable serial port 1 clock 

GPIOA->CRH&=0XFFFFF00F; 

GPIOA->CRH|=0X000008B0; //IO status setting

  

RCC->APB2RSTR|=1<<14; //Reset serial port 1

RCC->APB2RSTR&=~(1<<14);//stop reset        

//Baud rate setting

  USART1->BRR=mantissa; // baud rate setting  

USART1->CR1|=0X200C; //1-bit stop, no parity bit.

 

 

#ifdef EN_USART1_RX //If reception is enabled

// Enable receive interrupt

USART1->CR1|=1<<8; //PE interrupt enable

USART1->CR1|=1<<5; //Receive buffer not empty interrupt enable    

MY_NVIC_Init(3,3,USART1_IRQChannel,2); //Group 2, lowest priority 

#endif

/****************************************************** *******************************/

//Initialization of serial port 2

//PORTA port clock //Serial port 2 corresponds to Tx is PA2 RX is PA3

  temp2=(float)(pclk2/2*1000000)/(bound*16);//get USARTDIV

mantissa2=temp2; //get the integer part

fraction2=(temp2-mantissa2)*16; //get the decimal part  

    mantissa2<<=4;

mantissa2+=fraction2;


    RCC->APB2ENR|=1<<2; //Enable PORTA port clock //Serial port 2 corresponds to Tx PA2 RX PA3

RCC->APB1ENR|=1<<17; //Enable serial port 2 clock 

GPIOA->CRL&=0XFFFF00FF; //Set PC10 to output mode and PC11 to input mode

GPIOA->CRL|=0X00008B00; //IO status setting

  

RCC->APB1RSTR|=1<<17; //Reset serial port 3

RCC->APB1RSTR&=~(1<<17);//stop reset        

//Baud rate setting

  USART2->BRR=mantissa2; // baud rate setting The crystal oscillators used by serial ports 2-5 are all 36Mhz. Serial ports 2~5 use pclk1, which is 36M, instead of 72M of serial port 1.  

USART2->CR1|=0X200C; //1-bit stop, no parity bit.

 

#ifdef EN_USART2_RX //If reception is enabled

// Enable receive interrupt

USART2->CR1|=1<<8; //PE interrupt enable

USART2->CR1|=1<<5; //Receive buffer not empty interrupt enable    

MY_NVIC_Init(3,3,USART2_IRQChannel,1); //Group 1, lowest priority 

#endif

/****************************************************** *******************************/

//Initialization of serial port 3    

temp3=(float)(pclk2/2*1000000)/(bound*16); //Get USARTDIV

mantissa3=temp3; //get the integer part

fraction3=(temp3-mantissa3)*16; //get the decimal part  

    mantissa3<<=4;

mantissa3+=fraction3;


    RCC->APB1ENR|=1<<3; //Enable PORTC port clock //Serial port 3 corresponds to Tx PB10 RX PB11

RCC->APB1ENR|=1<<18; //Enable serial port 3 clock 

GPIOB->CRH&=0XFFFF00FF; //Set PB10 to output mode and PB11 to input mode

GPIOB->CRH|=0X00008B00; //IO status setting

  

RCC->APB1RSTR|=1<<18; //Reset serial port 3

RCC->APB1RSTR&=~(1<<18);//stop reset        

//Baud rate setting

  USART3->BRR=mantissa3; // baud rate setting The crystal oscillators used by serial ports 2-5 are all 36Mhz. Serial ports 2~5 use pclk1, which is 36M, instead of 72M of serial port 1.  

USART3->CR1|=0X200C; //1-bit stop, no parity bit.

 

#ifdef EN_USART3_RX //If reception is enabled

// Enable receive interrupt

USART3->CR1|=1<<8; //PE interrupt enable

USART3->CR1|=1<<5; //Receive buffer not empty interrupt enable    

MY_NVIC_Init(3,3,USART3_IRQChannel,1); //Group 1, lowest priority 

#endif

}

 

timer.h

#ifndef __TIMER_H

#define __TIMER_H

#include "sys.h"

///////////////////////////////////////////////////// ////////////////////////////////////  

//This program is for learning purposes only and may not be used for any other purpose without the author's permission.

//Mini STM32 development board

//General timer driver code    

//Atom on point @ALIENTEK

//Technical forum: www.openedv.com

//Modification date: 2010/12/03

//Version: V1.0

//All rights reserved. Piracy will be prosecuted.

//Copyright(C) Zhengdian Atom 2009-2019

//All rights reserved

///////////////////////////////////////////////////// ////////////////////////////////////   

 

//Change the duty cycle by changing the value of TIM3->CCR2 to control the brightness of LED0

#define LED0_PWM_VAL TIM3->CCR2 

 

void Timerx_Init(u16 arr,u16 psc);

void PWM_Init(u16 arr,u16 psc);

#endif


timer.c

 

#include "timer.h"

#include "led.h"

///////////////////////////////////////////////////// ////////////////////////////////////  

//This program is for learning purposes only and may not be used for any other purpose without the author's permission.

//Mini STM32 development board

//General timer driver code    

//Atom on point @ALIENTEK

//Technical forum: www.openedv.com

//Modification date: 2010/12/03

//Version: V1.0

//All rights reserved. Piracy will be prosecuted.

//Copyright(C) Zhengdian Atom 2009-2019

//All rights reserved

///////////////////////////////////////////////////// ////////////////////////////////////   

 

//Timer 3 interrupt service routine  

void TIM3_IRQHandler(void)

{           

if(TIM3->SR&0X0001)//overflow interrupt

{

LED1=!LED1;                  

}    

TIM3->SR&=~(1<<0); //Clear interrupt flag     

}

//General timer interrupt initialization

//The clock here is selected to be twice that of APB1, and APB1 is 36M

//arr: automatically reload value.

//psc: clock pre-division number

//Timer 3 is used here!

void Timerx_Init(u16 arr,u16 psc)

{

RCC->APB1ENR|=1<<1; //TIM3 clock enable    

  TIM3->ARR=arr; //Set the counter to automatically reload the value //Exactly 1ms    

TIM3->PSC=psc; //Prescaler 7200, get 10Khz counting clock

//These two things must be set at the same time to use the interrupt

TIM3->DIER|=1<<0; //Enable update interrupt

TIM3->DIER|=1<<6; //Enable trigger interrupt

      

TIM3->CR1|=0x01; //Enable timer 3

  MY_NVIC_Init(1,3,TIM3_IRQChannel,2); //Preempt 1, subpriority 3, group 2  

}

 

//TIM3 PWM part

//Atom on point @ALIENTEK

//2010/6/2  

 

//PWM output initialization

//arr: automatically reload value

//psc: clock pre-division number

void PWM_Init(u16 arr,u16 psc)

{

/****************************************************** *******************************/

//The overall is 3 parts

//1. Enable the timer clock, because PWM is generated by the timer.

// Actually, the GPIOA pin is used here, so the GPIOA clock also needs to be enabled, but it has been set in the led.c file, so it is omitted here

// In addition, the GPIO output PWM used here is multiplexed, so you need to configure the default multiplexing function of the GPIO port. Please note that it must be the default multiplexing function. You can check the 3 steps in led.c

//2. Configure the timer configuration. After TIM3-> structure, it is the configuration of timer 3.

//3. Enable the timer peripheral, TIM3->CR1|=0x01; 

 

//This part requires manual modification of IO port settings

RCC->APB1ENR|=1<<1; //TIM3 clock enable

    

//The following two sentences are just for connecting PA7 and PA8 with jumper caps and using LED lights to observe PWM output.

GPIOA->CRH&=0XFFFFFFF0; //PA8 output

GPIOA->CRH|=0X00000004; //Floating input The floating input here is to prevent interference with the output of PA8, because PA8 is connected to the LED light on minisTM32

 

GPIOA->CRL&=0X0FFFFFFF; //PA7 output

GPIOA->CRL|=0XB0000000; //Multiplexing function output   

GPIOA->ODR|=1<<7; //PA7 pull-up

 

TIM3->ARR=arr; //Set the counter to automatically reload value 

TIM3->PSC=psc; //Prescaler does not divide


//TIM3->CCMR1|=7<<12; //CH2 PWM2 mode This acts on the light DS0 on the board

TIM3->CCMR1|=6<<12; //CH2 PWM2 mode The polarity is opposite to the above sentence. If you use this to control the servo, please use this PWM to output a positive level square wave  

TIM3->CCMR1|=1<<11; //CH2 preload enable    

 

TIM3->CCER|=1<<4; //OC2 output enable    

 

TIM3->CR1=0x8000; //ARPE enable 

TIM3->CR1|=0x01; //Enable timer 3 


/****************************************************** *******************************/

//General purpose timer 4 1 channel (PB6) and 2 channel (PB7)

 

RCC->APB1ENR|=1<<2; //TIM4 clock enable    

RCC->APB2ENR|=1<<3; //This GPIO port must be enabled. GPIOA has been defined in led.c, but GPIO port B has not yet been defined.

  

GPIOB->CRL&=0X00FFFFFF; //Clear the original settings of PB7 and PB6 without affecting the settings of other bits

GPIOB->CRL|=0XBB000000; //Multiplexing function output The default multiplexing function of PB7 is 2 channels of TIM4

GPIOB->ODR|=1<<7;//PB7

GPIOB->ODR|=1<<6;//PB6

 

TIM4->ARR=arr; //Set the counter to automatically reload value 

TIM4->PSC=psc; //Prescaler does not divide

 

//Here is an explanation, CCMR1 register is in configuration mode, a total of 7 modes can be set, CCMR1 controls CH1 and CH2 CCMR2 controls CH3 and CH4

//TIM4->CCMR1|=7<<12; //

TIM4->CCMR1|=6<<12; //The default multiplexing function of PB7 is TIM4's 2-channel CH2 PWM2 mode and the polarity is a positive level square wave

TIM4->CCMR1|=6<<4; //CH1 PWM2 mode


TIM4->CCMR1|=1<<11; //CH2 preload enable

TIM4->CCMR1|=1<<3; //ch1 preload enable is PB6 port  


TIM4->CCER|=1<<0; //Output enable This register controls the switch of each input and output channel, so if there is output, it must be enabled

TIM4->CCER|=1<<4; //output enable

   

TIM4->CR1=0x8000; //ARPE enable 

TIM4->CR1|=0x01; //Enable timer 4    

}   


Keywords:stm32 Reference address:stm32-led-serial-port-PWM

Previous article:STM32 dynamically changes PWM wave frequency and duty cycle
Next article:STM32 uses PWM to control multiple servos

Recommended ReadingLatest update time:2024-11-15 17:03

Tips for selecting chips for LED driver power design
  LED light source technology is becoming more mature, and the luminous lumens per watt are increasing rapidly, which has led to a gradual price reduction. The massive market of LED green lamps and the steady growth in demand for several years will be the super tsunami of the consumer electronics market after VCD, DVD
[Power Management]
Simple LED oscilloscope circuit sharing
This article describes a simple LED oscilloscope circuit that can be used to analyze low-frequency waveforms with a 10 x 10 LED matrix display. Since there are only 100 LEDs involved in the display board and the resolution is low, the waveform display clarity is not that impressive. However, this LED oscilloscope circ
[Test Measurement]
Simple LED oscilloscope circuit sharing
TQ210_Bare Metal Programming (II)——Button Control LED Light
First, we can find the circuit diagram of the button in the supporting materials of the development board, E: TQ210_CD development board supporting circuit diagram Bottom pdf format TQ210_BOARD_V4_20121023. You can see that the address lines corresponding to keys key1~key6 are XEINT0~XEINT5. We will only use the fir
[Microcontroller]
TQ210_Bare Metal Programming (II)——Button Control LED Light
How to define variables in flash in stm32
Purpose: Define variables in flash Actually, writing this is just a record. Suddenly, I was working on the font display problem. I thought that if the font data is put in the memory, it will inevitably cause problems. It is better to put it in the flash so that it does not need to be changed. int a; a in memory cons
[Microcontroller]
Solution to the problem that the STM32 I/O port cannot output high and low levels normally
The I/O port cannot output normally because the port is reused. In addition to checking whether there is a program to reuse the port in the program, you should also pay attention to the following: some ports are reused by default when the microcontroller is powered on, such as the PA13, PA14, PA15, PB3, and PB4 pins r
[Microcontroller]
Solution to the problem that the STM32 I/O port cannot output high and low levels normally
How to use PTC thermistors to protect LED lighting equipment from overheating?
As the performance of LED lighting equipment (light emitting diodes) continues to improve and prices become cheaper, its market is expanding rapidly. LED lighting equipment has achieved low prices, but compared with traditional incandescent lamps and fluorescent lamps, its performance as a lighting equipment is still
[Power Management]
How to use PTC thermistors to protect LED lighting equipment from overheating?
Zhongjing Electronics: HDI products have a high market share in the fields of small-pitch LED/MiniLED, etc.
Recently, Zhongjing Electronics disclosed research activity information showing that the company's current HDI products are mainly 2-level and above, and 3-level and above HDI (including AnyLayer) have been mass-produced. Since 2019, the company's HDI products have been in short supply for a long time, among which HDI
[Mobile phone portable]
Noise Countermeasures for LED Bulbs Using High Voltage Ceramic Capacitors
Recently, in addition to the previous requirements for small and thin, energy-saving, and low noise, electronic equipment is expected to meet ecological needs from the perspective of preventing global warming. Under such market demand, LED bulbs, which have been popular since 2009, have achieved high ecological perfor
[Power Management]
Noise Countermeasures for LED Bulbs Using High Voltage Ceramic Capacitors
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号