99
5.4 人人人人人人人人人人人

5.4 人机接口电路设计及编程

Embed Size (px)

DESCRIPTION

5.4 人机接口电路设计及编程. 5.4.1 键盘电路设计及编程. 1. 电路. 键盘接口电路 如图 5-12 所示 ,板上扩展了一个 4×4 行列式矩阵键盘接口。 该键盘采用中断扫描方式进行工作 , 行线选用 PORTG4~7 输出,列线选用 PORTF5~8 为输入。 行线 接上拉电阻保持高电平,并通过“与”门将输出信号与 MCU 的中断 EXINT0 连接; 列线 接上拉电阻保持高电平。. 2. 编程. (1) I/O 口和中断初始化 ① I/O 引脚设置: rPDATE=0X60; - PowerPoint PPT Presentation

Citation preview

Page 1: 5.4     人机接口电路设计及编程

5.4 人机接口电路设计及编程

Page 2: 5.4     人机接口电路设计及编程

5.4.1 键盘电路设计及编程

Page 3: 5.4     人机接口电路设计及编程

1. 电路 键盘接口电路如图5-12所示,板上扩展了

一个 4×4 行列式矩阵键盘接口。 该键盘采用中断扫描方式进行工作 , 行线选用 PORTG4~7 输出,列线选用

PORTF5~8 为输入。 行线接上拉电阻保持高电平,并通过“与”门将输出信号与 MCU 的中断 EXINT0连接; 列线接上拉电阻保持高电平。

Page 4: 5.4     人机接口电路设计及编程

2. 编程 (1) I/O 口和中断初始化 ① I/O 引脚设置:

rPDATE=0X60;rPCONF=0x2A; 列线 PORTF5~8 为输入rPUPF=0x0; 列线接上拉电阻rPDATG=0x0; rPCONG=0x55FF; 行线 PORTG4~7 输出, PORTG0 作为 EXINT0 连接rPUPG=0x0; 行线接上拉电阻

Page 5: 5.4     人机接口电路设计及编程

② 中断初始化 rINTCON=0x5;

// 非向量模式 ,IRQ 允许 ,FIQ 禁止 rINTMOD=0x0;

// 全部 IRQ 模式 rINTMSK =~(BIT_GLOBAL|BIT_EINT0);

//EXINT0 允许, 所有中断屏蔽位允许 pISR_EINT0=(unsigned)keyboard_ISR;

// 指定中断服务程序

Page 6: 5.4     人机接口电路设计及编程

(2) 程序 将行线 PORTG4~7 输出为低电平,当有键盘按下时,该行线被拉为低电平,使得EXINT0 输入也为低电平, MCU 产生中断。 中断产生后通过对键盘的行和列进行扫描的方法,可以计算出是哪个键按下,并跳到相应的键盘处理程序中去。

Page 7: 5.4     人机接口电路设计及编程

