使用Platformio平臺的libopencm3開發框架來開發STM32G0,以下使用ADC進行NTC溫度采集。
1 新建項目
- 建立ntc_temp項目
在PIO的Home頁面新建項目,項目名稱ntc_temp,選擇開發板為 MonkeyPi_STM32_G070RB,開發框架選擇libopencm3;
1upload_protocol = cmsis-dap
2debug_tool = cmsis-dap
- 為了能使用printf的浮點功能,可以加入如下配置:
1build_flags =
2 -Wl,-u,_printf_float
2 編寫程序
2.1 ADC設置
1void adc_setup()
2{
3 rcc_periph_clock_enable(RCC_GPIOA);
4 rcc_periph_clock_enable(RCC_ADC);
5
6 gpio_mode_setup(GPIOA,GPIO_MODE_ANALOG,GPIO_PUPD_NONE,GPIO0);
7
8 adc_power_off(ADC1);
9 adc_set_clk_prescale(ADC1,ADC_CCR_PRESC_DIV2);
10 adc_set_single_conversion_mode(ADC1);
11 adc_set_right_aligned(ADC1);
12 adc_set_sample_time_on_all_channels(ADC1,ADC_SMPTIME_160DOT5);
13 uint8_t channel = 0;
14 adc_set_regular_sequence(ADC1,1,&channel);
15 adc_set_resolution(ADC1,ADC_CFGR1_RES_12_BIT);
16
17 adc_power_on(ADC1);
18
19 delay_ms(10);
20
21}
ADC設置按照之前文章介紹的方法設置PA0為ADC輸入;
2.2 ADC讀取
1uint16_t adc_sample()
2{
3 adc_start_conversion_regular(ADC1);
4 return adc_read_regular(ADC1);
5}
2.3 ADC與NTC的溫度轉換
- 首先根據所選的NTC規格的溫度-電阻對應表得到其ADC值的關系表:
這里的NTC分壓電阻為10K,ADC分辨率為12位,因此ADC采集值為:(NTC電阻 x 4095) ÷ (NTC電阻 + 10K),即可得到如下所示的表格:
image-20220926234050183
在EXCEL中計算出ADC采樣數值-溫度對應表,為了簡單ADC進行取整,就可以得到電阻-55到125攝氏度的ADC對應表:
1const uint16_t ntcDATA[] = {
24040,4038,4035,4031,4027,4023,4018,4013,4007,4001,3994,3987,3980,3972,3964,3956,
3
43947,3937,3928,3917,3907,3896,3884,3872,3860,3847,3833,3819,3804,3789,3773,3757,
5
63740,3722,3703,3684,3664,3644,3622,3600,3577,3553,3528,3502,3475,3448,3419,3390,
7
83360,3329,3297,3264,3230,3195,3160,3123,3086,3048,3010,2970,2930,2889,2848,2806,
9
102763,2720,2676,2633,2588,2544,2499,2454,2408,2363,2317,2272,2226,2181,2136,2091,
11
122048,2001,1957,1913,1869,1826,1783,1741,1699,1658,1617,1576,1537,1498,1459,1422,
13
141385,1348,1312,1277,1243,1209,1176,1144,1112,1081,1051,1022,993,965,937,910,
15
16884,859,834,810,786,764,741,720,699,679,659,639,621,602,585,568,
17
18551,535,519,504,490,475,461,448,435,422,410,398,387,376,365,355,
19
20345,335,325,316,307,299,290,282,274,267,259,252,245,239,232,226,
21
22220,214,208,202,197,192,187,182,177,172,168,163,159,155,151,146,
23
24143,139,135,132,129
25};
- 然后根據表格獲取溫度,即每個ADC對應的索引即為溫度值,如4040為索引0,對應第一個溫度-55℃;
- 表格中數據是有序的,因此這里可以使用二分法查找,對于兩個數中間值則取其相近的那個值:
1#define TEMP_HEADER_VALUE -55 //the first temp in table
2
3#define ITEM_NUM(items) sizeof(items) / sizeof(items[0])
4
5/**
6 * @brief search the table, return a midium value if not found
7 *
8 * @param table the data to search
9 * @param len the table length
10 * @param up if data is min to max
11 * @return int32_t -1 -> if not found
12 */
13int32_t bsearch_ret_mid(const uint16_t *table, uint16_t len, bool up, uint16_t key)
14{
15 uint16_t bot;
16 uint16_t mid;
17 uint16_t check;
18 uint16_t top;
19
20 if (len == 0) {
21 return -1;
22 }
23
24 if (up) {
25 //the first data will be min
26 if (key < table[0]) {
27 return -1;
28 }
29
30 //bigger then the last data
31 if (key > table[len - 1]) {
32 return -1;
33 }
34 } else {
35 if (key > table[0]) {
36 return -1;
37 }
38
39 if (key < table[len - 1]) {
40 return -1;
41 }
42 }
43
44 bot = 0;
45 top = len - 1;
46
47 if (up) {
48 while (bot < top) {
49 mid = top - (top - bot) / 2;
50
51 if (key < table[mid]) {
52 top = mid - 1;
53 } else {
54 bot = mid;
55 }
56 }
57 } else {
58 while (bot < top) {
59 mid = top - (top - bot) / 2;
60
61 if (key > table[mid]) {
62 top = mid - 1;
63 } else {
64 bot = mid;
65 }
66 }
67 }
68
69 if (key == table[top]) {
70 return top;
71 }
72
73 //not equal the data in table
74 if (up) {
75 if (key > table[top]) {
76 return top;
77 }
78 } else {
79 if (key < table[top]) {
80 return top;
81 }
82 }
83
84 return -1;
85}
- 然后根據索引得到溫度:
1//get temperature , x10
2int16_t ntc2tem(uint16_t adc)
3{
4 int32_t index = 0;
5 int16_t temperature = 0;
6
7 index = bsearch_ret_mid(ntcDATA, ITEM_NUM(ntcDATA),false,adc);
8
9 //max, the first value
10 if(index==0){
11 temperature = TEMP_HEADER_VALUE*10;
12 }
13 //min, the last value
14 else if(index>= ITEM_NUM(ntcDATA)){
15 temperature = 10*(TEMP_HEADER_VALUE + ITEM_NUM(ntcDATA));
16 }
17 else{
18 //just get integer number
19 // temperature = TEMP_HEADER_VALUE + index;
20
21 //get approximation data
22 temperature = TEMP_HEADER_VALUE + index;
23
24 //at middle
25 temperature = (temperature+1)*10 - 10.0 * (adc-ntcDATA[index+1])/(ntcDATA[index]-ntcDATA[index+1]);
26 }
27
28 return temperature;
29
30}
表格中的溫度是1度進行變化的,如果需要稍微精確的,這里在1度中間的值近似看做線性進行計算;
這里為了減小計算誤差,先對其擴大十倍計算,顯示時候再轉為小數:
1uint16_t adc = adc_sample();
2
3int16_t temp_int = ntc2tem(adc);
4float temp = temp_int/10.0;
5
6printf("adc: %d, temp: %.1f\\r\\n",adc, temp);
3 連接硬件并測試
3.1 連接硬件
按照如下圖,將NTC和10K電阻連接到PA0腳:
image-20220926233017743
3.2 測試
打開串口,當手放在NTC上可以看到溫度變化:
image-20220926232610018
-
NTC
+關注
關注
7文章
426瀏覽量
52063 -
adc
+關注
關注
98文章
6498瀏覽量
544629 -
仿真器
+關注
關注
14文章
1018瀏覽量
83741 -
開發板
+關注
關注
25文章
5050瀏覽量
97456 -
STM3
+關注
關注
0文章
5瀏覽量
8910
發布評論請先 登錄
相關推薦
評論