|
普冉的M0系列MCU PY32F030K28自帶的LED數碼管驅動,省去了外部驅動IC。本例程演示通過模擬輸入PA7引腳采集NTC(熱敏電阻)電壓計算對應溫度并驅動四位LED數碼管顯示。
py32f030_ntc.jpg (5.37 MB, 下載次數: 8)
下載附件
2024-8-25 10:51 上傳
py32f030k28_kfb.png (81.37 KB, 下載次數: 9)
下載附件
2024-8-25 10:52 上傳
- /**
- ******************************************************************************
- * 文件名程: main.c
- * 作 者: 鄧凱哥
- * 功 能: 主函數
- * 硬 件: PY32F030K28-StartKit-V0.1
- * 軟件版本 V0.0.1(2024/4/16 16:02)
- ******************************************************************************
- **/
- #include "main.h"
- #include "ntc.h"
- #include "timepare.h"
- #define LED_DISP_c 0x61 //溫度符號小c
- /* Private variables ---------------------------------------------------------*/
- const uint8_t dispArr[] = {LL_LED_DISP_0, LL_LED_DISP_1, LL_LED_DISP_2, LL_LED_DISP_3, LL_LED_DISP_4, \
- LL_LED_DISP_5, LL_LED_DISP_6, LL_LED_DISP_7, LL_LED_DISP_8, LL_LED_DISP_9
- };
- int32_t acc_adcval,mean_value;
- uint32_t ADC1_Datas[128];
- int16_t ADC_ConverDone,adc_count,tempval;
- /* Private user code ---------------------------------------------------------*/
- /* Private macro -------------------------------------------------------------*/
- /* Private function prototypes -----------------------------------------------*/
- static void APP_SystemClockConfig(void);
- static void APP_AdcConfig(void);
- static void APP_AdcEnable(void);
- static void APP_AdcCalibrate(void);
- static void APP_ConfigLed(void);
- static void ADC1_DMA_Config(void);
- static void APP_ConfigUsart1(void);
- /******************************************************************************
- **函數信息 :System_Tick(uint32_t Ticks)
- **功能描述 :系統嘀嗒時鐘配置
- **輸入參數 :Ticks 頻率
- **輸出參數 :無
- **說 明 :
- ******************************************************************************/
- void System_Tick(uint32_t Ticks)
- {
- SysTick->LOAD = (uint32_t)((SystemCoreClock / Ticks) - 1UL); /* set reload register */
- SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
- SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
- SysTick_CTRL_TICKINT_Msk |
- SysTick_CTRL_ENABLE_Msk; /* Enable the Systick Timer */
- }
- /******************************************************************************
- **函數信息 :fputc( int data, FILE *f )
- **功能描述 :重定向fputc函數
- **輸入參數 :data 要打印字符 , *f 文件指針
- **輸出參數 :無
- **說 明 :
- ******************************************************************************/
- struct __FILE
- {
- int handle;
- };
- FILE __stdout;
- int fputc(int data, FILE *f)
- {
- /* Send a byte to USART */
- LL_USART_TransmitData8(USART1, data);
- while (!LL_USART_IsActiveFlag_TC(USART1));
- LL_USART_ClearFlag_TC(USART1);
- return (data);
- }
- /**
- * @brief 應用程序入口函數.
- * @retval int
- */
- int main(void)
- {
- /* 配置系統時鐘 */
- APP_SystemClockConfig();
-
- /* 配置USART1相關參數 */
- APP_ConfigUsart1();
-
- /* ADC復位 */
- LL_ADC_Reset(ADC1);
- /* ADC模塊時鐘使能 */
- LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_ADC1);
- /* ADC校準 */
- APP_AdcCalibrate();
- /* 配置ADC相關參數 */
- APP_AdcConfig();
-
- /* 配置ADC DMA參數 */
- ADC1_DMA_Config();
-
- /* 配置LED相關參數 */
- APP_ConfigLed();
- /* 使能ADC */
- APP_AdcEnable();
- /* 開始ADC轉換(如果是軟件觸發則直接開始轉換) */
- LL_ADC_REG_StartConversion(ADC1);
-
- /* 開啟系統嘀嗒定時器 */
- System_Tick(1000);
- while (1)
- {
-
- if( TimePare.Tim1ms_flag == 1 ) //1ms任務
- {
- TimePare.Tim1ms_flag = 0;
- if( ++TimePare.Tim10ms_count >= 10 )
- {
- TimePare.Tim10ms_count = 0;
- TimePare.Tim10ms_flag = 1;
- }
-
- if( ++TimePare.Tim50ms_count >= 50 )
- {
- TimePare.Tim50ms_count = 0;
- TimePare.Tim50ms_flag = 1;
- }
- }
-
-
-
- if( TimePare.Tim10ms_flag == 1 ) //10ms 任務
- {
-
- TimePare.Tim10ms_flag = 0;
- if( ++TimePare.Tim100ms_count >= 10 )
- {
- TimePare.Tim100ms_count = 0;
- TimePare.Tim100ms_flag = 1;
- }
-
- if( ++TimePare.Tim200ms_count >= 20 )
- {
- TimePare.Tim200ms_count = 0;
- TimePare.Tim200ms_flag = 1;
- }
- }
-
-
- if( TimePare.Tim50ms_flag == 1 ) //50ms 任務
- {
-
- TimePare.Tim50ms_flag = 0;
- }
-
- if( TimePare.Tim100ms_flag == 1 ) //100ms 任務
- {
-
- TimePare.Tim100ms_flag = 0;
- if( ++TimePare.Tim500ms_count >= 5 )
- {
- TimePare.Tim500ms_count = 0;
- TimePare.Tim500ms_flag = 1;
- }
- }
-
- if( TimePare.Tim200ms_flag == 1 ) //200ms 任務
- {
- TimePare.Tim200ms_flag = 0;
- }
-
- if( TimePare.Tim500ms_flag == 1 ) //500ms 任務
- {
- ///顯示NTC溫度
- // LL_LED_SetDisplayValue(LED, LL_LED_COM0, dispArr[(tempval) /100]);
- LL_LED_SetDisplayValue(LED, LL_LED_COM1, dispArr[(tempval) %100/10]);
- LL_LED_SetDisplayValue(LED, LL_LED_COM2, dispArr[(tempval) %100%10]);
- LL_LED_SetDisplayValue(LED, LL_LED_COM3, LED_DISP_c);
-
- printf("ADC_VALUE = %d, NTC_VALUE = %d\r\n",mean_value, tempval); //串口打印ADC數值和NTC溫度值
-
- TimePare.Tim500ms_flag = 0;
- if( ++TimePare.Tim1s_count >= 2 )
- {
- TimePare.Tim1s_count = 0;
- TimePare.Tim1s_flag = 1;
- }
- }
-
- if( TimePare.Tim1s_flag == 1 ) //1000ms 任務
- {
- TimePare.Tim1s_flag = 0;
- }
- }
- }
- /**
- * @brief 系統時鐘配置函數
- * @param 無
- * @retval 無
- */
- static void APP_SystemClockConfig(void)
- {
- /* 使能HSI */
- LL_RCC_HSI_Enable();
- LL_RCC_HSI_SetCalibFreq(LL_RCC_HSICALIBRATION_24MHz);
- while(LL_RCC_HSI_IsReady() != 1)
- {
- }
- /* 設置 AHB 分頻*/
- LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
- /* 配置HSISYS作為系統時鐘源 */
- LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSISYS);
- while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSISYS)
- {
- }
- /* 設置 APB1 分頻*/
- LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
- LL_Init1msTick(24000000);
- /* 更新系統時鐘全局變量SystemCoreClock(也可以通過調用SystemCoreClockUpdate函數更新) */
- LL_SetSystemCoreClock(24000000);
- }
- /**
- * @brief USART配置函數
- * @param USARTx:USART模塊,可以是USART1、USART2
- * @retval 無
- */
- static void APP_ConfigUsart1(void)
- {
- /*使能GPIOA時鐘*/
- LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
- /*使能USART1時鐘*/
- LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_USART1);
- /*GPIOA配置*/
- LL_GPIO_InitTypeDef GPIO_InitStruct;
- /*選擇PA9引腳*/
- GPIO_InitStruct.Pin = LL_GPIO_PIN_9;
- /*選擇復用模式*/
- GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
- /*選擇輸出速度*/
- GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
- /*選擇輸出模式*/
- GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
- /*選擇上拉*/
- GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
- /*復用為USART1功能*/
- GPIO_InitStruct.Alternate = LL_GPIO_AF1_USART1;
- /*GPIOA初始化*/
- LL_GPIO_Init(GPIOA,&GPIO_InitStruct);
- /*選擇PA10引腳*/
- GPIO_InitStruct.Pin = LL_GPIO_PIN_10;
- /*復用為USART1功能*/
- GPIO_InitStruct.Alternate = LL_GPIO_AF1_USART1;
- /*GPIOA初始化*/
- LL_GPIO_Init(GPIOA,&GPIO_InitStruct);
- /*配置USART功能*/
- LL_USART_InitTypeDef USART_InitStruct;
- /*設置波特率*/
- USART_InitStruct.BaudRate = 9600;
- /*設置數據長度*/
- USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B;
- /*停止位*/
- USART_InitStruct.StopBits = LL_USART_STOPBITS_1;
- /*設置校驗位*/
- USART_InitStruct.Parity = LL_USART_PARITY_NONE;
- USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;
- USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
- USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16;
- /*USART1初始化*/
- LL_USART_Init(USART1, &USART_InitStruct);
- /*配置為全雙工異步模式*/
- LL_USART_ConfigAsyncMode(USART1);
- /*使能UART1模塊*/
- LL_USART_Enable(USART1);
- }
- /**
- * @brief ADC校準函數
- * @param 無
- * @retval 無
- */
- static void APP_AdcCalibrate(void)
- {
- __IO uint32_t wait_loop_index = 0;
- __IO uint32_t backup_setting_adc_dma_transfer = 0;
- #if (USE_TIMEOUT == 1)
- uint32_t Timeout = 0;
- #endif
- if (LL_ADC_IsEnabled(ADC1) == 0)
- {
- /* 校準時關閉ADC的DMA配置 */
- backup_setting_adc_dma_transfer = LL_ADC_REG_GetDMATransfer(ADC1);
- LL_ADC_REG_SetDMATransfer(ADC1, LL_ADC_REG_DMA_TRANSFER_NONE);
- /* 使能校準 */
- LL_ADC_StartCalibration(ADC1);
- #if (USE_TIMEOUT == 1)
- Timeout = ADC_CALIBRATION_TIMEOUT_MS;
- #endif
- while (LL_ADC_IsCalibrationOnGoing(ADC1) != 0)
- {
- #if (USE_TIMEOUT == 1)
- /* 檢測校準是否超時 */
- if (LL_SYSTICK_IsActiveCounterFlag())
- {
- if(Timeout-- == 0)
- {
- }
- }
- #endif
- }
- /* ADC校準結束和使能ADC之間的延時最低4個ADC Clock */
- LL_mDelay(1);
- /* 還原ADC的DMA配置 */
- LL_ADC_REG_SetDMATransfer(ADC1, backup_setting_adc_dma_transfer);
- }
- }
- /**
- * @brief ADC配置函數
- * @param 無
- * @retval 無
- */
- static void APP_AdcConfig(void)
- {
- /* 使能GPIOA時鐘 */
- LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
- /* 配置管腳PA7為模擬輸入 */
- LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_7, LL_GPIO_MODE_ANALOG);
- /* ADC通道和時鐘源需在ADEN=0時配置,其余的需在ADSTART=0時配置 */
- /* 配置內部轉換通道 */
- LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(ADC1), LL_ADC_PATH_INTERNAL_NONE);
- /* 設置ADC時鐘 */
- LL_ADC_SetClock(ADC1, LL_ADC_CLOCK_SYNC_PCLK_DIV2);
- /* 設置12位分辨率 */
- LL_ADC_SetResolution(ADC1, LL_ADC_RESOLUTION_12B);
- /* 設置數據右對齊 */
- LL_ADC_SetResolution(ADC1, LL_ADC_DATA_ALIGN_RIGHT);
- /* 設置低功耗模式無 */
- LL_ADC_SetLowPowerMode(ADC1, LL_ADC_LP_MODE_NONE);
- /* 設置通道轉換時間 */
- LL_ADC_SetSamplingTimeCommonChannels(ADC1, LL_ADC_SAMPLINGTIME_239CYCLES_5);
- /* 設置觸發源為Software */
- LL_ADC_REG_SetTriggerSource(ADC1, LL_ADC_REG_TRIG_SOFTWARE);
- /* 設置轉換模式為連續轉換 */
- LL_ADC_REG_SetContinuousMode(ADC1, LL_ADC_REG_CONV_CONTINUOUS);
- /* 設置DMA模式為循環 */
- LL_ADC_REG_SetDMATransfer(ADC1, LL_ADC_REG_DMA_TRANSFER_UNLIMITED);
- /* 設置過載管理模式為覆蓋上一個值 */
- LL_ADC_REG_SetOverrun(ADC1, LL_ADC_REG_OVR_DATA_OVERWRITTEN);
- /* 使用PA7 ADC通道7,掃描方向必須為向上 */
- LL_ADC_REG_SetSequencerScanDirection(ADC1,LL_ADC_REG_SEQ_SCAN_DIR_FORWARD);
- /* 設置非連續模式為不使能 */
- LL_ADC_REG_SetSequencerDiscont(ADC1, LL_ADC_REG_SEQ_DISCONT_DISABLE);
- /* 設置通道7為轉換通道 */
- LL_ADC_REG_SetSequencerChannels(ADC1,LL_ADC_CHANNEL_7);
- }
- /**
- * @brief ADC使能函數
- * @param 無
- * @retval 無
- */
- static void APP_AdcEnable(void)
- {
- /* 使能ADC */
- LL_ADC_Enable(ADC1);
- /* 使能ADC 穩定時間,最低8個ADC Clock */
- LL_mDelay(1);
- }
- /**
- * @brief 配置LED數碼管
- * @param 無
- * @retval 無
- */
- static void APP_ConfigLed(void)
- {
- /* 使能時鐘 */
- LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_LED);
- LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
- LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOB);
- LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
- /* 配置 PB3, PB4, PB5 為 com1 com2 com3 */
- GPIO_InitStruct.Pin = LL_GPIO_PIN_3 | LL_GPIO_PIN_4 | LL_GPIO_PIN_5;
- GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
- GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
- GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
- GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
- GPIO_InitStruct.Alternate = LL_GPIO_AF_6;
- LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
- /* 配置 PA15 為 com0 */
- GPIO_InitStruct.Pin = LL_GPIO_PIN_15;
- GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
- GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
- GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
- GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
- GPIO_InitStruct.Alternate = LL_GPIO_AF_6;
- LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
- /* 配置 PA0, PA1, PA2, PA3, PA4, PA5, PA6 為 SEG B C D E F G DP */
- GPIO_InitStruct.Pin = LL_GPIO_PIN_0 | LL_GPIO_PIN_1 | LL_GPIO_PIN_2 | LL_GPIO_PIN_3 | \
- LL_GPIO_PIN_4 | LL_GPIO_PIN_5 | LL_GPIO_PIN_6;
- GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
- GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
- GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
- GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
- GPIO_InitStruct.Alternate = LL_GPIO_AF_3;
- LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
- /* 配置 PB8 為 SEG A */
- GPIO_InitStruct.Pin = LL_GPIO_PIN_8;
- GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
- GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
- GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
- GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
- GPIO_InitStruct.Alternate = LL_GPIO_AF_3;
- LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
- /* 設置 LED COM 驅動能力 */
- LL_LED_SetComDrive(LED, LL_LED_COMDRIVE_LOW);
- /* 設置 COM 打開數 */
- LL_LED_SetComNum(LED, LL_LED_COMSELECT_4COM);
- /* 設置 LED 預分頻值 */
- LL_LED_SetPrescaler(LED, 9);
- /* 設置 LED 點亮和切換時間 */
- LL_LED_SetLightAndDeadTime(LED, 0xf0, 0x10);
- /* 使能 LED */
- LL_LED_Enable(LED);
- }
- /******************************************************************************
- **函數信息 : ADC1_DMA_Config(void)
- **功能描述 :ADC1 DMA通道配置
- **輸入參數 :無
- **輸出參數 :無
- **說 明 :
- ******************************************************************************/
- void ADC1_DMA_Config()
- {
- /* 使能DMA1 時鐘 */
- LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);
- /* 使能syscfg 時鐘 */
- LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_SYSCFG);
- /* ADC對應通道LL_DMA_CHANNEL_1 */
- SET_BIT(SYSCFG->CFGR3, 0x0);
- /* 配置DMA傳輸方向為外設到存儲器 */
- LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_1, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
- /* 配置DMA優先級為高 */
- LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PRIORITY_HIGH);
- /* 配置DMA循環模式 */
- LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MODE_CIRCULAR);
- /* 配置DMA外設地址不變模式 */
- LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PERIPH_NOINCREMENT);
- /* 配置DMA存儲地址自增模式 */
- LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MEMORY_INCREMENT);
- /* 配置DMA外設傳輸方式為字 */
- LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PDATAALIGN_WORD);
- /* 配置DMA存儲器傳輸方式為字 */
- LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MDATAALIGN_WORD);
- /* 配置DMA傳輸長度為128 */
- LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, 128);
- /* 配置DMA外設和存儲器的地址 */
- LL_DMA_ConfigAddresses(DMA1, LL_DMA_CHANNEL_1, (uint32_t)&ADC1->DR,\
- (uint32_t)ADC1_Datas, LL_DMA_GetDataTransferDirection(DMA1, LL_DMA_CHANNEL_1));
- /* 使能DMA傳輸完成中斷 */
- LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1);
- /* DMA中斷配置 */
- NVIC_SetPriority(DMA1_Channel1_IRQn, 0);
- NVIC_EnableIRQ(DMA1_Channel1_IRQn);
- /* 使能DMA */
- LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
- }
- /******************************************************************************
- **函數信息 : ADC_DMATransferCompleteCallback(void)
- **功能描述 :ADC中斷回調
- **輸入參數 :無
- **輸出參數 :無
- **說 明 :
- ******************************************************************************/
- void ADC_DMATransferCompleteCallback()
- {
- uint8_t i;
- acc_adcval = 0;
- for( i=0; i<128; i++)
- {
- acc_adcval += ADC1_Datas[i];
- }
- mean_value = acc_adcval >>7; //求128次ADC采樣的平均值,用移位比除法運算更高效
- tempval = ADC_Get_TempValue( mean_value);
- }
- /**
- * @brief 錯誤執行函數
- * @param 無
- * @retval 無
- */
- void APP_ErrorHandler(void)
- {
- /* 無限循環 */
- while (1)
- {
- }
- }
- #ifdef USE_FULL_ASSERT
- /**
- * @brief 輸出產生斷言錯誤的源文件名及行號
- * @param file:源文件名指針
- * @param line:發生斷言錯誤的行號
- * @retval 無
- */
- void assert_failed(uint8_t *file, uint32_t line)
- {
- /* 用戶可以根據需要添加自己的打印信息,
- 例如: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
- /* 無限循環 */
- while (1)
- {
- }
- }
- #endif /* USE_FULL_ASSERT */
復制代碼
代碼下載:
|
評分
-
查看全部評分
|