JZ2440 ADC和触摸屏学习笔记
来源:互联网 发布:python分布式爬虫系统 编辑:程序博客网 时间:2024/05/21 05:43
裸机系列代码地址:链接:http://pan.baidu.com/s/1pLHOd0v 密码:4x5s
S3C2440的CMOS模数转换器可以接收8个通道的模拟信号输入,并将它们转换成10位的二进制数据
S3C2440的触摸屏接口向外提供4个控制引脚(XP,XM,YP,YM)与触摸屏的直接相连。S3C2440的ADC和触摸屏机构图如下所示图中有两个中断信号:INT_ADC,INT_TC,前者表示A/D转换已经完成,后者表示触摸屏被按下了,或者弹起了。
在使用触摸屏是AIN[7:4]被用来和触摸屏相连,所以只有剩下的AIN[3:0]可以作为普通A/D转换通道用,不使用触摸屏时AIN[7:0]均可用作普通A/D转换通道
ADC的启动方式有两种:1、手工启动,第一次转换是使用
2、读结果时就自动启动下一次转换,除第一次转换外使用
也有两种方法得知转换结束:1、查询状态位
2、转换结束时发出中断INT_ADC_S
下面看一看ADC和触摸屏使用时主要使用的寄存器
ADCCON寄存器格式
[15]:只读,A/D转换结束标志。0=正在转换,1=转换结束
[14]:决定A/D转换器的时钟是否使用预分频。0=不使用,1=使用。通常情况需要使用预分频
[13:6]:预分频系数PRSCVL,取值0~255,A/D时钟=PCLK/(PRSCVL)。注意:A/D时钟必须小于PCLK的1/5
[5:3]:选择进行AD转换的通道
[2]:选择静态模式,0=正常模式,1=静态模式
[1]:读数据时是否启动下一次转换。0=不启动,1=启动
[0]:启动A/D转换。0=无作用,1=启动(真正转换开始时,此位被置0)
ADCDAT0寄存器格式
[15]:对于触摸屏,使用“等待中断模式”时,0=触摸屏被按下,1=触摸屏没有被按下
[14]:决定是否使用自动(连续)X/Y轴坐标转换模式
[13:12]:手动X/Y轴坐标转换模式
[11:10]:保留
[9:0]:x轴坐标转换数值
ADCDAT1数据格式和ADCDAT0相似
ADCTSC寄存器格式
[8]:表示检测的中断类型。0=触点按下中断,1=触点松开中断
[7]:0=YM驱动禁止(高阻),1=YM驱动使能(接地)
[6]:0=YP驱动禁止(接外部电压),1=YP驱动使能(接模拟输入)
[5]:0=XM驱动禁止(高阻),1=XM驱动使能(接地)
[4]:0=XP驱动禁止(接外部电压),1=XP驱动使能(接模拟输入)
[3]:PULL_UP,XP上拉使能,0=禁止上拉,1=使能上拉
[2]:AUTO_PST,是否使用自动(连续)X/Y轴坐标转换模式,0=普通模式,1=自动转换模式
[1:0]:手动量测X,Y轴坐标。00=无操作模式,01=量测x轴,10=量测y轴,11=等待中断模式
等待中断模式,如下为等待中断模式的触摸屏等效电路图,ADCTSC寄存器的设置参考此图
图中,S4,S5闭合,S1,S2,S3断开,即YM接地,XP上拉,XP作为模拟输入,YP作为模拟输入,XM高阻
从图中可知,设置ADCTSC寄存器为0xd3即可令触摸屏处于等待中断模式,这时,它在等待触摸屏被按下或是等待弹起。触摸屏
按下时产生INT_TC中断,弹起时亦产生此中断。
自动(连续)X/Y轴坐标转换模式
设置ADCTSC寄存器为0x0c进入此模式,触摸屏控制器就会自动转换触点的x,y坐标值,并分别写入ADCDAT0和ADCDAT1寄存器中
然后发出INT_ADC中断
对于普通转换模式,分离的x/y轴坐标转换模式,自动(连续)X/Y轴坐标转换模式,都可以通过ADCDLY寄存器来设置采样的延时时间
触摸屏的程序流程图和控制的状态转移图如下所示
下面是一个触摸屏的实例程序
Makefile 文件
objs:= head.o init.o main.o irq.oadcts.bin: $(objs) arm-linux-ld -Tadc_ts.lds -o adcts_elf $^arm-linux-objcopy -O binary -S adcts_elf $@arm-linux-objdump -D -m arm adcts_elf > adcts.dis%.o:%.c arm-linux-gcc -Wall -O2 -c -o $@ $<%.o:%.s arm-linux-gcc -Wall -O2 -c -o $@ $< clean:rm -f adcts_elf adcts.dis adcts.bin *.o链接文件
SECTIONS { . = 0x30000000; .text : { *(.text) } .rodata ALIGN(4) : {*(.rodata)} .data ALIGN(4) : { *(.data) } .bss ALIGN(4) : { *(.bss) *(COMMON) }}head.S
.text.global _start_start:b reset HandleUndef:b HandleUndefHandlerSWI:b HandlerSWI HandlePrefetchAbort:b HandlePrefetchAbortHandleDataAbort:b HandleDataAbortHandleNotUsed:b HandleNotUsed b HandleIRQ /*中断向量表的位置必须固定,即 b HandleIRQ运行位置必须在0x18处*/HandleFIQ:b HandleFIQreset:ldr sp,=4096 /*设置C函数使用的栈*/bl disable_watch_dogmsr cpsr_c,#0xd2 /*进入中断模式*/ ldr sp,=3072 /*设置中断模式栈指针*/msr cpsr_c,#0xd3 /*进入系统模式*/ldr sp,=4096 /*设置系统模式栈指针*/msr cpsr_c,#0x5f /*开IRQ中断,这之后程序可以响应中断*/bl init_clock /*设置系统时钟,使得uart使用PCLK为50MHZ*/bl memsetup /*初始化存储控制器使得SDRAM可用*/bl copy_steppingstone_to_sdram /*将代码复制到SDRAM中*/ldr pc,=on_sdram /*地址相关代码,从这里开始程序在SDRAM中运行*/on_sdram:ldr sp,=0x34000000 /*设置代码在SDRAM中运行时的栈*/bl init_uart0 /*初始化串口0*/bl main bl halt_loophalt_loop:b halt_loop HandleIRQ:sub lr,lr,#4stmdb sp!,{r0-r12,lr} ldr lr,=int_return ldr pc,=EINT_Handleint_return:ldmia sp!,{r0-r12,pc}^init.c
#include "s3c2440.h"void disable_watch_dog(void){WTCON = 0x53000000;}/*注意这里必须用这种方式,用数组循环赋值的方式不可取*/void memsetup(void){volatile unsigned long *p = (volatile unsigned long *)0x48000000;/* 这个函数之所以这样赋值,而不是像前面的实验(比如mmu实验)那样将配置值 * 写在数组中,是因为要生成”位置无关的代码”,使得这个函数可以在被复制到 * SDRAM之前就可以在steppingstone中运行 */ /* 存储控制器13个寄存器的值 */ p[0] = 0x22011110; //BWSCON p[1] = 0x00000700; //BANKCON0 p[2] = 0x00000700; //BANKCON1 p[3] = 0x00000700; //BANKCON2 p[4] = 0x00000700; //BANKCON3 p[5] = 0x00000700; //BANKCON4 p[6] = 0x00000700; //BANKCON5 p[7] = 0x00018005; //BANKCON6 p[8] = 0x00018005; //BANKCON7 /* REFRESH, * HCLK=12MHz: 0x008C07A3, * HCLK=100MHz: 0x008C04F4 */ p[9] = 0x008C04F4; p[10] = 0x000000B1; //BANKSIZE p[11] = 0x00000030; //MRSRB6 p[12] = 0x00000030; //MRSRB7}void copy_steppingstone_to_sdram(void){unsigned int *pdest = (unsigned int *)0x30000000;unsigned int *psrc = (unsigned int *)0x00000000;while(psrc<(unsigned int *)4096){*pdest = *psrc;pdest++;psrc++;}}void init_clock(void){#define MPLL_200MHZ ((0x5c<<12)|(0x01<<4)|(0x02))CLKDIVN = 0x03;__asm__( "mrc p15, 0, r1, c1, c0, 0\n" /* 读出控制寄存器 */ "orr r1, r1, #0xc0000000\n" /* 设置为“asynchronous bus mode” */ "mcr p15, 0, r1, c1, c0, 0\n" /* 写入控制寄存器 */ );MPLLCON = MPLL_200MHZ;}void init_uart0(void){GPHCON = 0xa0; /*GPH2,GPH3用作TXD0,RXD0*/GPHUP = 0x0c; /*GPH2,GPH3内部上拉*/#define UART_PCLK 50000000#define baurd 115200#define UART_BRD ((UART_PCLK/(baurd*16)) -1 )ULCON0 = 0x03; /*数据位数为8,一个停止位,无奇偶校验*/UCON0 = 0x05; /*查询方式,UART时钟源为PCLK*/UFCON0 = 0x00; /*不使用FIFO*/UMCON0 = 0x00; /*不使用流控*/UBRDIV0 = UART_BRD; /*波特率为115200*/}irq.c
#include "s3c2440.h"#define TXD0READY (1<<2)#define RXD0READY (1)#define ADC_START (1 << 0)#define PRESCALE_EN (1 << 14)#define PRSCVL(x) ((x) << 6)void putcc(char c){while( !(UTRSTAT0 & TXD0READY));UTXH0 = c;}unsigned char getcc(void){while(!(UTRSTAT0 & 1));return URXH0;}void putstring(char *p){while(*p != '\0'){putcc(*p);p++;}}static void isr_tc(void){if(ADCDAT0 & 0x8000){putstring("stylus up\n\r");ADCTSC = 0xd3; /*进入等待中断模式,检测触电按下*/}else{putstring("stylus down\n\r");ADCTSC = 0x0c; /*进入自动X/Y连续转换模式*/ADCCON |= ADC_START; /*开启ADC转换*/}/*清除中断*/SUBSRCPND |= BIT_SUB_TC;SRCPND |= BIT_ADC;INTPND |= BIT_ADC;}static void isr_adc(void){int x,y;x = (int)(ADCDAT0 & 0x3ff);y = (int)(ADCDAT1 & 0x3ff);char ptx[4]={'\0','\0','\0','\0'};char pty[4]={'\0','\0','\0','\0'};ptx[0]=x/100+'0';ptx[1]=(x%100)/10+'0';ptx[2]=x%10+'0';pty[0]=y/100+'0';pty[1]=(y%100)/10+'0';pty[2]=y%10+'0';putstring(ptx);putstring("\n\r");putstring(pty);putstring("\n\r");ADCTSC = 0x1d3;; /*进入等待中断模式,检测触电松开*//*清除中断*/SUBSRCPND |= BIT_SUB_ADC;SRCPND |= BIT_ADC;INTPND |= BIT_ADC;}void EINT_Handle(void){if(SUBSRCPND & BIT_SUB_TC) /*如果是TC中断,则进入TC中断的处理函数*/isr_tc();if(SUBSRCPND & BIT_SUB_ADC) /*如果是ADC中断,则进入ADC中断的处理函数*/isr_adc();}void Test_Ts(void){ INTMSK &= ~BIT_ADC; // 开启ADC总中断 INTSUBMSK &= ~(BIT_SUB_TC); // 开启INT_TC中断,即触摸屏被按下或松开时产生中断 INTSUBMSK &= ~(BIT_SUB_ADC); // 开启INT_ADC中断,即A/D转换结束时产生中断 INTMOD &= ~BIT_ADC; // 使能预分频功能,设置A/D转换器的时钟 = PCLK/(49+1) ADCCON = PRESCALE_EN | PRSCVL(49); /* 采样延时时间 = (1/3.6864M)*50000 = 13.56ms * 即按下触摸屏后,再过13.56ms才采样 */ ADCDLY = 50000;ADCTSC = 0xd3; /* 进入"等待中断模式",等待触摸屏被按下 */}main.c
#include "s3c2440.h"extern void Test_Ts(void);extern void putstring(char *);int main(){Test_Ts();while(1);return 0;}
阅读全文
0 0
- JZ2440 ADC和触摸屏学习笔记
- JZ2440 第14章 ADC和触摸屏接口
- TQ2440 学习笔记—— 26、ADC 和触摸屏接口
- ADC和触摸屏接口
- s3c2440的ADC触摸屏驱动——学习笔记
- 触摸屏和ADC驱动移植
- JZ2440学习笔记
- JZ2440 LCD学习笔记
- S5PV210芯片ADC&触摸屏接口学习
- S3C2440A的ADC和触摸屏接口
- linux adc驱动和触摸屏驱动
- 关于S5PV210 的ADC和触摸屏控制器
- S3C2440A的ADC和触摸屏接口
- asm335x系列adc和触摸屏驱动
- 触摸屏和ADC驱动的移植 (fl2440)
- s3c2440 触摸屏和ADC驱动移植
- 触摸屏驱动-JZ2440
- Linux触摸屏驱动-jz2440
- gerrit权限控制
- phpStorm快捷键
- PhxSQL设计与实现
- Java基础语法
- 微信支付接入流程——APP支付
- JZ2440 ADC和触摸屏学习笔记
- Openstack Newton虚拟机迁移计算节点补充配置
- myeclipse一直停留在Loading workbench界面上的处理办法
- linux安装jdk以及配置防火墙开放端口
- C++ istream_iterator
- sql2008“备份集中的数据库备份与现有的xx数据库不同”解决方法
- c#设计模式-单例模式
- Android 广播(Broadcast Receiver)使用详解
- JS 教程