-
Notifications
You must be signed in to change notification settings - Fork 30
/
Main.c
178 lines (158 loc) · 4.95 KB
/
Main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/********************************** (C) COPYRIGHT *******************************
* File Name : Main.c
* Author : WCH
* Version : V1.0
* Date : 2021/03/09
* Description : adc采样示例,包括温度检测、单通道检测、差分通道检测、TouchKey检测、中断方式采样。
*********************************************************************************
* 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.
*******************************************************************************/
#include "CH58x_common.h"
uint16_t adcBuff[40];
volatile uint8_t adclen;
volatile uint8_t DMA_end = 0;
/*********************************************************************
* @fn DebugInit
*
* @brief 调试初始化
*
* @return none
*/
void DebugInit(void)
{
GPIOA_SetBits(GPIO_Pin_9);
GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);
GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA);
UART1_DefInit();
}
/*********************************************************************
* @fn main
*
* @brief 主函数
*
* @return none
*/
int main()
{
uint8_t i;
signed short RoughCalib_Value = 0; // ADC粗调偏差值
SetSysClock(CLK_SOURCE_PLL_60MHz);
/* 配置串口调试 */
DebugInit();
PRINT("Start @ChipID=%02X\n", R8_CHIP_ID);
/* 温度采样并输出 */
PRINT("\n1.Temperature sampling...\n");
ADC_InterTSSampInit();
for(i = 0; i < 20; i++)
{
adcBuff[i] = ADC_ExcutSingleConver(); // 连续采样20次
}
for(i = 0; i < 20; i++)
{
PRINT("%d \n", adc_to_temperature_celsius(adcBuff[i]));
}
/* 单通道采样:选择adc通道0做采样,对应 PA4引脚, 带数据校准功能 */
PRINT("\n2.Single channel sampling...\n");
GPIOA_ModeCfg(GPIO_Pin_4, GPIO_ModeIN_Floating);
ADC_ExtSingleChSampInit(SampleFreq_3_2, ADC_PGA_0);
RoughCalib_Value = ADC_DataCalib_Rough(); // 用于计算ADC内部偏差,记录到全局变量 RoughCalib_Value中
PRINT("RoughCalib_Value =%d \n", RoughCalib_Value);
ADC_ChannelCfg(0);
for(i = 0; i < 20; i++)
{
adcBuff[i] = ADC_ExcutSingleConver() + RoughCalib_Value; // 连续采样20次
}
for(i = 0; i < 20; i++)
{
PRINT("%d \n", adcBuff[i]); // 注意:由于ADC内部偏差的存在,当采样电压在所选增益范围极限附近的时候,可能会出现数据溢出的现象
}
/* DMA单通道采样:选择adc通道0做采样,对应 PA4引脚 */
PRINT("\n3.Single channel DMA sampling...\n");
GPIOA_ModeCfg(GPIO_Pin_4, GPIO_ModeIN_Floating);
ADC_ExtSingleChSampInit(SampleFreq_3_2, ADC_PGA_0);
ADC_ChannelCfg(0);
ADC_AutoConverCycle(192); // 采样周期为 (256-192)*16个系统时钟
ADC_DMACfg(ENABLE, (uint16_t)(uint32_t)&adcBuff[0], (uint16_t)(uint32_t)&adcBuff[40], ADC_Mode_Single);
PFIC_EnableIRQ(ADC_IRQn);
ADC_StartDMA();
while(!DMA_end);
DMA_end = 0;
ADC_DMACfg(DISABLE, 0, 0, 0);
for(i = 0; i < 40; i++)
{
PRINT("%d \n", adcBuff[i]);
}
/* 差分通道采样:选择adc通道0做采样,对应 PA4(AIN0)、PA12(AIN2) */
PRINT("\n4.Diff channel sampling...\n");
GPIOA_ModeCfg(GPIO_Pin_4 | GPIO_Pin_12, GPIO_ModeIN_Floating);
ADC_ExtDiffChSampInit(SampleFreq_3_2, ADC_PGA_0);
ADC_ChannelCfg(0);
for(i = 0; i < 20; i++)
{
adcBuff[i] = ADC_ExcutSingleConver(); // 连续采样20次
}
for(i = 0; i < 20; i++)
{
PRINT("%d \n", adcBuff[i]);
}
/* TouchKey采样:选择adc通道 2 做采样,对应 PA12 */
PRINT("\n5.TouchKey sampling...\n");
GPIOA_ModeCfg(GPIO_Pin_12, GPIO_ModeIN_Floating);
TouchKey_ChSampInit();
ADC_ChannelCfg(2);
for(i = 0; i < 20; i++)
{
adcBuff[i] = TouchKey_ExcutSingleConver(0x10, 0); // 连续采样20次
}
for(i = 0; i < 20; i++)
{
PRINT("%d \n", adcBuff[i]);
}
/* 单通道采样:中断方式,选择adc通道1做采样,对应 PA5引脚, 不带数据校准功能 */
PRINT("\n6.Single channel sampling in interrupt mode...\n");
GPIOA_ModeCfg(GPIO_Pin_5, GPIO_ModeIN_Floating);
ADC_ExtSingleChSampInit(SampleFreq_3_2, ADC_PGA_0);
ADC_ChannelCfg(1);
adclen = 0;
ADC_ClearITFlag();
PFIC_EnableIRQ(ADC_IRQn);
ADC_StartUp();
while(adclen < 20);
PFIC_DisableIRQ(ADC_IRQn);
for(i = 0; i < 20; i++)
{
PRINT("%d \n", adcBuff[i]);
}
while(1);
}
/*********************************************************************
* @fn ADC_IRQHandler
*
* @brief ADC中断函数
*
* @return none
*/
__INTERRUPT
__HIGH_CODE
void ADC_IRQHandler(void) //adc中断服务程序
{
if(ADC_GetDMAStatus())
{
ADC_StopDMA();
R16_ADC_DMA_BEG = ((uint32_t)adcBuff) & 0xffff;
ADC_ClearDMAFlag();
DMA_end = 1;
}
if(ADC_GetITStatus())
{
ADC_ClearITFlag();
if(adclen < 20)
{
adcBuff[adclen] = ADC_ReadConverValue();
ADC_StartUp(); // 作用清除中断标志并开启新一轮采样
}
adclen++;
}
}