qlb1234 发表于 2009-10-13 20:43:07

[教程]手把手教你用AVR Studio+WinAVR+QTouch Lib点亮蜗牛触摸板

鉴于早期的QTouch Lib都只支持用IAR编译的,官方的程序范例也是IAR的,所以特别针对AVR Studio和论坛上的蜗牛触摸板,教大家在AVR Studio中使用QTouch Lib。由于本人水平有限,难免有错漏之处,欢迎大家指正。

首先,确定你有下面这些东西。

1、爱特梅尔QTouch库用户指南(原名:Atmel QTouch Library User Guide)。这里建议大家使用最新版本。
http://www.atmel.com/dyn/resources/prod_documents/doc8207.pdf

2、AVR Studio 4.17 build 666
http://www.atmel.com/forms/software_download.asp?fn=dl_AvrStudio417Setup.exe(下载前需注册)

3、WinAVR-20090313
http://downloads.sourceforge.net/project/winavr/WinAVR/20090313/WinAVR-20090313-install.exe

4、Atmel QTouch Library 3.0
http://www.atmel.com/forms/software_download.asp?fn=dl_Atmel_QTouch_Libraries_3.0.exe

安装好AVR Studio、WinAVR和Atmel QTouch Library后,运行AVR Studio,新建一个工程,在左方工程名上点击右键,选择“Edit Configuration Options...”。
http://cache.amobbs.com/bbs_upload782111/files_20/ourdev_491219.JPG
在工程名上点击右键 (原文件名:1.JPG)






选择“Include Directories”,再点右上方的按钮“New(Insert)”,添加库里面包含文件的路径。默认安装的话,路径是“C:\Program Files\Atmel\Atmel QTouch Libraries 3.0\include\”。

http://cache.amobbs.com/bbs_upload782111/files_20/ourdev_491220.JPG
设置包含文件目录 (原文件名:2.JPG)






选择“Libraries”,同样点击右上方的按钮“New(Insert)”,添加库文件的路径。默认安装的话,路径是“C:\Program Files\Atmel\Atmel QTouch Libraries 3.0\megaAVR, tinyAVRand XMEGA libray\QTouch library\library files\”。此时,再在“Available Link”里选“libavr4g2-8qt-k-2rs.a”,点击“Add Library --”按钮。下文将解释为什么要选这个。
http://cache.amobbs.com/bbs_upload782111/files_20/ourdev_491221.JPG
加入库 (原文件名:3.JPG)





接下来就可以动手写代码了。
要使用QTouch Lib里的函数,必须包含touch_api.h。这个文件在默认的情况下,在“C:\Program Files\Atmel\Atmel QTouch Libraries 3.0\include\”里面。而上面我们已经把这个目录添加为包含目录了,所以就可以省去冗长的路径,直接写出文件名。
#include"touch_api.h"

然而,在包含这个目录之前,QTouch Lib还要求我们先对几个参数进行定义,定义的方法是预编译。
#define _QTOUCH_
#define QT_NUM_CHANNELS 8
#define QT_MAX_NUM_ROTORS_SLIDERS 2
#define _ROTOR_SLIDER_
#define SNSK B
#define SNS D
#define QT_DELAY_CYCLES 10

_QTOUCH_
使用QTouch技术,而非其它时,需作此声明。

QT_NUM_CHANNELS
这是感应通道的总数。应注意,这个定义必须和所选的库一致,即为8。即使你只使用了1个通道,也务必请你定义成“8”,否则将不能正常工作。

QT_MAX_NUM_ROTORS_SLIDERS 2
这是滑轮和滑条的最大总数目。这里,我们包含的库最多只支持两个,而蜗牛触摸板上也刚好只有一个滑轮和一个滑条,1+1=2。

_ROTOR_SLIDER_
若使用滑轮和滑条,需作此声明。

SNSK
这是感应按键的端口。这一端通过一个电阻连接到按键。

SNS
这是感应端口,通过一个电容后连接到SNSK。

QT_DELAY_CYCLES
延迟的时钟周期个数,需要根据工作频率设定。

再次提醒,包含touch_api.h前,需作上述定义。

定义好以后,就可以包含头文件了。这里我们用到了三个头文件。
#include"avr\io.h"
#include"avr\interrupt.h"
#include"touch_api.h"

要使用QTouch技术的话,I/O口的内部上拉电阻必须禁用。方法是让MCUCR里的PUD置位。
MCUCR|=(1<<PUD);

