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);
完整的Word格式文档51黑下载地址:
CUBE学习.docx
(35.03 KB, 下载次数: 37)
|