RT1176 LPADC

步骤一 在MCU CONFIG TOOLS配置对应引脚

在这里插入图片描述

步骤二

从上层往下,依次将
a. RTT层: rt-thread/components/drivers/misc/adc.c
b. 中间层:libraries/drv_lpadc.c
c. 硬件层:libraries/MIMXRT1176/drivers/fsl_lpadc.c
添加构建,

其中中间层的 drv_lpadc.c编译时报错,参照SDK做了些修改(注释掉的是修改前的代码)

static rt_err_t imxrt_hp_adc_convert(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value)
{
    //LPADC1 *base; //Modified by Hao 22/08/01
    ADC_Type *base;
    lpadc_conv_command_config_t mLpadcCommandConfigStruct;
    lpadc_conv_trigger_config_t mLpadcTriggerConfigStruct;
    lpadc_conv_result_t mLpadcResultConfigStruct;
    //base = (LPADC1_BASE *)(device->parent.user_data); //Modified by Hao 22/08/01
    base = (ADC_Type *)(device->parent.user_data);

步骤三 编写自己的应用 之ADC设置

RTT官方链接
RTT对ADC的操作流程如下,但一次只能读取单个通道的数据,效率不高,所以根据应用编写自己的代码

#include <rtthread.h>
#include <rtdevice.h>

#define ADC_DEV_NAME        "adc1"      /* ADC 设备名称 */
#define ADC_DEV_CHANNEL     5           /* ADC 通道 */
#define REFER_VOLTAGE       330         /* 参考电压 3.3V,数据精度乘以100保留2位小数*/
#define CONVERT_BITS        (1 << 12)   /* 转换位数为12位 */

static int adc_vol_sample(int argc, char *argv[])
{
    rt_adc_device_t adc_dev;
    rt_uint32_t value, vol;
    rt_err_t ret = RT_EOK;

    /* 查找设备 */
    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;
    }

    /* 使能设备 */
    ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL);

    /* 读取采样值 */
    value = rt_adc_read(adc_dev, ADC_DEV_CHANNEL);
    rt_kprintf("the value is :%d \n", value);

    /* 转换为对应电压值 */
    vol = value * REFER_VOLTAGE / CONVERT_BITS;
    rt_kprintf("the voltage is :%d.%02d \n", vol / 100, vol % 100);

    /* 关闭通道 */
    ret = rt_adc_disable(adc_dev, ADC_DEV_CHANNEL);

    return ret;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(adc_vol_sample, adc voltage convert sample);

我的需求是,一次性读取11个电位器的数据,
RT176的ADC分成两部分,ADC1和ADC2,

在这里插入图片描述
特别的是ADC1 的 channel1,还分成了 sideA 和 sideB

所以正常调用 RTT的接口,无法读取sideB的数据。

那么如何操作,能读取到sideB的数据?
lpadc_conv_command_config_t mLpadcCommandConfigStruct1;
mLpadcCommandConfigStruct1.sampleChannelMode = kLPADC_SampleChannelSingleEndSideB;
接下来问题又来了,怎么连续读取几次数据呢?
mLpadcCommandConfigStruct1.enableAutoChannelIncrement = true;
mLpadcCommandConfigStruct1.loopCount = 4; 
//假如读取的第一个通道是 channel0,那么loopCount=4,就会读取channel0-4,一共5个通道的数据
那么怎么一次触发就读完 sideA 和 sideB的数据?
mLpadcCommandConfigStruct1.chainedNextCommandNumber = 2;
//比如读取sideA五个通道的指令为1号,读取sideB四个通道的指令是2号,这句话的意思是,执行完1号指令就会执行2号指令

步骤四 编写自己的应用之 读取数据

以下是NXP RT1176的代码,可以看出每次只会返回一个32位的数据,
但我们有11个通道怎么办?

bool LPADC_GetConvResult(ADC_Type *base, lpadc_conv_result_t *result)
{
    assert(result != NULL); /* Check if the input pointer is available. */

    uint32_t tmp32;

    tmp32 = base->RESFIFO;

    if (0U == (ADC_RESFIFO_VALID_MASK & tmp32))
    {
        return false; /* FIFO is empty. Discard any read from RESFIFO. */
    }

    result->commandIdSource = (tmp32 & ADC_RESFIFO_CMDSRC_MASK) >> ADC_RESFIFO_CMDSRC_SHIFT;
    result->loopCountIndex = (tmp32 & ADC_RESFIFO_LOOPCNT_MASK) >> ADC_RESFIFO_LOOPCNT_SHIFT;
    result->triggerIdSource = (tmp32 & ADC_RESFIFO_TSRC_MASK) >> ADC_RESFIFO_TSRC_SHIFT;
    result->convValue = (uint16_t)(tmp32 & ADC_RESFIFO_D_MASK);

    return true;
}

NXP都帮我们想好了,每次都读回来的数据,
都会带着 commandIdSource 和 loopCountIndex
也就是前面说到的几号指令,和循环读取的次数。
这样我们就能知道是sideA或B,第几个通道的数据了

