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); |
来源:网络版权归原作者所有,如有侵权,请联系删除。