前回に引き続き、ch32funのライブラリーの1つであるGPIOライブラリーを使用してADCに挑戦して行きたいと思います。
GPIOライブラリーを使用するには、"ch32v003_GPIO_branchless.h"をインクルードすることと、Makefileの中に”CH32FUN=$(HOME)/ch32fun/ch32fun”を設定することです。
では早速GPIOを使用したADCのプログラムを書いてみましょう。
CH32V003J4M6 8pinダイブのPD6(1pin)に接続した可変抵抗器のアナログ値をADC変換してprintf文を通じて読み込んでみます。
回路図は下記のとおりです。
PD6をアナログ入力pinとして設定します。
// 入力PINとの関連付け
#define ADC_IN1 GPIOv_from_PORT_PIN(GPIO_port_D, 6) //PD6 port
Dポートを活性化し、PD6ポートをアナログ入力として設定し、ADCを初期化します。
GPIO_port_enable(GPIO_port_D); // gpio Dポートを活性化
GPIO_pinMode(ADC_IN1, GPIO_pinMode_I_analog, GPIO_Speed_In); // gpioの補給クロックとpinをアナログ入力に設定
GPIO_ADCinit();
PD6からアナログ値を読み込み、ADCの値と、32倍したADC値をprintf文で出力します。
while(1){
analog_data = GPIO_analogRead(GPIO_Ain6_D6); // 該当のpinにアナログ入力する
analog_input_data = analog_data*32;
printf("ADC = %d (%x)\n\r",analog_input_data,analog_data);
Delay_Ms(500);
}
全体のプログラムは下記のとおりです。
//CH32V003J4M6 8pin GPIO ADC プログラム
#include "ch32fun.h"
#include "ch32v003_GPIO_branchless.h"
#include <stdio.h>
// 入力PINとの関連付け
#define ADC_IN1 GPIOv_from_PORT_PIN(GPIO_port_D, 6) //PD6 port
int main() {
SystemInit(); // デバイスの初期化
GPIO_port_enable(GPIO_port_D); // gpio Dポートを活性化
GPIO_pinMode(ADC_IN1, GPIO_pinMode_I_analog, GPIO_Speed_In); // gpioの補給クロックとpinをアナログ入力に設定
GPIO_ADCinit();
printf("Start GPIO ADC input !\n\r");
uint16_t analog_input_data,analog_data;
while(1){
analog_data = GPIO_analogRead(GPIO_Ain6_D6); // 該当のpinにアナログ入力する
analog_input_data = analog_data*32;
printf("ADC = %d (%x)\n\r",analog_input_data,analog_data);
Delay_Ms(500);
}
}
上記プログラムをGPIO_adc.cとして保存します。
all : flash
TARGET:=GPIO_adc
CH32FUN=$(HOME)/ch32fun/ch32fun
TARGET_MCU?=CH32V003
include ~/ch32fun/ch32fun/ch32fun.mk
flash : cv_flash
clean : cv_clean
Makefileとして保存します。
funconfig.hを~/ch32fun/examples/GPIOからコピーします。何も編集はしません。
これで必要なファイルが揃いました。
~/prog/ch32v003/ch32fun/GPIO_ADC01 $ ls
GPIO_adc.c Makefile funconfig.h
WCH-LinkEをusbに差して、makeします。
~/prog/ch32v003/ch32fun/GPIO_ADC01 $ make
riscv64-unknown-elf-gcc -E -P -x c -DTARGET_MCU=CH32V003 -DMCU_PACKAGE=1 -DTARGET_MCU_LD=0 -DTARGET_MCU_MEMORY_SPLIT= /home/rika/ch32fun/ch32fun/ch32fun.ld > /home/rika/ch32fun/ch32fun/generated__.ld
riscv64-unknown-elf-gcc -o GPIO_adc.elf /home/rika/ch32fun/ch32fun/ch32fun.c GPIO_adc.c -g -Os -flto -ffunction-sections -fdata-sections -fmessage-length=0 -msmall-data-limit=8 -march=rv32ec -mabi=ilp32e -DCH32V003 -static-libgcc -I/usr/include/newlib -I/home/rika/ch32fun/ch32fun/../extralibs -I/home/rika/ch32fun/ch32fun -nostdlib -I. -Wall -Wl,--print-memory-usage -Wl,-Map=GPIO_adc.map -L/home/rika/ch32fun/ch32fun/../misc -lgcc -lgcc -T /home/rika/ch32fun/ch32fun/generated__.ld -Wl,--gc-sections
Memory region Used Size Region Size %age Used
FLASH: 1748 B 16 KB 10.67%
RAM: 0 GB 2 KB 0.00%
riscv64-unknown-elf-objdump -S GPIO_adc.elf > GPIO_adc.lst
riscv64-unknown-elf-objcopy -O binary GPIO_adc.elf GPIO_adc.bin
riscv64-unknown-elf-objcopy -O ihex GPIO_adc.elf GPIO_adc.hex
make -C /home/rika/ch32fun/ch32fun/../minichlink all
make[1]: ディレクトリ '/home/rika/ch32fun/minichlink' に入ります
make[1]: 'all' に対して行うべき事はありません.
make[1]: ディレクトリ '/home/rika/ch32fun/minichlink' から出ます
/home/rika/ch32fun/ch32fun/../minichlink/minichlink -w GPIO_adc.bin flash -b
Found WCH Link
WCH Programmer is LinkE version 2.18
Detected CH32V003
Flash Storage: 16 kB
Part UUID: 57-5f-ab-cd-c0-80-bd-54
Part Type: 00-33-05-10
Read protection: disabled
Interface Setup
Writing image
Image written.
minichlinkを通して、printf文の内容を読み出します。
~/prog/ch32v003/ch32fun/GPIO_ADC01 $ minichlink -T
Found WCH Link
WCH Programmer is LinkE version 2.18
Detected CH32V003
Flash Storage: 16 kB
Part UUID: 57-5f-ab-cd-c0-80-bd-54
Part Type: 00-33-05-10
Read protection: disabled
Interface Setup
Terminal started
Start GPIO ADC input !
ADC = 32736 (3ff)
ADC = 32736 (3ff)
ADC = 32736 (3ff)
ADC = 32736 (3ff)
ADC = 32736 (3ff)
ADC = 32736 (3ff)
ADC = 32736 (3ff)
ADC = 32736 (3ff)
ADC = 32736 (3ff)
ADC = 32736 (3ff)
ADC = 32736 (3ff)
ADC = 31456 (3d7)
ADC = 28992 (38a)
ADC = 25824 (327)
ADC = 22752 (2c7)
ADC = 14944 (1d3)
ADC = 10400 (145)
ADC = 5824 (b6)
ADC = 96 (3)
ADC = 224 (7)
ADC = 64 (2)
ADC = 96 (3)
ADC = 64 (2)
ADC = 96 (3)
ADC = 64 (2)
ADC = 96 (3)
ADC = 64 (2)
[1]+ 停止 minichlink -T
読み出した値は、読み込んだADCに32倍した値と、()内はADCそのものの値です。
下記の電圧変換値は、あくまでも参考値です。読み取りの精度を表したものではありません。
テスタと比べた値は下記の通りです
テスタ値 ADC*32 ADC(hex)
3.263 32567 3fa
3.010 30432 3b7
2.243 22404 2ba
1.251 12480 186
0.617 6304 c5
0.359 3680 73
0.0 64 2
下記の回路は、人感センサーと明暗センサーを使用して、暗いときに人が近づくとLEDが点灯するものです。
人感センサーには、SR602を、明暗センサーには、CdSセンサー(R3)を使用しました。
回路図は下記のとおりです。
人感センサーPC1(5pin)にHレベルが入力されたとき(人は近づいたとき)、PD6(1pin)に入力されたCdSセンサーと100Kとの分圧値はADC変換されます。入力されたADCの値は、IF文によりしきい値と比較されるコンパレータ的なプログラムにより、明るい/暗いの2値の値になります。ここではしきい値として800を設定しています。しきい値以上であれば、暗いと認識し、約12秒LEDを点灯します。
プログラムが下記のとおりです。
//CH32V003J4M6 8pin GPIO LED 人感/明暗センサー プログラム
#include "ch32fun.h"
#include "ch32v003_GPIO_branchless.h"
#include <stdio.h>
// 該当LEDと出力PINとの関連付け
#define LED1 GPIOv_from_PORT_PIN(GPIO_port_C, 2) //C2 port output
#define ADC_IN1 GPIOv_from_PORT_PIN(GPIO_port_D, 6) //D6 port ADC
// 該当SWと入力PINとの関連付け
#define SW1 GPIOv_from_PORT_PIN(GPIO_port_C, 1) //C1 port input
int main() {
SystemInit(); // デバイスの初期化
GPIO_port_enable(GPIO_port_C); // gpio Cポートを活性化
GPIO_port_enable(GPIO_port_D); // gpio Dポートを活性化
GPIO_pinMode(LED1, GPIO_pinMode_O_openDrainMux, GPIO_Speed_10MHz); // gpioの補給クロックとpinを出力に設定
GPIO_pinMode(SW1, GPIO_pinMode_I_pullUp, GPIO_Speed_In); // gpioの補給クロックとpinを入力に設定
GPIO_pinMode(ADC_IN1, GPIO_pinMode_I_analog, GPIO_Speed_In); // gpioの補給クロックとpinをアナログ入力に設定
GPIO_ADCinit();
uint16_t analog_data;
printf("Start GPIO !\n\r");
GPIO_digitalWrite(LED1, low); // 該当のpin出力をHレベルにする
while(1){
while(GPIO_digitalRead(SW1) == 1) {
// printf("SW input \n\r");
analog_data = GPIO_analogRead(GPIO_Ain6_D6); // 該当のpinにアナログ入力する
// printf("data = %d \n\r",analog_data);
if(analog_data >= 800){
// printf("LED = %d \n\r",analog_data);
GPIO_digitalWrite(LED1, high); // 該当のpin出力をHレベルにする
Delay_Ms( 12000 );
GPIO_digitalWrite(LED1, low); // 該当のpin出力をLレベルにする
}
GPIO_digitalWrite(LED1, low); // 該当のpin出力をLレベルにする
}
}
}
上記プログラムをGPIO_adc_jinkan.cとして保存します。
Makefileを作成します。
all : flash
TARGET:=GPIO_adc_jinkan
CH32FUN=$(HOME)/ch32fun/ch32fun
TARGET_MCU?=CH32V003
include ~/ch32fun/ch32fun/ch32fun.mk
flash : cv_flash
clean : cv_clean
funconfig.hを~/ch32fun/examples/GPIOからコピーします。何も編集はしません。
これで必要なファイルが揃いました。
~/prog/ch32v003/ch32fun/GPIO_ADC02 $ ls
GPIO_adc_jinkan.c Makefile funconfig.h
WCH-LinkEをusbに差して、makeします。
~/prog/ch32v003/ch32fun/GPIO_ADC02 $ make
riscv64-unknown-elf-gcc -E -P -x c -DTARGET_MCU=CH32V003 -DMCU_PACKAGE=1 -DTARGET_MCU_LD=0 -DTARGET_MCU_MEMORY_SPLIT= /home/rika/ch32fun/ch32fun/ch32fun.ld > /home/rika/ch32fun/ch32fun/generated__.ld
riscv64-unknown-elf-gcc -o GPIO_adc_jinkan.elf /home/rika/ch32fun/ch32fun/ch32fun.c GPIO_adc_jinkan.c -g -Os -flto -ffunction-sections -fdata-sections -fmessage-length=0 -msmall-data-limit=8 -march=rv32ec -mabi=ilp32e -DCH32V003 -static-libgcc -I/usr/include/newlib -I/home/rika/ch32fun/ch32fun/../extralibs -I/home/rika/ch32fun/ch32fun -nostdlib -I. -Wall -Wl,--print-memory-usage -Wl,-Map=GPIO_adc_jinkan.map -L/home/rika/ch32fun/ch32fun/../misc -lgcc -lgcc -T /home/rika/ch32fun/ch32fun/generated__.ld -Wl,--gc-sections
Memory region Used Size Region Size %age Used
FLASH: 1796 B 16 KB 10.96%
RAM: 0 GB 2 KB 0.00%
riscv64-unknown-elf-objdump -S GPIO_adc_jinkan.elf > GPIO_adc_jinkan.lst
riscv64-unknown-elf-objcopy -O binary GPIO_adc_jinkan.elf GPIO_adc_jinkan.bin
riscv64-unknown-elf-objcopy -O ihex GPIO_adc_jinkan.elf GPIO_adc_jinkan.hex
make -C /home/rika/ch32fun/ch32fun/../minichlink all
make[1]: ディレクトリ '/home/rika/ch32fun/minichlink' に入ります
make[1]: 'all' に対して行うべき事はありません.
make[1]: ディレクトリ '/home/rika/ch32fun/minichlink' から出ます
/home/rika/ch32fun/ch32fun/../minichlink/minichlink -w GPIO_adc_jinkan.bin flash -b
Found WCH Link
WCH Programmer is LinkE version 2.18
Detected CH32V003
Flash Storage: 16 kB
Part UUID: 57-5f-ab-cd-c0-80-bd-54
Part Type: 00-33-05-10
Read protection: disabled
Interface Setup
Writing image
Image written.
暗くして、人が近づくとLEDが点灯すると思います。