资源描述
专业课程设计嵌入式
成绩 _______
指导教师评定成绩:
审定成绩:
重 庆 邮 电 大 学 移 通 学 院
课程设计报告
设计题目: 基于ARM的交通灯设计
学 校: 重庆邮电大学移动学院
学 生 姓 名: 刘星
专 业: 电气工程及其自动化
班 级: 05111301
学 号: 2013212290
指 导 教 师: 黄 娜
设计时间: 2016 年 11 月
重庆邮电大学移通学院
《嵌入式系统》课程设计任务书
引言:嵌入式系统课程设计是自动化专业的一个重要教学环节,既有别于毕业设计,又不同于课堂教学。它需要学生统筹运用所学各个专业的基本理论、基本方法对现实生活中的实际问题进行设计和调试。
一、 设计题目:基于ARM的交通灯设计
掌握嵌入式系统设计的基本方法,熟悉S3C24X0的开发环境及软硬件的调试过程,了解S3C24X0芯片各个引脚功能,工作方式,计时/定时,I/O口,中断等的相关原理,根据控制要求进行编程,解决十字路口交通灯控制的问题。巩固和加深对理论课中知识的理解,提高对所学知识的综合运用能力。
二、 系统工作过程说明
车辆遇到红灯停绿灯行的行走情况,红绿灯时间均为60s,切换时间为10s,最后5s为黄灯闪烁。
利用S3C24X0 ARM芯片实现单路交通灯的控制:
① 实现红、绿、黄灯的循环控制。使用红、黄、绿三种不同颜色的LED灯实现此功能,由南往北方向红、黄、绿三个灯依次在P1.18、P1.19、P1.20上,由北往南方向的红、黄、绿三个灯依次接在P1.21、P1.22、P1.23上,人行道用红、绿两个灯控制,依次接在P1.24、P1.25上,用软件控制灯的亮与灭来控制车辆和行人的通行。
② 用数码管显示倒计时。可以利用动态显示或静态显示,串行并出或者并行并出实现。
③ 南北方向控制车辆的绿灯熄灭的同时,控制蜂鸣器响2秒来作为警报。蜂鸣器接P0.7引脚。
交通路口示意图如下图:
设计内容:
(1)完成S3C24X0最小系统的硬件电路设计,并用Protel DXP设计电路原理图;
(2)完成交通指示灯控制程序代码设计,在实验箱上调试并且能正常工作。
三、 设计步骤:
(1)对系统进行需求分析;
(2)初始化配置(各种寄存器);
(3)编写各种相关的中断程序并在主函数中调用这些程序;
(4)编译程序;
(5)使用仿真器进行调试。
摘要
本设计此次试验以S3C2440嵌入式开发平台为硬件基础,主要介绍了嵌入式实时操作系统中的最小系统的各个组成部分,其中包括电源、时钟、复位、存储器、JTAG接口电路原理图及交通灯电路图的设计。随着移动设备的流行和发展,嵌入式系统已经成为一个热点。它并不是最近出现的新技术,只是随着微电子技术和计算机技术的发展,微控制芯片功能越来越大,而嵌入微控制芯片的设备和系统越来越多,从而使得这种技术越来越引人注目。它对软硬件的体积大小、成本、功耗和可靠性都提出了严格的要求。嵌入式系统的功能越来越强大,实现也越来越复杂,随之出现的就是可靠性大大降低。最近的一种趋势是一个功能强大的嵌入式系统通常需要一种操作系统来给予支持,这种操作系统是已经成熟并且稳定的,可以是嵌入式的Linux,WINCE等等。本文所要研究的就是基于ARM嵌入式系统的交通灯系统的设计与实现。
关键词:ARM 交通灯 控制
一、绪论
1、设计目的
掌握嵌入式系统设计的基本方法,熟悉S3C24X0的开发环境及软硬件的调试过程,了解S3C24X0芯片各个引脚功能,工作方式,计时/定时,I/O口,中断等的相关原理,根据控制要求进行编程,解决十字路口交通灯控制的问题。巩固和加深对理论课中知识的理解,提高对所学知识的综合运用能力。
2、设计内容
1. 查阅相关文献资料,熟悉所选ARM芯片
2. 总体设计方案规划,设计车辆遇到红灯停绿灯行情况,红绿灯时间均为60s,切换时间为10s,最后5s为黄灯闪烁。
3. 系统硬件设计,熟悉I/O接口,定时器,计数器工作原理
4. 系统软件设计,包括交通信号灯的工作流程软件实现,用C语言编程
5. 设计心得体会及总结。
3、要实现的目标
通过设计,培养自己综合运用所学知识、独立分析和解决实际问题的能力,培养创新意识和创新能力,并获得科学研究的基础训练,加深对ARM芯片的了解;熟悉ARM芯片各个引脚的功能,工作方式,计数/定时,I/O口,中断等相关原理,巩固学习嵌入式的相关内容知识。 利用ARM芯片模拟实现交通灯控制。自行选择所需ARM芯片,查阅相关文献资料,熟悉所选ARM芯片,了解所选ARM芯片各个引脚功能,工作方式,计数/定时,I/O口,中断等相关原理,通过软硬件设计实现利用ARM芯片完成交通灯的模拟控制。
二、系统分析及硬件设计
1、S3C24X0芯片介绍
S3C2440A 基于 ARM920T 核心,0.13µm 的 CMOS 标准宏单元和存储器单元。低功耗,简单,精致,且全静态设计特别适合于对成本和功率敏感型的应用。
它采用了新的总线架构如先进微控制总线构架(AMBA)。S3C2440A 的突出特点是其处理器核心,是一个由 Advanced RISC Machines(ARM)公司设计的 16/32 位 ARM920T 的 RISC 处理器。
ARM920T 实现了 MMU,AMBA 总线和哈佛结构高速缓冲体系结构。这一结构具有独立的 16KB 指令高速缓存和 16KB 数据高速缓存。每个都是由具有 8 字长的行(line)组成。
S3C2440A 集成的以下片上功能:
1.2V 内核供电, 1.8V/2.5V/3.3V 储存器供电, 3.3V 外部 I/O 供电, 具备 16KB 的指令缓存和 16KB 的数据缓存和 MMU 的微处理器
● 外部存储控制器(SDRAM 控制和片选逻辑)
● LCD 控制器(最大支持 4K 色 STN 和 256K 色 TFT)提供 1 通道 LCD 专用 DMA
● 4 通道 DMA 并有外部请求引脚
● 3 通道 UART(IrDA1.0, 64 字节发送 FIFO 和 64 字节接收 FIFO)
● 2 通道 SPI
● 1 通道 IIC 总线接口(支持多主机)
● 1 通道 IIS 总线音频编码器接口
● AC’97 编解码器接口
● 兼容 SD 主接口协议 1.0 版和 MMC 卡协议 2.11 兼容版
● 2 通道 USB 主机/1 通道 USB 设备(1.1 版)
● 4 通道 PWM 定时器和 1 通道内部定时器/看门狗定时器
● 8 通道 10 位 ADC 和触摸屏接口
● 具有日历功能的 RTC
● 摄像头接口(最大支持 4096×4096 像素输入;2048×2048 像素输入支持缩放)
● 130 个通用 I/O 口和 24 通道外部中断源
● 具有普通,慢速,空闲和掉电模式
● 具有 PLL 片上时钟发生器 系统管理
● 支持大/小端
● 地址空间:每 Bank 128M 字节(总共 1G 字节)
● 支持可编程的每 Bank 8/16/32 位数据总线宽度
● BANK0 到 BANK6 固定 Bank 的起始地址
● BANK7 具有可编程 Bank 起始地址和大小
● 8 个存储器 Bank:
● 六个存储器 Bank 为 ROM,SRAM 和其它
● 两个存储器 Bank 为 ROM/SRAM/ SDRAM
● 所有存储器具备完整可编程访问周期
● 支持外部等待信号来扩展总线周期
● 支持 SDRAM 掉电时自刷新模式
● 支持从各种类型 ROM 启动(NOR/NAND Flash, EEPROM 或其它) NAND Flash 启动引导 (BootLoader )
● 支持从 NAND Flash 启动
● 4KB 的启动内部缓冲区
● 支持启动后 NAND flash 作为存储器
● 支持先进 NAND Flash
2、系统电路设计
3、电路原理图
三、系统软件设计
1、系统流程图
2、系统程序设计
1.首先从设定系统初始值开始,将所有交通灯,数码管的选位,以及倒数计数的数组设定。
2.开始设定子程序,定时器0中断服务子程序 重装初值,计数增减,人行道红灯马路绿灯,并且开始计数递减,若在55内并且是0时开始显示黄灯闪烁,闪烁3秒,若是55秒的话马路黄灯人行道红灯,若是在55到60秒之内,黄灯开始闪烁,当到60秒时,马路红灯人行道绿灯。
3.主程序开始时,要先对中断程序进行中断初始化。
4.对主程序开始调试,先设置引脚位置和输出位置,初始化定时器,然后引用中断程序,根据定时器的定时,设定红绿黄灯跳转。
四、系统调试
总结
了解所选择的ARM芯片各个引脚功能,工作方式,计数/定时,I/O口,中断等的相关原理,并巩固学习嵌入式的相关内容知识。
这毕竟第一次做的,难免会遇到过各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固,比如说不懂一些元器件的使用方法,对汇编语言掌握得不好……通过这次课程设计之后,一定把以前所学过的知识重新温故。
附录
一、 源程序
#include"at89x51.h"
Unsigned char
num[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //数字0~9
unsigned char ctr[]={0x7e,0xf5};//0xfa(P3_0和P3_2为0,即高位有效) unsigned char disEW[2];//记录东西向高低位数值
unsigned char disSN[2];//记录南北向高低位数值
unsigned char v;
unsigned char cnt_ctr;
unsigned int scdEW,scdSN;
unsigned int cntSN,cntEW;
unsigned char cntP3_4,cntP3_5,cntP3_6;
unsigned int cnt_num,cnt_key,cnt_flash,keyMemory;
int greenEW = 56,yellowEW = 3,greenSN = 56,yellowSN = 3;//延时函数,a为1延时1毫秒
void delay_ms(unsigned int a)
{
int i;
while(a--)
{
i = 70;
while(i--);
}
}
//设置红绿黄灯秒数
void setSecond(void)
{
while(P3_4 == 0);
cntP3_4++;//标志设置键被按下的次数
switch(cntP3_4)
{
case 1:
cntEW = 5;
P1 = 0xf7;
break;
case 2:
cntEW = 1;
P1 = 0xef;
break;
case 3:
cntSN = 1;
P1 = 0xfe;
break;
case 4:
cntSN = 3;
P1 = 0xfd;
break;
case 5:
cntEW = 5;
cntSN = 5;
cnt_num = 0;
cntP3_4 = 0;
break;
}
}
//秒数加1
void addSecond(void)
{
while(P3_5 == 0);
cnt_key = 0; //记录长按键的参数清零
switch(cntP3_4)
{
case 1:
if(keyMemory != greenEW + 10) //判断按键是否已经加10,如果没 有加10则秒数加1,如果已经加10则不加1
{
greenEW++;
}
if(greenEW == 90)
{
greenEW = 0;
}
scdEW = greenEW;
scdSN = greenEW + yellowEW + 1;
break;
case 2:
if(yellowEW++ == 9)
{
yellowEW = 0;
}
scdEW = yellowEW;
break;
case 3:
if(keyMemory != greenSN + 10)
{
greenSN++;
}
if( greenSN == 90)
{
greenSN = 0;
}
scdEW = greenSN + yellowSN + 1;
scdSN = greenSN;
break;
case 4:
if(yellowSN++ == 9)
{
yellowSN = 0;
}
scdSN = yellowSN;
break;
}
}
//秒数减1
void subSecond(void)
{
while(P3_6 == 0);
cnt_key = 0;
//记录长按键的参数清零
switch(cntP3_4)
{
case 1:
if(keyMemory != greenEW - 10) //判断按键是否已经减10,如果没 有减10则秒数减1,如果已经减10则不减1
{
greenEW--;
}
if(greenEW == -1)
{
greenEW = 89;
}
scdEW = greenEW;
scdSN = greenEW + yellowEW + 1;
break;
case 2:
if(yellowEW-- == 0)
{
yellowEW = 9;
}
scdEW = yellowEW;
break;
case 3:
if(keyMemory != greenSN - 10)
{
greenSN--;
}
if(greenSN == -1)
{
greenSN = 89;
}
scdEW = greenSN + yellowSN + 1;
scdSN = greenSN;
break;
case 4:
if(yellowSN-- == 0)
{
yellowSN = 9;
}
scdSN = yellowSN;
break;
}
}
//正常显示秒数
void display(void)
{
cnt_num++;
if(cnt_ctr == 10)
{
cnt_ctr = 0;
P3 = 0xff;
P3 = ctr[v];
P2 = num[disEW[v]]; //显示东西方向秒数
P0 = num[disSN[v]]; //显示南北方向秒数
if(v++ == 1)
{
v = 0;
}
}
}
//闪烁显示秒数
void dspFlash(void)
{
cnt_flash++;
if(cnt_flash < 660)
{
P3 = 0xff;
//数码管灭
}
else
{
if(cnt_flash == 1333)
//数码管亮 1333=4000/3 即1秒闪3次
{
cnt_flash = 0;
}
if(cnt_ctr == 59)
{
cnt_ctr = 0;
P3 = 0xff;
P3 = ctr[v];
switch(cntP3_4)
{
case 1:
P3_0 = 1;
P3_1 = 1;
P2 = num[disEW[v]];
break;
case 2:
P3_0 = 1;
P3_1 = 1;
P2 = num[disEW[v]];
break;
case 3:
P3_2 = 1;
P3_3 = 1;
P0 = num[disSN[v]];;
break;
case 4:
P3_2 = 1;
P3_3 = 1;
P0 = num[disSN[v]];
break;
}
if(v++ == 1)
{
v = 0;
}
}
}
} //长按加10秒
void add_10s(void)
{
cnt_key = 0;
switch(cntP3_4)
{
case 1:
greenEW = greenEW + 10; //长按秒数加10
if(greenEW >= 90)
{
greenEW = 0;
}
keyMemory = greenEW + 10; //keyMemory用来标记秒数已经加10
scdEW = greenEW;
scdSN = greenEW + yellowEW + 1;
break;
case 3:
greenSN = greenSN + 10;
if(greenSN >=90)
{
greenSN = 0;
}
keyMemory = greenSN + 10;
scdEW = greenSN + yellowSN + 1;
scdSN = greenSN;
break;
}
}
//长按减10秒
void sub_10s(void)
{
cnt_key = 0;
switch(cntP3_4)
{
case 1:
greenEW = greenEW - 10; //长按秒数减10
if(greenEW < 0)
{
greenEW = 89;
}
keyMemory = greenEW - 10; //keyMemory用来标记秒数已经减10
scdEW = greenEW;
scdSN = greenEW + yellowEW + 1;
break;
case 3:
greenSN = greenSN - 10;
if(greenSN < 0)
{
greenSN = 89;
}
keyMemory = greenSN - 10;
scdEW = greenSN + yellowSN + 1;
scdSN = greenSN; break;
}
} //T0中断
void t0(void) interrupt 1
{
cnt_ctr++;
if(cntP3_4 == 0)
{
display(); //正常显示秒数
}
if(cntP3_4 != 0)
{
dspFlash(); //闪烁显示秒数
}
if(cnt_num == 4000)
{
cnt_num = 0;
if(scdEW-- == 0)
{
cntEW++; //东西向秒数减至0,标志位加1
}
if(scdSN-- == 0)
{
cntSN++; //南北向秒数减至0,标志位加1
}
}
switch(cntEW)
{
case 1:
scdEW = yellowEW; //东西向黄灯亮,显示黄灯秒数
P1_3 = 1;
P1_4 = 0;
P1_5 = 1;
cntEW++; //避免程序到此阻塞,故将其至为2
break;
case 3: //避免cntEW为2
scdEW = greenSN + yellowSN + 1; //东西向红灯亮,显示红灯秒 数
P1_3 = 1;
P1_4 = 1;
P1_5 = 0;
cntEW++; //避免程序到此阻塞,故将其至为4
break;
case 5: //避免cntEW为4
scdEW = greenEW; //东西向绿灯亮,显示绿灯秒数
P1_3 = 0;
P1_4 = 1;
P1_5 = 1;
cntEW = 0;
break;
}
switch(cntSN)
{
case 1:
scdSN = greenSN; //南北向绿灯亮,显示绿灯秒数
P1_0 = 0;
P1_1 = 1;
P1_2 = 1;
cntSN++; //避免程序到此阻塞,故将其至为2
break;
case 3: //避免cntSN为2
scdSN = yellowSN; //南北向黄灯亮,显示黄灯秒数
P1_0 = 1;
P1_1 = 0;
P1_2 = 1;
cntSN++; //避免程序到此阻塞,故将其至为4
break;
case 5: //避免cntSN为4
scdSN = greenEW + yellowEW + 1; //南北向红灯亮,显示红灯秒 数
P1_0 = 1;
P1_1 = 1;
P1_2 = 0;
cntSN = 0;
break;
}
if(P3_5 == 0)
{
if(cnt_key++ == 4000)
{
add_10s(); //长按数码管加10秒
}
}
if(P3_6 == 0)
{
if(cnt_key++ == 4000)
{
sub_10s(); //长按数码管减10秒
}
}
disEW[0] = scdEW/10;
disEW[1] = scdEW%10;
disSN[0] = scdSN/10;
disSN[1] = scdSN%10; }
//主函数
void main(void)
{
TMOD = 0x02; //设置定时器0为工作方式2
TH0 = 0x06;
TL0 = 0x06; //初始化8位定时器 (256 - 6)*40000 = 1s
EA = 1; //总中断允许
ET0 = 1; //T0中断允许
TR0 = 1; //打开T0中断
EX0 = 1; //xiugai::开外部中断
P1 = 0xf3; //东西向绿灯,南北向红灯
P3_4 = 1;
scdEW = greenEW; //设置东西向显示秒数
scdSN = greenEW + yellowEW + 1; //设置南北向显示秒数
while(1)
{
if(P3_4 == 0)
{
delay_ms(15);
if(P3_4 == 0)
{
setSecond(); //设置红绿黄灯秒数
}
}
else
if(P3_5 == 0)
{
delay_ms(15);
if(P3_5 == 0)
{
addSecond();
}
}
else if(P3_6 == 0)
{
delay_ms(15);
if(P3_6 == 0)
{
subSecond();
}
}
keyMemory = 200; //给keyMemory任意赋值,防止长按加10或减10 后不能正常加减
}
}
25
展开阅读全文