接下来就可以定义按键、滑轮和滑条了。定义按键,用qt_enable_key()函数。这个函数有四个参数,分别是通道编号、邻键抑制组、重校正门限百分比和滞后百分比。
按照手册上的说法,连接I/O口第1位的,为通道1,以次类推。按照这个说法,A键应为通道6。实际试验下,A键也确实为通道6,B键为通道7。原理图上的标注有误。
我们来定义A键。
qt_enable_key(CHANNEL_6, NO_AKS_GROUP, RECAL_12_5, HYST_25);

如果想同时使用A键和B键,只需在定义完A键后,继续定义B键即可。我们再来定义B键。
qt_enable_key(CHANNEL_7, NO_AKS_GROUP, RECAL_12_5, HYST_25);

定义滑轮和滑条的方法与按键一样,只是所使用的函数和参数不一样,在这里不再展开叙述,请参考官方说明文档。
定义滑轮用qt_enable_rotor()。
qt_enable_rotor(CHANNEL_3, CHANNEL_5, NO_AKS_GROUP, 10u, HYST_50, RES_2_BIT, HYST_50);

滑条用qt_enable_slider()
qt_enable_slider(CHANNEL_0, CHANNEL_2, NO_AKS_GROUP, 10u, HYST_50, RES_2_BIT, HYST_50);

这样,我们的整个定义过程就完成了。
qt_enable_key(CHANNEL_6, NO_AKS_GROUP, RECAL_12_5, HYST_25);
qt_enable_key(CHANNEL_7, NO_AKS_GROUP, RECAL_12_5, HYST_25);
qt_enable_rotor(CHANNEL_3, CHANNEL_5, NO_AKS_GROUP, 10u, HYST_50, RES_2_BIT, HYST_50);
qt_enable_slider(CHANNEL_0, CHANNEL_2, NO_AKS_GROUP, 10u, HYST_50, RES_2_BIT, HYST_50);

定义完成后,需要让各个感应器初始化,方法是使用qt_init_sensing()函数。
qt_init_sensing();

这样,感应器就可以工作了。
QTouch的感应器,是不能产生中断的,所以我们要用查询的方法来检测按键、滑轮等的状态是否发生了变化。并且这个检测过程,也是要我们手动调用函数来进行的。想让QTouch检测各个通道的状态,需要调用qt_measure_sensors()。这个函数有一个参数,是当前系统的运行时间(或曰QTouch被开启的时间,手册上未明确说明)。这个时间是以毫秒为单位的,类型是unsigned int。所以,我们还需要开启一个定时器,来计算时间。在8MHz的时钟频率下,T1采用64分频,记数125次,恰好是1毫秒。于是我们定义一个全局变量hw_time_ms。
volatile unsigned int hw_time_ms;

每次命令QTouch去检测各通道的情况时,我们就用
qt_measure_sensors(hw_time_ms);

调用完这个函数后,可以通过查询sensor_states数组(其元素为unsigned char类型)来获取各感应器当前的状态。对于滑轮和滑条,则需查询数组rotor_slider_values。sensor_states位于结构体qt_touch_status_t里,而qt_touch_status_t则位于另一个结构体qt_touch_lib_measure_data_t当中。并且,qt_touch_lib_measure_data_t不需要我们去定义,touch_api.h已经帮我们做好了这个工作了。touch_api.h里有这样的语句
typedef struct tag_qt_touch_lib_measure_data_t
{
    /*   measured signal on each channel*/
    uint16_t channel_signals;
    /*   reference signal for each channel   */
    uint16_t channel_references;
    /*   state of sensors*/
    qt_touch_status_t qt_touch_status;
} qt_touch_lib_measure_data_t;
……
extern qt_touch_lib_measure_data_t qt_measure_data;

所以,在实际应用中,我们只需要这样写,便能查询按键A是否被按下了。
qt_measure_data.qt_touch_status.sensor_states[0]&0x01

sensor_states这个数组,第1个元素的第一位,记录着第1个感应器的状态。比如说上面的那条语句,就可以判断第1个感应器是否被触摸了。在这里,第1个感应器是A键。若为1,则表明A键被按下了;若为0,则表明未被按下。为什么第1位就代表按键A(通道6)呢?这涉及到一个顺序问题,将在下面统一讲解。

于是,查询程序可以这样编写。下面这段代码可以实现A键被按下时,A灯亮起;松开时,A灯熄灭。
while(1)
{
qt_measure_sensors(hw_time_ms);
if(qt_measure_data.qt_touch_status.sensor_states[0]&0x01)
PORTC&=~(1<<PC0);//A灯亮
else
PORTC|=(1<<PC0);//A灯灭
}