void keyboard_ISR(void) {

char x,y,xrecord,yrecord,temp; rI_ISPC=BIT_EINT0;

//clear pending_bit Delay(400);

//delay 40ms if((rPDATF&0x1E0)==0x1E0)

{ return 0;

//no keyboard press,return }

Page 8: 5.4     人机接口电路设计及编程

else { x=1; y=1; xrecord=(~((rPDATF&0x1E0)>>1)); xrecord=xrecord>>4; while(xrecord!=0x1) //judge row { x=x+1; xrecord=xrecord>>1;

Page 9: 5.4     人机接口电路设计及编程

if(xrecord==0) {

rPDATG=0X0F; // no ,return return 0;}

} Delay(200); //delay 20ms rPDATG=0XEF; //input high

Page 10: 5.4     人机接口电路设计及编程

while((rPDATF&0x1E0)==0x1E0) {

rPDATG=rPDATG<<1; temp=rPDATG; if((temp&0xf0)==0XF0) //noboard

press,return { rPDATG=0X0F; return 0;} }

Page 11: 5.4     人机接口电路设计及编程

Delay(200); //delay 10msyrecord=~((rPDATG&0xF0)>>4)&0x0F; while(yrecord!=0x1) // judge line

{ y=y+1; yrecord=yrecord>>1; if(yrecord==0) { rPDATG=0X0F; //no board press,return return 0;} }

Page 12: 5.4     人机接口电路设计及编程

Led_Display(x+(y-1)*4-1); Uart_Printf("%3d",x+(y-1)*4-1); Delay(1200); //delay 40ms rPDATG=0X0F; }}

Page 13: 5.4     人机接口电路设计及编程

5.4.2 LCD 接口电路设计及编程

Page 14: 5.4     人机接口电路设计及编程

1. LCD 接口信号 EV44B0 II 现配有 160×240 的单色显示屏, 4 比特单扫描。 EV44B0 II 将 LCD 控制信号线连接到 JP6 上,与 LCD 模块相连,其原理如图5-13所示。 在 LCD 模块上,集成了 LCD 驱动器和专门的电压转换电路,用以驱动 LCD 屏幕和适

配 LCD 工作电压。 LCD 连接器的信号定义如表5-4所示。

Page 15: 5.4     人机接口电路设计及编程

1. LCD 接口信号 EV44B0 II 现配有 160×240 的单色显示屏, 4 比特单扫描。 EV44B0 II 将 LCD 控制信号线连接到 JP6 上,与 LCD 模块相连,其原理如图5-13所示。 在 LCD 模块上,集成了 LCD 驱动器和专门的电压转换电路,用以驱动 LCD 屏幕和适

配 LCD 工作电压。 LCD 连接器的信号定义如表5-4所示。

Page 16: 5.4     人机接口电路设计及编程

2. 编程 显示缓冲区与 LCD 象素对应关系图如图

5-14所示。

Page 17: 5.4     人机接口电路设计及编程

(1) LCD 初始化程序 通常采用 S3C44B0X 的 PORTC 口和PPORTD 口作为 LCD 驱动接口,因此需要设置它们工作在第 3 功能状态,设置 I/O 口控制寄存器的语句如下: rPDATC=0x8400; rPCONC=0x5F5FFFFF; rPUPC=0x33ff; //should be enabled rPCOND=0xaaaa; rPUPD=0xff;

Page 18: 5.4     人机接口电路设计及编程

LCD 初始化程序如下:void Lcd_MonoInit(void){//160x240 1bit/1pixel LCD#define MVAL_USED 0rLCDCON1=(0)|(1<<5)|(MVAL_USED<<7)

|(0x3<<8)|(0x3<<10)|(CLKVAL_MONO<<12);//disable,4B_SNGL_SCAN,WDLY=8clk,WLH=8clk,rLCDCON2=(LINEVAL)|(HOZVAL<<10)|(10<<21); //LINEBLANK=10

Page 19: 5.4     人机接口电路设计及编程

rLCDSADDR1=(0x0<<27)|(((U32)frameBuffer1>>22) <<21)|M5D((U32)frameBuffer1>>1); // monochrome, LCDBANK, LCDBASEU

rLCDSADDR2=M5D((((U32)frameBuffer1+(SCR_X SIZE*LCD_YSIZE/8))>>1))|(MVAL<<21)|(1<<29);

rLCDSADDR3= (LCD_XSIZE/16)|(((SCR_X SIZE-LCD_XSIZE)/16)<<9);

rLCDCON1=(1)|(1<<5)|(MVAL_USED<<7)|(0x3<<8)| (0x3<<10)|(CLKVAL_MONO<<12);

//enable,4B_SNGL_SCAN,WDLY=8clk,WLH=8clk, }

Page 20: 5.4     人机接口电路设计及编程

(2) LCD 显示程序 LCD 显示程序如下:

#define frameBuffer1 0xc400000extern unsigned char *Buf;void displaylcd(void){ unsigned int *pbuffer,temp_data; int i; pbuffer =(U32*) frameBuffer1;

Page 21: 5.4     人机接口电路设计及编程

for(i = 0; i< (4800/4) ;i++) { temp_data = (Buf[i*4+3] << 24) + (Buf[i*4+2] << 16) + (Buf[i*4+1] << 8) +(Buf[i*4]); pbuffer[i] = ~temp_data; Delay(10); }}

Page 22: 5.4     人机接口电路设计及编程

(3) LCD 清屏程序 LCD 清屏程序如下:

void clrscreen(void){int i,j;unsigned int *pbuffer;pbuffer =(U32*) frameBuffer1;for (i=0;i<4800/4;i++) { pbuffer[i] =0;//(0x0FFFFFFFF); }}

Page 23: 5.4     人机接口电路设计及编程

5.4.3 触摸屏电路设计及编程1. 触摸屏的工作原理 触摸屏按其工作原理的不同分为表面声波屏、电容屏、电阻屏和红外屏几种。 常见的又数电阻触摸屏。如图5-15 所示,电阻触摸屏的屏体部分是一块与显示器表面非常配合的多层复合薄膜,由一层玻璃或有机玻璃作为基层,表面涂有一层透明的导电层,上面再盖有一层外表面硬化处理、光滑防刮的塑料层,它的内表面也涂有一层透明导电层,在两层导电层之间有许多细小 ( 小于千分之一英寸 ) 的透明隔离点把它们隔开绝缘。

Page 24: 5.4     人机接口电路设计及编程

如图5-16所示,当手指或笔触摸屏幕时 ( 图c) ,平常相互绝缘的两层导电层就在触摸点位置有了一个接触,因其中一面导电层(顶层)接通X 轴方向的 5V 均匀电压场 ( 图 a) ,使得检测层(底层)的电压由零变为非零,控制器侦测到这个接通后,进行 A/D 转换,并将得到的电压值与 5V 相比即可得触摸点的 X 轴坐标为(原点在靠近接地点的那端):

Xi=Lx * Vi/V (即分压原理)同理得出 Y 轴的坐标,这就是所有电阻触摸屏共同的最基本原理。

Page 25: 5.4     人机接口电路设计及编程

2. 触摸屏电路控制 触摸屏的控制采用专用芯片,专门处理是否有笔或手指按下触摸屏,并在按下时分别给两组电极通电,然后将其对应位置的摸拟电压信号经过 A/D 转换送回处理器 .

Page 26: 5.4     人机接口电路设计及编程

我们选取 GPG 口与 ADS7843 接口。共运用了 PG2 ~ PG7 口共 6 条口线。你也可以选择其它的 I/O 口,但注意不要与 I/O 口上已经设定的功能(例如串口)相冲突。参考电路图如下:按照下图用导线将两个模块连接起来。如图5-17所示。

Page 27: 5.4     人机接口电路设计及编程

3. 编程(1) PCONG 寄存器配置 按照以上电路来设置 ,PG6 和 PG5 输入,

PG4 ~ PG2 输出, PG7 作为中断 EINT7且加内部上拉电阻,初始化语句如下: rPCONG=0x015f; rPUPG &=0x80 ;

Page 28: 5.4     人机接口电路设计及编程

(2) ADS7843 编程 ADS7843 的控制字如表5-5所示,其中

S 为数据传输起始标志位,该位必为1。 A2 ~ A0 进行通道选择。 MODE 用来选择 A/D 转换的精度, 1--选择8位,0 -- 选择 12 位。 SER/DFR 选择参考电压的输入模式。

Page 29: 5.4     人机接口电路设计及编程

PD1 和 PD0 选择省电模式: 00-- 为省电模式允许,在两次 A/D 转换之间掉电,且中断允许; 01 同 00 ,只是不允许中断; 10 保留; 11 禁止省电模式。 A0~A2 用来进行开关切换 , 如表5-6所示

Page 30: 5.4     人机接口电路设计及编程

我们采用固定参考电压模式,因此 SER/DFR = 1 。 程序中首先探测 PENIRQ 是否为低电平,如果为高则认为触摸屏没有接触;如果探测到 PENIRQ 为低电平,则认为有接触。 利用软件模拟 DIN 、 DOUT 、 DCLK 上的 3 线串行传输的时序,将读取 X 坐标数值或 Y 坐标数值的控制字串行送入 ADS7843 ,并串行读出坐标值。

Page 31: 5.4     人机接口电路设计及编程

① 检测 PENIRQ

#define TOUCH_MSR_Y 0x9c; //读 Y 轴坐标命令#define TOUCH_MSR_X 0xdc; //读 X 轴坐标命令……if((rPDATG&0x80)==0) //PENIRQ 电平为低{//TouchState.pressed=1;_State.Pressed=1; //说明已经按下temp=TOUCH_MSR_X;_State.x=ReadTouch(temp);temp=TOUCH_MSR_Y;_State.y=ReadTouch(temp);……

}

Page 32: 5.4     人机接口电路设计及编程

② 送控制字并读取结果子程序int ReadTouch(unsigned char command){unsigned char temp,i,ack,j,k;ack=0;//PG7<-PENIRQ,PG6<-BUSY,PG5<-DOUT,

PG4->CS,PG3->DCLK,PG2->DINrPDATG&=0xe7; //cs 置低 ;dclk 置低temp=0x80;

Page 33: 5.4     人机接口电路设计及编程

for(i=0;i<8;i++) //发送 1 个字节{if(command&temp) // 将控制字分解为位rPDATG|=0x04; // 将 din 置 1elserPDATG&=0xfb; // 将 din 清 0rPDATG|=0x08; // 置高 dclkdelay(2);rPDATG&=0xf7; // 清除 dclk , 1 位送出delay(2);temp=temp>>1; //移位}

Page 34: 5.4     人机接口电路设计及编程

while((temp=(rPDATG&0x40))==0); 等待 BUSY 变低 rPDATG&=0xdf;//din 清零 // 再 1 个时钟以后开始接收数据 rPDATG|=0x08; // 置高 dclk delay(2); rPDATG&=0xf7; // 清零 dclk delay(2);

Page 35: 5.4     人机接口电路设计及编程

for(i=0;i<7;i++)取得前 7 位坐标数据(高位在前){rPDATG|=0x08; // 置高 dclkif(temp=rPDATG&0x20) //取得 din 上的 1 位数据ack+=1;ack=ack<<1;delay(2);rPDATG&=0xf7; // 清零 dclkdelay(2);}rPDATG|=0x08; // 置高 dclk

Page 36: 5.4     人机接口电路设计及编程

if(temp=rPDATG&0x20) // 接收最后 1 位ack+=1;delay(2);rPDATG&=0xf7; // 清零 dclkrPDATG|=0x10; // 置高 csreturn ack; //返回接收结果

}

Page 37: 5.4     人机接口电路设计及编程

4. 触摸屏与显示器的配合 ADS7843 送回控制器的 X 与 Y 值仅是对当前触摸点的电压值的 A/D 转换值,它不具有实用价值。 这个值的大小不但与触摸屏的分辨率有关,而且也与触摸屏与 LCD 贴合的情况有关。而且, LCD 分辨率与触摸屏的分辨率一般来说是不一样,坐标也不一样。 因此,如果想得到体现 LCD 坐标的触摸屏位置,还需要在程序中进行转换。

Page 38: 5.4     人机接口电路设计及编程

假设 LCD 分辨率是 320×240,坐标原点在左上角;触摸屏分辨率是 900×900,坐标原点在左上角,则转换公式如下 : xLCD=[320*(x-x2)/(x1-x2)]; yLCD=[240*(y-y2)/(y1-y2)];

Page 39: 5.4     人机接口电路设计及编程

如果坐标原点不一致,比如 LCD 坐标原点在右下角,而触摸屏原点在左上角,则还可以进行如下转换: xLCD=320-[320*(x-x2)/(x1-x2)]; yLCD=240-[240*(y-y2)/(y1-y2)]; 最后得到的值,便可以尽可能得使

LCD 坐标与触摸屏坐标一致,这样,更具有实际意义。

Page 40: 5.4     人机接口电路设计及编程

5.4.4 8段数码管电路设计及编程1. 电路设计

系统使用了一个 8段数码 LED ,如图2-18所示。该数码管是共阳极的,低电平信号使LED 点亮。

CPU 数据总线 DATA(0~7) 经 74LS573驱动器对数码管进行驱动。其片选信号由CPU 的 nGCS3 信号选通,而 8段的内容则由 CPU 低 8 位数据线决定。 口地址为 0x6000000。

Page 41: 5.4     人机接口电路设计及编程

2. 编程8段数码管显示程序如下:void Led_Display(unsigned char data){ unsigned char * ledbuffer = (unsigned char *) 0x6000000 switch(data){ case 0: *ledbuffer=0x12; break; ... case 0xf: *ledbuffer=0x68; break;

} }

Page 42: 5.4     人机接口电路设计及编程

5.5 串行接口电路设计及编程

Page 43: 5.4     人机接口电路设计及编程

5.5.1 串行电路接口 串行接口电路如图5-19所示。系统提供两个 RS232 标准串行接口 (DB9) , UART0/l 可与 PC 或 MODOM 进行串行通信。 PORTC10~15 分别作为nRTS1 、 nCTS1 、 TXD1 、 RXD1 、 nRTS0和 nCTS0 信号, PE1 和 PE2 作为 TXD0 和RXD0 信号。

两个接口则采用两片MAX2322C 作为电平转换器。

Page 44: 5.4     人机接口电路设计及编程

5.5.2 编程1. I/O 接口配置初始化 对 PORTC 和 PORTE 初始化语句如下:

rPCONC = 0x0f000000|rPCONC; rPUPC = 0x3000 ; // 设置内部上拉 rPCONE = (rPCONE&0xfc3)|0xeb; rPUPE = 0x6;

2. UART 初始化 对 UART 口进行初始化设置程序如下:

Page 45: 5.4     人机接口电路设计及编程

static int UartNum=0;void myUart_Init(int whichuart, int baud)

// 设置串口波特率等初始化工作。{

if(whichuart==0){ UartNum=0; rUFCON0=0x0; // 不使用 FIFO rUMCON0=0x0; // 不使用自动流控制 rULCON0=0x3;

// 不采用红外线传输模式,无奇偶校验 位, 1 个停止位, //8 个数据位

Page 46: 5.4     人机接口电路设计及编程

rUCON0=0x245; //发送中断为电平方式,接收中断为 边沿方式,禁止超时 // 中断,允许产生错误状态中断,禁止回 送模式,禁止中 // 止信号,传输模式为中断请求模式,接 收模式也为中断 //请求模式。

rUBRDIV0=((int)(MCLK/16./baud + 0.5)-1); //根据波特率计算 UBRDIV0 的值

}

Page 47: 5.4     人机接口电路设计及编程

else if(whichuart==1){UartNum=1;rUFCON1=0x0;rUMCON1=0x0;rULCON1=0x3;rUCON1=0x245;rUBRDIV1 = ( (int)(MCLK/16./baud + 0.5) -1 );}

}

Page 48: 5.4     人机接口电路设计及编程

3.字符发送程序#define WrUTXH0(ch)(*(volatile unsigned char*)0xld00020)=(unsigned char)(ch)#define WrUTXH0(ch)(*(volatile unsigned char*)0xld04020)=(unsigned char)(ch)Void myUart_SendByte(char ch){ if(UartNum==0) { if(ch==“\n”) { while(!(rUTRSTAT0&0x2)); //等待,直到发送缓冲区为空 Delay(10); //超级中断的响应速度较慢 WrUTXH0(“\r”); //发送回车符 } while(!(rUTRSTAT0&0x2)); //等待,知道发送缓冲区为空 Delay(10); WrUTXH0(ch); //发送字符 }

Page 49: 5.4     人机接口电路设计及编程

else { if(ch==“\n”) { while(!(rUTRSTAT1&0x2)); Delay(10); // 因为超级终端响应较慢 rUTXH1=“\r”; } While(!(rUTRSTAT1&0x2)); //等待 THR空。 Delay(10); WrUTXH1(ch); }}

Page 50: 5.4     人机接口电路设计及编程

字符接受程序#define RdURXH0()(*(volatile unsigned char*)(0xld00027))#define RdURXH1()(*(volatile unsigned char*)(0xld04027))Char Uart_Getch(void){ if(whichUart==0) //串口 0 { while(!(rUTRSTAT0&0x1)); //读出接收到的数据(一直到读完) return RdURXH0(); //URXH0 : UART0 接收缓冲寄存器 } else //串口 1 { while(!(rUTRSTAT1&0x1)); //Receive data ready return rURXH1; }}

Page 51: 5.4     人机接口电路设计及编程

5.6 ⅡC 接口电路设计及编程

Page 52: 5.4     人机接口电路设计及编程

5.6.1 EEPROM芯片介绍

Page 53: 5.4     人机接口电路设计及编程

目前 , 通用存储器芯片多为 EEPTOM, 其常用的协议主要有两线串行连接协议 (ⅡC) 和三线串行连接协议。 带Ⅱ C总线接口的 EEPROM 有许多型号 ,其中 AT24Cxx 系列使用十分普遍 , 产品包括

AT2401/02/04/08/16等 , 其容量 (字节数 ×页 )分别为 128×8/256×8/512×8/1024×8/2048×8 ,适用于 2~5V 的低电压操作,具有低功耗和高可靠性等优点。

Page 54: 5.4     人机接口电路设计及编程

AT24 系列存储器芯片采用 CMOS 工艺制造,内置有高压泵 , 可在单电压供电条件下工作。其标准封装为 8 引脚 DIP封装形式 ,如图5-20所示。

Page 55: 5.4     人机接口电路设计及编程

1. SCL 串行时钟。遵循 ISO/IEC7816 同步协议;漏极开路,需接上拉电阻;在该引脚的上升沿,系统将数据输入到每个 EEPROM 器件,在下降沿输出。 2. SDA 双向串行数据线,漏极开路,需接上拉电阻,可与其它开路器件“线或”。

Page 56: 5.4     人机接口电路设计及编程

3. A0 、 A1 、 A2 器件 /页面寻址地址输入端。在AT24C01/02 中,引脚被硬连接。其他AT24Cxx 均可接寻址地址线。

4. WP 读 /写保护。接低电平时可对整片空间进行读 /写;接高电平时不能对受保护区进行读 /写。5. VCC/GND +5V 的工作电压。

Page 57: 5.4     人机接口电路设计及编程

5.6.2 EEPROM读/写操作1. AT24C04结构与应用简述 AT24C04 由输入缓冲器和 EEPROM 阵列组成。 由于 EEPROM 的半导体工艺特性写入时间为 5~ 10 ms ,如果从外部直接写入

EEPROM ,则每写一个字节都要等候5~10ms ,成批数据写入时就要等候更长时间。具有 SRAM 输入缓冲器的 EEPROM 器件,其写入操作变成对 SRAM 缓冲器的装载。装载完后启动一个自动写入逻辑将缓冲器中的全部数据一次写入 EEPROM 阵

Page 58: 5.4     人机接口电路设计及编程

对缓冲器的输人称为页写,缓冲器的容量 称为页写字节数。 AT24C04 的页写字节数为8 ,占用最低 3 位地址。当写入不超过页写字节数时,对 EEPROM 器件的写入操作与对SRAM 的写入操作相同;当超过页写字节数时,应等候 5~10 ms 后再启动一次写操作。

由于 EEPROM 器件缓冲区容量较小 (只占据最低 3 位 ) ,且不具备溢出进位检测功能,所以,从非零地址写入 8 个字节数或从零地址写入超过 8 个字节数会形成地址翻卷,导致写入出错。

Page 59: 5.4     人机接口电路设计及编程

2. 设备地址 (DADDR) AT24C04xx 的器件地址是 1010。

Page 60: 5.4     人机接口电路设计及编程

3. AT24Cxx 的数据操作格式 在 IIC总线中 , 对 AT24C04 内部存储单元读/写,除了要给出器件的设备地址 (DADDR)外 ,还须指定读/写的页面地址 (PADDR) 。两者组成操作地址 (OPADDR) 如下: 1010 A2 A1 – R/W (“–” 为无效 ) 系统中引脚 A2A1A0 为 000 ,因此,系统可寻址 AT24C04 全部页面,共 4K 位。按照

AT24C04 器件手册读/写地址 (ADDR = 1010 A2 A1–R/W) 中的数据操作格式如下:

Page 61: 5.4     人机接口电路设计及编程

(1) 写入操作格式 任意写一个字节到地址 ADDR_W ,其时序图如图5-21所示,写入操作格式为: START_C OPADDR_W ACK

ADDR_W ACK data ACK STOP_C

Page 62: 5.4     人机接口电路设计及编程

从地址 ADDR_W起连续写人 n 个字节( 同一页面 ) ,其时序图如图5-22所示,写人格式为:

START_C OPADDR_W ACK ADDR_W ACK data1 ACK data2 ACK...datan ACK STOP_C

Page 63: 5.4     人机接口电路设计及编程

(2) 读出操作格式 从任意地址 ADDR_R读一个字节的时序图如图5-23所示,读出操作格式为:

START_C OPADDR_W ACK ADDR_R ACK OPADDR_R ACK data STOP_C

Page 64: 5.4     人机接口电路设计及编程

从地址 ADDR_R起连续读出 n 个字节( 同一页面 ) ,其时序图如图5-24所示,读出操作格式为:

START_C OPADDR_R ACK data1 ACK data2 ACK ... datan ACK STOP_C

Page 65: 5.4     人机接口电路设计及编程

在读任意地址操作中,除了发送读地址外,还要发送页面地址 (PADDR) ; 因此,在连续读出 72 个字节操作前,要进行 1 个字节 PADDR写入操作,然后重新启动读操作。 注意,读操作完成后没有 ACK 。

Page 66: 5.4     人机接口电路设计及编程

5.6.3 编程1. I/O 端口 IIC 功能设置

我们采用 PF0 口和 PF1 口工作在第 2功能模式下,分别作为 IIC总线的 SCL 和SDA 与 24LC04B 相连。

因此,需要设置 PF0 和 PF1 工作在第 2功能模式下。采用以下语句: rPCONF |= 0xa; //PF0:IICSCL, PF1:IICSDA rPUPF |= 0x3; //pull-up disable

Page 67: 5.4     人机接口电路设计及编程

2. IIC 中断使能 由于是采用中断的方式了解每个字节的传输是否成功。 因此需要定义中断处理程序入口,并且使能中断。采用以下语句实现: pISR_IIC= (unsigned)IIC_Int; // 将 IIC 中断处理程序指针指向 IIC_Int rINTMSK= ~ (BIT_GLOBAL|BIT_IIC); // 使能中断

Page 68: 5.4     人机接口电路设计及编程

3. 初始化 IIC 接口 对 IICCON 进行设置:

rIICCON = (1<<7) | (0<<6 ) | (1<<5) | (0xf ); // 使能 ACK 的产生 , IICCLK=MCLK/16, 使能发送 / 接收中断,清除 pending 位以便响应 // 中断, Tx

clock =( 64MHz/16 ) / ( 15+1 ) = 250KHz

Page 69: 5.4     人机接口电路设计及编程

4. 向 24LC04B 中写入数据子程序 #define IICBUFSIZE 0x20 U8 _iicData[IICBUFSIZE]; //写数据缓存 volatile int _iicDataCount; // 数据长度 volatile int _iicStatus; volatile int _iicMode; int _iicPt;

Page 70: 5.4     人机接口电路设计及编程

void Wr24LCxx(U32 slvAddr,U32 addr,U8 data) { _iicMode=WRDATA; //写数据模式 _iicPt=0; _iicData[0]=(U8)addr; //字节写入模式,数据格式 参考教材内容 _iicData[1]=data; _iicDataCount=2; rIICDS=0xa0 ; // 控制字节 rIICSTAT=0xf0; //主设备发送模式,产生起 始条件,使能发送 / 接收 while(_iicDataCount != -1); _iicMode=POLLACK;

Page 71: 5.4     人机接口电路设计及编程

while(1) { rIICDS=slvAddr; _iicStatus=0x100; rIICSTAT=0xf0; //MasTx,Start rIICCON=0xaf; //resumes IIC operation. while(_iicStatus==0x100); if(!(_iicStatus&0x1)) break; // 成功接收到 ACK } rIICSTAT=0xd0; // 产生停止条件 rIICCON=0xaf; //释放 IIC 操作 Delay(1); //等待,直到停止条件起作用 ,写入成功 }

Page 72: 5.4     人机接口电路设计及编程

5. 从 24LC04B读出数据子程序void Rd24LCxx(U32 slvAddr,U32 addr,U8 *data){_iicMode=SETRDADDR;_iicPt=0;_iicData[0]=(U8)addr;_iicDataCount=1;rIICDS=slvAddr;rIICSTAT=0xf0; //MasTx,Start

Page 73: 5.4     人机接口电路设计及编程

while(_iicDataCount != -1);_iicMode=RDDATA;_iicPt=0;_iicDataCount=1;rIICDS=slvAddr;rIICSTAT=0xb0; //MasRx,StartrIICCON=0xaf; //resumes IIC operation.while(_iicDataCount != -1);*data=_iicData[1];}

Page 74: 5.4     人机接口电路设计及编程

6. IIC 中断处理子程序void __irq IIC_Int (void){U32 iicSt, i ;rI_ISPC=BIT_IIC; // 清除 pending 位iicSt=rIICSTAT; //读入 IIC 总线单前状态,以 便进行各种错误处理if(iicSt&0x8){} // when bus arbitration is failed.if(iicSt&0x4){} // when a slave address is matched with IICADDif(iicSt&0x2){} // when a slave address is 0000000bif(iicSt&0x1){} // when ACK isn't received

Page 75: 5.4     人机接口电路设计及编程

switch(_iicMode) //根据当前操作模式进行相应处理{case POLLACK: //等待 ACK 模式_iicStatus=iicSt; //读入 IICSTAT ,第 0 位表示是否 接收到 ACKbreak;case RDDATA: //读数据模式if((_iicDataCount --)==0) //只要读取 1 字节数据{_iicData[_iicPt++]=rIICDS;rIICSTAT=0x90; //停止主设备读取模式rIICCON=0xaf; //释放 IIC 操作Delay(1); //等待直到停止条件起作用break;}

Page 76: 5.4     人机接口电路设计及编程

_iicData[_iicPt++]=rIICDS; //未读完所有数据最后一个字节不能产生 ACK

if((_iicDataCount)==0) // 如果读完了所有数据(最后一个字节)rIICCON=0x2f; // 产生 NOACK.释放 IIC 操作elserIICCON=0xaf; // 产生 ACK 释放 IIC 操作break;case WRDATA: //写数据模式if((_iicDataCount--)==0) // 如果数据写完{rIICSTAT=0xd0; //停止主设备发送传输rIICCON=0xaf; //恢复 IIC 操作Delay(1); //等待,直到停止条件起效break;}

Page 77: 5.4     人机接口电路设计及编程

rIICDS=_iicData[_iicPt++]; //_iicData[0] has dummy.for(i=0;i<10;i++); //for setup time until rising edge of IICSCLrIICCON=0xaf; //释放 IIC 总线操作break;case SETRDADDR: // 设置读地址模式//Uart_Printf("[S%d]",_iicDataCount);

Page 78: 5.4     人机接口电路设计及编程

if((_iicDataCount--)==0){break; //IIC operation is stopped because of IICCON[4]}rIICDS=_iicData[_iicPt++]for(i=0;i<10;i++); //for setup time until rising edge of IICSCLrIICCON=0xaf; //释放 IIC 总线操作break;default:break;}}

Page 79: 5.4     人机接口电路设计及编程

5.7 其他接口电路设计及编程

Page 80: 5.4     人机接口电路设计及编程

5.7.1 定时器编程 让定时器 0 的 TOUT0 引脚输出频率为 1

6K ,占空比为 30%的 PWM 脉冲调制波形;定时约 0.5秒后产生定时中断。

Page 81: 5.4     人机接口电路设计及编程

1. 定时器初始化(1) I/O 口设置 采用以下语句对 PE 口的工作方式进行设置,使之工作在定时器输出状态:

rPCONE=0xaaa8; //Tout0/1/2/3/4, RxD0, TxD0 rPUPE |=0xf8;

(2) 定时器时钟源频率设置 通过以下语句来设置定时器的时钟源:rTCFG0=0x1010101; // 预分频值为 1rTCFG1=0x01; // 分割比例 =1/4经过设置后,定时器时钟源频率 = (MCLK/1)/4

Page 82: 5.4     人机接口电路设计及编程

(3) 设置输出波形频率 通过以下语句来设置输出波形的频率: rTCNTB0=1000; 经过设置,输出 PWM 波形的频率为 MCLK/4000 ;

由于系统采用的 MCLK= 64M ,因此, PWM 波形频率为 16K 。

(4) 设置占空比 通过以下语句来设置输出波形的占空比: rTCMPB0=300; 针对实验要求: 300/1000= 30%

Page 83: 5.4     人机接口电路设计及编程

(5) 设置定时器控制寄存器、启动定时器 rTCON=0xaaaa0a;

//自动重载模式,关闭反转功能,手动更 新,关闭死区rTCON=0x999909;

//启动 PWM 操作 定时器启动后,可以采用示波器观察 TOUT0输出波形,是否满足要求。

Page 84: 5.4     人机接口电路设计及编程

2. 定时器中断主程序 参考程序如下:volatile int variable0 ;void Test_TimerInt(void){ rINTMSK=~(BIT_GLOBAL|BIT_TIMER0) pISR_TIMER0=(int)Timer0Done; //修改中断处理函数的指针 rTCFG0=0x00f;

//dead zone=0, pre0=0xf // 设定时钟源频率 rTCFG1=0x04; //all interrupt, mux0=1/32 rTCNTB0=0xffff; //(1/(64MHz/15/32))*0xffff=0.49s

Page 85: 5.4     人机接口电路设计及编程

rTCON=0x02;// 手动更新 timer0 的设置rTCON=0x01;//T0=one shot,启动定时器while(variable0==0); //等待中断发生rTCON=0x0;//停止定时器rINTMSK=BIT_GLOBAL; // 关闭中断}

Page 86: 5.4     人机接口电路设计及编程

3. 定时中断服务程序void __irq Timer0Done(void){rI_ISPC=BIT_TIMER0; // 清中断 pending 位variable0++; //更新变量}

Page 87: 5.4     人机接口电路设计及编程

5.7.2 实时日历时钟 RTC

1. 电路 如图5-25为 32.768KHZ 晶振的电路连接示例:

Page 88: 5.4     人机接口电路设计及编程

2. 编程(1) 实时时钟初始化初始化示例程序如下:#define TESTYEAR 0x99#define TESTMONTH 0x12#define TESTDAY 0x31#define TESTDATE 0x06 //星期五#define TESTHOUR 0x23#define TESTMIN 0x59#define TESTSEC 0x30

Page 89: 5.4     人机接口电路设计及编程

void Rtc_Init(void){rRTCCON = 0x01; //读写使能 , 1/32768, Normal(merge), No resetrBCDYEAR = TESTYEAR;rBCDMON = TESTMONTH;rBCDDAY = TESTDAY;

// SUN:1 MON:2 TUE:3 WED:4 THU:5 FRI:6 SAT:7

Page 90: 5.4     人机接口电路设计及编程

rBCDDATE = TESTDATE;rBCDHOUR = TESTHOUR;rBCDMIN = TESTMIN;rBCDSEC = TESTSEC;rRTCCON = 0x00; //读写禁止}

以上程序对控制寄存器进行了设置,并更新了 RTC 日期时间寄存器,从此刻开始 RTC 就从设置的日期时间开始如钟表一样自动运转。

Page 91: 5.4     人机接口电路设计及编程

(2) 显示当前时间示例程序如下:void Display_Rtc(void){

int year, int month,day,weekday,hour,min,sec;

rRTCCON = 0x01; // 使能读写 , 1/32768, Normal(merge), No reset

Page 92: 5.4     人机接口电路设计及编程

if(rBCDYEAR == 0x99)year = 0x1999;elseyear = 0x2000 + rBCDYEAR;month=rBCDMON;day=rBCDDAY;weekday=rBCDDATE;hour=rBCDHOUR;min=rBCDMIN;sec=rBCDSEC;// 显示(向串口输出)时间rRTCCON = 0x0; // 禁止读写}

Page 93: 5.4     人机接口电路设计及编程

5.7.3 A/D 转换器电路设计及编程1. 电路 如图5-26所示. 手动调节电位器上的旋钮,

产生缓慢变化的模拟信号,改变输入 ADC 的模拟电压值。

Page 94: 5.4     人机接口电路设计及编程

2. 编程(1) ADC 控制寄存器初始化

采用以下语句对 ADC 相关寄存器进行初始化: CLKCON=0x7ff8; // 时钟控制寄存器,使能 MCLK 作为 ADC 的时钟源 rADCCON=0x1|(0<<2); //启动 A/D 转换 Delay(100); //等待一定的时间使 ADC 的参电压稳定下来 rADCPSR=0x20; // 设置时钟预分频值

Page 95: 5.4     人机接口电路设计及编程

(2) 读取 A/D 转换数值子程序参考以下程序:

int ReadAdc(int ch) //参数:采样通道{int i;static int prevCh=-1;if(prevCh!=ch){rADCCON=0x0|(ch<<2); // 设置采样通道for(i=0;i<150;i++); //等待最小 15uS}

Page 96: 5.4     人机接口电路设计及编程

rADCCON=0x1|(ch<<2); //启动 A/D 转换while(rADCCON &0x1);

//To avoid The first FLAG error case. //(The START bit is cleared in one ADC clock.)

while(!(rADCCON & 0x40)); //A/D 转换是否结束?for(i=0;i<rADCPSR;i++);

//To avoid The second FLAG error caseprevCh=ch;return rADCDAT; //返回转换结果

}

Page 97: 5.4     人机接口电路设计及编程

5.8 本章小结 本章主要介绍 EV44B0II 开发板的存储和

I/O 地址空间分布,介绍了 Boot loader 在存储地址空间的分布情况。 给出了电源时钟复位电路、 Boot FLASH 接口电路、 SDRAM 接口电路、网络 USB 及IIS 接口电路、键盘数码管接口电路、 LCD接口电路、触摸屏接口电路、串行口接口电路、 IIC 接口电路和 A/D等接口电路等的设计及编程。

Page 98: 5.4     人机接口电路设计及编程

练习题1. Boot loader 的作用。2. 简述 EV44B0II 的地址空间分布情况。3. 简述 IIS 接口电路原理。4. 简述矩阵式键盘循环扫描检测法工作原理。5. 假设要将 44b0X 的 UART1 设置为:波特率 9600bps , 7位数据位, 2个停止位,1位奇偶校验位,并采用流控制工作,该如何设置?给出完成该设置功能的代码段。

Page 99: 5.4     人机接口电路设计及编程

6. 如何设置定时器的时钟源频率?工作在主频64M下,要获得 4M的时钟源频率,应该如何设置?

7. 24LC04B具有多大的存储空间?在 IIC 总线上它是作为主器件还是从器件?8. S3C44B0X 具有哪些与 ADC 相关的寄存器,它们的作用分别是什么?9. ADS7843 的控制字是什么?每一位代表什么意义?