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)
2019-6-20 22:45 上傳
點擊文件名下載附件
stm32 cube 的使用總結 下載積分: 黑幣 -5
|