uint32_t = g_LpadcmyResultShift = 3
static rt_err_t my_adc_convert()
{
    lpadc_conv_result_t mLpadcResultConfigStruct;
    while(1)
    {
       LPADC_DoSoftwareTrigger(base, 1U);
       for(uint8_t i=0;i<9;i++)
       {
           while (!LPADC_GetConvResult(base, &mLpadcResultConfigStruct))
           {
				//等待读取结束
           }
           ReadVal[i]  = (mLpadcResultConfigStruct.convValue) >> g_LpadcmyResultShift;
           rt_kprintf("Channel%d = %d\n",i,ReadVal[i] );
       }
       rt_thread_mdelay(2000);
    }

碰到的坑

1. 关于VREFH
读取AD值时发现,电位器的中间值不是 2048(12bit的最大值,4096的一半),而是3500左右
后来发现2V之后,读取的AD值就已经满4096了,原因在引脚 ADC_VREFH

在这里插入图片描述
如果输入电压是 1.8V,那么量程就是 0 - 1.8V。
但是电位器接的是 3V3,是不是就没办法了呢??

RT1176还提供了缩放量程的功能,在ADC设置时打开就可以了

mLpadcCommandConfigStruct1.sampleScaleMode = kLPADC_SamplePartScale;
//    kLPADC_SamplePartScale = 0U, /*!< Use divided input voltage signal. (Factor of 30/64). */

比如现在接入的是 1.8V, 选择这个模式之后,上限变成 1.8 * 64 / 30 = 3.84V,完全可以覆盖3.3V。
所以1.6V读取到的AD值约为 1650 左右,这样问题就解决了

  1. 10月24日更新
    连续采样的command需要是同一个ADC下的,比如同样是ADC1的指令,否则数据采集不到
    所以采集两个ADC的数据,可以按照下面这样写
lpadc_conv_result_t mLpadcResultConfigStruct;

	LPADC_DoSoftwareTrigger(LPADC2, 1U);
	for(uint8_t i=0;i<4;i++)
	 {
		 while (!LPADC_GetConvResult(LPADC2, &mLpadcResultConfigStruct))
		 {
				
		 }
		 ReadVal[i]  = (mLpadcResultConfigStruct.convValue) >> g_LpadcResultShift;
	 }
	 LPADC_DoSoftwareTrigger(LPADC1, 2U);
	 while (!LPADC_GetConvResult(LPADC1, &mLpadcResultConfigStruct))
	{
			
	 }
	 ReadVal[4]  = (mLpadcResultConfigStruct.convValue) >> g_LpadcResultShift;
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: NXP RT1176是一款嵌入式处理器,支持UVC(USB Video Class)协议。UVC是一种用于传输视频数据的标准协议,可以在实时应用、监控、远程会议等场景中使用。 NXP RT1176 UVC Demo是基于该处理器开发的演示程序。该演示程序通过连接一个摄像头,实现了将摄像头捕获的视频数据传输到计算机上显示的功能。 演示程序首先利用RT1176处理器的媒体处理能力,实时采集摄像头输出的视频数据。然后,通过USB接口将视频数据传输到计算机上。计算机上安装了合适的UVC驱动程序后,可以自动识别并接收RT1176传输的视频数据。 在计算机上,用户可以使用视频播放软件或者流媒体应用程序来查看和处理RT1176传输的视频数据。用户可以实时观看摄像头捕获的画面,进行录制、拍照等操作。同时,经过RT1176处理器的硬件加速,视频质量和帧率也能得到保证。 NXP RT1176 UVC Demo的开发可为用户提供了一种快速开发基于UVC协议的视频应用的途径。用户可以基于该演示程序进行二次开发,定制自己的视频产品或者应用。 ### 回答2: NXP RT1176是一款高性能的嵌入式处理器芯片,支持多媒体应用和图像处理。UVC(USB Video Class)是一种标准的USB视频设备协议,用于将视频数据传输到计算机上。 NXP RT1176 UVC Demo是基于该芯片的UVC演示项目。这个演示项目通过使用RT1176芯片的视频编解码能力,实现了将图像数据传输到计算机上,并在计算机上显示出来的功能。 在这个演示项目中,RT1176芯片负责从摄像头获取视频数据,并对数据进行编码处理,然后通过USB接口将编码后的数据传输到计算机上。计算机上的UVC驱动程序负责接收并解码这些数据,最后将视频图像显示在计算机的屏幕上。 通过这个演示项目,我们能够看到RT1176芯片强大的处理能力和优秀的图像处理性能。它可以实时采集、编码和传输视频数据,使我们能够方便地在计算机上观看图像。 除了视频传输功能,NXP RT1176还具有丰富的外设接口和强大的计算能力,可以广泛应用于智能摄像头、机器视觉、人工智能等领域。它的高性能和灵活性能够满足不同应用的需求,为用户提供更好的视觉体验。 总之,NXP RT1176 UVC Demo展示了RT1176芯片的视频处理能力和UVC协议的应用。通过这个演示项目,人们可以更好地了解和体验这款芯片的特性,为开发各种视频应用提供参考和灵感。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值