From 75c13d656b723b26b4c204e9f6cf4e6ecc1dda0f Mon Sep 17 00:00:00 2001 From: huoyujia081 Date: Wed, 29 May 2024 10:05:51 +0800 Subject: [PATCH] Add ADC module and fix the bug of Delay_MS in ch32v208rbt6 1. Add internal_temperature command in letter-shell. 2. Fix the bug of method Delay_MS in debug.c. Original method didn't store the state of Systick, and the new Delay_MS method store the state. --- .../arch/risc-v/ch32v208rbt6/Debug/debug.c | 21 +++ .../XiZi_IIoT/board/ch32v208rbt6/board.c | 4 + .../ch32v208rbt6/third_party_driver/Kconfig | 4 + .../ch32v208rbt6/third_party_driver/Makefile | 3 + .../third_party_driver/adc/Makefile | 4 + .../ch32v208rbt6/third_party_driver/adc/adc.c | 169 ++++++++++++++++++ .../third_party_driver/adc/test/Makefile | 3 + .../adc/test/internal_temperature.c | 36 ++++ .../third_party_driver/ethernet/test/ping.c | 2 +- .../third_party_driver/include/adc.h | 9 + 10 files changed, 254 insertions(+), 1 deletion(-) create mode 100644 Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/adc/Makefile create mode 100644 Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/adc/adc.c create mode 100644 Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/adc/test/Makefile create mode 100644 Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/adc/test/internal_temperature.c create mode 100644 Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/include/adc.h diff --git a/Ubiquitous/XiZi_IIoT/arch/risc-v/ch32v208rbt6/Debug/debug.c b/Ubiquitous/XiZi_IIoT/arch/risc-v/ch32v208rbt6/Debug/debug.c index fbe4e1978..766bb6cef 100644 --- a/Ubiquitous/XiZi_IIoT/arch/risc-v/ch32v208rbt6/Debug/debug.c +++ b/Ubiquitous/XiZi_IIoT/arch/risc-v/ch32v208rbt6/Debug/debug.c @@ -15,6 +15,16 @@ static uint8_t p_us = 0; static uint16_t p_ms = 0; +// 定义一个结构体保存所有状态 +typedef struct { + uint32_t SR; + uint32_t CMP; + uint32_t CTLR; +} SysTickState; + +// 定义一个静态变量保存原始状态 +static SysTickState originalSysTickState = {0}; + #define DEBUG_DATA0_ADDRESS ((volatile uint32_t*)0xE0000380) #define DEBUG_DATA1_ADDRESS ((volatile uint32_t*)0xE0000384) @@ -67,6 +77,13 @@ void Delay_Us(uint32_t n) void Delay_Ms(uint32_t n) { uint32_t i; + + // 保存原始状态 + if (originalSysTickState.SR == 0) { + originalSysTickState.SR = SysTick->SR; + originalSysTickState.CMP = SysTick->CMP; + originalSysTickState.CTLR = SysTick->CTLR; + } SysTick->SR &= ~(1 << 0); i = (uint32_t)n * p_ms; @@ -77,6 +94,10 @@ void Delay_Ms(uint32_t n) while((SysTick->SR & (1 << 0)) != (1 << 0)); SysTick->CTLR &= ~(1 << 0); + // 恢复原始状态 + SysTick->SR = originalSysTickState.SR; + SysTick->CMP = originalSysTickState.CMP; + SysTick->CTLR = originalSysTickState.CTLR; } /********************************************************************* diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/board.c b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/board.c index 110a432b8..8a66700c2 100644 --- a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/board.c +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/board.c @@ -37,6 +37,7 @@ #include #include #include "connect_ether.h" +#include "adc.h" // core clock. extern uint32_t SystemCoreClock; @@ -70,6 +71,9 @@ void InitBoardHardware() InstallConsole("uart1", SERIAL_DRV_NAME_1, SERIAL_1_DEVICE_NAME_0); #ifdef BSP_USING_ETH InitHwEth(); +#endif +#ifdef BSP_USING_ADC + ADC_Function_Init(); #endif KPrintf("consle init completed.\n"); KPrintf("board initialization......\n"); diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/Kconfig b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/Kconfig index aa3b10601..9dd39483c 100755 --- a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/Kconfig @@ -10,4 +10,8 @@ menuconfig BSP_USING_UART menuconfig BSP_USING_ETH bool "Using Ethernet" default y + +menuconfig BSP_USING_ADC + bool "Using ADC" + default y \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/Makefile b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/Makefile index 2fd2d3af4..2e6e56216 100644 --- a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/Makefile +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/Makefile @@ -7,4 +7,7 @@ endif ifeq ($(CONFIG_BSP_USING_ETH),y) SRC_DIR += ethernet endif +ifeq ($(CONFIG_BSP_USING_ADC),y) + SRC_DIR += adc +endif include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/adc/Makefile b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/adc/Makefile new file mode 100644 index 000000000..39219261a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/adc/Makefile @@ -0,0 +1,4 @@ +SRC_FILES := adc.c +SRC_DIR := test + +include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/adc/adc.c b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/adc/adc.c new file mode 100644 index 000000000..2a7b158fb --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/adc/adc.c @@ -0,0 +1,169 @@ +/********************************** (C) COPYRIGHT ******************************* + * File Name : main.c + * Author : WCH + * Version : V1.0.0 + * Date : 2021/06/06 + * Description : Main program body. + ********************************************************************************* + * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. + * Attention: This software (modified or not) and binary are used for + * microcontroller manufactured by Nanjing Qinheng Microelectronics. + *******************************************************************************/ + +/* + *@Note + *Internal temperature sensor routine: + *Through the ADC channel 16, the output voltage value and temperature value of + *the internal temperature sensor are collected. + * + */ + +#include "debug.h" + +/* Global Variable */ +s16 Calibrattion_Val = 0; + +/********************************************************************* + * @fn ADC_Function_Init + * + * @brief Initializes ADC collection. + * + * @return none + */ +void ADC_Function_Init(void) +{ + ADC_InitTypeDef ADC_InitStructure = {0}; + GPIO_InitTypeDef GPIO_InitStructure = {0}; + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); + RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); + RCC_ADCCLKConfig(RCC_PCLK2_Div8); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; + GPIO_Init(GPIOA, &GPIO_InitStructure); + + ADC_DeInit(ADC1); + ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; + ADC_InitStructure.ADC_ScanConvMode = DISABLE; + ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; + ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; + ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; + ADC_InitStructure.ADC_NbrOfChannel = 1; + ADC_Init(ADC1, &ADC_InitStructure); + + ADC_Cmd(ADC1, ENABLE); + + ADC_BufferCmd(ADC1, DISABLE); //disable buffer + ADC_ResetCalibration(ADC1); + while(ADC_GetResetCalibrationStatus(ADC1)); + ADC_StartCalibration(ADC1); + while(ADC_GetCalibrationStatus(ADC1)); + Calibrattion_Val = Get_CalibrationValue(ADC1); + + ADC_BufferCmd(ADC1, ENABLE); //enable buffer + + ADC_TempSensorVrefintCmd(ENABLE); +} + +/********************************************************************* + * @fn Get_ADC_Val + * + * @brief Returns ADCx conversion result data. + * + * @param ch - ADC channel. + * ADC_Channel_0 - ADC Channel0 selected. + * ADC_Channel_1 - ADC Channel1 selected. + * ADC_Channel_2 - ADC Channel2 selected. + * ADC_Channel_3 - ADC Channel3 selected. + * ADC_Channel_4 - ADC Channel4 selected. + * ADC_Channel_5 - ADC Channel5 selected. + * ADC_Channel_6 - ADC Channel6 selected. + * ADC_Channel_7 - ADC Channel7 selected. + * ADC_Channel_8 - ADC Channel8 selected. + * ADC_Channel_9 - ADC Channel9 selected. + * ADC_Channel_10 - ADC Channel10 selected. + * ADC_Channel_11 - ADC Channel11 selected. + * ADC_Channel_12 - ADC Channel12 selected. + * ADC_Channel_13 - ADC Channel13 selected. + * ADC_Channel_14 - ADC Channel14 selected. + * ADC_Channel_15 - ADC Channel15 selected. + * ADC_Channel_16 - ADC Channel16 selected. + * ADC_Channel_17 - ADC Channel17 selected. + * + * @return none + */ +u16 Get_ADC_Val(u8 ch) +{ + u16 val; + + ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5); + ADC_SoftwareStartConvCmd(ADC1, ENABLE); + + while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)); + + val = ADC_GetConversionValue(ADC1); + + return val; +} + +/********************************************************************* + * @fn Get_ADC_Average + * + * @brief Returns ADCx conversion result average data. + * + * @param ch - ADC channel. + * ADC_Channel_0 - ADC Channel0 selected. + * ADC_Channel_1 - ADC Channel1 selected. + * ADC_Channel_2 - ADC Channel2 selected. + * ADC_Channel_3 - ADC Channel3 selected. + * ADC_Channel_4 - ADC Channel4 selected. + * ADC_Channel_5 - ADC Channel5 selected. + * ADC_Channel_6 - ADC Channel6 selected. + * ADC_Channel_7 - ADC Channel7 selected. + * ADC_Channel_8 - ADC Channel8 selected. + * ADC_Channel_9 - ADC Channel9 selected. + * ADC_Channel_10 - ADC Channel10 selected. + * ADC_Channel_11 - ADC Channel11 selected. + * ADC_Channel_12 - ADC Channel12 selected. + * ADC_Channel_13 - ADC Channel13 selected. + * ADC_Channel_14 - ADC Channel14 selected. + * ADC_Channel_15 - ADC Channel15 selected. + * ADC_Channel_16 - ADC Channel16 selected. + * ADC_Channel_17 - ADC Channel17 selected. + * + * @return val - The Data conversion value. + */ +u16 Get_ADC_Average(u8 ch, u8 times) +{ + u32 temp_val = 0; + u8 t; + u16 val; + + for(t = 0; t < times; t++) { + temp_val += Get_ADC_Val(ch); + Delay_Ms(5); + } + + val = temp_val / times; + + return val; +} + +/********************************************************************* + * @fn Get_ConversionVal + * + * @brief Get Conversion Value. + * + * @param val - Sampling value + * + * @return val+Calibrattion_Val - Conversion Value. + */ +u16 Get_ConversionVal(s16 val) +{ + if((val + Calibrattion_Val) < 0|| val==0) + return 0; + if((Calibrattion_Val + val) > 4095|| val==4095) + return 4095; + return (val + Calibrattion_Val); +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/adc/test/Makefile b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/adc/test/Makefile new file mode 100644 index 000000000..d3b10aa87 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/adc/test/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := internal_temperature.c + +include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/adc/test/internal_temperature.c b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/adc/test/internal_temperature.c new file mode 100644 index 000000000..1fb687e18 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/adc/test/internal_temperature.c @@ -0,0 +1,36 @@ +/********************************************************************* + * @fn main + * + * @brief Main program. + * + * @return none + */ + +#include "adc.h" +#include "debug.h" +#include "shell.h" +#include "xs_base.h" + +extern s16 Calibrattion_Val; +int internal_temperature(int argc, char *argv[]) { + u16 ADC_val; + s32 val_mv; + KPrintf("CalibrattionValue:%d\n", Calibrattion_Val); + + ADC_val = Get_ADC_Average(ADC_Channel_TempSensor, 10); + Delay_Ms(500); + + ADC_val = Get_ConversionVal(ADC_val); + KPrintf("ADC-Val:%04d\r\n", ADC_val); + + val_mv = (ADC_val * 3300 / 4096); // ADC_val以3.3V为基准,4096为ADC分辨率 + + KPrintf("mv-T-%d,%0d\n", val_mv, TempSensor_Volt_To_Temper(val_mv)); + + Delay_Ms(2); + return 0; +} + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), + internal_temperature, internal_temperature, + test internal temperature sensor); \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/ethernet/test/ping.c b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/ethernet/test/ping.c index 8661a52e3..3807840d1 100644 --- a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/ethernet/test/ping.c +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/ethernet/test/ping.c @@ -403,4 +403,4 @@ int ping(int argc, char *argv[]) { } SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), - ping, ping, test tcp client); \ No newline at end of file + ping, ping, test ping command); \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/include/adc.h b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/include/adc.h new file mode 100644 index 000000000..eb5a4e1fa --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/include/adc.h @@ -0,0 +1,9 @@ +#ifndef ADC_H +#define ADC_H + +#include +void ADC_Function_Init(void); +u16 Get_ADC_Val(u8 ch); +u16 Get_ADC_Average(u8 ch, u8 times); +u16 Get_ConversionVal(s16 val); +#endif \ No newline at end of file