OS version: RT thread 4.0.0
Chip: STM32F407
The following is the reference provider provided by the official ADC
Access ADC device
The application program accesses the ADC hardware through the ADC device management interface provided by RT thread, and the relevant interfaces are as follows:
function | describe |
---|---|
rt_device_find() | Find device and get device handle according to ADC device name |
rt_adc_enable() | Enable ADC device |
rt_adc_read() | Read ADC device data |
rt_adc_disable() | Turn off ADC device |
Here is a brief analysis of the main implementation methods of the driver source code:
In DRV? ADC. C, there is no support for RT? Using? Device? OPS item. Add the following code
#Ifdef RT? Using? Device? OPS / / added support for RT? Using? Device? Ops const static struct rt_device_ops adc_ops = { RT_NULL, RT_NULL, RT_NULL, _adc_read, RT_NULL, _adc_control }; #endif rt_err_t rt_hw_adc_register(rt_adc_device_t device, const char *name, const struct rt_adc_ops *ops, const void *user_data) { rt_err_t result = RT_EOK; RT_ASSERT(ops != RT_NULL && ops->convert != RT_NULL); device->parent.type = RT_Device_Class_Miscellaneous; #ifdef RT_USING_DEVICE_OPS device->parent.ops = &adc_ops; #else device->parent.init = RT_NULL; device->parent.open = RT_NULL; device->parent.close = RT_NULL; device->parent.read = _adc_read; device->parent.write = RT_NULL; device->parent.control = _adc_control; #endif device->ops = ops; device->parent.user_data = (void *)user_data; result = rt_device_register(&device->parent, name, RT_DEVICE_FLAG_RDWR); return result; }
Among them, the device ops interface needs to realize ADC ﹣ ops
const static struct rt_device_ops adc_ops = { RT_NULL, RT_NULL, RT_NULL, _adc_read, RT_NULL, _adc_control };
The subclass of device, RT ﹣ ADC ﹣ device, needs to implement the OPS of RT ﹣ ADC ﹣ ops
static const struct rt_adc_ops stm_adc_ops = { .enabled = stm32_adc_enabled, .convert = stm32_get_adc_value, };
Where, call STM32 ADC enabled, call STM32 get ADC value;
In the official example, in order to simplify the ADC driver operation, directly export the relevant ADC operation functions for the user to use, as follows:
rt_adc_device_t adc_dev; rt_uint32_t value, vol; rt_err_t ret = RT_EOK; /* Search device */ adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME); if (adc_dev == RT_NULL) { rt_kprintf("adc sample run failed! can't find %s device!\n", ADC_DEV_NAME); return RT_ERROR; } /* Enabling equipment */ ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL); /* Read sample value */ value = rt_adc_read(adc_dev, ADC_DEV_CHANNEL); rt_kprintf("the value is :%d \n", value); /* Convert to corresponding voltage value */ vol = value * REFER_VOLTAGE / CONVERT_BITS; rt_kprintf("the voltage is :%d.%02d \n", vol / 100, vol % 100); /* Close channel */ ret = rt_adc_disable(adc_dev, ADC_DEV_CHANNEL);
Since there is an I/O device model, the driver interface is too scattered by using this method. Here is an example of adc collection using the I/O device interface:
When using RT? Device? Read, pay attention to the meaning of pos and size
rt_device_t adc_dev = rt_device_find(ADC_DEV_NAME); rt_device_open(adc_dev, RT_DEVICE_FLAG_RDWR); //Remember to open the device, otherwise the rt_device_read unavailable ret = rt_device_control(adc_dev, RT_ADC_CMD_ENABLE, (void*)ADC_DEV_CHANNEL); //Enable ADC ret = rt_device_read(adc_dev, ADC_DEV_CHANNEL, &value, 4); //When the program is not modified,_adc_read Functional pos Item representation adc Passageway size Is a multiple of 4. If it is greater than 4, the subsequent channels will be read in order // value = rt_adc_read((rt_adc_device_t)adc_dev, ADC_DEV_CHANNEL); rt_kprintf("the value is :%d %d %d\n", value, ret, *_rt_errno()); vol = value * REFER_VOLTAGE / CONVERT_BITS; rt_kprintf("the voltage is :%d.%02d \n", vol / 100, vol % 100); ret = rt_device_control(adc_dev, RT_ADC_CMD_DISABLE, (void*)ADC_DEV_CHANNEL); //prohibit ADC