请问怎样利用M3中的ADC,同时实现数据采集和触摸屏控制

2019-03-24 11:44发布

背景:已经有很多例程实现了ADC数据采集,TI也提供了基于M3片内ADC的触摸屏驱动,但同时实现数据采集和触摸屏控制的例程并没有想法:由于M3只有一颗或两颗ADC集成在内,如果尽量保证数据采集,触摸屏只能在一轮数据采集完成间隙,通过轮询方式,使用ADC,获取坐标值,执行相应的触摸事件处理。难点:1)TI提供的触摸屏驱动采用定时器触发(ADC_TRIGGER_TIMER)方式,每毫秒自动触发ADC获取触摸屏信息一次,需要改为处理器触发(ADC_TRIGGER_PROCESSOR)方式,由程序控制触发,便于保证数据采样不受干扰;2)处理器触发获得的触摸屏事件和坐标需要传递给StellarisWare图形库的控件wedge;3)ADC工作状态切换。当前进展:上述1)已经实现,后文附代码;上述2)出现了wedge不能响应触摸屏的问题,求解,代码已包含在1)中;上述3)还没有进行。请教大家,以上思路有没有问题,出现的问题该怎样解决。另外可否用M3咬尾中断,使得每次数据采样结束自动触发触摸屏坐标采样。谢谢!【附代码】1.触摸屏驱动-只修改了启动初始化代码-修改计时器定时触发为处理器触发-由于处理器软件触发,禁止了触摸屏ADC中断-去除触摸屏中断服务子程序在中断向量表中的调用,改由main()在主循环中调用
  1. void
    TouchScreenInit(void)
    {
    //
    // Set the initial state of the touch screen driver's state machine.
    //
    g_ulTSState = TS_STATE_INIT;

    //
    // There is no touch screen handler initially.
    //
    g_pfnTSHandler = 0;

    //
    // 第一步,使能相关部件
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); // 使能ADC0
    SysCtlPeripheralEnable(TS_X_PERIPH); // 使能触摸屏输入
    SysCtlPeripheralEnable(TS_Y_PERIPH); // 使能触摸屏输入
    // SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    // 由Timer0计数中断改为处理器事件驱动,因此不用使能计数器
    GPIOPinTypeADC(TS_Y_BASE, GPIO_PIN_2);
    //
    // 第二步,配置ADC
    //
    // SysCtlADCSpeedSet(SYSCTL_ADCSPEED_125KSPS);
    // 1、设置ADC采样速率
    // 此处不设置ADC采样率,而是Timer0或处理器调用一次触摸屏时,ADC采样一次

    ADCSequenceDisable(ADC_BASE, 0);
    // 2、配置采用序列前先禁止采样序列

    ADCHardwareOversampleConfigure(ADC0_BASE, 4);
    // 设定ADC0为4倍过采样,因为一个触摸屏坐标值共由XP XN YP YN四个值确定

    ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_PROCESSOR, 0);
    // 3、采样序列设置:ADC基址0,采样序列3,处理器触发事件,采样优先级为0

    ADCSequenceStepConfigure(ADC0_BASE, // 4、采样序列步进设置:ADC0基址,
    3, // 采样序列3,
    0, // 第0步,
    ADC_CTL_CH_YP | // 采样通道ADC_CTL_CH_YP即ADC_CTL_CH6
    // 由于前面配置了4倍过采样,YP最后被采样后产生中断
    ADC_CTL_END | // 采样结束
    ADC_CTL_IE); // 申请中断

    ADCSequenceEnable(ADC0_BASE, 3);
    // 5、重新使能ADC序列

    //
    // 6、Clear the interrupt status flag. This is done to make sure the
    // interrupt flag is cleared before we sample.
    //
    // ADCIntClear(ADC0_BASE, 3);

    //
    // 第三步,启动中断
    //
    // ADCIntEnable(ADC0_BASE, 3); // 使能ADC中断
    // IntEnable(INT_ADC0SS3); // 使能ADC采样序列中断

    //
    // Configure the GPIOs used to drive the touch screen layers.
    //
    GPIOPinTypeGPIOOutput(TS_X_BASE, TS_XP_PIN | TS_XN_PIN);
    GPIOPinTypeGPIOOutput(TS_Y_BASE, TS_YP_PIN | TS_YN_PIN);
    GPIOPinWrite(TS_X_BASE, TS_XP_PIN | TS_XN_PIN, 0x00);
    GPIOPinWrite(TS_Y_BASE, TS_YP_PIN | TS_YN_PIN, 0x00);

    /* //
    // See if the ADC trigger timer has been configured, and configure it only
    // if it has not been configured yet.
    //
    if((HWREG(TIMER0_BASE + TIMER_O_CTL) & TIMER_CTL_TAEN) == 0)
    {
    //
    // Configure the timer to trigger the sampling of the touch screen
    // every millisecond.
    //
    TimerConfigure(TIMER0_BASE, (TIMER_CFG_16_BIT_PAIR |
    TIMER_CFG_A_PERIODIC |
    TIMER_CFG_B_PERIODIC));
    TimerLoadSet(TIMER0_BASE, TIMER_A, (SysCtlClockGet() / 1000) - 1);
    TimerControlTrigger(TIMER0_BASE, TIMER_A, true);

    //
    // Enable the timer. At this point, the touch screen state machine
    // will sample and run once per millisecond.
    //
    TimerEnable(TIMER0_BASE, TIMER_A);
    }*/
    }
