基于DSP的输出电压范围可调的高精度毫伏信号发生器设计(内附完整程序)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

目录
0 摘要--------------------------------------------------------2
1 设计任务与要求----------------------------------------------
2 1.1 设计任务-----------------------------------------------2 1.2 基本电压-----------------------------------------------2
1.3 发挥部分-----------------------------------------------2
2 系统方案论证------------------------------------------------2
3 系统设计与理论分析------------------------------------------2 3.1 核心模块TMS320DSP芯片---------------------------------2 3.2 数模转换模块-------------------------------------------3 3.3 基准电压源模块-----------------------------------------3
3.4 模数转换模块-------------------------------------------4
3.5 485通信模块-------------------------------------------5
3.6 显示模块-----------------------------------------------6
4 系统调试----------------------------------------------------7 4.1 调试仪器仪表-------------------------------------------7 4.2 调试及分析---------------------------------------------7
4.3 误差分析-----------------------------------------------7
5 设计总结----------------------------------------------------8
6 元件清单----------------------------------------------------8
7 参考文献----------------------------------------------------9
8 程序清单----------------------------------------------------10
0、摘要:本系统以DSP芯片为核心,控制过程是DSP接收数据并送入DA电路,利用AD820作为比较器,正端接D/A输出,负端接地,反馈输出接AD采样,失调电压调零,输出形成闭环回路,通过AD转换电路将实际值采回DSP,由DSP进行运算,得输入值与采回值之差即误差,输出结果通过12864液晶屏显示。

系统通过LM4050为A/D,D/A提供基准电压,使系统具有较高的可靠性。

采用的DSP减少了由运放产生的非线性误差。

关键字:信号发生器TMS320DSP芯片基准电源芯片LM4050
1、设计任务与要求
1.1设计任务:设计出有一定输出电压范围高精度毫伏信号发生器,并能够检测其输出精度
1.2基本要求
(1)输出电压:范围0~+1V,步进0.5mV;具有输出电压值(测量值)显示功能;由“+”、“-”两键分别控制输出电压步进增减;
(2)具备485通讯能力,波特率可设置,即4800、9600、19200、38400 、56000、57600、 115200bps可设置;
(3)能显示设定值与实际值及其误差。

1.3发挥部分
(1)输出电压:范围0~+2V,步进0.1mV;指定输出范围内任意电压值;
(2)能提高精度模拟J型热电偶分度简表(见附表)输出(输入温度后,自动输出电压值);
(3)检测部分可单独成为电压测量模块,测量范围、精度参考电压输出部分;
2、系统方案论证
用DSP作为核心芯片,输出的数字信号由D/A转换成模拟信号,再经由A/D采回芯片内部形成反馈。

利用LM4050提供基准电压,7809稳定基准电压源的输出电压, UA741做电压跟随器使其工作稳定。

为了使其工作更加精确,需要再加一个AD820作为比较器来减小非线性误差。

而与单片机相比,DSP器件具有较高的集成度。

DSP具有更快的CPU,更大容量的存储器,内置有波特率发生器和FIFO缓冲器。

提供高速、同步串口和标准异步串口。

有的片内集成了A/D 和采样/保持电路,可提供PWM输出。

DSP器件采用改进的哈佛结构,具有独立的程序和数据空间,允许同时存取程序和数据。

内置高速的硬件乘法器,增强的多级流水线,使DSP器件具有高速的数据运算能力。

DSP器件比16位单片机单指令执行时间快8~10倍,完成一次乘加运算快16~30倍。

3、系统设计与理论分析
3.1 核心模块TMS320DSP芯片
DSP是一种独特的微处理器,是以数字信号来处理大量信息的器件。

其工作原理是接收模拟信号,转换为0或1的数字信号。

再对数字信号进行修改、删除、强化,并在其他系统芯片中把数字数据解译回模拟数据或实际环境格式。

DSP微处理器一般具有如下主要特点:(1)在一个指令周期内可完成一次乘法和一次加法;
(2)程序和数据空间分开,可以同时访问指令和数据;
(3)片内具有快速RAM,通常可通过独立的数据总线在两块中同时访问;
(4)具有低开销或无开销循环及跳转的硬件支持;
(5)快速的中断处理和硬件I/O支持;
(6)具有在单周期内操作的多个硬件地址产生器;
(7)可以并行执行多个操作;
(8)支持流水线操作,使取指、译码和执行等操作可以重叠执行。

3.2 数模转换模块
3.2.1 D/A转换电路如图所示,通过AD5541芯片实现将数字量转换为模拟量,送给电压比较器。