下面来解释感应器的顺序问题。如上文所述,为什么sensor_states[0]的第1位表示着按键A,即通道6的状态呢?原来我们在定义按键等时,是这样定义的。
qt_enable_key(CHANNEL_6, NO_AKS_GROUP, RECAL_12_5, HYST_25);//A键
qt_enable_key(CHANNEL_7, NO_AKS_GROUP, RECAL_12_5, HYST_25);//B键
qt_enable_rotor(CHANNEL_3, CHANNEL_5, NO_AKS_GROUP,10u,HYST_50, RES_2_BIT, HYST_50);//滑轮
qt_enable_slider(CHANNEL_0, CHANNEL_2, NO_AKS_GROUP,10u,HYST_50, RES_2_BIT, HYST_50);//滑条


我们第1行语句,就定义了通道6,这决定了通道6为感应器1。第2行语句定义了通道7,所以通道7为感应器2。同理,通道3——通道5(整个滑轮)为感应器3,通道0——通道2(整个滑条)为感应器4。而sensor_states是8位的,它的第1位告诉我们感应器1的通道(通道6)有没有被触摸,第2位告诉我们感应器2的通道(通道7)有没有被触摸。被触摸,即为1;未被触摸,当然就是0。而通道3、4、5(即感应器3的各个通道)中的任何一个通道被触摸,都会使sensor_states的第3位为1。同样,通道0、1、2(即感应器4的各个通道)中的任何一个通道被触摸,都会使sensor_states的第4位为1。
所以,在这个定义顺序下,当A键和滑条同时被触摸,而其余未被触摸时,sensor_states的值为0bXXXX1001(“X”表示该位因无感应器而无法判断)。而当B键和滑轮同时被触摸,而其它未然时,sensor_states的值应为0bXXXX0110。

若我们改变定义的顺序,成为下面的情形时,就要发生相应的改变了。
qt_enable_key(CHANNEL_6, NO_AKS_GROUP, RECAL_12_5, HYST_25);//A键
qt_enable_rotor(CHANNEL_3, CHANNEL_5, NO_AKS_GROUP, 10u, HYST_50, RES_2_BIT, HYST_50);//滑轮
qt_enable_key(CHANNEL_7, NO_AKS_GROUP, RECAL_12_5, HYST_25);//B键
qt_enable_slider(CHANNEL_0, CHANNEL_2, NO_AKS_GROUP, 10u, HYST_50, RES_2_BIT, HYST_50);//滑条

A键为感应器1,对应sensor_states的第1位;
滑轮为感应器2,对应sensor_states的第2位;
B键位感应器3,对应sensor_states的第3位;
滑条为感应器4,对应sensor_states的第1位。

另外,若通道超过8个,则第9个通道的被触标志位,会被安排到sensor_states的第1位;第10个通道的被触标志位,会被安排到sensor_states的第2位,以次类推。

滑轮和滑条除了能通过查询sensor_states来判断是否被触摸以外,还能通过查询rotor_slider_values来获取角度、位置信息。对于滑轮,rotor_slider_values中记录的是角度;对于滑条,记录的则是被触点离边缘的距离。
rotor_slider_values是个unsigned int类型的数组。它的第1个元素,是第1个被定义的滑轮(或滑条),以次类推。比如上面的两次定义,都是先定义滑轮,再定义滑条的,所以滑轮对应着rotor_slider_values,滑条对应着rotor_slider_values。
应当注意,rotor_slider_values里各感应器的顺序,是独立于sensor_states里的顺序的,即rotor_slider_values与sensor_states无关。如果你先定义了100个按键,再去定义1个滑轮,那么这个滑轮的角度仍然应当用rotor_slider_values去查询。若你想知道这个滑轮是否被碰到了,可以用sensor_states。sensor_states到sensor_states对应的是前面100个按键。

接下来,要讲的是库文件命名规则。我们选的库是libavr4g2-8qt-k-2rs.a。其中,“libavr4g2”是ATmega88这款芯片本身决定的,通过查手册获得。“8qt”表示这个库最多支持8个通道,“2rs”表示最多支持2个滑轮或滑条(两者之和)。

到这里,讲解就全部结束了。其余没有提到的部分(邻键抑制组、重校正门限百分比等)请自行参考手册。最后送上已经调通的代码和HEX文件。工作时钟为8MHz,-0s优化方式,不进行时钟分频。
[相关下载]
代码及HEX文件ourdev_491248.zip(文件大小:6K) (原文件名:Snail Touch.zip)

Gorgon_Meducer 发表于 2009-10-15 10:25:33

