这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » 【转载】学习stm32CubeMX的一些总结----from三叶

共1条 1/1 1 跳转至

【转载】学习stm32CubeMX的一些总结----from三叶

工程师
2023-10-18 10:09:08     打赏
ADC部分
MX_ADC1_Init();
MX_ADC2_Init();
HAL_ADC_Start(&hadc1);                               //start ADC   
while(!(ADC1->SR&1<<1));
ADC1_DATA=ADC1->DR;
//   HAL_ADC_PollForConversion(&hadc1,10);                //
//   ADC1_DATA=HAL_ADC_GetValue(&hadc1);

unsigned int Get_Adc(unsigned int ch)   
{
    ADC_ChannelConfTypeDef  ADC1_ChanConf;
   
    ADC1_ChanConf.Channel=ch;                                       ADC1_ChanConf.Rank=1;                                      
    ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_239CYCLES_5;      //²ÉÑùʱ¼ä               
    HAL_ADC_ConfigChannel(&hadc1,&ADC1_ChanConf);        /
    HAL_ADC_Start(&hadc1);                               //¿ªÆôADC
   
    HAL_ADC_PollForConversion(&hadc1,10);                 
    return (unsigned int)HAL_ADC_GetValue(&hadc1);            
}

unsigned int Get_Adc_Average(unsigned char ch,unsigned char times)
{
    uint32_t temp_val=0;
    char t;
    for(t=0;t<times;t++)
    {
        temp_val+=Get_Adc(ch);
        HAL_Delay(2);
    }
    return temp_val/times;
}         

HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length)
  HAL_ADCEx_Calibration_Start(&hadc1,2);
  HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&ADCxConvertedValue1, 3);

DAC部分
//DAC_OUTx = VREF+ * DOR / 4095
MX_DAC_Init();
HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, 200);
  HAL_DAC_Start(&hdac, DAC_CHANNEL_1);
  先设定值再启动DAC
  HAL_DAC_SetValue(&hdac, DAC_CHANNEL_2, DAC_ALIGN_8B_R, 000);
  HAL_DAC_Start(&hdac, DAC_CHANNEL_2);
   
    LL_DAC_EnableTrigger(DAC, LL_DAC_CHANNEL_2);
    LL_DAC_Enable(DAC, LL_DAC_CHANNEL_2);
LL_DAC_ConvertData12RightAligned(DAC, LL_DAC_CHANNEL_2, 2000);
    LL_DAC_TrigSWConversion(DAC, LL_DAC_CHANNEL_2);   

定时器部分
ENCODE
uint32_t uwDirection = 0;
uint32_t pulsecount = 0;

HAL_TIM_Encoder_Start(&htim1,TIM_CHANNEL_ALL);
__HAL_TIM_SetCounter(&htim1,0);

uwDirection = __HAL_TIM_DIRECTION_STATUS(&htim1);
pulsecount = __HAL_TIM_GetCounter(&htim1);

PWM生成:
  MX_TIM2_Init(void)
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);//
  HAL_TIM_PWM_Stop(&htim2,TIM_CHANNEL_2);
改变PWM值,  值《 Period
void TIM_SetTIM2Compare2(unsigned long int compare)
{    TIM2->CCR2=compare;  }
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 30);
__HAL_TIM_SET_COUNTER(&htim3, 1000)

生成互补PWM
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);
HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1);
HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_2);
HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_3);

PWM频率占空比设置:
1.改分频比寄存器方法
SysFreq=(PWMfreq*(Perio+1))*(Prescaler+1)
Period=100-1 //pwm 0-99占空比
Prescaler=SysFreq/(PWMfreq*100)-1
48000000/3000*100-1=159//3K
Pulse=0-99
或:
Period=1000-1 //pwm 0-99.9占空比
Prescaler=SysFreq/(PWMfreq*1000)-1
Pulse=0-999
Pulse就是占空比
2.    改预置寄存器方法
Prescaler=0
Period = (SystemCoreClock /PWMfreq)
Pulse = DutyCycle * (Period - 1) / 100
Channel4Pulse = (uint16_t) (((uint32_t) 125 * (TimerPeriod- 1)) / 1000);//占空比12.5
定时器溢出中断:
先初始化定时器
Tout=((arr+1)*(psc+1))/Ft us.
   MX_TIM3_Init();
     //HAL_TIM_Base_Start_IT(&htim1);