该电路通过LM4050提供基准电压源,UA741做电压跟随器,使电压稳定。

AD820作为比较器,正端接D/A输出,负端接地,反馈输出接AD采样,失调电压调零,输出形成闭环回路,减少由运放产生的非线性误差,由DSP进行运算。

算法:输出值=(D/65535)*REF,其中D为载入DAC代码。

D/A转换电路
3.2.2 AD5541芯片
AD5541为单通道、16位、串行输入、电压输出数模转换器(DAC),采用5 V ± 10%单电源供电。

AD5541采用多功能三线式接口,并且与SPI、QSPI™、MICROWIRE™、DSP接口标准兼容。

这些DAC可提供16位性能,无需进行任何调整。

DAC输出不经过缓冲,可降低功耗,并减少输出缓冲所造成的失调误差。

3.3 基准电压源模块
3.3.1 LM4050芯片
LM4050/是精密的二端、并联模式、带隙电压基准,具有多种固定反向击穿电压:1.225V、2.048V、2.500V、3.000V、3.3V、4.096V和5.000V。

LM4050/LM4051采用超小型、3引脚SC70表贴封装(1.8mm x 1.8mm),比采用SOT23表贴封装的同类器件缩小了50%。

如图所示电路,即为基准电压电路,它为A/D模块,D/A模块提供稳定的基准电压。

对电路稳定性起着至关重要的作用。

基准电压模块电路
3.3.2 UA741芯片
如图所示,UA741是高增益运算放大器这类单片硅集成电路器。

件提供输出短路保护和闭锁自由运作。

这些类型还具有广泛的共同模式,差模信号范围和低失调电压调零能力与使用适当的电位。

1和5为偏置(调零端),2为正向输入端,3为反向输入端,4接地,6为输出,7接电源 8空脚
3.4 模数转换模块
3.4.1 ADS8320芯片
AD8320其特点及功能:ADS8320是Burr-Brown公司生产的逐次逼近式串行16位微功耗CMOS
型高速A/D转换器,它的线性度为±0.05%,工作电源在2.7V~5.25V范围内,采样频率最高可达100kHz;在2.7V供电和100kHz采样速率下,其功耗仅为1.8mW,而在10kHz低速采样时的功耗仅为0.3mW;在非转换状态时可处于关闭模式,此时功耗可低至100μW;ADS8320具有同步串行SPI/SSI接口,因而占用微处理器的端口较少;其差动输入信号范围为500mV~VCC(工作电源);采用8引脚MSOP小体积封装
算法:送入DSP芯片的数值=(输入的模拟值/REF)*65535
A/D 转换电路
3.4.2 AD820芯片
AD820是一款精密、低功耗、FET输入运算放大器,可以采用5 V至36 V单电源或±2.5 V 至±18 V双电源供电。

该放大器具有单电源供电能力,输入电压范围可扩展至负供电轨以下,因此在单电源模式下可以处理地电压以下的输入信号。

输出电压摆幅可扩展至各供电轨10 mV 以内,以提供最大的输出动态范围。

直流精度性能包括最大800 μV的失调电压、2 μV/°C 的失调电压漂移、小于25 pA的典型输入偏置电流以及低输入电压噪声,源阻抗最高可达1 G Ω。

单位增益带宽为1.8 MHz,10 kHz时总谐波失真(THD)为−93 dB,压摆率为3 V/μs,电源电流低至800 μA。

AD820可直接驱动最高350 pF的容性负载,并可提供最低15 mA的输出电流。

因此,该放大器能够处理各种负载情况。

AD820在A/D转换电路中有电压跟随器的作用。

3.5 485通信模块
3.5.1 max485芯片
MAX485是用于RS-485与RS-422通信的低功耗收发器。

MAX485的驱动器摆率不受限制, 可以实现最高2.5Mbps的传输速率。

这些收发器在驱动器禁用的空载或满载状态下,吸取的电源电流在120μA至500μA之间。

所有器件都工作在5V单电源下。

驱动器具有短路电流限制,并可以通过热关断电路将驱动器输出置为高阻状态。

接收器输入具有失效保护特性,当输入开路时,可以确保逻辑高电平输出。

具有较高的抗干扰性能。

MAX485是市面上最为常见的RS422芯片,亦是用量最大的RS422芯片,性价比高,优质,供货稳定是大部分厂家采用MAX485接口芯片是Maxim公司的一种RS-485芯片。

MAX485芯片的结构和引脚都非常简单,内部含有一个驱动器和接收器。

