void RST_CLK_PCLKcmd(uint32_t RST_CLK_PCLK, FunctionalState NewState);
The function has two parameters: #ifdef USE_MDR1986VE9x /* For cortex M3 */ #define RST_CLK_PCLK_CAN1 PCLK_BIT(MDR_CAN1_BASE) #define RST_CLK_PCLK_CAN2 PCLK_BIT(MDR_CAN2_BASE) #define RST_CLK_PCLK_USB PCLK_BIT(MDR_USB_BASE) #define RST_CLK_PCLK_EEPROM PCLK_BIT(MDR_EEPROM_BASE) #define RST_CLK_PCLK_RST_CLK PCLK_BIT(MDR_RST_CLK_BASE) #define RST_CLK_PCLK_DMA PCLK_BIT(MDR_DMA_BASE) #define RST_CLK_PCLK_UART1 PCLK_BIT(MDR_UART1_BASE) #define RST_CLK_PCLK_UART2 PCLK_BIT(MDR_UART2_BASE) #define RST_CLK_PCLK_SSP1 PCLK_BIT(MDR_SSP1_BASE) #define RST_CLK_PCLK_09 PCLK_BIT(0x40048000) #define RST_CLK_PCLK_I2C PCLK_BIT(MDR_I2C_BASE) #define RST_CLK_PCLK_POWER PCLK_BIT(MDR_POWER_BASE) #define RST_CLK_PCLK_WWDG PCLK_BIT(MDR_WWDG_BASE) #define RST_CLK_PCLK_IWDG PCLK_BIT(MDR_IWDG_BASE) #define RST_CLK_PCLK_TIMER1 PCLK_BIT(MDR_TIMER1_BASE) #define RST_CLK_PCLK_TIMER2 PCLK_BIT(MDR_TIMER2_BASE) #define RST_CLK_PCLK_TIMER3 PCLK_BIT(MDR_TIMER3_BASE) #define RST_CLK_PCLK_ADC PCLK_BIT(MDR_ADC_BASE) #define RST_CLK_PCLK_DAC PCLK_BIT(MDR_DAC_BASE) #define RST_CLK_PCLK_COMP PCLK_BIT(MDR_COMP_BASE) #define RST_CLK_PCLK_SSP2 PCLK_BIT(MDR_SSP2_BASE) #define RST_CLK_PCLK_PORTA PCLK_BIT(MDR_PORTA_BASE) #define RST_CLK_PCLK_PORTB PCLK_BIT(MDR_PORTB_BASE) #define RST_CLK_PCLK_PORTC PCLK_BIT(MDR_PORTC_BASE) #define RST_CLK_PCLK_PORTD PCLK_BIT(MDR_PORTD_BASE) #define RST_CLK_PCLK_PORTE PCLK_BIT(MDR_PORTE_BASE) #define RST_CLK_PCLK_26 PCLK_BIT(0x400D0000) #define RST_CLK_PCLK_BKP PCLK_BIT(MDR_BKP_BASE) #define RST_CLK_PCLK_28 PCLK_BIT(0x400E0000) #define RST_CLK_PCLK_PORTF PCLK_BIT(MDR_PORTF_BASE) #define RST_CLK_PCLK_EBC PCLK_BIT(MDR_EBC_BASE) #define RST_CLK_PCLK_31 PCLK_BIT(0x400F8000) #define IS_RST_CLK_PCLK(PCLK) ((((PCLK) & RST_CLK_PCLK_09) == 0x00) && \ (((PCLK) & RST_CLK_PCLK_26) == 0x00) && \ (((PCLK) & RST_CLK_PCLK_28) == 0x00) && \ (((PCLK) & RST_CLK_PCLK_31) == 0x00)) #endif // #ifdef USE_MDR1986VE9x /* For cortex M3 */
RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTC, ENABLE); // C.
Now we have a clock signal on the I / O port we need and we can begin to configure it. First we need to find the function that configures the port. It is in the file MDR32F9Qx_port.h . Called PORT_Init and has the following form. void PORT_Init(MDR_PORT_TypeDef* PORTx, const PORT_InitTypeDef* PORT_InitStruct);
As we can see, this function also has 2 parameters: typedef struct { uint16_t PORT_Pin; /*!< Specifies PORT pins to be configured. This parameter is a mask of @ref PORT_pins_define values. */ PORT_OE_TypeDef PORT_OE; /*!< Specifies in/out mode for the selected pins. This parameter is one of @ref PORT_OE_TypeDef values. */ PORT_PULL_UP_TypeDef PORT_PULL_UP; /*!< Specifies pull up state for the selected pins. This parameter is one of @ref PORT_PULL_UP_TypeDef values. */ PORT_PULL_DOWN_TypeDef PORT_PULL_DOWN; /*!< Specifies pull down state for the selected pins. This parameter is one of @ref PORT_PULL_DOWN_TypeDef values. */ PORT_PD_SHM_TypeDef PORT_PD_SHM; /*!< Specifies SHM state for the selected pins. This parameter is one of @ref PORT_PD_SHM_TypeDef values. */ PORT_PD_TypeDef PORT_PD; /*!< Specifies PD state for the selected pins. This parameter is one of @ref PORT_PD_TypeDef values. */ PORT_GFEN_TypeDef PORT_GFEN; /*!< Specifies GFEN state for the selected pins. This parameter is one of @ref PORT_GFEN_TypeDef values. */ PORT_FUNC_TypeDef PORT_FUNC; /*!< Specifies operating function for the selected pins. This parameter is one of @ref PORT_FUNC_TypeDef values. */ PORT_SPEED_TypeDef PORT_SPEED; /*!< Specifies the speed for the selected pins. This parameter is one of @ref PORT_SPEED_TypeDef values. */ PORT_MODE_TypeDef PORT_MODE; /*!< Specifies the operating mode for the selected pins. This parameter is one of @ref PORT_MODE_TypeDef values. */ }PORT_InitTypeDef;
PORT_InitTypeDef Led0PortC_structInit; // C.
Here PORT_InitTypeDef is a type . In other words - just a template, on the basis of which the “markup” of memory occurs. Led0PortC_structInit - the name of a specific structure, invented by us. Like creating a variable of type uint32_t, we set its name, for example Loop, and here we create a structure of type PORT_InitTypeDef with the name Led0PortC_structInit. It is important to note that the declaration of the structure must be done in the function before the first command. Otherwise the project will not meet. After creating the structure you need to fill it. Filling is as follows. _._ = - ;
And so - for each parameter from the description. In the description of each cell there is an explanation of what values ​​you can write to it. As a rule, if the value is not some arbitrary number from any range, then the description contains the word ref . With the help of the word after it, you can find in the file all the available values ​​for this cell. Take the first cell as an example. uint16_t PORT_Pin; /*!< Specifies PORT pins to be configured. This parameter is a mask of @ref PORT_pins_define values. */
Using the search, we find PORT_pins_define . #define PORT_Pin_0 0x0001U /*!< Pin 0 selected */ #define PORT_Pin_1 0x0002U /*!< Pin 1 selected */ #define PORT_Pin_2 0x0004U /*!< Pin 2 selected */ #define PORT_Pin_3 0x0008U /*!< Pin 3 selected */ #define PORT_Pin_4 0x0010U /*!< Pin 4 selected */ #define PORT_Pin_5 0x0020U /*!< Pin 5 selected */ #define PORT_Pin_6 0x0040U /*!< Pin 6 selected */ #define PORT_Pin_7 0x0080U /*!< Pin 7 selected */ #define PORT_Pin_8 0x0100U /*!< Pin 8 selected */ #define PORT_Pin_9 0x0200U /*!< Pin 9 selected */ #define PORT_Pin_10 0x0400U /*!< Pin 10 selected */ #define PORT_Pin_11 0x0800U /*!< Pin 11 selected */ #define PORT_Pin_12 0x1000U /*!< Pin 12 selected */ #define PORT_Pin_13 0x2000U /*!< Pin 13 selected */ #define PORT_Pin_14 0x4000U /*!< Pin 14 selected */ #define PORT_Pin_15 0x8000U /*!< Pin 15 selected */ #define PORT_Pin_All 0xFFFFU /*!< All pins selected */
Led0PortC_structInit.PORT_Pin = PORT_Pin_1;
But we still have such a define since the last article. // . #define LED0 (1<<0) // PORTC. #define LED1 (1<<1) // PORTC.
This is the same port mask as in the description, but with a different name. But it gives a clearer idea of ​​what we are connecting, so I will write it down. Led0PortC_structInit.PORT_Pin = LED1; // .
void initPinPortCForLedSPL (void) { PORT_InitTypeDef Led0PortC_structInit; // C. RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTC, ENABLE); // C. Led0PortC_structInit.PORT_Pin = LED1; // . Led0PortC_structInit.PORT_FUNC = PORT_FUNC_PORT; // . Led0PortC_structInit.PORT_GFEN = PORT_GFEN_OFF; // . Led0PortC_structInit.PORT_MODE = PORT_MODE_DIGITAL; // . Led0PortC_structInit.PORT_OE = PORT_OE_OUT; // . Led0PortC_structInit.PORT_PD = PORT_PD_DRIVER; // . Led0PortC_structInit.PORT_PD_SHM = PORT_PD_SHM_OFF; // . Led0PortC_structInit.PORT_PULL_DOWN = PORT_PULL_DOWN_OFF; // 0 . Led0PortC_structInit.PORT_PULL_UP = PORT_PULL_UP_OFF; // 1 . Led0PortC_structInit.PORT_SPEED = PORT_SPEED_MAXFAST; // . PORT_Init(MDR_PORTC, &Led0PortC_structInit); // . }
void initPinForButtonSPL (void) { // . PORT_InitTypeDef buttonPortB_structInit; // C. PORT_InitTypeDef buttonPortC_structInit; // C. PORT_InitTypeDef buttonPortE_structInit; // E. // . RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTB, ENABLE); // B. RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTC, ENABLE); // C. RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTE, ENABLE); // E. // . buttonPortB_structInit.PORT_FUNC = PORT_FUNC_PORT; // . buttonPortB_structInit.PORT_GFEN = PORT_GFEN_ON; // . buttonPortB_structInit.PORT_MODE = PORT_MODE_DIGITAL; // . buttonPortB_structInit.PORT_OE = PORT_OE_IN; // . buttonPortB_structInit.PORT_PD = PORT_PD_DRIVER; // . buttonPortB_structInit.PORT_PD_SHM = PORT_PD_SHM_OFF; // . buttonPortB_structInit.PORT_Pin = UP_MSK|RIGHT_MSK; // . buttonPortB_structInit.PORT_PULL_DOWN = PORT_PULL_DOWN_OFF; // 0 . buttonPortB_structInit.PORT_PULL_UP = PORT_PULL_UP_OFF; // 1 . buttonPortB_structInit.PORT_SPEED = PORT_SPEED_MAXFAST; // . buttonPortC_structInit.PORT_FUNC = PORT_FUNC_PORT; // PORTC. buttonPortC_structInit.PORT_GFEN = PORT_GFEN_ON; buttonPortC_structInit.PORT_MODE = PORT_MODE_DIGITAL; buttonPortC_structInit.PORT_OE = PORT_OE_IN; buttonPortC_structInit.PORT_PD = PORT_PD_DRIVER; buttonPortC_structInit.PORT_PD_SHM = PORT_PD_SHM_OFF; buttonPortC_structInit.PORT_Pin = SELECT_MSK; buttonPortC_structInit.PORT_PULL_DOWN = PORT_PULL_DOWN_OFF; buttonPortC_structInit.PORT_PULL_UP = PORT_PULL_UP_OFF; buttonPortC_structInit.PORT_SPEED = PORT_SPEED_MAXFAST; buttonPortE_structInit.PORT_FUNC = PORT_FUNC_PORT; // PORTE. buttonPortE_structInit.PORT_GFEN = PORT_GFEN_ON; buttonPortE_structInit.PORT_MODE = PORT_MODE_DIGITAL; buttonPortE_structInit.PORT_OE = PORT_OE_IN; buttonPortE_structInit.PORT_PD = PORT_PD_DRIVER; buttonPortE_structInit.PORT_PD_SHM = PORT_PD_SHM_OFF; buttonPortE_structInit.PORT_Pin = DOWN_MSK|LEFT_MSK; buttonPortE_structInit.PORT_PULL_DOWN = PORT_PULL_DOWN_OFF; buttonPortE_structInit.PORT_PULL_UP = PORT_PULL_UP_OFF; buttonPortE_structInit.PORT_SPEED = PORT_SPEED_MAXFAST; // . PORT_Init(MDR_PORTB, &buttonPortB_structInit); PORT_Init(MDR_PORTC, &buttonPortC_structInit); PORT_Init(MDR_PORTE, &buttonPortE_structInit); }
RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTA, ENABLE); // A. PWMPortA_structInit.PORT_FUNC = PORT_FUNC_ALTER; // . PWMPortA_structInit.PORT_GFEN = PORT_GFEN_OFF; // . PWMPortA_structInit.PORT_MODE = PORT_MODE_DIGITAL; // . PWMPortA_structInit.PORT_OE = PORT_OE_OUT; // . PWMPortA_structInit.PORT_PD = PORT_PD_DRIVER; // . PWMPortA_structInit.PORT_PD_SHM = PORT_PD_SHM_OFF; // . PWMPortA_structInit.PORT_Pin = PORT_Pin_1; // . PWMPortA_structInit.PORT_PULL_DOWN = PORT_PULL_DOWN_OFF; // 0 . PWMPortA_structInit.PORT_PULL_UP = PORT_PULL_UP_OFF; // 1 . PWMPortA_structInit.PORT_SPEED = PORT_SPEED_MAXFAST; // . PORT_Init(MDR_PORTA, &PWMPortA_structInit); // .
RST_CLK_PCLKcmd(RST_CLK_PCLK_TIMER1, ENABLE); // 1.
Next is to clearly identify the task. We need: void TIMER_CntInit(MDR_TIMER_TypeDef* TIMERx, const TIMER_CntInitTypeDef* TIMER_CntInitStruct);
Here are two parameters. TIMER_CntInitTypeDef timerPWM_structInit; // ( ). // . timerPWM_structInit.TIMER_ARR_UpdateMode = TIMER_ARR_Update_Immediately; // ARR . timerPWM_structInit.TIMER_BRK_Polarity = TIMER_BRKPolarity_NonInverted; // BRK ( ). timerPWM_structInit.TIMER_CounterDirection = TIMER_CntDir_Up; // "". CNT (CNT++). timerPWM_structInit.TIMER_CounterMode = TIMER_CntMode_ClkFixedDir; // , . timerPWM_structInit.TIMER_ETR_FilterConf = TIMER_Filter_1FF_at_TIMER_CLK; // 1- TIM_CLK ( -). timerPWM_structInit.TIMER_ETR_Polarity = TIMER_ETRPolarity_NonInverted; // ETR ( ). timerPWM_structInit.TIMER_ETR_Prescaler = TIMER_ETR_Prescaler_None; // ETR (ETR .). timerPWM_structInit.TIMER_EventSource = TIMER_EvSrc_None; // . timerPWM_structInit.TIMER_FilterSampling = TIMER_FDTS_TIMER_CLK_div_1; // FDTS = TIMER_CLK. ( .). timerPWM_structInit.TIMER_IniCounter = 0; // 0. . (CNT = 0.). timerPWM_structInit.TIMER_Period = PWM_speed; // (ARR = PWM_speed). timerPWM_structInit.TIMER_Prescaler = 32000 - 1;// . PSG . TIMER_CntInit(MDR_TIMER1, &timerPWM_structInit); // .
void TIMER_ChnInit(MDR_TIMER_TypeDef* TIMERx, const TIMER_ChnInitTypeDef* TIMER_ChnInitStruct)
The first parameter is the name of the timer being initialized. It remains the same as that of the initial timer initialization function. But the structure is of type TIMER_ChnInitTypeDef . TIMER_ChnInitTypeDef timerPWM_channelStructInit; // . // PWM . timerPWM_channelStructInit.TIMER_CH_BRK_Reset = TIMER_CH_BRK_RESET_Disable; // BRK (BRK ). timerPWM_channelStructInit.TIMER_CH_CCR1_Ena = DISABLE; // CCR1 . timerPWM_channelStructInit.TIMER_CH_CCR1_EventSource = TIMER_CH_CCR1EvSrc_PE; // CAP1: Chi. ( , ). timerPWM_channelStructInit.TIMER_CH_CCR_UpdateMode = TIMER_CH_CCR_Update_Immediately; // CCR (CCR ). timerPWM_channelStructInit.TIMER_CH_ETR_Ena = DISABLE; // ETR . timerPWM_channelStructInit.TIMER_CH_ETR_Reset = TIMER_CH_ETR_RESET_Disable; // ETR . timerPWM_channelStructInit.TIMER_CH_EventSource = TIMER_CH_EvSrc_PE; // : . ( ). timerPWM_channelStructInit.TIMER_CH_FilterConf = TIMER_Filter_1FF_at_TIMER_CLK; // TIMER_CLK . timerPWM_channelStructInit.TIMER_CH_Mode = TIMER_CH_MODE_PWM; // . timerPWM_channelStructInit.TIMER_CH_Number = TIMER_CHANNEL1; // . timerPWM_channelStructInit.TIMER_CH_Prescaler = TIMER_CH_Prescaler_None; // . timerPWM_channelStructInit.TIMER_CH_REF_Format = TIMER_CH_REF_Format3; // REF CNT == ARR. TIMER_ChnInit(MDR_TIMER1, &timerPWM_channelStructInit); // .
void TIMER_ChnOutInit(MDR_TIMER_TypeDef* TIMERx, const TIMER_ChnOutInitTypeDef* TIMER_ChnOutInitStruct);
The first parameter is the name of our timer. The second is the TIMER_ChnOutInitStruct structure. TIMER_ChnOutInitTypeDef timerPWM_channelOUTPWMStructInit; // . // . timerPWM_channelOUTPWMStructInit.TIMER_CH_DirOut_Mode = TIMER_CH_OutMode_Output; // . timerPWM_channelOUTPWMStructInit.TIMER_CH_DirOut_Polarity = TIMER_CHOPolarity_NonInverted; // . timerPWM_channelOUTPWMStructInit.TIMER_CH_DirOut_Source = TIMER_CH_OutSrc_REF; // REF . timerPWM_channelOUTPWMStructInit.TIMER_CH_DTG_AuxPrescaler = 0; // . timerPWM_channelOUTPWMStructInit.TIMER_CH_DTG_ClockSource = TIMER_CH_DTG_ClkSrc_TIMER_CLK; // DTG - TIMER_CLK. DTG . timerPWM_channelOUTPWMStructInit.TIMER_CH_DTG_MainPrescaler = 0; // DTG. timerPWM_channelOUTPWMStructInit.TIMER_CH_NegOut_Mode = TIMER_CH_OutMode_Input; // . , .. . timerPWM_channelOUTPWMStructInit.TIMER_CH_NegOut_Polarity = TIMER_CHOPolarity_NonInverted; // . timerPWM_channelOUTPWMStructInit.TIMER_CH_NegOut_Source = TIMER_CH_DTG_ClkSrc_TIMER_CLK; // DTG - TIMER_CLK. timerPWM_channelOUTPWMStructInit.TIMER_CH_Number = TIMER_CHANNEL1; // . TIMER_ChnOutInit(MDR_TIMER1, &timerPWM_channelOUTPWMStructInit); // .
void TIMER_BRGInit(MDR_TIMER_TypeDef* TIMERx, uint32_t TIMER_BRG);
The first parameter, as usual, is the name of the timer, the second is the divisor. The divider is calculated in the same way as for the PSG register in the previous article (in fact, this function is only written by our divider in the PSG ...). I also note that the same function also allows the clock signal to be sent to the default timer. Well, for the inclusion of the function responsible TIMER_Cmd . void TIMER_Cmd(MDR_TIMER_TypeDef* TIMERx, FunctionalState NewState)
Parameters - the name of the timer and its state ENABLE / DISABLE . #define TIMER_EvSrc_None (((uint32_t)0x0) << TIMER_CNTRL_EVENT_SEL_Pos) /*!< No events. */ #define TIMER_EvSrc_TM1 (((uint32_t)0x1) << TIMER_CNTRL_EVENT_SEL_Pos) /*!< Selects TIMER1 (CNT == ARR) event. */ #define TIMER_EvSrc_TM2 (((uint32_t)0x2) << TIMER_CNTRL_EVENT_SEL_Pos) /*!< Selects TIMER2 (CNT == ARR) event. */ #define TIMER_EvSrc_TM3 (((uint32_t)0x3) << TIMER_CNTRL_EVENT_SEL_Pos) /*!< Selects TIMER3 (CNT == ARR) event. */ #define TIMER_EvSrc_CH1 (((uint32_t)0x4) << TIMER_CNTRL_EVENT_SEL_Pos) /*!< Selects Channel 1 event. */ #define TIMER_EvSrc_CH2 (((uint32_t)0x5) << TIMER_CNTRL_EVENT_SEL_Pos) /*!< Selects Channel 2 event. */ #define TIMER_EvSrc_CH3 (((uint32_t)0x6) << TIMER_CNTRL_EVENT_SEL_Pos) /*!< Selects Channel 3 event. */ #define TIMER_EvSrc_CH4 (((uint32_t)0x7) << TIMER_CNTRL_EVENT_SEL_Pos) /*!< Selects Channel 4 event. */ #define TIMER_EvSrc_ETR (((uint32_t)0x8) << TIMER_CNTRL_EVENT_SEL_Pos) /*!< Selects ETR event. */
// 25 SPL. void initTimerButtonCheckSPL (void) { TIMER_CntInitTypeDef timerButtonCheck_structInit; // . RST_CLK_PCLKcmd(RST_CLK_PCLK_TIMER2, ENABLE); // 1. TIMER_BRGInit(MDR_TIMER2, TIMER_HCLKdiv1); // ( ). // . timerButtonCheck_structInit.TIMER_ARR_UpdateMode = TIMER_ARR_Update_Immediately; // ARR . timerButtonCheck_structInit.TIMER_BRK_Polarity = TIMER_BRKPolarity_NonInverted; // BRK ( ). timerButtonCheck_structInit.TIMER_CounterDirection = TIMER_CntDir_Up; // "". CNT (CNT++). timerButtonCheck_structInit.TIMER_CounterMode = TIMER_CntMode_ClkFixedDir; // , . timerButtonCheck_structInit.TIMER_ETR_FilterConf = TIMER_Filter_1FF_at_TIMER_CLK; // 1- TIM_CLK ( -). timerButtonCheck_structInit.TIMER_ETR_Polarity = TIMER_ETRPolarity_NonInverted; // ETR ( ). timerButtonCheck_structInit.TIMER_ETR_Prescaler = TIMER_ETR_Prescaler_None; // ETR (ETR .). timerButtonCheck_structInit.TIMER_EventSource = TIMER_EvSrc_TM2; // CNT = ARR. timerButtonCheck_structInit.TIMER_FilterSampling = TIMER_FDTS_TIMER_CLK_div_1; // FDTS = TIMER_CLK. ( .). timerButtonCheck_structInit.TIMER_IniCounter = 0; // 0. . (CNT = 0.). timerButtonCheck_structInit.TIMER_Period = 250/25; // (ARR = PWM_speed). timerButtonCheck_structInit.TIMER_Prescaler = 32000 - 1; // . PSG . TIMER_CntInit(MDR_TIMER2, &timerButtonCheck_structInit); // . TIMER_ITConfig(MDR_TIMER2, TIMER_STATUS_CNT_ARR, ENABLE); // CNT = ARR. NVIC_EnableIRQ(Timer2_IRQn); // . TIMER_Cmd(MDR_TIMER2, ENABLE); // . }
void TIMER_ClearFlag(MDR_TIMER_TypeDef* TIMERx, uint32_t Flags)
As parameters, you must specify the name of the port and the interrupt flag. In our case will be: TIMER_ClearFlag(MDR_TIMER2, TIMER_STATUS_CNT_ARR); // . .
After that, we inverted the LED state, indicating that the interrupt worked. In the SPL there is no function to invert a bit, but there is a function to read and write single bits. And we will use them. uint8_t PORT_ReadInputDataBit(MDR_PORT_TypeDef* PORTx, uint32_t PORT_Pin); void PORT_WriteBit(MDR_PORT_TypeDef* PORTx, uint32_t PORT_Pin, BitAction BitVal);
For both, the first parameter is the name of the port, then the reading function needs to specify the pin name. Specified exactly mask . In the recording function, after the port name you should specify the bit that is written (also masked) and the value of the bit (0 or 1). The read function can be used as a write function parameter. Then we get: PORT_WriteBit(MDR_PORTC, LED1, !PORT_ReadInputDataBit(MDR_PORTC, LED1)); // .
After that we need to read data from the buttons. And one button. To do this, we use the PORT_ReadInputDataBit function , which has been parsed above. if (PORT_ReadInputDataBit(MDR_PORTB, UP_MSK) == 0) PWM_speed--; // , - . - - . else if (PORT_ReadInputDataBit(MDR_PORTE, DOWN_MSK) == 0) PWM_speed++; else if (PORT_ReadInputDataBit(MDR_PORTE, LEFT_MSK) == 0) PWM_speed--; else if (PORT_ReadInputDataBit(MDR_PORTB, RIGHT_MSK)== 0) PWM_speed++;
void TIMER_SetCntAutoreload(MDR_TIMER_TypeDef* TIMERx, uint16_t Autoreload)
We only need to specify a timer with PWM and a new frequency. void Timer2_IRQHandler (void) { TIMER_ClearFlag(MDR_TIMER2, TIMER_STATUS_CNT_ARR); // . . PORT_WriteBit(MDR_PORTC, LED1, !PORT_ReadInputDataBit(MDR_PORTC, LED1)); // . if (PORT_ReadInputDataBit(MDR_PORTB, UP_MSK) == 0) PWM_speed--; // , - . - - . else if (PORT_ReadInputDataBit(MDR_PORTE, DOWN_MSK) == 0) PWM_speed++; else if (PORT_ReadInputDataBit(MDR_PORTE, LEFT_MSK) == 0) PWM_speed--; else if (PORT_ReadInputDataBit(MDR_PORTB, RIGHT_MSK)== 0) PWM_speed++; // , 250 0.5 . if (PWM_speed < 1) PWM_speed = 1; else if (PWM_speed > 500) PWM_speed = 500; TIMER_SetCntAutoreload(MDR_TIMER1, PWM_speed); // . }
Source: https://habr.com/ru/post/270863/
All Articles