背景:已经有很多例程实现了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
",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)
{
}
}
复制代码
此帖出自
小平头技术问答
一周热门 更多>