RO和DI端分别为接收器的输出和驱动器的输入端,与单片机连接时只需分别与单片机的RXD和TXD相连即可;/RE 和DE端分别为接收和发送的使能端,当/RE为逻辑0时,器件处于接收状态;当DE为逻辑1
时,器件处于发送状态,因为MAX485工作在半双工状态,所以只需用单片机的一个管脚控制这两个引脚即可;A端和B端分别为接收和发送的差分信号端,当A引脚的电平高于B时,代表发送的数据为1;当A的电平低于B端时,代表发送的数据为0。

在与单片机连接时接线非常简单。

只需要一个信号控制MAX485的接收和发送即可。

同时将A和B端之间加匹配电阻,一般可选100Ω的电阻。

MAX引脚(管脚)图及工作电路
3.5.2 MAX232芯片
第一部分是电荷泵电路。

由1、2、3、4、5、6脚和4只电容构成。

功能是产生+12v和-12v两个电源,提供给RS-232串口电平的需要。

第二部分是数据转换通道。

由7、8、9、10、11、12、13、14脚构成两个数据通道。

其中13脚(R1IN)、12脚(R1OUT)、11脚(T1IN)、14脚(T1OUT)为第一数据通道。

8脚(R2IN)、9脚(R2OUT)、10脚(T2IN)、7脚(T2OUT)为第二数据通道。

TTL/CMOS数据从T1IN、T2IN输入转换成RS-232数据从T1OUT、T2OUT送到电脑DB9插头;DB9插头的RS-232数据从R1IN、R2IN输入转换成TTL/CMOS数据后从R1OUT、R2OUT 输出。

第三部分是供电。

15脚GND、16脚VCC(+5v)。

3.5.3 485串口通信电路
串口电路
3.6 显示模块
显示电路采用12864液晶屏,该点阵的屏显成本相对较低,适用于各类仪器,小型设备的
显示领域。

液晶屏连线方式
4、系统调试
4.1 调试仪器仪表
仪器名称型号数量
双通道示波器RIG—OL 1
数字万用表UT52 1
4.2 调试及分析
首先,把DA和AD 的基准电压源调到两伏,然后满量程输出的值就应该是2伏,而实际上我们得到的是1.89伏,原因是因为DA的输出有漂移,DSP把数字信号送给DA5541,DA 输出模拟信号,经过ADS8320输出模拟信号,整个过程,为了使输出的电压更加稳定,加入了AD820作为电压跟随器,利用它的输入阻抗高,输出阻抗低的特点,同时通过减法器使实测电压缓慢的接近输入电压值,通过验证,AD采回的数值偏高,这样我们又加入ua741电压跟随器来调整基准电压的输出,最后调整到输入电压值和实测电压值偏差接近0.2毫伏之内,最后把基准电压确定在2.0伏,然后通过万用表和示波器测量出AD样值和AD的输出值通过LCD12864液晶屏将输入电压和实测电压显示出来,误差接近0.1毫伏,通过按键调整波特率,同时使输入电压步进0.1毫伏,这样反复通过AD820减法器使实测电压值接近输入值,这样就达到了本实验的要求和目的。

4.3 误差分析
造成误差的原因有
(1)零点漂移:由于运算放大器的零点漂移,温度漂移等带来的误差,可以通过温度补偿措施来解决此误差。

(2)A/D,D/A转换误差:受AD转换器精度及基准源稳定程度的限制,不可避免地带来一定的误差。

为了更精确的输出电源电压,选用更多位数的AD,DA芯片。

(3)因外界突发干扰或仪表显示值等引起的随机误差或粗大误差。

(4)采样电阻自热效应引起的误差:由于电阻在温度上升时阻值会发生变化,因此会引起温度飘移,给系统带来测量的误差。

5、设计总结
直流毫伏信号发生器可以实现如下功能:
(1)输出电压:范围0~+1V,步进0.5mV;具有输出电压值(测量值)显示功能;由“+”、“-”两键分别控制输出电压步进增减;
(2)具备485通讯能力,波特率可设置,即4800、9600、19200、38400 、56000、57600、115200bps可设置;
(3)能显示设定值与实际值及其误差。

本设计制作完成了题目要求的基本部分的全部要求和发挥部分的大部分要求,而且部分功能大大高于发挥部分的要求。

目前,在电子仪器,设备中经常要用到直流毫伏信号发生器,有时要求应具有良好的稳定性,而且精度较高。

该设计完全符合了这些要求,如果再经过结构优化,将具有良好的市场前景。

通过本次电子设计大赛的学习,对DSP的应用有了基本的了解,对DSP软件编程及调试有了基本的掌握。

这对我们来说是一个质的提高。

在本次设计大赛的过程中,我们的团队精神体现了重要的作用。