好帖子,第一个顶!

winmcu 发表于 2009-10-15 11:59:33

cool,

linyu0395 发表于 2009-10-15 19:58:18

非常好啊刚好在展会前需要这个

linyu0395 发表于 2009-10-16 12:03:03

qt_init_sensing()完之后出现错误提示啊

E:\Prog\Avrstudio\QTouch\default/../QTouch.c:25: undefined reference to `burst_10_DC'

请问一下这个是什么问题呢?

qlb1234 发表于 2009-10-16 13:01:35

楼上的朋友,能说一下详细的情况吗?
AVR Studio和QTouch Lib的版本是多少呢?
最后请你把代码发上来。

linyu0395 发表于 2009-10-16 15:15:40

我后来比较了一下好像不能设置 D和C 的口要不然就是那个提示

qlb1234 发表于 2009-10-16 17:42:49

请查阅手册7.1.5.1节,关于端口组合问题。红色部分是不能用的。
当SNSK为D时,SNS只能是D、E、F、G。

peak 发表于 2009-11-10 12:33:44

Thank you very much!

a1z26 发表于 2009-11-10 17:09:24

mark

qlb1234 发表于 2009-11-10 17:24:25

又被顶起了,标题还搞成了蓝色,呵呵。
可惜我的蜗牛小板板已经死翘翘了,唉。

joystring 发表于 2009-11-19 10:00:28

好贴,不顶不行啊,用的你的程序,A点不知道为什么点不亮,再仔细看看。

aduc812 发表于 2009-11-19 10:10:24

ding!

jerico 发表于 2009-12-7 17:35:09

讲得很好!

tanxu123 发表于 2009-12-26 21:52:20

讲得好详细谢谢了啊

liang.li 发表于 2010-2-6 16:27:03

讲得好详细谢谢了

xuetingxun2010 发表于 2010-3-9 11:23:44

受益了,谢谢,讲得好

xuetingxun2010 发表于 2010-3-21 09:46:27

我现在做了一个qmatrix,现在主攻防水部分,现在还没头绪的,希望楼顶指教下下。谢谢

neulq 发表于 2010-5-21 09:55:12

大家好

eric_wang 发表于 2010-5-21 10:34:16

好貼,頂一下!

hpdell 发表于 2010-7-14 16:12:14

行!!!!!!!!!!!!!11

sunjingwei1203 发表于 2010-7-28 11:02:10

好贴,楼主真是热心

renxupeng 发表于 2010-8-27 13:00:54

mark

mkzlovedamy 发表于 2010-10-13 18:12:23

duliuben 发表于 2010-10-20 21:29:41

不知道这个库能用在MEGA8上面吗?88比较难找

junyizhi 发表于 2010-11-10 16:16:03

是不是用什么AVR芯片都可以吗楼主这是用什么芯片的呢 想试试

polar 发表于 2010-12-9 01:01:41

好教程 马克一下

zhang1007 发表于 2011-1-4 09:57:20

我编译了一下通不过,请楼主分析一下:
a88pa -Wall -gdwarf-2 -Os -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT main.o -MF dep/main.o.d-c../main.c

../main.c:15: warning: 'SIG_OVERFLOW1' appears to be a misspelled signal handler
avr-gcc -mmcu=atmega88pa -Wl,-Map=qtouch10.map main.o   -L"C:\Program Files\atmel\Atmel_QTouch_Libraries_4.3\Generic_QTouch_Libraries\AVR_Tiny_Mega_XMega\QTouch\library_files"-lavr4g1-8qt-k-2rs-o qtouch10.elf
C:\Program Files\atmel\Atmel_QTouch_Libraries_4.3\Generic_QTouch_Libraries\AVR_Tiny_Mega_XMega\QTouch\library_files\libavr4g1-8qt-k-2rs.a(burst_0_1_00_0.o): In function `burst_0_1_00_0':
burst_0_1_00_0.c:(.text+0x28): undefined reference to `_0111010111_'
burst_0_1_00_0.c:(.text+0x54): undefined reference to `_01001010111_'
burst_0_1_00_0.c:(.text+0xf6): undefined reference to `_0101110111_'
make: *** Error 1
Build failed with 3 errors and 1 warnings...

AVR studio 4.18 sp3.
Qtouch Lib 4.3
winAVR 20100110

刚好有个项目要用到,急呀

junyizhi 发表于 2011-1-6 18:34:47

请问 通道1~7 怎么知道他对应于单片机的那一个IO口呀??
初学 希望高手赐教!不胜感激!@

halobear 发表于 2011-2-14 16:46:27

回复【27楼】zhang1007
我编译了一下通不过,请楼主分析一下:
a88pa -wall -gdwarf-2 -os -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -md -mp -mt main.o -mf dep/main.o.d-c../main.c
../main.c:15: warning: 'sig_overflow1' appears to be a misspelled signal handler
avr-gcc -mmcu=atmega88pa -wl,-map=qtouch10.map main.o   -l"c:\program files\atmel\atmel_qtouch_libraries_4.3\generic_qtouch_libraries\avr_tiny_m......
-----------------------------------------------------------------------

请把Atmel\Atmel_QTouch_Libraries_4.3\Generic_QTouch_Libraries\AVR_Tiny_Mega_XMega\QTouch\common_files下面的qt_asm_tiny_mega.S拷贝到项目文件夹下,然后再source files里添加该.S文件,即可编译通过

meijingguoyu 发表于 2011-6-18 21:32:12

thanks for sharing, and thank you very much

ljun16888 发表于 2011-7-4 21:09:52

我正在找,就顶一下....

tujp1990 发表于 2011-7-13 20:56:57

先看看再说。

xidxid 发表于 2011-10-25 10:38:03

看不懂,winavr在这里起什么作用?avr studio又起什么作用,C程序编写、编译是在avrstudio里进行的?

zou_hui1988 发表于 2011-11-14 14:34:31

请问楼主你们的抗干扰算法怎样弄的?我也弄出一个,但放在工业上就有干扰

yaoxiaofeng 发表于 2011-12-14 12:33:53

正好有套QT600的板,多谢楼主了

Garbage614 发表于 2011-12-15 21:14:44

mark

lidongxin 发表于 2011-12-23 14:35:12

回复【楼主位】qlb1234清蓝冰
-----------------------------------------------------------------------

mark

pisgah 发表于 2012-3-28 08:49:10

又找到這個帖子了,太好了

中国 发表于 2012-3-30 08:45:24

辛苦楼主了,谢谢了

wgco 发表于 2012-5-5 22:22:38

大哥,有没有完整的程序,只一个通道发出信号就行

liangws201 发表于 2012-5-23 10:57:37

不错这个帖子。

wolfojc 发表于 2012-6-14 08:17:30

好...资料!

wtk001 发表于 2012-6-26 15:27:42

楼主能把代码重新上传下么?

qlb1234 发表于 2012-6-26 16:18:28

wtk001 发表于 2012-6-26 15:27 static/image/common/back.gif
楼主能把代码重新上传下么?

衹能儘量找一下。

wtk001 发表于 2012-7-3 14:07:04

qlb1234 发表于 2012-6-26 16:18 static/image/common/back.gif
衹能儘量找一下。

十分的谢谢···

jade1988 发表于 2012-7-3 15:39:36

qlb1234 发表于 2012-6-26 16:18 static/image/common/back.gif
衹能儘量找一下。

大侠看看这个贴子呗,我就是看你的帖子写的,不知为何不行:

http://www.amobbs.com/thread-5483517-1-1.html

IO口没有震荡啊?

哇嘎 发表于 2012-7-20 09:36:04

突然不知道怎么往里灌程序了。我现在有个JTAGICE ,能用吗?

leicai05 发表于 2012-8-10 11:58:35

Gorgon_Meducer 发表于 2009-10-15 10:25 static/image/common/back.gif
好帖子,第一个顶!

请教我的qtouch studio软件打开,file中就exit选项,不能新建,也不能配置,求解

Gorgon_Meducer 发表于 2012-8-10 13:40:25

leicai05 发表于 2012-8-10 11:58 static/image/common/back.gif
请教我的qtouch studio软件打开,file中就exit选项,不能新建,也不能配置,求解 ...

那个软件是配合官方的QT600评估板用的。

lucky_jeck 发表于 2012-8-13 14:07:04

好貼,頂一個咧

liutong0525 发表于 2012-9-5 11:03:16

MARK,产品需要用到了,学习

qqtfh 发表于 2012-10-29 14:56:14

{:lol:}{:lol:}{:lol:}{:lol:}{:lol:}{:lol:}

jz701209李 发表于 2013-2-21 18:15:29

谢谢楼主......

lxh413458727 发表于 2013-6-26 16:01:39

太好了,一直不知道这个怎么玩

zenghl 发表于 2013-6-26 18:04:41

好贴,顶一个!{:lol:}
页: [1]
查看完整版本: [教程]手把手教你用AVR Studio+WinAVR+QTouch Lib点亮蜗牛触摸板