实验一
实验题目:搭建嵌入式开发环境
实验类型:验证型
实验日期:10.12(第一组),10.14(第二组)
1.实验目的及要求
安装、熟悉ADS1.2开发环境,学会ARM仿真器的使用。使用ADS编译、调试并跟踪一段已有的程序(Examples\asm\strcopy.mcp),了解嵌入式开发的基本思想和过程。
2.实验仪器设备与软件环境
硬件:ARM嵌入式开发平台、PC机、串口线。
软件:PC机操作系统Windows XP或Windows 7、ARM ADS1.2 集成开发环境、超级终端通讯程序。
3.实验过程及实验结果分析
(以下文字为提示内容,不要出现在实验报告中)
对strcopy.s的源代码做出注释;
通过截图说明ADS中项目(mcp)的概念,如何编译项目;
通过截图说明在AXD中如何单步执行、观察寄存器、内存的值。
实验二
实验题目:ARM汇编编程
实验类型:设计型
实验日期:10.19(第一组),10.21(第二组)
1.实验目的及要求
熟悉ADS1.2开发环境,熟练使用AXD调试程序。掌握ARM指令集及汇编编程方法,编写汇编程序,实现冒泡排序。汇编程序包含一个代码段和一个数据段,由代码段的程序对数据段的10个整数进行从小到大排序。
2.实验仪器设备与软件环境
硬件:ARM嵌入式开发平台、PC机、串口线。
软件:PC机操作系统Windows XP或Windows 7、ARM ADS1.2 集成开发环境、超级终端通讯程序。
3.实验过程及实验结果分析
(以下文字为提示内容,不要出现在实验报告中)
写出汇编程序,并对关键源代码做出注释;
通过截图说明在AXD中如何观察排序前和排序后的数据
实验三
实验题目:ARM汇编与C语言混合编程
实验类型:设计型
实验日期:10.26(第一组),10.28(第二组)
1.实验目的及要求
熟悉ADS1.2开发环境,熟练使用AXD调试程序。掌握APTCS标准,实现ARM汇编与C语言的混合编程。新建一个工程,包含一个C源码文件(.c)和一个汇编源码文件(.s)。在C代码中定义一个包含10个元素的整型数组,任意输入10个数存入数组,调用汇编程序对该数组进行排序,输出排序后的数组。在汇编代码中,用选择排序对数组进行从小到大排序。
2.实验仪器设备与软件环境
硬件:ARM嵌入式开发平台、PC机、串口线。
软件:PC机操作系统Windows XP或Windows 7、ARM ADS1.2 集成开发环境、超级终端通讯程序。
3.实验过程及实验结果分析
(以下文字为提示内容,不要出现在实验报告中)
写出汇编程序,并对关键源代码做出注释;
通过截图说明在AXD中如何输入数据,观察排序前和排序后的数据
实验四
实验题目:UART串口通信
实验类型:设计型
实验日期:10.27(第一组),10.30(第二组)
1.实验目的及要求
目的:掌握ARM的串行口工作原理;学习编程实现ARM的UART通讯;掌握CPU利用串口通讯的方法。
要求:阅读ARM芯片文档,掌握ARM的UART相关寄存器的功能,熟悉ARM系统硬件的UART相关接口。编程实现ARM和计算机实现串行通讯:ARM监视串行口,将接收到的字符再发送给串口,即按PC键盘通过超级终端发送数据,开发板将接收到的数据再返送给PC,在超级终端上显示。要求在超级终端输入“2+3=”,ARM接收字符后,完成计算把字符“5”反馈到超级终端。
2.实验仪器设备与软件环境
硬件:ARM嵌入式开发平台、PC机、串口线。
软件:PC机操作系统Windows XP或Windows 7、ARM ADS1.2 集成开发环境、超级终端通讯程序。
3.实验过程及实验结果分析
(以下文字为提示内容,不要出现在实验报告中)
从实验指导手册中选取适当内容:串口通信原理、ARM9中的UART寄存器;
写出main.c程序,对关键代码给出注释;
对超级终端的显示结果进行截图。
实验五
实验题目:触摸屏驱动编程
实验类型:设计型
实验日期:10.31(第一组),10.31(第二组)
1.实验目的及要求
了解触摸屏基本概念与原理;
理解触摸屏如何与LCD的密切配合;
编程实现对触摸屏的控制。
2.实验仪器设备与软件环境
硬件:ARM嵌入式开发平台、PC机、串口线。
软件:PC机操作系统Windows XP或Windows 7、ARM ADS1.2 集成开发环境、超级终端通讯程序。
3.实验过程及实验结果分析
(以下文字为提示内容,不要出现在实验报告中)
从实验指导手册中选取适当内容:触摸屏的工作原理、FM7843芯片的管脚功能和工作原理、FM7843和ARM处理器的连接原理图、触摸屏与显示器的配合;
写出main.c程序,对关键代码给出注释;
对超级终端的显示结果进行截图。
实验六
实验题目:LCD驱动编程
实验类型:设计型
实验日期:11.2(第一组),11.4(第二组)
1.实验目的及要求
了解LCD的工作原理;
理解LCD的驱动控制;
熟悉用总线方式驱动LCD模块;
熟悉用ARM内置的LCD控制器驱动LCD。
2.实验仪器设备与软件环境
硬件:ARM嵌入式开发平台、PC机、串口线。
软件:PC机操作系统Windows XP或Windows 7、ARM ADS1.2 集成开发环境、超级终端通讯程序。
3.实验过程及实验结果分析
(以下文字为提示内容,不要出现在实验报告中)
从实验指导手册中选取适当内容:LCD工作原理、用S3C2410X中内置的LCD控制器驱动LCD屏幕的方法、与ARM自带LCD驱动器有关的寄存器;
写出main.c程序,对关键代码给出注释; 对超级终端的显示结果进行截图。
第二篇:嵌入式定期实时时钟实验报告
综合性设计性实验报告
课程名称: 嵌入式系统原理
开设时间: 20##学年第二学期
专业班级: 07软件工程(1)班
指导教师: 殷建军
提交时间: 2010年6月4日
综合性设计性实验成绩单
1、实验题目分析
1.1 问题描述
结合实时时钟,IIC(控制小键盘和数码管等)来做具备定期功能的实时时钟。
1.2功能分析
至少完成以下功能:
(1)能显示每秒的时刻
(2)按下功能键能切换显示日期
(3)能设置定时闹钟,定时到产生某种输出
(4)可以扩展考虑加入外部中断,如停止闹钟功能等。
1.3 开发平台及工具介绍
实验器材有:
CITK2410开发板,JTAG连接线,RS-232直通连接线
RVDS集成开发环境,超级终端工具,
2、实验概要设计
2.1 实验基本原理
IIC总线:IIC总线的器件分为主器件和从器件。主器件的功能是启动在总线上传送数据,并产生时钟脉冲,以允许与被寻址的器件进行数据传送。
SCL线为高电平期间,SDA线由高电平向低电平的变化表示起始信号;SCL线为高电平期间,SDA线由低电平向高电平的变化表示终止信号。
I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。
超始和停止信号图
数据传送时序图
IIC总线(IICSDA、IICSCL)经过VDD33的上拉后,进入ZLG7290
数码管:实验使用的数码管是广州周立公司单片机发展有限公司自行设计的一款数码管显示驱动及键盘扫描管理芯片。下面是介绍该数码管的特点还有电路图:
1 I2C 串行接口提供键盘中断信号方便与处理器接口
2 可驱动8 位共阴数码管或64 只独立LED 和64 个按键
3 可控扫描位数可控任一数码管闪烁
4 提供数据译码和循环移位段寻址等控制
5 8 个功能键可检测任一键的连击次数
6 无需外接元件即直接驱LED 可扩展驱动电流和驱动电压
7 提供工业级器件多种封装形式PDIP24 SO24
采用24 引脚封装引脚图如图所示其引脚功能分述如下:
实时时钟(Real Time Clock):2410提供了一个实时时钟,该时钟使用独立的一路1.8V供电,保证主电源切断时能正常维持RTC工作。2410的RTC支持两个中断:Time Tick(固定在一个频率内发出的时钟中断) 和Alarm中断(在某个时刻产生闹铃中断)。利用这两个中断可以设置每一秒中断一次显示变化时间,用Alarm中断实现闹钟功能。以下为S3C2410内部RTC模块结构图:
2.2 实验电路图
ZLG7290功能电路图:
IIC总线接口电路图:
2.3 实验主要步骤
1.初始化配置(各种寄存器)。
2.编写各种相关的中断程序。
3.主函数调用这几个中断程序。
4.编译程序,在zoc串口工具进行测试。
5.使用zoc下载和调试。
3、实验详细过程
3.1 具体实验过程和内容
(1)实现实时时钟功能
设置rRTCCON、rTICNT、rRTCALM寄存器
TICNT[6:0]=127;可以设置rTICNT=(1<<7)|(127)实现每秒中断一次。
可以设置闹铃寄存器,例如每秒的第几秒中断一次,实现定时闹钟的功能。
要设置初始化当前时间。
这里还包括编写Time Tick中断和Alarm中断的中断服务程序。
(2)初始化IIC总线
编写一个IIC的操作库。包括发送和接受功能。
编写可以向ZLG7290发出指令的函数。
(3)编写键盘中断处理程序
通过键盘中断,实现数码管显示日期和时间的切换,还有停止。
(4)使用RVDS集成开发环境编译调试程序
(5)使用ZOV软件测试
3.2 程序流程图
3.3 实验和程序问题分析
这次试验实际上是融合了三个实验的要求,要实验实时时钟的功能,包括显示当前时间,还有设置闹钟,主要使用到2410的RTC的两个中断:Time Tick和Alarm中断。
而要实现在数码管上显示当前时间,并且按键盘时实现时间与日期的切换,需要用到数码管和IIC总线的知识。
而实现的难处在于如何把几个内容融合在一起并且实现所需的功能,这也是实验要求做的。
4、实验输出界面
选取主要界面的截图。
5、总结
这次实验其实是包含了几个内容的,有实验5的实时时钟(RTC)实验,实验6的IIC总线与数码管实验。试验7的IIC总线与键盘实验。而实现的功能也相应增加了,因此难度加大了一点。要分别掌握RTC,IIC,还有数码管的知识。但是通过这次实验,我对它们的知识得到了巩固。
在没有学RTC的时候,我就对某些事情感到好奇,我的手机拥有定时开机和关机功能,闹钟功能,疑惑的是,既然手机都关了,为何能够自动开机甚至是在关机的情况下相应闹钟功能。通过学习RTC的知识,我明白了2410提供了一个实时时钟,该时钟使用独立的一路1.8V供电,保证主电源切断时能正常维持RTC工作。手机相应闹铃和自动开机都有着相似的原理,帮我解惑不少。要想设计一个实时时钟和闹钟的功能,只需要RTC的两个中断,Time Tick和Alarm,需要设置一些寄存器的初值。
另外,通过使用数码管,还有自己上网搜索一些资料,了解到如何使晶体管发亮,而形成自己所要显示的字符或者数字形状,例如显示时间。而这次实验就是要用数码管显示时间或者日期。由于发光是用硬件实现的,而要控制得到我们要的输出,要通过我们编写代码,幸好中间的过程已经被实现了,我们实际上在键盘上打入数字,我们只需要初始化一些寄存器的值,数码管就会有显示。
而ZLG7290产生的中断,主机通过IIC总线可以读取。而IIC总线协议是需要了解过程的。
学习嵌入式系统的时间并不长,而且又是第一次接触,因此有很多东西还是不太了解,
虽然说时间不长,但是还是很有收获的,这次毕竟使自己有机会去学习一些贴近硬件的知识,如果将来有机会再学习,我还是很乐意的。毕竟一个真正学习计算机的人不能只知道软件的知识。
附录:主要程序代码:
#include "2410addr.h"
#include "target.h"
#include "2410lib.h"
#include "iic.h"
void iic_init(void)
{
rGPEUP |= 0xc000; // 禁止上拉
rGPECON |= 0xa00000; // 设置 GPIO 为 IIC 总线
// Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
//rIICCON = (1<<7) | (0<<6) | (1<<5) | (0xf);
//rIICADD = 0x10; // 2410 从设备地址
//rIICSTAT = 0x10; // IIC 总线输出有效
}
void iic_send_master(unsigned char *buf, int size)
{
// IIC 总线 Master 模式数据发送函数
int fc1;
// ZLG7290要求IIC传输速率不大于32Kbit/s,即Tx clock不大于32KHz
// 设置IICCLK=PCLK/512 Tx clock=IICCLK/4,则
// 如果FLCK=200MHz,则最大Tx clock = 24kHz,处于可接受范围
// 初始化 IIC
rIICCON = (1<<7) | (1<<6) | (1<<5) | (0<<4) | (3<<0);
rIICSTAT = 0xD0;
// 发送从设备地址
rIICDS = *(buf++) & 0xFE;
size--;
rIICSTAT = 0xF0;
while(!(rIICCON & IIC_PENDING_BIT));
while(size>0)
{
// 发送 buf 数据
rIICDS=*(buf++);
size--;
// 等待 IICSCL 到达触发沿
for(fc1=0;fc1<10;fc1++){;}
if(size!=0)
{
rIICCON = rIICCON & IIC_PENDING_MASK;
}
else
{
// 最后发送不需要应答
rIICCON = rIICCON & IIC_PENDING_MASK & IIC_ACK_MASK;
}
// 等待发送完成
while(!(rIICCON & IIC_PENDING_BIT));
}
// 停止 IIC
rIICSTAT = 0xD0;
rIICCON = rIICCON & IIC_PENDING_MASK;
Delay(10);
}
void iic_receive_master(unsigned char *cmdbuf, int cmdsize, unsigned char *buf, int size)
{
// IIC 总线 Master 模式数据接收函数
int fc1;
// ZLG7290要求IIC传输速率不大于32Kbit/s,即Tx clock不大于32KHz
// 设置IICCLK=PCLK/512 Tx clock=IICCLK/4,则
// 如果FLCK=200MHz,则最大Tx clock = 24kHz,处于可接受范围
int slave_addr;
rIICCON = (1<<7) | (1<<6) | (1<<5) | (0<<4) | (3<<0);
rIICSTAT = 0xD0;
// 发送从设备地址
slave_addr = *(cmdbuf++);
cmdsize--;
rIICDS = slave_addr & 0xFE;
rIICSTAT = 0xF0;
while(!(rIICCON & IIC_PENDING_BIT));
while(cmdsize>0)
{
// 发送 buf 数据
rIICDS=*(cmdbuf++);
cmdsize--;
// 等待 IICSCL 到达触发沿
for(fc1=0;fc1<10;fc1++){;}
rIICCON = rIICCON & IIC_PENDING_MASK;
// 等待发送完成
while(!(rIICCON & IIC_PENDING_BIT)){;}
}
rIICDS = slave_addr | 0x01;
rIICSTAT = 0xB0;
while(size>0)
{
if(size>1)
{
rIICCON = rIICCON & IIC_PENDING_MASK;
}
else
{
// 最后接收不需要应答
rIICCON = rIICCON & IIC_PENDING_MASK & IIC_ACK_MASK;
}
// 等待接收完成
while(!(rIICCON & IIC_PENDING_BIT)){;}
// 取出数据
*(buf++) = rIICDS;
size--;
}
// 停止 IIC
rIICSTAT = 0x90;
rIICCON = rIICCON & IIC_PENDING_MASK;
Delay(10);
}
void __irq isr_keyboard(void)
{
unsigned char cmdbuf[4];
unsigned char key[5];
// 关闭1号外中断
rINTMSK = rINTMSK | BIT_EINT1;
// 清除中断位
rINTPND = BIT_EINT1;
rSRCPND = BIT_EINT1;
// 等待 IIC 总线空闲
while(rIICCON & IIC_PENDING_BIT){;}
// 读取键值
cmdbuf[0]=IIC_ADDR_ZLG7290;
cmdbuf[1]=IIC_ADDR_ZLG7290_KEY;
iic_receive_master(cmdbuf,2,key,4);
// 判断是否有效按键
if(key[1] == 0x01)
{
// 数字左移2位
for(fc1=0;fc1<4;fc1++)
{
cmdbuf[1]=IIC_ADDR_ZLG7290_DPM0+date[fc1];
cmdbuf[2]=0xff;
iic_send_master(cmdbuf,3);
}
}
else if(key[1] == 0x02)
{
// 数字左移2位
for(fc1=0;fc1<4;fc1++)
{
cmdbuf[1]=IIC_ADDR_ZLG7290_DPM0+time[fc1];
cmdbuf[2]=0xff;
iic_send_master(cmdbuf,3);
}
}
// 打开1号外中断
rINTMSK = rINTMSK & ~BIT_EINT1;
}
void __irq isr_alarm(void)
{
rINTMSK = rINTMSK | BIT_RTC;
Uart_Printf("This is a alarm interrupt occur at the 30th second every minute.\n");
// 清除中断位
rINTPND = BIT_RTC;
rSRCPND = BIT_RTC;
rINTMSK = rINTMSK & ~BIT_RTC;
}
void __irq isr_tick(void)
{
public int tmpintmsk;
public int year;
public int month;
public int day;
public int date;
public int hour;
public int minute;
public int second;
public int readtime=0;
public int date[3];
public int time[3];
// 在实际应用中,由于“嘀嗒”中断实时性要求较高,中断时间固定,而且处理时间不长
// 所以需要屏蔽所有中断,并且清除中断位操作必须尽快执行
// 屏蔽所有中断
tmpintmsk = rINTMSK;
rINTMSK = BIT_ALLMSK;
// 清除中断位
rINTPND = BIT_TICK;
rSRCPND = BIT_TICK;
// “嘀嗒”中断服务处理
// 读时间
// 由于读时间时可能跨越了年、月、日、时、分界限
// 例如:本来时间是20##年12月31日23时59分59秒,但刚好读取到hour的时候,到达了20##年的0秒
// 从而造成了读出的时间前后不一致性
// 所以,如果遇到了秒读取是0的话,则需要再读一次。这样就能解决问题
do
{
year = ((rBCDYEAR & 0xF0)>>4)*10 + (rBCDYEAR & 0x0F);
month = ((rBCDMON & 0x10)>>4)*10 + (rBCDMON & 0x0F);
date = ((rBCDDAY & 0x70)>>4)*10 + (rBCDDAY & 0x0F);
hour = ((rBCDHOUR & 0x70)>>4)*10 + (rBCDHOUR & 0x0F);
minute = ((rBCDMIN & 0x70)>>4)*10 + (rBCDMIN & 0x0F);
second = ((rBCDSEC & 0x70)>>4)*10 + (rBCDSEC & 0x0F);
day = (rBCDDAY & 0x07);
readtime++;
}while(second==0 && readtime<=1);
date[0]=year;
date[1]=month;
date[2]=date;
time[0]=hour;
time[1]=minute;
time[2]=second;
Uart_Printf("Time is now: %.2d.%.2d.%.2d %.2d:%.2d:%.2d, %d\n",year,month,date,hour,minute,second,day);
// 恢复中断
rINTMSK = tmpintmsk;
}
void main(void)
{
iic_init();
// Init target board (call this function before anything can go!)
Target_Init();
Uart_Printf("CITK2410 RTC demo using RTC.\n");
// 初始化 RTC 和“嘀嗒”中断控制器
rRTCCON = (1<<3) | (0<<2) | (0<<1) | (0); // RTC 设置只读(为了 RTC 稳定,需要写的时候再打开写允许位)
rTICNT = (1<<7) | (127); // 允许“嘀嗒”中断,每1秒中断一次
rRTCALM = (1<<6) | (0<<5) | (0<<4) | (0<<3) | (0<<2) | (0<<1) | (1); // 设置闹铃计时器只对秒有效
// 设置闹铃寄存器(BCD格式)
rALMSEC = 0x30;
rALMMIN = 0x00;
rALMHOUR = 0x00;
rALMDATE = 0x00;
rALMMON = 0x00;
rALMYEAR = 0x00;
// 初始化时间
rRTCCON = (1<<3) | (0<<2) | (0<<1) | (1);
rBCDYEAR = 0x10;
rBCDMON = 0x06;
rBCDDATE = 0x05;
rBCDHOUR = 0x9;
rBCDMIN = 0x30;
rBCDSEC = 0x02;
rBCDDAY = 0x7;
rRTCCON = (1<<3) | (0<<2) | (0<<1) | (0);
// 设置 RTC 中断服务程序地址
// pISR_TICK 为时钟“嘀嗒”中断(Time tick interrupt)
// pISR_RTC 为闹铃中断(Alarm interrupt)
pISR_RTC = (unsigned int)isr_alarm;
pISR_TICK = (unsigned int)isr_tick;
// 打开 RTC 和“嘀嗒”中断
rINTMSK = rINTMSK & ~BIT_RTC;
rINTMSK = rINTMSK & ~BIT_TICK;
// 设置键盘中断服务程序地址
pISR_EINT1=(unsigned)isr_keyboard;
rINTMSK = rINTMSK & ~BIT_EINT1;
while(1)
{
;
}
}