请问怎样利用M3中的ADC,同时实现数据采集和触摸屏控制
[复制链接]
背景:已经有很多例程实现了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()在主循环中调用 - 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图形系统处理控件事件 - 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\r",ulLoop,ulADC0_Value[ulLoop]); UARTprintf("TouchX = %3d,",g_sTouchX); UARTprintf("TouchY = %3d.\r",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) { } }
复制代码
|