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.
This commit is contained in:
huoyujia081 2024-05-29 10:05:51 +08:00
parent 6936e0e565
commit 75c13d656b
10 changed files with 254 additions and 1 deletions

View File

@ -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;
}
/*********************************************************************

View File

@ -37,6 +37,7 @@
#include <xizi.h>
#include <xs_base.h>
#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");

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,4 @@
SRC_FILES := adc.c
SRC_DIR := test
include $(KERNEL_ROOT)/compiler.mk

View File

@ -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);
}

View File

@ -0,0 +1,3 @@
SRC_FILES := internal_temperature.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -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);

View File

@ -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);
ping, ping, test ping command);

View File

@ -0,0 +1,9 @@
#ifndef ADC_H
#define ADC_H
#include <ch32v20x.h>
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