6、元件清单
TMS320F2812PGF芯片一片
AD5541芯片一片
12864液晶屏一块
LM4050芯片一片
AD820芯片二片
ADS8320芯片一片
UA741芯片一片
MAX485芯片一片
MAX232芯片一片
胆电容一个
开关四个
三端稳压器7805,AS2830各一片
电阻,电容,导线若干
7、参考文献:
[1] 全国大学生电子设计设计竞赛组委员会.全国大学生电子设计竞赛训练教程[M].北京电
子工业出版社,2005年
[2] 全国大学生电子设计设计竞赛组委员会.全国大学生电子设计竞赛获奖作品汇编(第一
届~第五届)[M].北京理工大学出版社,2004年
[3] 模拟电子技术基础. 童诗白,华成英主编
[4] 现代电力电子器件原理与应用.机械工业出版社
[5] TMS320x28xxx原理与开发. 苏奎峰编
8、程序清单
//BUS LCD
#include "DSP281x_Device.h" // DSP281x Headerfile Include File
#include "DSP281x_Examples.h" // DSP281x Examples Include File
#include "LED.C"
//****************************************************
//定义区
unsigned int value;
unsigned char ADV AL[8]={'x','.','x','x','x','x','\0'};
unsigned char ADVAL_err[8]={'0','.','0','0','0','0',' ','\0'};
unsigned int key=0x4E20;
unsigned char key_baud=0x00;
unsigned int key_value=0x0000;
char key_false=0x00;
//****************************************************
#define A VG 10 // Average sample limit
#define BUF_SIZE 10 // Sample buffer size
Uint16 Sample_AD=0x0000;
Uint16 SampleTable[BUF_SIZE];
Uint32 Sample=0,Sample_A VG=0;
// SCI发送接收数据中间变量
Uint16 sdataB[16]; // Send data for SCI-A
Uint16 rdataB[8]; // Received data for SCI-A
Uint16 rdata_pointB; // Used for checking the received data
//****************************************************
unsigned char baud_disp[8]={'4','8','0','0',' ',' ','\0'};
unsigned char baud_disp1[8]={'9','6','0','0',' ',' ','\0'};
unsigned char baud_disp2[8]={'1','9','2','0','0',' ','\0'};
unsigned char baud_disp3[8]={'3','8','4','0','0',' ','\0'};
unsigned char baud_disp4[8]={'5','6','0','0','0',' ','\0'};
unsigned char baud_disp5[8]={'5','7','6','0','0',' ','\0'};
unsigned char baud_disp6[8]={'1','1','5','2','0','0','\0'};
unsigned char number_tab[]={'0','1','2','3','4','5','6','7','8','9'};
//***********************************************
//***********************************************
//波特率设定首位高字节,二位低字节
//SCI_PRD[14]={4800,9600,19200,38400,56000,57600,115200};
unsigned char
SCI_PRD[14]={0x03,0xCF,0x01,0xE7,0x00,0xF3,0x00,0x79,0x00,0x52,0x00,0x50,0x00,0x27};
void initlcm(void); //初始化LCM
void sendCMD(char dat); //写控制指令
void sendDAT(char dat); //写显示数据;也可以写一个单字节字符
void display(char x_add,char dat,char dat1);//写汉字到LCD屏指定位置
void delay(unsigned int t);
//****************************************************
//SCI函数声明FIFO模式
interrupt void scibTxFifoIsr(void);
interrupt void scibRxFifoIsr(void);
interrupt void cpu_timer0_isr(void);
void scib_fifo_init(void);
void delay_ad(void);
//****************************************************
//**************************************************** Uint16 spi_data=0x0000; // send data
void delay_loop(void);
void spi_xmit(Uint16 a);
void spi_fifo_init(void);
void spi_init(void);
void error(void);
//****************************************************
//发送半角数字和字母字符串
//*p为字符串指针
//amount 所发送字符串的最大数量
void char_string (unsigned char *p,unsigned char amount); unsigned char title[]={"输入电压"};//标题
unsigned char title1[]={"实测电压"};//标题
unsigned char title2[]={"输入波特率"};//标题
unsigned char title3[]={"实际偏差"};//标题
///////////////////////////////////////////////
void delay(unsigned int t)
{
while(t>0)
t--;
}
//**************************************************
void sendBYTE(char dat) //串行传送一字节数据
{
char i;
GpioMuxRegs.GPBDIR.all|=SID;
for (i=0;i<8;i++)
{
delay(1000);
GpioDataRegs.GPBDAT.all&=~SCK; //SCK=0 if((dat & 0x80)!=0)
GpioDataRegs.GPBDAT.all|=SID; //SID=1
else
GpioDataRegs.GPBDAT.all&=~SID; //SID=0
GpioDataRegs.GPBDAT.all|=SCK; //SCK=1;
dat = dat<<1;
}
}
//****************************************************
//如果需要改变半字地址,也是用此程序.只需输入地址就可以.
void sendCMD(char dat) //写控制指令
{
sendBYTE(0xf8);
sendBYTE(dat & 0xf0);
sendBYTE((dat<<4)&0xf0);
}
//****************************************************
void sendDAT(char dat)//写显示数据;也可以写一个单字节字符
{
sendBYTE(0xfa);
sendBYTE(dat & 0xf0);
sendBYTE((dat<<4)&0xf0);
}
//****************************************************
void display(char x_add,char dat,char dat1)
//写汉字到LCD屏指定位置
//x_add显示RAM地址
//dat/dat1显示汉字编码
{
sendCMD(x_add);
sendDAT(dat);
sendDAT(dat1);
}
//*****************************************************
void initlcm(void)//初始化LCM
{
delay(1000);
GpioMuxRegs.GPBDIR.all|=SCK; //SCK设为输出
sendCMD(0x30);//功能设置:一次送8位数据,基本指令集
sendCMD(0x04);//点设定:显示字符/ 光标从左到右移位,DDRAM地址加一sendCMD(0x0f);//显示设定:开显示,显示光标,当前显示位反白闪动sendCMD(0x0f);//显示设定:开显示,显示光标,当前显示位反白闪动sendCMD(0x01);//清DDRAM
sendCMD(0x02);//*DDRAM 地址归位
}
//****************************************************
//发送半角数字和字母字符串
//*p为字符串指针
//x_add 所要显示的地址
void char_string (unsigned char *p, unsigned char x_add)
{
unsigned char n;
if((x_add >= GM12232_MINADD_L1)&&(x_add <GM12232_MAXADD_L1)) { sendCMD(x_add);
for (n=0; p[n]!='\0'; n++)
{ sendDAT(p[n]); }
}
else if ((x_add >= GM12232_MINADD_L2)&&(x_add <GM12232_MAXADD_L2))
{ sendCMD(x_add);
for (n=0; p[n]!='\0'; n++)
{ sendDAT(p[n]); }
}
else if ((x_add >= GM12232_MINADD_L3)&&(x_add <GM12232_MAXADD_L3))
{ sendCMD(x_add);
for (n=0; p[n]!='\0'; n++)
{ sendDAT(p[n]); }
}
else if ((x_add >= GM12232_MINADD_L4)&&(x_add <GM12232_MAXADD_L4))
{ sendCMD(x_add);
for (n=0; p[n]!='\0'; n++)
{ sendDAT(p[n]); }
}
else
return ;
}
//说明:实验标题1,应用单实形式发送.
void send_title() //标题显示
{ sendCMD(DDRAM_0); //DDRAM
sendCMD(off_cursor); //关光标
}
//****************************************************
//说明:单片机初始化
void init(void)
{ initlcm(); //LCD初始化
char_string (title,LCD_L11); //发送本实验标题1
char_string (title1,LCD_L21); //发送本实验标题1
char_string (title2,LCD_L31); //发送本实验标题1
char_string (title3,LCD_L41); //发送本实验标题1
char_string (baud_disp,LCD_L36);
send_title(); //发送本实验标题2
sendCMD(off_cursor); //关光标
}
//****************************************************
//说明:数值转换
void conv(unsigned int intdata, unsigned char *pc,unsigned char set_or_ad)//set=0x00,ad=0x01 { unsigned int a,b,c,d;
if(0x00==set_or_ad)
{
sdataB[0]=0x41;
sdataB[1]=ADV AL[0]=number_tab[intdata/10000] ;
a=intdata%10000 ;
sdataB[2]= ADV AL[2]=number_tab[a/1000] ;
b=a%1000 ;
sdataB[3]=ADV AL[3]=number_tab[b/100] ;
c=b%100;
sdataB[4]=ADV AL[4]=number_tab[c/10] ;
d=c%10;
sdataB[5]=ADV AL[5]=number_tab[d/1] ;
sdataB[6]=0x30;
sdataB[7]=0x30;
pc[0]=ADV AL[0];
pc[1]='.';
pc[2]=ADV AL[2];
pc[3]=ADV AL[3];
pc[4]=ADV AL[4];
pc[5]=ADV AL[5];
pc[6]='\0';
}
if(0x01==set_or_ad)
{
sdataB[8]=0x42;
sdataB[9]=ADV AL[0]=number_tab[intdata/10000] ;
a=intdata%10000 ;
sdataB[10]= ADV AL[2]=number_tab[a/1000] ;
b=a%1000 ;
sdataB[11]=ADV AL[3]=number_tab[b/100] ;
c=b%100;
sdataB[12]=ADV AL[4]=number_tab[c/10] ;
d=c%10;
sdataB[13]=ADV AL[5]=number_tab[d/1] ; sdataB[14]=0x30;
sdataB[15]=0x30;
pc[0]=ADV AL[0];
pc[1]='.';
pc[2]=ADV AL[2];
pc[3]=ADV AL[3];
pc[4]=ADV AL[4];
pc[5]=ADV AL[5];
pc[6]='\0';
}
if(0x02==set_or_ad)
{
intdata=abs((float)key-Sample_AD);
ADV AL[0]=number_tab[intdata/10000] ;
a=intdata%10000 ;
ADV AL[2]=number_tab[a/1000] ;
b=a%1000 ;
ADV AL[3]=number_tab[b/100] ;
c=b%100;
ADV AL[4]=number_tab[c/10] ;
d=c%10;
ADV AL[5]=number_tab[d/1] ;
pc[0]=ADV AL[0];
pc[1]='.';
pc[2]=ADV AL[2];
pc[3]=ADV AL[3];
pc[4]=ADV AL[4];
pc[5]=ADV AL[5];
pc[6]='\0';
}
}
//**************************************************** unsigned int DA_OUT(void)
{ float vol_const=3.27675;
float key_voltage;
unsigned int key_vol;
key_voltage=(float)key;
key_voltage*=vol_const;
spi_data=key_voltage;
}
void delay_ad(void)
{
unsigned int i,j;
for(i=0;i<6;i++)
{
for(j=0;j<10;j++);
}
}
Uint16 ads8320(void)
{
unsigned int i,da=0x0000;
GpioDataRegs.GPADAT.bit.GPIOA0=1;
GpioDataRegs.GPADAT.bit.GPIOA1=1;
delay_ad();
GpioDataRegs.GPADAT.bit.GPIOA0=0;
GpioDataRegs.GPADAT.bit.GPIOA1=1;
delay_ad();
while(1)
{
GpioDataRegs.GPADAT.bit.GPIOA1=1;
delay_ad();
if( GpioDataRegs.GPADAT.bit.GPIOA2==0)
break;
GpioDataRegs.GPADAT.bit.GPIOA1=0;
delay_ad();
}
for(i=0;i<0x10;i++)
{
GpioDataRegs.GPADAT.bit.GPIOA1=1;
delay_ad();
if( GpioDataRegs.GPADAT.bit.GPIOA2==0)
da=da<<1;
else
{
da=da|0x0001;
da=da<<1;
}
GpioDataRegs.GPADAT.bit.GPIOA1=0;
delay_ad();
}
GpioDataRegs.GPADAT.bit.GPIOA0=1;
delay_ad();
return(da);
}
void AD_SUM_A VG(void)
{
unsigned int i=0;
float aF=0.9;
static float Sample_A VG_fst=0.0;
Sample=0;
for (i=0; i<A VG; i++)
{
SampleTable[i]=ads8320();
Sample=Sample+SampleTable[i];
}
Sample_A VG=Sample/A VG;
Sample_A VG=(1-aF)*Sample_A VG+aF*Sample_A VG_fst;
Sample_AD=Sample_A VG*0.327675;
Sample_A VG_fst=Sample_A VG;
}
void main(void)
{
InitSysCtrl(); //初始化系统
//初始化系统时钟,系统时钟150M,低俗时钟37.5M,打开外设时钟SPI控制37.5M EALLOW;
SysCtrlRegs.PCLKCR.bit.SPIENCLK=0x01;
EDIS;
//****************************************************
//初始化GPIOF,设定SPI外设控制
EALLOW;
GpioMuxRegs.GPFMUX.all=0x000F; // Select GPIOs to be SPI pins
// Port F MUX - x000 0000 0000 1111 EDIS;
//初始化GPIOA,设定GPA0为AD8320的CS,GPA1为SCK,GPA2为Dout EALLOW;
GpioMuxRegs.GPAMUX.all=0x0000; // GPIOI/Os
GpioMuxRegs.GPADIR.all=0xFFFB; // GPIO DIR select GPIOs as output GpioDataRegs.GPADAT.bit.GPIOA0=1; //ads8320--cs
GpioDataRegs.GPADAT.bit.GPIOA1=1; //ads8320--clk
EDIS;
//初始化SCI,GP4为TXD,GP5为RXD
EALLOW;
GpioMuxRegs.GPGMUX.bit.SCITXDB_GPIOG4 = 1;
GpioMuxRegs.GPGMUX.bit.SCIRXDB_GPIOG5 = 1;
EDIS;
//初始化GPIOB,设定低四位为按键输入
EALLOW;
GpioMuxRegs.GPBMUX.all=0x0000; // peripheral I/Os
GpioMuxRegs.GPBDIR.all=0xFF00; // GPIO DIR select GPIOs as output EDIS;
//****************************************************
//****************************************************
DINT; //关闭中断
IER = 0x0000;
IFR = 0x0000;
//****************************************************
InitPieCtrl(); //初始化PIE控制寄存器
InitPieVectTable(); //初始化PIE参数表
init(); //初始化液晶显示
//****************************************************
EALLOW; // This is needed to write to EALLOW protected registers PieVectTable.RXBINT = &scibRxFifoIsr;
PieVectTable.TXBINT = &scibTxFifoIsr;
EDIS; // This is needed to disable write to EALLOW protected registers
//****************************************************
scib_fifo_init(); // Init SCI-B
spi_fifo_init(); // Initialize the Spi FIFO
spi_init(); // init SPI
//****************************************************
// Enable interrupts required for this example
PieCtrlRegs.PIECRTL.bit.ENPIE=1; // Enable the PIE block PieCtrlRegs.PIEIER9.bit.INTx3=1; // PIE Group 9, INT1
PieCtrlRegs.PIEIER9.bit.INTx4=1; // PIE Group 9, INT2
//****************************************************
// PieCtrlRegs.PIEIER6.bit.INTx1=1; // Enable PIE Group 6, INT 1
// PieCtrlRegs.PIEIER6.bit.INTx2=1; // Enable PIE Group 6, INT 2
EINT;
//****************************************************
EALLOW;
GpioDataRegs.GPADAT.bit.GPIOA1=1;
GpioDataRegs.GPADAT.bit.GPIOA0=0;
EDIS;
//****************************************************
EALLOW;
PieVectTable.TINT0=&cpu_timer0_isr; //将CPU定时器0的中断服务程序入口地址写到PIE向量表中
EDIS;
InitCpuTimers();
ConfigCpuTimer(&CpuTimer0,150,250000);
PieCtrlRegs.PIEIER1.bit.INTx7=1; //使能PIE中组1的第7个中断TINT0-PIE 级中断使能
IER = 0x121; // Enable CPU INT
CpuTimer0Regs.TCR.bit.TSS=0; //停止定时器0的运行
//****************************************************
while(1)
{
Uint16 i;
AD_SUM_A VG();
DA_OUT();
spi_xmit(spi_data);
char_string (title,LCD_L11); //发送本实验标题1_输入电压
char_string (title1,LCD_L21); //发送本实验标题2_实测电压
char_string (title2,LCD_L31); //发送本实验标题3_输入波特率
conv(Sample_AD,ADV AL,0x01); //数据转换调用
char_string (ADV AL,LCD_L25); //发送实测电压值
for(i=0;i<500;i++)
{
delay(5000);
}
conv(key,ADV AL,0x00); //数据转换调用
char_string (ADV AL,LCD_L15); //发送输入电压值
for(i=0;i<500;i++)
{
delay(5000);
}
conv(key_false,ADV AL_err,0x02); //数据转换调用
char_string (ADV AL_err,LCD_L45); //发送实测电压值
for(i=0;i<500;i++)
{
delay(5000);
}
}
}
interrupt void cpu_timer0_isr(void)
{ static char key4=0x00;
CpuTimer0Regs.TCR.bit.TSS=1;//关闭定时器
key_value=GpioDataRegs.GPBDAT.all;
if((key_value&BIT3)==BIT3)
{
key4=key4^0x01;
}
if(((key_value&BIT0)==BIT0)&&(key4==0x01))//输入减1
{
if(key==0x0000)
{key=0x0000;}
else
key-- ;
}
if(((key_value&BIT1)==BIT1)&&(key4==0x01))//输入加1
{
if(key==0x4E20)
{key=0x4E20;}
else
key++;
}
//**************************************************** if((key_value&BIT2)==BIT2) //波特率设定
{
CpuTimer0Regs.TCR.bit.TSS=1; //关闭定时器
key_baud++;
if(key_baud==0x07)
{key_baud=0x00;}
switch(key_baud)
{
case 0:
char_string (baud_disp,LCD_L36);
ScibRegs.SCIHBAUD=SCI_PRD[0];
ScibRegs.SCILBAUD=SCI_PRD[1];
break; //显示波特率4800
case 1:
char_string (baud_disp1,LCD_L36);
ScibRegs.SCIHBAUD=SCI_PRD[2];
ScibRegs.SCILBAUD=SCI_PRD[3];
break; //显示波特率9600
case 2:
char_string (baud_disp2,LCD_L36);
ScibRegs.SCIHBAUD=SCI_PRD[4];
ScibRegs.SCILBAUD=SCI_PRD[5];
break;
case 3:
char_string (baud_disp3,LCD_L36);
ScibRegs.SCIHBAUD=SCI_PRD[6];
ScibRegs.SCILBAUD=SCI_PRD[7];
break; //显示波特率38400
case 4:
ScibRegs.SCIHBAUD=SCI_PRD[8];
ScibRegs.SCILBAUD=SCI_PRD[9];
char_string (baud_disp4,LCD_L36);
break; //显示波特率56000
case 5:
ScibRegs.SCIHBAUD=SCI_PRD[10];
ScibRegs.SCILBAUD=SCI_PRD[11];
char_string (baud_disp5,LCD_L36);
break; //显示波特率57600
case 6:
ScibRegs.SCIHBAUD=SCI_PRD[12];
ScibRegs.SCILBAUD=SCI_PRD[13];
char_string (baud_disp6,LCD_L36);
break; //显示波特率115200
}
}
CpuTimer0Regs.TCR.bit.TSS=0; //重新启动定时器}
interrupt void scibTxFifoIsr(void)
{
Uint16 i;
static char set_back=0x00;
set_back=set_back^0x01;
if(set_back==0x00)
{for(i=0; i< 8; i++)
{
ScibRegs.SCITXBUF=sdataB[i]; // Send data }
}
if(set_back==0x01)
{for(i=8; i< 15; i++)
{
ScibRegs.SCITXBUF=sdataB[i]; // Send data }
}
ScibRegs.SCIFFTX.bit.TXINTCLR=1; // Clear Interrupt flag PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ACK
}
interrupt void scibRxFifoIsr(void)
{
Uint16 i;
while(ScibRegs.SCIFFRX.bit.RXFIFST==0){}
for(i=0;i<8;i++)
{
rdataB[i]=ScibRegs.SCIRXBUF.all; // Read data
}
ScibRegs.SCIFFRX.bit.RXFFOVRCLR=1; // Clear Overflow flag
ScibRegs.SCIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flag
PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ack
}
void scib_fifo_init()
{
ScibRegs.SCICCR.all =0x0007;
// async mode, idle-line protocol
ScibRegs.SCICTL1.all =0x0001; // enable TX, RX, internal SCICLK,
// Disable RX ERR, SLEEP, TXWAKE ScibRegs.SCICTL2.bit.TXINTENA =1;
ScibRegs.SCICTL2.bit.RXBKINTENA =1;
ScibRegs.SCIHBAUD =SCI_PRD[0];
ScibRegs.SCILBAUD =SCI_PRD[1];
ScibRegs.SCICCR.bit.LOOPBKENA =0; // Enable loop back
ScibRegs.SCIFFTX.all=0xC028;
ScibRegs.SCIFFRX.all=0x0028;
ScibRegs.SCIFFCT.all=0x00;
ScibRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset
ScibRegs.SCIFFTX.bit.TXFIFOXRESET=1;
ScibRegs.SCIFFRX.bit.RXFIFORESET=1;
rdataB[0]=ScibRegs.SCIRXBUF.all;
}
void spi_init()
{
SpiaRegs.SPICCR.all =0x000F; // Reset on, rising edge, 16-bit char bits
SpiaRegs.SPICTL.all =0x0006; // Enable master mode, normal phase,
// enable talk, and SPI int disabled.
EALLOW;
SpiaRegs.SPICCR.bit.CLKPOLARITY=0;
SpiaRegs.SPICTL.bit.CLK_PHASE=1;
EDIS;
SpiaRegs.SPIBRR =0x007F;
SpiaRegs.SPICCR.all =0x009F; // Relinquish SPI from Reset
SpiaRegs.SPIPRI.bit.FREE = 1; // Set so breakpoints don't disturb xmission
}
void spi_xmit(Uint16 a)
{
SpiaRegs.SPITXBUF=a;
}
void spi_fifo_init()
{
// Initialize SPI FIFO registers
SpiaRegs.SPIFFTX.all=0xE040;
SpiaRegs.SPIFFRX.all=0x204f;
SpiaRegs.SPIFFCT.all=0x0;
}
//=================================================================== ========
// No more.
//=================================================================== ========。

相关文档
最新文档