启动停止定时器时钟
__HAL_RCC_TIM3_CLK_ENABLE();
__HAL_RCC_TIM3_CLK_DISABLE();
/* Blocking mode: Polling */
HAL_TIM_Base_Start(&htim1);
HAL_TIM_Base_Stop(&htim1);
启动定时中断
    HAL_TIM_Base_Start_IT(&htim3);
定时回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{      if (htim->Instance == TIM1)
{
//        TRG_RUNLED();
       }
        if (htim->Instance == TIM3)
{
        TRG_RUNLED();
       }
}


定时器使用问题:
问题1:定时器配置后,启用定时器中断模式(HAL_TIM_Base_Start_IT) 中断立即触发。
解决: 在初始化后清除中断标志:
__HAL_TIM_CLEAR_FLAG(&TIMX_Handler,TIM_IT_UPDATE);
重要指令宏:&htim2,TIM_CHANNEL_2
__HAL_TIM_ENABLE(&htim3);
__HAL_TIM_DISABLE(&htim3);
__HAL_TIM_ENABLE_IT(&htim2, TIM_IT_UPDATE);
(TIM_IT_CC1;TIM_IT_COM;TIM_IT_TRIGGER)
__HAL_TIM_DISABLE_IT(__HANDLE__, __INTERRUPT__)
__HAL_TIM_GET_FLAG(&htim2, TIM_FLAG_UPDATE);
(TIM_FLAG_CC1,TIM_FLAG_COM,TIM_FLAG_CC2OF)
__HAL_TIM_CLEAR_FLAG(__HANDLE__, __FLAG__)
__HAL_TIM_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__)
__HAL_TIM_CLEAR_IT(__HANDLE__, __INTERRUPT__)



定时器输出比较模式
1.    设置 PRESCALE
2.    设置 AUTORELOAD为0xFFFF
3.    设置 COMPARE
4.    启动定时器

设置预分频系数
__HAL_TIM_SET_PRESCALER(&htim3,4800-1)
__HAL_TIM_SET_AUTORELOAD(&htim3,100-1)
__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_2, 30) ;
__HAL_TIM_SET_COUNTER(&htim2,1000);
__HAL_TIM_GET_AUTORELOAD(__HANDLE__)
Count=__HAL_TIM_GET_COMPARE(&htim2, TIM_CHANNEL_2);
Count=__HAL_TIM_GET_COUNTER(&htim2);



定时器比较中断:
读当前定时器的COUNT
delay_new = __HAL_TIM_GET_COUNTER(&htim2, TIM_CHANNEL_2);
清除定时器的COUNT
__HAL_TIM_SET_COUNTER ( &htim2, 0); // 设置0
启动比较中断,开启定时器
HAL_TIM_OC_Start_IT(&htim1, TIM_CHANNEL_1);
HAL_TIM_OC_Start_IT(&htim1, TIM_CHANNEL_2);
关闭比较中断
HAL_TIM_OC_Stop_IT ( &htim1, TIM_CHANNEL_1);
重设输出比较寄存器
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, delay_new );
回调函数处理:



void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{  if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
    {}
     HAL_TIM_OC_Stop_IT  ( &htim2, TIM_CHANNEL_1);
if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
{}
     HAL_TIM_OC_Stop_IT  ( &htim2, TIM_CHANNEL_2);
}

LL库操作:
LL_TIM_EnableCounter(TIM_TypeDef *TIMx);
LL_TIM_DisableCounter(TIM_TypeDef *TIMx);
LL_TIM_SetCounter(TIM_TypeDef *TIMx, uint32_t Counter);
LL_TIM_GetCounter(TIM_TypeDef *TIMx);
LL_TIM_SetPrescaler(TIM_TypeDef *TIMx, uint32_t Prescaler);
LL_TIM_SetAutoReload(TIM_TypeDef *TIMx, uint32_t AutoReload);
LL_TIM_CC_EnableChannel(TIM_TypeDef *TIMx, uint32_t Channels);//LL_TIM_CHANNEL_CH1
LL_TIM_CC_DisableChannel(TIM_TypeDef *TIMx, uint32_t Channels);//LL_TIM_CHANNEL_CH1
LL_TIM_OC_SetCompareCH1(TIM_TypeDef *TIMx, uint32_t CompareValue)
LL_TIM_OC_SetCompareCH2(TIM_TypeDef *TIMx, uint32_t CompareValue)
LL_TIM_OC_GetCompareCH2(TIM_TypeDef *TIMx);


