基于DSP实验系统的串口通信.docx
《基于DSP实验系统的串口通信.docx》由会员分享,可在线阅读,更多相关《基于DSP实验系统的串口通信.docx(17页珍藏版)》请在冰豆网上搜索。
基于DSP实验系统的串口通信
课程设计报告
(2014--2015年度第二学期)
课程名称:
DSP课程设计
题目:
基于DSP实验系统的串口通信
院系:
电子与通信工程系
班级:
电子
学号:
学生姓名:
指导教师:
设计周数:
2
成绩:
日期:
2015年7月16日
一、课程设计的目的与要求
1.设计方案:
通过TMS320C5509A的串口与电脑进行通信,利用串口调试助手发送数据,由DSP接收到,DSP读到收到数据进行下一步的让四位LED灯亮,实现数据的通信,并在lcd12864上显示发送的数据,还有显示拨码开关的数值。
2.设计指标:
电脑只能发送0~15,因为读出数据的时候比较方便解码,比如发送4就可以直接给LED直接赋值,让第三个灯亮,也就是一般的二进制转换。
二、设计正文
1.设计思路(系统组成介绍)
DSP总线
TMS320VC5509APGE
JTAG
片上资源:
主频:
400MIPS,双核
RAM:
128K*16bit
ROM:
32K*16bit
SDRAM:
4M*16bit
JTAG
FLASH:
8Mbit
寄存器组
LCD液晶
LED灯
UART
CPLD
2.主要部分硬件设计:
串口模块:
TL16C550是一个标准的串口接口芯片,它的控制寄存器基地址为0x400200,寄存器占用TMS320VC5509的8个地址单元。
串口中断与TMS320VC5509的INT0连接。
用户可以使用TMS320VC5509的中断0响应串口中断。
TL16C550有11个寄存器,这11个寄存器是通过TMS320VC5509的3个地址线(A3~A1)和线路控制寄存器中的DLAB位对它们进行寻址的。
板上加上16C550、Max232和驱动电路。
驱动电路主要完成将输出的0-3.3V电平转换成异步串口的工作电平,转换电平的工作由MAX232芯片完成,但由于它是5V器件,所以它同DSP间的信号线必须有电平转换,此板采用的是74LVC245。
实验箱上的液晶模块采用的型号是TJDM12864M
TJDM12864M是一款带中文字库的图形点阵模块,由动态驱动方式驱动128×64点阵显示。
低功耗,供应电电压范围宽。
内含多功能的指令集,操作简易。
采用COB工艺制作,结构稳固,使用寿命长。
特性:
1.提供8位,4位及串行接口可选
2.64×16位字符显示RAM(DDRAM最多16字符×4行,LCD显示范围16×2行)
3.2M位中文字型ROM(CGROM),总共提供8192个中文字型(16×16点阵)
4.16K位半宽字型ROM(HCGROM),总共提供126个西文字型(16×8点阵)
5.64×16位字符产生RAM(CGRAM)
6.15×16位总共240点的ICONRAM(ICONRAM)
7.自动复位(RESET)功能
8.绘图及文字画面混合显示功能
9.提供多功能指令:
——画面清除(displayclear)
——游标归位(returnhome)
——显示开/关(displayon/off)
——游标显示/隐藏(cursoron/off)
——字符闪烁(displaycharacterblink)
——游标移位(cursorshift)
——显示移位(displayshift)
——垂直画面旋转(verticallinescoll)
——反白显示(By-linereversedisplay)
——睡眠模式(sleepmode)
DSP与LCD的连接:
3.软件设计流程:
1
0
4.在试验箱上模拟实现
用随实验箱附带的串口线(两端均为9孔“D”形插头)连接计算机com1或com2插座和ICETEK–VC5509-A板上标准RS-232插座,编译、下载、运行。
然后在电脑上使用串口调试助手对DSP进行数据的发送,在DSP上可以看到LED的点亮方式及个数,而且在LCD上也显示发送来的数据。
具体代码见附录。
三.课程设计总结
1.问题与思考
1.1串口使用中用到的波特率该怎么算?
BRR=1—65535时的串行通信接口异步
波特率:
串行通信接口异步波特率=SYSCLK/[(BRR+1)*8]
其中,BRR=SYSCLK/(SCI异步波特率*8)-1;
BRR=0时的串行通信接口异步
波特率:
串行通信接口异步波特率=SYSCLK/16
这里BRR等于波特率选择寄存器的16位值。
波特率一般用9600HZ,或者115200HZ就行。
有一个方便的计算。
1.2串口发送接收数据的方式是怎样的?
串口发送数据为一位位的发送,例如发14,就是先发1,再发4,一位一位的对数据放入发送接收的缓存区,接收的时候也是一位一位的接收,一位一位都接收缓存区的里东西,知道这样才可以对收到数据进行读值解码。
.
1.3LCD12864及LED的介绍
LCD12864带中文字库的图形点阵模块,128×64点阵显示。
可以直接写入数据所对应的阿斯特码值进行显示,还有自己的中文字库,功能强大。
开发板上的LED为四位的共阳极的发光二级管,只要对对应的引脚进行低电平控制就可以让LED灯亮起来。
1.4在编译调试过程中出现的.cmd文件出错?
理解cmd文件中的内容。
.cmd文件类型及作用:
.cmd是链接器命令文件,用于存储器配置。
.cmd文件结构:
.cmd由两条链接伪指令来描述:
MEMORY和SECTIONS,其中:
MEMORY定义用户目标系统存储器的配置;
SECTIONS控制段的构建和存储器的分配。
sections是COFF文件中最重要的概念,它至少包含以下三个段:
.text段:
包含可执行代码;
.data段:
包含初始化数据;
.bss段:
为未初始化变量保留存储空间。
.cinit段:
包含初始化变量表和常数,C/C++的全局变量;
段的分类:
可分为已初始化段和未初始化段。
已初始化段:
包含数据或程序代码。
例如:
.text段,.data段和用.sect汇编命令建立的自定义段。
当汇编器遇到.text或.data或.sect命令时,将停止对当前段的汇编,然后将紧接着的程序代码或数据汇编到指定的段中,直到再遇见另一条命令为止。
未初始化段:
是‘C54x存储器中的保留空间,通常定义在RAM区。
包含:
.bss段和.usect段。
当汇编器遇到.bss或.usect命令时,并不停止对当前段的汇编,只是暂时从当前段脱离出来,并对新的段进行汇编。
个别有地址分配不足的可以根据手册进行地址长度修改或改变存储地址。
2.心得体会
本次课程设计我基本掌握了DSP基本的原理结构、TMS320C5509片上串口通信、外扩LCD和LED的编程使用。
通过对CCS集成开发工具的学习,给整个课程设计带来了极大的便利。
学会了CCS使用后,整个程序的设计、编辑、载入都可在一个集成环境下完成。
在学习串口的过程中学到了很多东西,串口是个非常实用的工具,调试软件的时候都会经常用到,还有串口本身还有一种接收中断,发送中断的方式,十分好用,但是由于本次课设使用的课本没有介绍,我也自己看看,他涉及中断,关及中断向量表的问题,还要对中断向量表进行配置,还要看进行汇编语言的设置中断向量表,我不会汇编语言,于是没有能用上接收中断,就觉得非常可惜,不然程序运行的会更好。
经过我不断的修改,最终程序调试完成,也基本达到了实验要求。
但由于时间的原因,这还有一些不尽如人意的地方,都可以继续改进。
说到中断不禁想起DSP的编程方式,真是大开眼界了,自己写着底层的库,老师说这是在锻炼我们,不仅仅学习软件方面的东西,还学习了DSP的硬件系统,知道每个寄存器的地址。
其实也有集成好的库,我也看过,要说的是,他自带的库用的是汇编语言写的,我们一般都看不懂,但是调用的时候竟然是c语言的调用,如果有时间好好看,应该也能用。
还有就是这种从底层写程序的方式虽然效率很低,不会的问题会很多,不通汇编语言的人学会很吃力,但是就像老师说的,得到了很好的锻炼,对DSP硬件软件都有了个很好的了解。
对以后的学习很有帮助。
总而言之,通过DSP课程设计,提高了自己的理论与实践编程能力,使得对DSP有了更为深刻的理解,在今后的学习中,我会更多的学习DSP的相关内容,不断努力提高设计与创新能力。
最后,非常感谢老师的指导与帮助,没有老师的指导我们将很难完成任务。
附录:
部分相关代码:
#include"myapp.h"
#include"5509.h"
#defineUART_BASE_ADDR0x400400
#defineRBR*((int*)(UART_BASE_ADDR+0))
#defineTHR*((int*)(UART_BASE_ADDR+0))
#defineIER*((int*)(UART_BASE_ADDR+1))
#defineIIR*((int*)(UART_BASE_ADDR+2))
#defineFCR*((int*)(UART_BASE_ADDR+2))
#defineLCR*((int*)(UART_BASE_ADDR+3))
#defineMCR*((int*)(UART_BASE_ADDR+4))
#defineLSR*((int*)(UART_BASE_ADDR+5))
#defineMSR*((int*)(UART_BASE_ADDR+6))
#defineSCR*((int*)(UART_BASE_ADDR+7))
#defineDLL*((int*)(UART_BASE_ADDR+0))
#defineDLM*((int*)(UART_BASE_ADDR+1))
//定义指示灯控制寄存器地址和寄存器类型
#defineLBDS(*((unsignedint*)0x400001))
//定义拨码开关控制寄存器地址和寄存器类型
#defineDIPS(*(unsignedint*)0x400002)
voidTMCR_reset(void);
voidEMIF_init(void);
voidwait(intnWait);
charcString[17]={"HelloPC!
Over|"},cReceive,cBuffer[17],
cAnswer[10]={"yousay"};
charcShu[11]={"0123456789"},a[17]={0};
intflagReceive=0,nLen=0;
unsignedintaBuffer[17],b[17]={0};
unsignedintrece=0;
intk=0,dipadd=0;
//主程序
main()
{
unsignedintuWork;
inti;
//flagReceive=0;
TMCR_reset();
PLL_Init(12);
EMIF_init();
SDRAM_init();//初始化EMIF接口
InitCTR();
clrram();
Smenu();
LCR=0x80;//分频
DLL=0x18;//分频低8
DLM=0x00;//分频高8
LCR=0x03;//8比特
FCR=0x01;//fifo模式
MCR=0x00;//
MSR=0x00;
IER=0x00;
for(;;)
{
if(flagReceive==0)
{
if(dipadd>=0&&dipadd<=9)
{
wr_lcd(0,0x98);//第四行
wr_lcd(1,cShu[dipadd]);
wr_lcd(1,'');
}
elseif(dipadd<16)
{
wr_lcd(0,0x98);//第四行
wr_lcd(1,cShu[1]);
wr_lcd(1,(cShu[dipadd%10]));
}
}
else
{
flagReceive=0;
for(i=0;i<7;i++)
{
do
{
uWork=LSR;//线路状态,接收数据
}while(uWork&0x040!
=0x040);//接收到,退出
THR=cAnswer[i];//发送yousay
wait(128);
}
for(i=0;i{
do
{
uWork=LSR;
}while(uWork&0x040!
=0x040);
THR=aBuffer[i];//发送接收到的数
wait(128);
}
if(b[1]=='.')
{
wr_lcd(0,0x90);//第二行
wr_lcd(1,(b[0]));
LBDS=b[0];
}
elseif(b[2]=='.')
{
wr_lcd(0,0x90);//第二行
wr_lcd(1,(b[0]));
wr_lcd(1,(b[1]));
LBDS=(b[0]+b[1]+9);
}
}
k=0;flagReceive=0;
while
(1)//接收发送到的,并计算字符表长度k
{
uWork=LSR;
if((uWork&1)==1)
{
cReceive=RBR;//接收到的数据
aBuffer[k]=cReceive&0x0ff;
a[k]=aBuffer[k];
b[k]=aBuffer[k];
if(cReceive=='.')
{
aBuffer[k+1]='\0';
nLen=k+1;
flagReceive=1;
break;
}
k++;k%=16;
}
Else//扫描拨码开关
{
dipadd=DIPS&0x000f;
break;
}
}
}
}
voidEMIF_init(void)
{
ioportunsignedint*ce21=(unsignedint*)0x809;
*ce21=0x1fff;
}
voidTMCR_reset(void)
{
ioportunsignedint*TMCR_MGS3=(unsignedint*)0x07FE;
ioportunsignedint*TMCR_MM=(unsignedint*)0x07FF;
*TMCR_MGS3=0x510;
*TMCR_MM=0x000;
}
voidwait(intnWait)
{
inti,j,k=0;
for(i=0;ifor(j=0;j<64;j++)
k++;
}
/*------------------写LCD------------------*/
voidwr_lcd(unsignedchardat_comm,unsignedintcontent)
{
if(dat_comm)
{
CTRGR=0x01;
TRLCDCR=0x03;
CTRLCDLCR=content;
CTRLCDCR=0x0b;
Delay(10);
CTRLCDCR=0x03;
CTRGR=0x02;
}
else
{
CTRGR=0x01;
CTRLCDCR=0x01;
CTRLCDLCR=content;
CTRLCDCR=0x09;
Delay(10);
CTRLCDCR=0x01;
CTRGR=0x02;
}
}
//LCD初始化
voidInitCTR()
{
CTRGR=0x01;//CTRGR=0x80;CTRGR=0;
Delay(10);
CTRLCDCR=0x00;
Delay(10);
CTRLCDCR=0x01;
wr_lcd(comm,0x30);/*30---基本指令动作*/
wr_lcd(comm,0x01);/*清屏,地址指针指向00H*/
wr_lcd(comm,0x06);/*光标的移动方向*/
wr_lcd(comm,0x0c);/*开显示,关游标*/
}
/*----------------清DDRAM------------------*/
voidclrram(void)
{
wr_lcd(comm,0x30);
wr_lcd(comm,0x01);
}
/*******************************************
函数名称:
LCD12864_datstr
功能:
向12864液晶写入一个字符串
参数:
ptString--字符串指针
返回值:
无
********************************************/
voidLCD12864_datstr(char*ptString)
{
while((*ptString)!
='\0')//字符串未结束一直写
{
wr_lcd(dat,*ptString++);
}
}