复制代码

2.主循环-加入了触摸屏采样触发,每次循环触发一次采样-在采样后调用触摸屏中断服务子程序来处理获得的坐标,并传递触摸屏事件和坐标到控件wedge-通知StellarisWare图形系统处理控件事件
  1. int
    main(void)
    {

    //
    // Set the system clock to run at 25MHz from the PLL
    //
    SysCtlClockSet(SYSCTL_SYSDIV_8 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
    SYSCTL_XTAL_8MHZ);

    //
    // 全局允许中断。
    //
    IntMasterEnable();

    //
    // Initialize the display driver.
    //
    Kitronix320x240x16_SSD2119Init();

    //
    // 初始化显示驱动程序。
    //
    Kitronix320x240x16_SSD2119BacklightOn(255);

    //
    // 初始化串口
    //
    InitConsole();

    //
    // 初始化触摸驱动程序。
    //
    TouchScreenInit();

    //
    // 设置触摸驱动凼数的回调凼数为图形库的处理凼数。
    //
    TouchScreenCallbackSet(WidgetPointerMessage);

    //
    // 将g_sBackground以下的控件加入控件树。
    //
    WidgetAdd(WIDGET_ROOT, (tWidget *)&g_sBackground);

    //
    // 绘制控件树中的所有控件。
    //
    WidgetPaint(WIDGET_ROOT);

    //
    // 主循环。
    //
    while(!g_bFirmwareUpdate)
    {

    //
    // 处理器触发一次触摸屏使用的ADC0之采样序列3,获取XP XN YP YN中的一个
    //
    ADCProcessorTrigger(ADC0_BASE, 3);
    // 等待触摸屏采样结束
    while(!ADCIntStatus(ADC0_BASE, 3, false))
    {
    }

    //
    // 读取采样序列值,XP XN YP YN中的一个值
    //
    // ADCSequenceDataGet(ADC0_BASE, 3, &ulADC0_Value[ulLoop]);
    //
    // Display the value on the console.
    //
    //UARTprintf("Touch Values%1d = %4d ",ulLoop,ulADC0_Value[ulLoop]);
    UARTprintf("TouchX = %3d,",g_sTouchX);
    UARTprintf("TouchY = %3d. ",g_sTouchY);
    //
    // 触摸屏中断服务子程序:配置ADC,获得触摸屏坐标,传递触屏事件
    //
    TouchScreenIntHandler();

    //
    // 处理所有控件事件。
    //
    WidgetMessageQueueProcess();

    }

    //
    // Process the message queue once more to make absolutely sure that the
    // last screen repaint takes place.
    //
    WidgetMessageQueueProcess();

    //
    // Transfer control to the bootloader to allow remote firmware update
    // via the serial port.
    //
    JumpToBootLoader();

    //
    // The boot loader should take control, so this should never be reached.
    // Just in case, loop forever.
    //
    while(1)
    {
    }
    }
复制代码

此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
8条回答
mangoal
2019-03-25 17:15
 精彩回答 2  元偷偷看……0人看过

一周热门 更多>

相关问题

    相关文章