资源描述
物理与机电学院课程设计报告
课程名称:微机原理与接口技术设计
系 部: 物 理 与 机 电 学 院
专业班级:08电子信息工程
学生姓名:凃 齐 赞
指引教师:李 建 华 涂 二 生
完毕时间: 5月29日
报告成绩:
评阅意见:
评阅教师 日期
目录
1. 设计目与规定 ………………………………………………3
1.1 设计目 ………………………………………………… 3
1.2设计规定……………………………………………………… 3
2. 方案设计与论证……………………………………………………4
1、设计分析…………………………………………………………4
2、方案论证…………………………………………………………4
3、方案选取…………………………………………………………4
3.硬件电路设计………………………………………………………4
4.软件设计………………………………………………………6
5.下载与调试……………………………………………………………8
6.结论与心得……………………………………………………10
7.参照文献…………………………………………………………………10
附录 实验程序……………………………………………………11
一、 设计目和规定
1.1设计目
(1)在学习了《进一步浅出ARM7》课程后,为了加深对理论知识理解,学习理论知识在实际中运用,培养动手能力和解决实际问题能力,通过实训,进一步熟悉和掌握ARM构造及工作原理。
(2)熟悉ARM Developer suitv1.2调试和仿真,提高软件调试能力。通过实际程序设计和调试,逐渐掌握模块化程序设计办法和调试技术。
(3)通过课程设计,掌握以ARM为核心电路设计基本办法和技术,理解电路参数计算办法。
(4)通过实训,电路检查能力,提高动手实践能力、提高科学思维能力。
(5)通过完毕一种程序开发完整过程,理解开发一种ARM应用系统全过程,为此后从事相应事业打下基本。
1.2设计规定
(1)ARM板DAC口P0.25连接数字示波器,默认状况下,输出一条直线流水等显示,数码管显示0;
(2)通过按住键1,波形切换为正弦波,伴有蜂鸣器鸣叫,数码管显示0;
(3)通过按住键2,波形切换为锯齿波,伴有蜂鸣器鸣叫,数码管显示1;
(4)通过按住键3,波形切换为三角波,伴有蜂鸣器鸣叫,数码管显示2;
(5)通过按住键4,波形切换为正弦半波,伴有蜂鸣器鸣叫,数码管显示3;
(6)在任意波形状况下,通过按住键5,可以线性调频;
(7)在任意波形状况下,通过按住键6,可以线性调幅;
二、方案设计与论证
1、设计分析:
本次实训目在于运用LPC2138开发板及外部中断方式进行函数信号发生器设计,实现函数信号发生器基本功能,并随着相应批示:产生各种波形以及波形切换和调频调幅(可以在此基本上进行添加,使其功能更加全面)。
2、方案论证:
方案一:采用ARMPWM功能产生方波,方波频率可以达到几百k,外接滤波电路,通过选频,得到各种波形。通过PWM直接调频调幅,或通过外接电路也可以调节。
方案二:采用ARMDAC功能产生任意波形,通过外部中断和定期调节调幅,在已有参照程序上做修改和补充。
3、方案选取:
本次实验选取第二种方案:第一种方案可以通过直接通过PWM来调幅调频,频率范畴比较宽,外接电路也很简朴。实现任意波形有点复杂,外接电路固定后,难于变化波形。第二种方案可以轻松通过编写任意波形函数,非常容易得到任意想要波形,不需外接电路也能实现上面功能。频率和幅度调节也可以通过数组较为容易实现。弊端频率范畴比较窄。这次选取了第二种方案。
三、硬件电路
1、器件
(1)选取芯片LPC2138运用EasyARM2131-LYXY开发板
(2) D/A 转换器 具备特性:
10 位数模转换器;
电阻串连构造;
缓冲输出;
掉电模式;
选取转换速率与功率关于。
她寄存器如下:
写程序时,只要将要转化值赋给DACR6到15位,然后定期器定期给她转换时间。则可以完毕转化。咱们采用10转化,也即1024个采样点转化,设定期时间为t0,则波形频率计算办法为:f=1/(1024*t0)。设赋值为value,则波形幅度计算办法为A=VALUE/1024*3.3.
(3)中断
LPC2138 通过向量中断控制器(VIC )管理中断。外设中断信号需要通过2 个开关才干 到达ARM 内核,真正产生异常,逻辑示意图如下图所示。如果在VIC中使能了相应外设中断,外设中断才干到达VIC并向内核发送中断祈求;只有使能了内核中断IRQ或者
FIQ,内核才干真正产生异常。硬件图如下
中断过程示意图如下:
(4)蜂鸣器连接图
在EasyARM2131开发板上,接有一种蜂鸣器,由P0.7控制,通过跳线JP11选取连接,控制电路图如下所示:本实验中由于和SPI片选有所冲突因此改用P0.11控制蜂鸣器,连接P0.11到P0.7即可实现功能。
高电平时蜂鸣器停止鸣叫,低电平时开始鸣叫
(5)按键连接图
进行GPIO输入实验时,先要设立IODIR使口线成为输入方式,然后读取IOPIN值即可。接线方式已在上面阐明。
不按下时为高电平,按下时变为低电平
(6)流水灯控制电路
EasyARM2131开发板上8路LED(LED8~LED1)分别可选取P1[25:18]进行控制,电路图如下所示:
(7)SPI接口方框图
SPI接口方框图
2、器件连接阐明
本次实训程序需要将实验板杜邦线线如下改接:
(1)JP5连接verf;
(2)KEY1连接p0.1;KEY2连接p0.3;KEY3连接p0.15;KEY4连接p0.9;
(3)数字示波器连接DAC、GND;
(4)P0.11接P0.7连接蜂鸣器。
四、软件设计
系统软件采用C语言编程,程序详情请看程序附件二;程序流程图如下图所示:
在按键同步数码管显示数字0、1、2、3分别相应正弦波、锯齿波
正弦半波,三角波,按键时蜂鸣器会蜂鸣一次,在整个过程中流水灯会始终不断循环。
1、 SPI管脚设立
2、蜂鸣器、流水灯机数码管设立均按照其各自功能和引脚程序设立,详细程序在附录主程序中给出。
按照教师规定将此引脚连接语句进行简化:
/* P0.25连接AOUT*/
PINSEL1&=~((uint32)0x03<<18);
PINSEL1|=((uint32)0x02<<18);
PINSEL1=PINSEL1&(~((uint32)0x00<<10));
PINSEL1=PINSEL1&(~((uint32)0x00<<8));
简化后语句同上面语句具备同样功能:
PINSEL1=0x00080000;
将UART0串口方式改为其她方式;
加入SPI七段数码管显示波形标示。详细办法请参照附录程序。
五、调试与成果
连接杜邦线,连接示波器。分别调试6个按键,观测波形变化。按KEY1键是正弦波,数码管显示0;按KEY2锯齿波,数码管显示1;按KEY3三角波,数码管显示2;按KEY4正弦半波,数码管显示3;并且流水灯也在不断循环。实现现象完全和预期同样。成果:
六、心得体会
通过这次实训虽然花了挺多精力和时间,但是学到了诸多知识并且较好实现了程序所有预期功能。在程序设计过程中两位教师耐心、有力指引给了我很大协助,尚有自己不断思考和查阅资料,再加上咱们小组中每一种人通力合伙较好完毕了这次课程设计。通过这次实训,使我对于软件制作流程有了更加深刻结识,并且更加能纯熟地使用有关软件。在编写程序过程中,要注意诸多问题,例如引脚使用有无冲突,怎么样才干同步运用两个同端口输出,怎么样把繁琐语句简化成简朴可行语句等等,这些都给我提出了规定,从中使我进步了诸多,不论在写程序还是程序阅读方面均有所加强,同步让我懂得独立思考和团队合伙重要性。这次实训不但仅是对于知识考察,更是考察了我细心与耐心,只有这样才干在实训中不至于迷失自己,找不到方向和突破口,也只有这样才干做到将学到知识较好应用到实际设计中去。总之,在实践中要多动脑筋,多动手,多查阅资料,将理论与实际完全结合好,才干做到最佳。
七、参照文献
【1】《进一步浅出ARM7》 北京航空航天大学出版社.周立功,张华等编著
【2】《电子报合订本(上)》 四川出版集团-四川科学技术出版社.
【3】《C程序设计完全手册》 人民邮电出版社
【4】《C程序设计》 清华大学出版社
【5】《数字电子技术基本》 高等教诲出版社
附录:实验程序
#include "config.h"
#include "math.h"
const uint32 LEDS8 = (0xFF << 18); // P1[25:18]控制LED8~LED1,低电平点亮
#define HC595_CS (1 << 29) // P0.29口为74HC595片选
#define BEEP 1 << 11 /* P0.7控制蜂鸣器 */
const uint32 KEY6 = 1 << 21; // P0.21连接KEY6
const uint32 KEY5 = 1 << 20; // P0.20连接KEY5
uint16 zhenxiantab[1024];
uint16 juchibotab[1024];
uint16 sanjiaotab[1024];
uint16 zhenbanbotab[1024];
uint16 zhenquanbotab[1024];
uint16 fangbotab[1024];
float fudu[16]={0.9,0.8,0.7,0.6,0.5,0.45,0.40,0.35,0.30,0.25,0.20,0.15,0.10,0.05,0.01,0};
uint32 pinlv[16]={10240000,9216000,819,7168000,6144000,510,4096000,307,2048000,1024000,921600,819600,716800,
614400,51,409600};
uint32 cnt1=0;
uint32 cnt2=0;
uint16 M;
void DelayNS (uint32 dly)
{
uint32 i;
for ( ;dly>0;dly--)
for (i=0;i<100000;i++);
}
/*
*********************************************************************************************************
** 函数名称 :main()
** 函数功能 :流水灯显示实验。
** 调试阐明 :连接跳线JP12至LED8~LED1。
**********************************************************************************************************/
/* 流水灯花样,低电平点亮,注意调用时候用了取反操作 */
const uint32 LED_TBL[] = {
0x00,0xFF, // 所有熄灭后,再所有点亮
0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80, // 依次逐个点亮
0x01,0x03,0x07,0x0F,0x1F,0x3F,0x7F,0xFF, // 依次逐个叠加
0xFF,0x7F,0x3F,0x1F,0x0F,0x07,0x03,0x01, // 依次逐个递减
0x81,0x42,0x24,0x18,0x18,0x24,0x42,0x81, // 两个靠拢后分开
0x81,0xC3,0xE7,0xFF,0xFF,0xE7,0xC3,0x81 // 从两边叠加后递减
};
/********************************************************************************************************
** 函数名称:MSPI_Init()
** 函数功能:初始化SPI接口,设立为主机。
** 入口参数:无
** 出口参数:无
*********************************************************************************************************/
void MSPI_Init(void)
{
PINSEL0 = (PINSEL0 & (~(0xFF << 8))) | (0x55 << 8) ;
SPCCR = 0x52; // 设立SPI时钟分频
SPCR = (0 << 3) | // CPHA = 0,数据在SCK 第一种时钟沿采样
(1 << 4) | // CPOL = 1,SCK 为低有效
(1 << 5) | // MSTR = 1,SPI 处在主模式
(0 << 6) | // LSBF = 0,SPI 数据传播MSB (位7)在先
(0 << 7); // SPIE = 0,SPI 中断被禁止
}
/********************************************************************************************************
** 函数名称:MSPI_SendData()
** 函数功能:向SPI总线发送数据。
** 入口参数:data 待发送数据
** 出口参数:返回值为读取数据
********************************************************************************************************/
uint8 MSPI_SendData(uint8 data)
{
IOCLR = HC595_CS; // 片选74HC595
SPI_SPDR = data;
while( 0 == (SPI_SPSR & 0x80)); // 等待SPIF置位,即等待数据发送完毕
IOSET = HC595_CS;
return(SPI_SPDR);
}
/* 此表为LED0~F以及L、P字模 */
uint8 const DISP_TAB[19] = {
// 0 1 2 3
0xC0,0xF9,0xA4,0xB0};/*
*******************************************************************************************
**************
** 函数名称 :IRQ_Eint0()
** 函数功能 :外部中断0 EINT0服务程序口。
** 入口参数 :无。
** 出口擦数 :无。
*******************************************************************************************
***************/
void __irq IRQ_Eint0 (void)
{
uint32 i;
i = IO0SET; /* 读取当前BEEP控制值 */
if ((i & BEEP) == 0)
IO0SET = BEEP;
else
IO0CLR = BEEP;
/* 正弦波输出 */
while(1)
{
MSPI_SendData(DISP_TAB[0]);
for(i=0;i<1024;i++)
{
M=zhenxiantab[i]*fudu[cnt2];
DACR=M<<6;
if((IO0PIN&KEY6)==0)
{
DelayNS(2);
if((IO0PIN&KEY6)==0)
{
cnt1%=16;
cnt1++;
DelayNS(50);
}
}
if((IO0PIN&KEY5)==0)
{
DelayNS(2);
if((IO0PIN&KEY5)==0)
{
cnt2%=16;
cnt2++;
DelayNS(50);
}
}
while ((T0IR & 0x01) == 0); /* 等待定期时间到 */
T0IR = 0x01; /* 清除中断标志 */
}
/* 等待外部中断信号恢复为高电平,若信号保持为低电平,中断标志会始终置位。*/
if ((EXTINT & 0x01) != 0)break;
}
EXTINT = 0x01; /* 清除EINT0中断标志 */
VICVectAddr = 0; /* 向量中断结束 */
}
/*
*******************************************************************************************
**************
** 函数名称 :IRQ_Eint1()
** 函数功能 :外部中断1 EINT1服务程序口。
** 入口参数 :无。
** 出口擦数 :无。
*******************************************************************************************
**************
*/
void __irq IRQ_Eint1 (void)
{
uint32 i;
i = IO0SET; /* 读取当前BEEP控制值 */
if ((i & BEEP) == 0)
IO0SET = BEEP;
else
IO0CLR = BEEP;
/* 锯齿波输出 */
while(1)
{
MSPI_SendData(DISP_TAB[1]);
for(i=0;i<1024;i++)
{
M=juchibotab[i]*fudu[cnt2];
DACR=M<<6;
if((IO0PIN&KEY6)==0)
{DelayNS(2);
if((IO0PIN&KEY6)==0)
{ cnt1%=16;
cnt1++;
DelayNS(50);
}
}
if((IO0PIN&KEY5)==0)
{DelayNS(2);
if((IO0PIN&KEY5)==0)
{ cnt2%=16;
cnt2++;
DelayNS(50);
}
}
while ((T0IR & 0x01) == 0); /* 等待定期时间到 */
T0IR = 0x01; /* 清除中断标志 */
}
/* 等待外部中断信号恢复为高电平,若信号保持为低电平,中断标志会始终置位。*/
if ((EXTINT & 0x02) != 0)break;
}
EXTINT = 0x02; /* 清除EINT1中断标志 */
VICVectAddr = 0; /* 向量中断结束 */
}
/*
*******************************************************************************************
**************
** 函数名称 :IRQ_Eint2()
** 函数功能 :外部中断2 EINT2服务程序口。
** 入口参数 :无。
** 出口擦数 :无。
*******************************************************************************************
***************/
void __irq IRQ_Eint2 (void)
{
uint32 i;
i = IO0SET; /* 读取当前BEEP控制值 */
if ((i & BEEP) == 0)
IO0SET = BEEP;
else
IO0CLR = BEEP;
/* 三角波输出 */
while(1)
{
MSPI_SendData(DISP_TAB[3]);
for(i=0;i<1024;i++)
{
M=sanjiaotab[i]*fudu[cnt2];
DACR=M<<6;
if((IO0PIN&KEY6)==0)
{DelayNS(2);
if((IO0PIN&KEY6)==0)
{ cnt1%=16;
cnt1++;
DelayNS(50);
}
}
if((IO0PIN&KEY5)==0)
{DelayNS(2);
if((IO0PIN&KEY5)==0)
{ cnt2%=16;
cnt2++;
DelayNS(50);
}
}
while ((T0IR & 0x01) == 0); /* 等待定期时间到 */
T0IR = 0x01; /* 清除中断标志 */
}
/* 等待外部中断信号恢复为高电平,若信号保持为低电平,中断标志会始终置位。*/
if ((EXTINT & 0x04) != 0)break;
}
EXTINT = 0x04; /* 清除EINT2中断标志 */
VICVectAddr = 0; /* 向量中断结束 */
}/*
*******************************************************************************************
**************
** 函数名称 :IRQ_Eint3()
** 函数功能 :外部中断3 EINT3服务程序口。
** 入口参数 :无。
** 出口擦数 :无。
*******************************************************************************************
***************/
void __irq IRQ_Eint3 (void)
{
uint32 i;
i = IO0SET; /* 读取当前BEEP控制值 */
if ((i & BEEP) == 0)
IO0SET = BEEP;
else
IO0CLR = BEEP;
/* 正弦全波输出 */
while(1)
{
MSPI_SendData(DISP_TAB[2]);
for(i=0;i<1024;i++)
{
M=zhenquanbotab[i]*fudu[cnt2];
DACR=M<<6;
if((IO0PIN&KEY6)==0)
{DelayNS(2);
if((IO0PIN&KEY6)==0)
{ cnt1%=16;
cnt1++;
DelayNS(50);
}
}
if((IO0PIN&KEY5)==0)
{DelayNS(2);
if((IO0PIN&KEY5)==0)
{ cnt2%=16;
cnt2++;
DelayNS(50);
}
}
while ((T0IR & 0x01) == 0); /* 等待定期时间到 */
T0IR = 0x01; /* 清除中断标志 */
}
/* 等待外部中断信号恢复为高电平,若信号保持为低电平,中断标志会始终置位。*/
if ((EXTINT & 0x08) != 0)break;
}
EXTINT = 0x08; /* 清除EINT3中断标志 */
VICVectAddr = 0; /* 向量中断结束 */
}
/*
*******************************************************************************************
**************
** 函数名称 :main()
** 函数功能 :初始化外部中断为向量中断,低电平触发,然后等待中断。
** 调试阐明 :在Startup.s文献中使能IRQ中断(清零CPSR中I位)。
*******************************************************************************************
***************/
uint8 rcv_data;
int main (void)
{
uint32 i;
PINSEL0 = 0x800c55cc; // 管脚连接GPIO,设立管脚连接,P0.1为EINT0,P0.3为EINT1,P0.9为EINT3,P0.15为EINT2
PINSEL2 = PINSEL2 & (~0x08); // P1[25:16]连接GPIO
IO1DIR = LEDS8; // 设立LED1控制口为输出
/* P0.25连接AOUT*/
PINSEL1=0x00080000;
IO0DIR = BEEP|HC595_CS;/* 设立BEEP控制口为输出,别的输入。*/
/* 定期器0初始化 */
T0TC = 0; /* 定期器设立为0 */
T0PR = 0; /* 时钟不分频 */
T0MCR = 0x03; /* 设立T0MR0匹配后复位T0TC,并产生中断标志 */
T0MR0 = Fpclk/pinlv[cnt2]; /* 0.5秒钟定期 */
T0TCR = 0x01; /* 启动定期器 */
EXTMODE = 0x00;/* 设立EINT0\EINT1\EINT2\EINT3为电平触发。 */
/* 极性寄存器使用默认值0。 */
IO0SET = BEEP;
/* 正弦波输出 */
for (i=0;i<1024;i++)
zhenxiantab[i]=512+511*sin(i*3.1415926/512);
/* 锯齿波输出 */
for (i=0;i<1024;i++)
juchibotab[i]=i%512*2;
/* 三角波输出 */
for (i=0;i<512;i++)
sanjiaotab[i]=i*2;
for (i=512;i<1024;i++)
sanjiaotab[i]=(1023-i)*2;
/* 正弦半波输出 */
for (i=0;i<512;i++)
zhenbanbotab[i]=512+511*sin(i*3.1415926/512);
for (i=512;i<1024;i++)
zhenbanbotab[i]=512;
/* 正弦全波输出 */
for (i=0;i<512;i++)
zhenquanbotab[i]=1024*sin(i*3.1415926/512);
for (i=512;i<1024;i++)
zhenquanbotab[i]=1024*sin((i-512)*3.1415926/512);
/* 方波输出 */
for (i=0;i<512;i++)
fangbotab[i]=0;
for (i=512;i<1024;i++)
fangbotab[i]=512;
MSPI_Init();
IRQEnable(); // 使能IRQ中断
/* 打开EINT0中断(使用向量中断) */
VICIntSelect = 0x00000000; /* 设立所有中断分派为IRQ中断 */
VICVectCntl0 = 0x20 | 14; /* 分派外部中断0到向量中断0 */
VICVectAddr0 = (uint32)IRQ_Eint0;/* 设立中断服务程序地址 */
/* 打开EINT1中断(使用向量中断) */
VICVectCntl1 = 0x20 | 15; /* 分派外部中断1到向量中断1 */
VICVectAddr1 = (uint32)IRQ_Eint1;/* 设立中断服务程序地址 */
/* 打开EINT2中断(使用向量中断) */
VICVectCntl2 = 0x20 | 16; /* 分派外部中断2到向量中断2 */
VICVectAddr2 = (uint32)IRQ_Eint2;/* 设立中断服务程序地址 */
/* 打开EINT3中断(使用向量中断) */
VICVectCntl3 = 0x20 | 17; /* 分派外部中断3到向量中断3 */
VICVectAddr3 = (uint32)IRQ_Eint3;/* 设立中断服务程序地址 */
EXTINT=0x0f; /* 清除外部所有中断标志 */
VICIntEnable = (1 << 14)|(1 << 15)|(1 << 16)|(1 << 17); /* 使能所有中断 */
while (1)
{
for (i=0;i<42;i++)
{ /* 流水灯花样显示 */
IO1SET = ~((LED_TBL[i]) << 18);
DelayNS(20);
IO1CLR = ((LED_TBL[i]) << 18);
DelayNS(20);
}
}
return (0);
}
/**********************************************
展开阅读全文