2440裸机学习心得(上)
拓展:LCD的字符显示
汉字库
中文字符和ASCII码混合在一样,如何区分它们呢?其实也很简单,ASCII码的最高位是0,而中文的最高位是1,因此当读取到的一个字节的最高位是0,则该字节为ASCII码,它的下一个字节与这个字节无关;当取得到的字节的最高位是1,则表示的是中文字符,并且该字节与它的下一个字节组合在一起表示完整的一个汉字。
把字库变换成一个超大的数组,那么我们就可以像操作数组一样读取字库了
#include "font_libs.h"//内有两个数组__HZK[ ]和__ASCII[ ]
if(String[k]&0x80)//中文字符
qh=String[k]-0xa0;//区号
wh=String[k+1]-0xa0;//位号
mould = & __HZK[ ( ( qh - 1 )*94 + wh- 1 )*32 ];
RTC实时时钟
内部的寄存器BCDSEC,BCDMIN,BCDHOUR,BCDDAY,BCDDATE,BCDMON和BCDYEAR分别存储了当前的秒,分,小时,星期,日,月和年,表示时间的数值都是BCD码。这些寄存器的内容可读可写,并且只有在寄存器RTCCON的第0位为1时才能进行读写操作。
“一秒误差”,因此当读取到的秒为0时,需要重新再读取一遍这些寄存器的内容,才能保证时间的正确。
以下两个中断实用,注意要按照一般中断初始化的格式:开屏蔽,清屏蔽
时间节拍中断pISR_TICK时间节拍中断的周期公式为:(n+1)÷128,单位是秒
其中n的值为1~127,它存储在寄存器TICNT的低6位中,当寄存器TICNT的第7位被置1时,表示开启时间节拍中断
报警中断pISR_RTCLMYEAR(年)、ALMMON(月)、ALMDATE(日)、ALMHOUR(小时)、ALMMIN(分)和ALMSEC(秒)。而如何报警,是由报警控制寄存器RTCALM控制的
要学习一下Fzb版本的控制台设计,其中提到一个专用函数
//将一个十位数转化为字符串输出(专用函数) BCD码转字符串
static void digit_to_char(char *buf, int number)
{
buf[0] = ((char)(number >> 4) + 48); //转换高4位
buf[1] = ((char)(number & 0x0f) + 48); //转换低4位
}
要多学习用结构体,数组,和指针
IIC总线(按中断法写的,和51时按时序法不同)
SDA->GPE15 , SCL->GPE14
寻址AT24C02A
S3C2440作为主机,所以就关注主机模式下的收/发
配置了IIC管脚所在的寄存器,然后配置了IIC工作的信号以及时钟源的配置。配置rIICCON,rIICSTAT
设立变量FLAG,来看是否进入了中断,出来中断后要清除
while(FLAG == 1)
for(i = 0;i < 100;i++);
FLAG = 1;
读函数的流程:首先是发出从设备寻找地址并指定为写入操作→写入要读取数据的首地址→发出从设备寻找地址并指定为读取操作→这时会先返回一个数据(这个是不需要的要抛弃,上面红色部分)→按照给定的数据长度读取数据(长度超过8位会折返读)→结束操作。
写函数的流程:发出从设备寻址地址并指定写入模式→向从设备写入要写入数据区的首地址→写入数据到设备中(最多8个字节)→结束。
几句经典的解析:
rIICCON = 0xaf; //清中断标记,开启中断
rIICSTAT = 0xf0; rIICSTAT = 0xb0;//使能接收,发送功能,S信号开始
rIICSTAT = 0xd0;rIICSTAT = 0x90; //发出P信号,停止
参考fzb的读写8位对齐法,很美观牛B
ADC和触摸屏
AD(轮询或中断自己选择)
A/D转换比较简单,主要应用的是ADC控制寄存器ADCCON和ADC转换数据寄存器ADCDAT0
这个想法不错:在AIN2引脚上接了一个温度传感器,被检测的温度范围为0度~99度,它对应于A/D转换数据的0~0x3FF。检测到的温度被实时地显示在LCD上,这里我们只显示温度的整数部分。
temperature = (int)readADC()*99/0x3ff;//读取温度?可以直接这样?不用写时序让温度传感器工作先?这种不是DS18B20,是那种直接纯传感
注意的地方:
根据S3C2440的中断体系,从INTOFFSET获取中断发生的种类标号然后就像这样处理各个中断。ADC的中断体系分为两个层次。首先是主要中断,由于ADC和触摸屏使用同一个主要中断标号,所以在这个中断处理中还需要判断次要中断以最终确定到底是ADC还是触摸屏发生了中断。
触摸屏
工作的两种典型模式:
自动(序列)X/Y坐标转换模式
自动(序列)X/Y坐标转换模式作为如下方式被操作。触摸屏控制器依次转换被触摸点的X坐标和Y坐标。在触摸控制器写X测量数据到ADCDAT0和Y测量数据到ADCDAT1过后,触摸屏接口产生中断到中断控制器在自动坐标转换模式中。
等待中断模式
触摸屏控制器产生中断信号(INT_TC)当触摸笔按下的时候。等待中断模式设置值是ADCTSC=0xd3(X_PU、XP_Dis、XM_Dis、YP_Dis、YM_En)。
一般来说,触摸屏的响应过程是:等待中断(触摸笔按下)模式→中断发生后进入自动(连续)X/Y轴转换→等待中断(触摸笔抬起)模式。
这三种模式的初始化分别为:
1等待中断(触摸笔按下):
rADCTSC=0;
rADCTSC=0xd3;
2(连续)X/Y轴转换:
rADCTSC=0;
rADCTSC=0x04;
3等待中断(触摸笔抬起):
rADCTSC=0;
rADCTSC=0xd3;
rADCTSC |=(1<<8);
晕,看回以前的写字板程序,都是错,没有区分清楚两个不同的中断
只有一个中断触发函数pISR_ADC但是对应着不同的两个中断,
要通过在中断中判断if(SUBSRCPND&(1<<9))和elseif(SUBSRCPND&(1<<10))
等待检测 AD处理中断
注意:在等待检测中,又分为按下中断和抬起中断
用if(ADCDAT0&0x8000)和 else来区分
抬起按下
拖曳功能的实现:
Y
按下——》xy自动模式转换——》收集数据,画点——》检测是否松手
N
X通过标志flagTC来判断是否松手,若松手,flagTC在松手中断中置1
上面那种标志的方法会与 void TC_interrupt()//等待模式中断,判断是按下还是松手
有矛盾
故还是直接采取在拖曳函数中test_down_still()直接判断
wait_up_init();
if(!(rADCDAT0&0x8000))
每次画点要延时一段时间,即控制好采样时间
校正:
利用三个坐标点通过公式计算出待定系数A,B,C,D,E,F,K,表示出触摸屏和LCD关系
公式:LCD上每个点PD的坐标为[XD,YD],触摸屏上每个点PT的坐标为[XT,YT]。
XD=A×XT+B×YT+C
YD=D×XT+E×YT+F
K=(XT0-XT2)×(YT1-YT2)-(XT1-XT2)×(YT0-YT2)
A=[(XD0-XD2)×(YT1-YT2)-(XD1-XD2)×(YT0-YT2)] / K
B=[(XT0-XT2)×(XD1-XD2)-(XD0-XD2)×(XT1-XT2)] / K
C=[YT0×(XT2×XD1-XT1×XD2)+YT1×(XT0×XD2-XT2×XD0)+YT2×(XT1×XD0-XT0×XD1)] / K
D=[(YD0-YD2)×(YT1-YT2)-(YD1-YD2)×(YT0-YT2)] / K
E=[(XT0-XT2)×(YD1-YD2)-(YD0-YD2)×(XT1-XT2)] / K
F=[YT0×(XT2×YD1-XT1×YD2)+YT1×(XT0×YD2-XT2×YD0)+YT2×(XT1×YD0-XT0×YD1)] / K
利用EEPROM来保存这几个参数,即A,B,C,D,E,F,K分别保存在以0x20,0x30,0x40,0x50,0x60,0x70,0x80为首地址内存的连续4个字节空间内,另外内存地址0x1F保存一个标识信息,当为0x6A时,表示这几个参数已计算并保存好了,只需从上述内存地址中读取参数就行,而当为其他值时,就需要进行校正。
关键词:
2440裸机学
评论