LL_TIM_EnableIT_UPDATE(TIM_TypeDef *TIMx)
LL_TIM_DisableIT_UPDATE(TIM_TypeDef *TIMx)
LL_TIM_ClearFlag_UPDATE(TIM_TypeDef *TIMx)
LL_TIM_IsActiveFlag_UPDATE(TIM_TypeDef *TIMx)

LL_TIM_EnableIT_CC1(TIM_TypeDef *TIMx)
LL_TIM_DisableIT_CC2(TIM_TypeDef *TIMx)
LL_TIM_ClearFlag_CC1(TIM_TypeDef *TIMx)
LL_TIM_IsActiveFlag_CC1(TIM_TypeDef *TIMx)

Pwm生成
//LL_TIM_SetPrescaler(TIM14,4700);//修改TIM14频率
// LL_TIM_SetCounter(TIM14,200);//改计数器值
  LL_TIM_EnableARRPreload(TIM14);//使能ARR自动装载寄存器
  LL_TIM_EnableCounter(TIM14);//使能计数器
  LL_TIM_CC_EnableChannel(TIM14,LL_TIM_CHANNEL_CH1);//使能TM14的通道一

定时计算
Unsigned    TX_Freq1K=2000;  //
Unsigned    TX_Freq=4300;    //
Unsigned    TX_Duty=40;      //

unsigned TX_Pluse;
unsigned TX_Period;
//  TX_Period=TX_Freq1K*1000/TX_Freq-1;
//    TX_Pluse=TX_Period*(100-TX_Duty)/100;

void Init_TxPwmParameter()
{
    TX_Period=TX_Freq1K*1000/TX_Freq-1;
TX_Pluse=TX_Period*(100-TX_Duty)/100;
}

单脉冲就是通过程序在一定可控延时后,产生一个脉宽可控的脉冲。这里的延时时间与脉冲宽度都可以设置,主要通过比较:定时器的计数值TIM_CNT、定时器的比较值TIM_CCRx(决定总周期)与定时器的周期值TIM_ARR(决定低电平周期) 这三个值来得出;单脉冲功能,只能在1、2通道上做
1.    设置PWM2输出模式
2.    勾中ONEPLUSE
3.    设置ARR、CCR
__HAL_TIM_ENABLE(&htim4);  
HAL_TIM_OnePulse_Start(&htim4, TIM_CHANNEL_2);  


GPIO:
HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);HAL_Delay(500);
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin);
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);
HAL_GPIO_TogglePin(Led1_GPIO_Port,Led1_Pin);



取反 IO 口输出电平
void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
设置 IO 电平
GPIOA->BSRR=1<<1; //设置 GPIOA.1 为高电平
GPIOA->BSRR=1<<(16+1) //设置 GPIOA.1 为低电平;
设置 GPIOB.5 输出高:
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET); //GPIOB.5 输出高
设置 GPIOB.5 输出低电平:
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5, GPIO_PIN_RESET); //GPIOB.5 输出低
读取 IO
HAL_GPIO_ReadPin(GPIOF, GPIO_PIN_5);//读取 PF5 的输入电平

#define KEY0   HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_3) //KEY0 按键 PH3
#define KEY1   HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_2) //KEY1 按键 PH2


LL_EXTI_EnableIT_0_31(uint32_t ExtiLine);//LL_EXTI_LINE_1
LL_EXTI_EnableIT_0_31(LL_EXTI_LINE_1);
LL_EXTI_DisableIT_0_31(uint32_t ExtiLine);//LL_EXTI_LINE_2
uint32_t LL_EXTI_IsActiveFlag_0_31(uint32_t ExtiLine)
uint32_t LL_EXTI_ReadFlag_0_31(uint32_t ExtiLine)
LL_EXTI_ClearFlag_0_31(uint32_t ExtiLine)

输出操作
LL_GPIO_SetOutputPin(GPIO_TypeDef *GPIOx, uint32_t PinMask)//
LL_GPIO_ResetOutputPin(GPIO_TypeDef *GPIOx, uint32_t PinMask)
LL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint32_t PinMask)
LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_0);
LL_GPIO_ResetOutputPin(GPIOA, LL_GPIO_PIN_0);
LL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);  LL_mDelay(100);


LL_GPIO_ReadInputPort(GPIO_TypeDef *GPIOx)
LL_GPIO_WriteOutputPort(GPIO_TypeDef *GPIOx, uint32_t PortValue)

LL_GPIO_IsInputPinSet(GPIO_TypeDef *GPIOx, uint32_t PinMask)
LL_GPIO_IsInputPinSet(GPIOA, LL_GPIO_PIN_0);
#define KEY1   LL_GPIO_IsInputPinSet(GPIOA, LL_GPIO_PIN_0);

void LL_EXTI_LINE_5_CallBack(void)
{
          if( (LL_GPIO_IsInputPinSet(GPIOA,LL_GPIO_PIN_5)!=SET))
          {Entry=1;}
         else
          {Entry=3;}
       }
}


unsigned int SendTimeCount,SetTimeCount;
float TimeCount=4.5;//4ms
unsigned int Delay_Freq1K=500;




        LL_EXTI_DisableIT_0_31(LL_EXTI_LINE_1);//LL_EXTI_LINE_2
       SetTimeCount=Delay_Freq1K*TimeCount;
        SendTimeCount=0;
        __HAL_TIM_SET_COUNTER(&htim17,0);
        HAL_TIM_Base_Start(&htim17);
        Set_LED4();
        TX_DATA_Enable();
        while(SendTimeCount<SetTimeCount)//4ms
        {
            SendTimeCount=__HAL_TIM_GET_COUNTER(&htim17);        
        }
        TX_DATA_Disable()
        Rst_LED4();
        HAL_TIM_Base_Stop(&htim17);
        LL_EXTI_EnableIT_0_31(LL_EXTI_LINE_1);

UART:
__HAL_UART_ENABLE_IT(huart,UART_IT_RXNE); //开启接收完成中断
uint8_t TxData[10]= "01234abcde";
HAL_UART_Transmit(&huart2,TxData,10,0xffff);

uint8_t value='F';
HAL_UART_Receive(&huart2,(uint8_t *)&value,1,1000);//在这个语句停留1000ms内等待接收1个字节数据,把数据存放在value中

LL_USART_TransmitData8(USART_TypeDef *USARTx, uint8_t Value)
uint8_t LL_USART_ReceiveData8(USART_TypeDef *USARTx)

void user_usartInit()
{
LL_USART_EnableIT_RXNE(USART1);
LL_USART_EnableIT_PE(USART1);      
}

void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
    uint8_t tmp;
    if(LL_USART_IsActiveFlag_RXNE(USART1))
    {
        LL_GPIO_ResetOutputPin(GPIOA,LL_GPIO_PIN_5);
        tmp=LL_USART_ReceiveData8(USART1);   
        LL_USART_TransmitData8(USART1,tmp);   
    }
  /* USER CODE END USART1_IRQn 0 */
  /* USER CODE BEGIN USART1_IRQn 1 */
   
  /* USER CODE END USART1_IRQn 1 */
}
1. UART接收的处理方法

        打开UART的接收中断,每收到一个字节就放到接收缓冲区,同时更新接收指针。当连续100ms没有收到接收字符,则认为本次帧接收完毕,置位帧接收完成标志,由主程序进行处理。

    2. UART发送的处理方法

        将需要发送的数据放到发送缓冲区,设置发送长度。然后发送第一个字节,并打开发送中断。在发送中断中判断是否已经发送了指定长度的数据。如果没有发送完成,则继续发送;发送完成,则关闭发送中断。

1. 定义需要的变量
uint8_t gcRXDBuffer[50], gcRXDPointer, gcRXDLength;    //接收的缓冲区、接收指针、接收的帧长度
uint8_t gcTXDBuffer[50], gcTXDPointer, gcTXDLength;    //发送的缓冲区,发送指针,发送的长度
uint8_t gcInRXDMode, gcInTXDMode;   //是否处于接收或发送的状态标志,在需要切入低功耗模式,或关闭

2初始化UART寄存器,这部分功能使用STM32CUBEMX自己生成就行,不用给自己编写。

3.    自己增加的初始化,初始化变量,并打开接收中断,此时不要打开发送中断。
*不带流控的USART2函数****************
*/
void uart2Init(void)
{
    gcRXDPointer=0;
    gcRXDLength=0;
    gcTXDPointer=0;
    gcTXDLength=0;
    gcInRXDMode=0;
    gcInTXDMode=0;
   
    LL_USART_EnableIT_RXNE(USART2);
    //LL_USART_EnableIT_TXE(USART2);

来源:网络版权归原作者所有,如有侵权,请联系删除。


共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]