波形采集储存与回放系统毕业论文
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
波形采集储存与回放系统毕业论文
目录
第一章方案设计与论证 (1)
1.1要求 (1)
1.1.1基本要求 (1)
1.1.2发挥部分 (2)
1.3方案论证 (2)
1.3.3方案一 (2)
1.3.4方案二 (2)
1.3.5方案三 (3)
第二章理论分析与计算 (4)
2.1主芯片分析 (4)
2.2 ADC12模块 (5)
2.3扫描速度与采样频率的关系 (5)
2.4信号采样技术的基本原理 (5)
2.4.1实时采样 (5)
2.4.2顺序采样 (6)
2.4.3随机采样 (6)
第三章系统设计与框图 (7)
3.1输入输出电路 (8)
3.1.1 A路输入 (8)
3.1.2 A路输出 (8)
3.1.3 B路输入 (9)
3.1.4 B路输出 (9)
3.2电源电路 (10)
3.3 MSP430F1479最小系统 (10)
3.4显示与控制模块 (11)
3.5掉电保护电路控制 (12)
第四章软件设计 (13)
第五章系统测试 (14)
5.1测试仪器 (14)
5.2输入阻抗 (14)
5.3测试方案 (14)
5.3.1基本要求测试 (14)
5.3.2发挥部分测试 (15)
第六章实验结果分析与讨论 (16)
6.1实验结果 (16)
第七章结论及意义 (18)
参考文献 (19)
致谢 (20)
附录 (21)
第一章方案设计与论证
设计并制作一个波形采集、存储与回放系统,示意图如图 1 所示。
该系统能同时采集两
路周期信号波形,要求系统断电恢复后,能连续回放已采集的信号,显示在示波器上
1.1要求
1.1.1基本要求
(1)能完成对 A 通道单极性信号(高电平约 4V、低电平接近 0V)、频率约 1kHz 信号
的采集、存储与连续回放。
要求系统输入阻抗不小于10 k?,输出阻抗不大于1k?。
(2)采集、回放时能测量并显示信号的高电平、低电平和信号的周期。
原信号与回放
信号电平之差的绝对值≤50 mV,周期之差的绝对值≤5%。
(3)系统功耗≤50mW,尽量降低系统功耗,系统不允许使用电池。
1.1.2发挥部分
(1)增加 B 通道对双极性、电压峰峰值为 100mV、频率为 10Hz~10kHz 信号的采集。
可同时采集、存储与连续回放A、B两路信号,并分别测量和显示A、B两路信号的周期。
B通道原信号与回放信号幅度峰峰值之差的绝对值≤10 mV,周期之差的
绝对值≤5%。
(2)A、B两路信号的周期不相同时,以两信号最小公倍周期连续回放信号。
(3)可以存储两次采集的信号,回放时用按键或开关选择显示指定的信号波形。
1.2题目要求及相关指标分析
题目的要求是将待测信号进行数字存储,并通过普通示波器将被测信号显示出来。
由于等测信号为模拟信号,存储过程为数字方式,故应该将模拟信号进行量化处理,然后存储到存储器中,当需要显示的时候,从存储器读出数据并恢复为模拟信号,并送往普通示波器Y输入端,在X输入端加入相应的扫描信号,采有X-Y方式观察信号的波形。
因此,设计的重点是模拟信号的处理与采样、数字信号的存储、普通示波器的显示控制、系统的控制4个方面。
1.3方案论证
1.3.3方案一
以单片机89s51为系统核心,以外部AD、存储、DA等器件实现信号的采集、存储与回放功能,整个系统简单灵活,便于实现,但无法完成对高速信号的处理,而且功率消耗过大。
1.3.4方案二
以带有IP核的FPGA/CPLD完成对信号的采集、存储、显示以及AD\DA转化等功能,由IP核实现人机交互及信号处理等功能。
该方案结构紧凑、可以实现复杂测量与控制只是操作过于繁琐、系统功耗也很大。
1.3.5方案三
核心采用MSP430F149单片机,利用单片机部的12位高精度AD转换器实现对信号的采集,采用外挂AT24C512存储信号数据,并由D/A完成DA功能转换,配合相应的输入输出电路完成相应的电压转换,1602液晶显示输出相应的各项信息,整个电路需要的相应外围电路少,功耗低简洁易行
经过以上各个方案的分析比较,次设计采用方案三
第二章理论分析与计算
题目的要求是将待测信号进行数字存储,并通过普通示波器将信号显示出来,由于被测信号为模拟信号,存储过程为数字方式,故应将模拟信号进行量化处理,然后存储到存储器中,当需要显示的时候,从存储器读出数据并回复成模拟信号,并送到普通示波器的Y输入端,在X输入端加上相应的扫描信号,采用x-y方式观察信号的波形。
因此,设计的重点是模拟信号的处理与采样,数字信号的存储、普通示波器的显示控制,系统的控制四方面
2.1主芯片分析
MSP430是TEAXS INSTRUMENTS(TI)生产的16位单片机的统称,该系列是一种RISC结构的16位单片机,其突出特点是功耗极低(在3V、1Mhz的工作方式下,电流消耗是250uA休眠方式只有0.1uA的电流);其次是他的部资源相当丰富全系列中总共包含以下模块:12-bit、8通道A\D转换,带3-10个单独的捕获、比较功能的定时器Timer-A和Timer-B,1-2路USART通信口,多至160段LED驱动,硬件乘法器,模拟信号比较器,FLL频率锁相环,2-3个时钟系统等等。
以上片资源,可以极大限度的简化本题的设计。
2.2ADC12模块
MSP430单片机的ADC12模块是一个12位的A/D转换模块,具有高速度,通用性等特点。
它具有5大功能模块,都可以独立配置,即具有采样、保持的ADC 功能核;可控制的转换存储;可控制的参考电平发生器;可控制和选择的时钟;可控制的采样及转换时序电路。
ADC12的主要特点是最大的采样速度达到200Ksps:转换为12位精度,1位差分非线性,1位积分非线性:8个可配置的外部信号采集通道。
2.3扫描速度与采样频率的关系
假设扫描速度为t s/div,每格点数为n采样频率为fs,则:fs=n/t,当t=20的时候,针对不同的扫描速度,可得到不同的采样频率。
在一定的情况下扫描速度的改变是通过改变采样频率来实现的。
对应10KHz的正弦波采样频率为200KHz时每周期可采集20个点,由采集值可以很好的恢复采集前的信号,按照系统结构,只需要2通道的A/D采样输入信号的最高频率为10KHz。
以MSP430D149为核心,外挂一个防掉电保护的EEPROM就可以完成系统设置的要求,系统功耗也能控制在要求之中。
2.4信号采样技术的基本原理
采样分实时采样和非实时采样两种。
从一个信号波形中取得所需样点称为实时采样。
从被测信号许多相邻波形上取得样点,以表示一个信号波形称为非实时采样,或者称为等效采样。
其实,对于非实时采样,还可以每隔10个、100个甚至更多个波形上取一个样点。
这样更有利于观测高速信号,当然这种高速信号必须是重复的。
2.4.1实时采样
实时采样是数字信号采集技术的最直接应用。
在这种方法下,示波器根据一
次触发事件连续的捕获被测量波形的n个采样数据,而后屏幕上显示波形的每个
点都是在一次采样周期中获取的,它可以完成单次非重复信号的捕捉。
实时采样
有三个重点特点:
(1)示波器先将一段完整的波形数据存入存储器,然后再进行显示和分析。
(2)在触发事件前,示波器开始对信号进行连续采样。
(3)自动完成多信号的同时采样。
能够观测触发前信号的能力称为负触发延迟,
它在故障分析中特别有用。
2.4.2顺序采样
顺序采样是对每一个信号周期仅采样一个点,用步进延迟的方法,对每个周期信号波形的不同点进行采样,从而获取整个波形的采样数据
2.4.3随机采样
与顺序采样相对应,随机采样的采样脉冲是由一个独立电路产生,它和被
测信号是不相关的。
因此,随机采样有三个特点:
(4)样点在信号波形上的排列是随机的。
(5)可以观测到触发前的信号。
随机采样过程中样点在信号波形上的位置是无序的,即时随机的,但是在对这些样点进行屏幕显示时必须反映原波形的变化规律。
否则,测量将没有实用价值。
因此,在采样过程中应该同时记录各个采样点在信号波形上的相对位置。
第三章系统设计与框图
系统整体设计框图如图所示。
模拟信号通过信号调理模块(阻抗变换、程控放大、触发电路),将模拟信号的幅值大小调理到高速AD(AD9225)的输入围0—4V。
然后通过AD9225对信号进性采样。
我们采用外部有源晶振作为高速AD的采样时钟来控制恒定的采样率4MHz(晶振的固有振荡频率),在FPGA部增加波形存储控制模块,当满足触发条件时FPGA以下抽样的方式对AD转换得到的数据进行存储,抽样频率由可水平分辩率来控制(若为AUTO功能,则与信号的频率有关)。
将抽样的数据分别存储到双口RAM中,在送入行列扫描电路(2片DAC0800)前经过了波形显示控制模块,它的作用是对RAM的数据及读入起始地址的进行处理。
从而实现波形在模拟示波器上的左右平移。
同时在FPGA部实现了512点的FFT计算,成功得分析了输入信号的频谱。
3.1输入输出电路
3.1.1A路输入
A路输入:系统要求A路输入信号为单极性(0-4V),而单片机设置A/D参考电平为2.5V,因此需要将输入信号变换为0-2.5V之,采集后在单片机部再做相应的运算处理,计算出相应的真正输入值,从而显示A路的最大值和最小值。
如图输入信号经过UIA同向跟随后,经R7做相应衰减送入单片机A/D进行采样,适当调节R7就可以进入A/D的值限幅在0-2.5V之
3.1.2A路输出
为保证回复A路信号(0-4V),故运放供电电压必须用5V供电,而D/A输出最高只能达到 2.5V,故该电路需要具有一定的放大功能,且要有一定的过滤作用。
这样才可以将D/A所产生的高频干扰滤除
3.1.3B路输入
系统要求D路输入信号为双极性(100mV VPP),因此需要将100mV放大至单片机A/D所所能判别的围,这样可以提高系统对B路信号的分辨率,同时需要将输入双极性信号转换为单极性信号,这样才能便于单片机识辨,图中VRF为1/2单片机A/D参考电压即1.25V,这样做的目的是给熟人信号加上一个1.25V 的片子电压之后再进行放大,如图输入信号经过U1B同向放大至0-2.5V后送给单片机A/D采样,适当调节R14即可改变放大器的放大倍数。
3.1.4B路输出
为保证B路信号(100mV VPP),输出采用电容交流隔直,而D/A输出为输入信号经放大后采集到的信号,其VPP可达到2.5V,故用R38进行相应衰减,适当调整E38可以输出幅值与输入一致,U28为1:1同向放大,可将D/A所能产
生的高频干扰滤波,C11可将单极性信号转为双极性信号,与输入保持一致。
3.2电源电路
TPS78001将5V转为3.3V供给单片机工作,5V用于运放和液晶以及24C512工作。
3.3MSP430F1479最小系统
单片机最小系统,或称为最小应用系统,是指用最少的元件组成的单片机可以工作的系统。
对于MSP430系列单片机来说,最小系统一般应该包括:单片机、晶振电路、复位电路。
本文介绍了MSP430F149单片机的特点,设计了MSP430最小系统中电源模块、晶振电路模块、复位电路模块、串口通讯模块和数据存储模
块的电路原理图,
3.4显示与控制模块
题目的要求采集和回放时规定采用十进制数字显示,周期以“ms”为单位,幅度以“mv”为单位。
没有要求做人机界面,所以现有常用的LCD1602即可以满足要求,控制部分也只要求几个简单的功能选择题,所以显示和控制模块直接到MCU的最小系统即可
3.5掉电保护电路控制
采用12C串行EEPROM非易失性存储器AT24C512实现掉电存储数据系统掉电恢复后,能连续回放以采集的信号。
AT24C512是ATMEL公司生
产的64KB串行电可擦的可编程存储器,部有512页,每一页为128字节,任一单元的地址为16位,地址围为0000-0FFFH.它采用8引脚封装,具
有结构紧凑,存储容量大等特点,可以在2线总线上并接4片芯片,特别适用于具有大容量数据存储要求的数据采集系统,因此在测控系统中被大
量采用。
第四章软件设计
依据题目要求,在设计中,系统启动后先检测是否有信号输入,若存在输入信号,则判断输入信号的通道,并为信号做标记(即A/B信号)且启动AD转换与计数定时。
转换结束,并将转换数据与信号的输入通道标记进行整合并暂存等待处理。
转换结束,由按键控制存储数据与回显,若存储侧调用存储单元对采集数据进行保存,若回显,则从存储单元调用采集数据并输出到DA转换单元处理等待显示。
整个操作过程由液晶显示程序提供周期、幅度等信号信息。
第五章系统测试
5.1测试仪器
SS2323双路可跟踪直流恒压电源‘
TFG6060 DDS信号源
岩崎 7802 模拟示波器
5.2输入阻抗
经测试本系统输入阻抗为5.32KΩ。
满足题目中输入阻抗不大于10KΩ的要求。
输出阻抗为134Ω满足不大于1KΩ的要求。
5.3测试方案
5.3.1基本要求测试
5.3.1.1功能测试
5.3.1.2电平测试
测试条件:输入电压峰-峰值4V,最大电压4V的方波
输入频率:1 KHz
5.3.2发挥部分测试
5.3.2.3功能测试
功能的测试过程为,依次输入高电平4V,低电平20mV的正弦波、三角波、方波,用示波器观察A通道输出,系统可以正确检测波形并输出。
5.3.2.4B通道指标测试
第六章实验结果分析与讨论
经测试,本设计能完成对A通道单极性信号、频率约1KHz信号的采集、存储与连续回放。
可以完成B通道双极性信号采集和回放。
采集、回放时能测量并显示信号的高电平、低电平和信号的周期。
原信号与回放信号电平之差的绝对值小于50mV,周期之差的绝对整理值小于50mV。
由于本系统采用的是STM32控制器,并且使用了部集成的高速AD、DA,加上显示及模拟信号调理电路,因此系统功耗略高。
可同时采集、存储与连续回放A、B两路信号,并分别测量和现实A、B 两路信号的周期。
6.1实验结果
1. 能完成对 A 通道单极性信号(高电平约 4V、低电平接近 0V)、频率约 1kHz 信号
的采集、存储与连续回放。
要求系统输入阻抗不小于10 k?,输出阻抗不大于1k?。
(2)采集、回放时能测量并显示信号的高电平、低电平和信号的周期。
原信号与回放
信号电平之差的绝对值≤50 mV,周期之差的绝对值≤5%。
(3)系统功耗≤50mW,尽量降低系统功耗,
2.本系统处理的正弦波信号频率围限定在 10Hz~10kHz,三角波信号频率围限定在
10Hz ~2kHz,方波信号频率围限定在10Hz ~1kHz。
3.采集、回放时显示的周期和幅度应是信号的实际测量值,规定采用十进制数字显示,
周期以“ms”为单位,幅度以“mV”为单位。
4. 增加 B 通道对双极性、电压峰峰值为 100mV、频率为 10Hz~10kHz 信号的采集。
可同时采集、存储与连续回放A、B两路信号,并分别测量和显示A、B两路信号的周期。
B通道原信号与回放信号幅度峰峰值之差的绝对值≤10 mV,周期之差的
绝对值≤5%。
(2)A、B两路信号的周期不相同时,以两信号最小公倍周期连续回放信号。
(3)可以存储两次采集的信号,回放时用按键或开关选择显示指定的信号波形。
第七章结论及意义
经过努力,基于终于设计完成了,过去一段时间的辛酸以及遇到难题时
的郁闷一挥而散了,现在回味起来真有点小小的成就感。
经过这次课程设计得到的收获还是特别多的,它不仅让我了解了做一个单片机系统的各项工作流程,让我在这个过程中学到了很多过去不知道的东西以及课本上所不能讲述给你的东西,同时也让我深刻地认识到我对知识的理解程度以及掌握程度还是极其有限的。
生命是有限的,我们就应该抓住每一个机会来锻炼自己、提高自己,只有在工作中你才能发现你自身的不足,才能让你端正学习、工作、生活态度,并且只有在工作中你才能真正细致地去学习一个东西、去研究一个东西。
可见生产实践是何其重要啊,它是
你提升你自己的有效平台。
通过本次课程设计让我认识到了以下几点:(1)自己的科研能力有待提高。
做一个单片机系统,大部分电路原理图都是在网上借鉴别人的,有很少是自己的,可见科研能力有待提高,要能够根据电路要求自行设计电路。
(2)自己的态度不太端正。
做一个项目就要坚持不懈、持之以恒,不做完美决不罢休,我在这点做的不是太好,也有最近课程比较多的原因,但最主要的还是自身定力不够的原因造成的,这是需要改正的。
(3)知识欠缺,创新能力不够。
这就要求我在课下尽可能多地进行知识积累。
(4)整体意识不足。
在焊硬件电路以及做软件设计时,这个问题表现得比较明显,所以在下面就要接受这次课程设计的教训,努力培养自身的整体意识。
参考文献
[1]董先明·信息与电脑(理论版)·科学,2010,(05), 192
[2]魏宁·中国信息技术教育·北京大学,2009,(15), 91-93
[3]童文军·汪仁煌 .《单片机与嵌入式系统应用》·维普资讯网,2003 第6期 , 1-18
[4]ISMAIL A B M, YOSHINOBU T, IWASAKI H. Investigation on light addressable potentiometric sensor as a possible cell semiconductor hybrid [J]. Biosensors and Bioelectronics, 2003, 18 (12): 1509-1514. [5]建华,艳琴,翟骁曙·MSP430系列16位超低功耗单片机原理与应用[M]·北京:清华大学,2004: 231-242.
[6] Texas Instruments. MSP430FG4619 datasheet [EB/OL]. (2007-10-15)[2009-06-30].http:∥.ti.//lit/gpn/msp430fg4619.
致谢
本论文的工作是在我的导师蒋志勇教授的悉心指导下完成的,蒋志勇教授严谨的治学态度和科学的工作方法给了我极大的帮助和影响。
在此衷心感谢三年来蒋志勇老师对我的关心和指导。
蒋志勇教授悉心指导我们完成了毕业论文工作,在学习上和生活上都给予了我很大的关心和帮助,在此向蒋志勇老师表示衷心的谢意。
蒋志勇教授对于我的论文提出了许多的宝贵意见,在此表示衷心的感谢。
在撰写论文期间,********等同学对我论文中的msp430研究工作给予了热情帮助,在此向他们表达我的感激之情。
另外也感谢家人,他们的理解和支持使我能够在学校专心完成我的学业。
附录
/*************************************************** 程序功能:静态显示各种字符
---------------------------------------------------- 测试说明:观察液晶显示
****************************************************/ #include <msp430.h>
void delay_1ms(void) //1ms延时函数
{
unsigned int i;
for (i=0;i<1140;i++);
}
void delay_nms(unsigned int n) //N ms延时函数{
unsigned int i=0;
for (i=0;i<n;i++)
delay_1ms();
}
#include "iic.h"
#include "init.h"
#include "lcd1602.h"
#include "show.h"
#include "timer.h"
#include "key.h"
/***********************主函数***********************\ ACLK Auxillary Clock 辅助时钟
MCLK Main System Clock 主系统时钟
SMCLK Sub System Clock 子系统时钟
\****************************************************/ void main( void )
{
WDTCTL = WDTPW + WDTHOLD; //关闭看门狗
//------选择系统主时钟为16MHz---------------------
XT2_init();
//------初始化ADC---------------------------------
//VREF管脚为部 2.5V基准
// 此处基准VREF使能为2.5V必须先于ADC初始化不然,DAC将无法使用VREF
ADC12CTL0 = REF2_5V + REFON;
//------初始化IIC----------------------------------
I2CInit();
//------初始化ADC----------------------------------
//ADC_init();
//------初始化DAC----------------------------------
//DAC_init();
//------初始化TimerA-------------------------------
//TimerA_init(99); //计数99个脉冲,调用中断用去一个,共100个脉冲
//--------------------------------------------------
P1OUT &= ~0x01;
P1DIR |= 0x0c; // P1.0 output-LED P1REN |=0xf0; //部上拉
LCD_Initial();//LCD初始化
Goto(2,0);
Print("welcome...");
//Goto(3,1);
//Print(shuzi);
//show();
delay_1ms();
_EINT(); //开全局中断
//ADC12CTL0 |= ADC12SC; //启动ADC转换
while(1)
{
asm("nop");
asm("nop");
asm("nop");
get_key();
}
}
#ifndef _LCD1602
#define _LCD1602
//-----------------------------------------------------------
//DataIO -> P40------P47
//数据口
#define DatO P4OUT //写
#define DatI P4IN //读
#define DatD P4DIR //方向
//-----------------------------------------------------------
//EN--P32 RW--P31 RS--P30
//命令口
#define ComO P3OUT
#define ComD P3DIR
//-----------------------------------------------------------
#define SET_E ComO|=(1<<2) //E=1
#define CLE_E ComO&=~(1<<2) //E=0
#define SET_RW ComO|=(1<<1) //RW=1
#define CLE_RW ComO&=~(1<<1) //RW=0
#define SET_RS ComO|=(1<<0) //RS=1
#define CLE_RS ComO&=~(1<<0) //RS=0
//-----------------------------------------------------------------------------------
void Wait(void); // 等待函数
//-----------------------------------------------------------------------------------
void Write(unsigned char style, unsigned char input); // 向LCD 写入命令或数据
#define COMMAND 0 // style
#define DATA 1 // style
#define CLEAR 0x01 // 清屏
#define HOMING 0x02 // 光标返回原点
#define PutChar(x) Write(DATA, x)kljo
#define ClearScreen(); Write(COMMAND,CLEAR); _delay_ms(100);
//-----------------------------------------------------------------------------------
void Goto(unsigned char x, unsigned char y); // 跳到LCD 的某个坐标点
//-----------------------------------------------------------------------------------
/************* DisplayMode ***************/
void SetDisplay(unsigned char DisplayMode); // 设置显示模式
#define SHOW 0x04
#define HIDE 0x00 // default
#define CURSOR 0x02
#define NO_CURSOR 0x00 // default
#define FLASH 0x01 // 光标闪动
#define NO_FLASH 0x00 // default
/*********** End DisplayMode *************/
//-----------------------------------------------------------------------------------
/************** InputMode ****************/
void SetInput(unsigned char InputMode); // 设置输入模式
#define AC_UP 0x02
#define AC_DOWN 0x00 // default
#define MOVE 0x01 // 画面可平移
#define NO_MOVE 0x00 //default
/************ End InputMode **************/
//-----------------------------------------------------------------------------------
void Move(unsigned char object, unsigned char direction); // 移动光标或屏幕
#define CURSOR 0x02
#define SCREEN 0x08
#define LEFT 0x00
#define RIGHT 0x04
//-----------------------------------------------------------------------------------
void Print(unsigned char *str); // 显示字符串str
//-----------------------------------------------------------------------------------
void LCD_Initial(void); // 液晶初始化函数
//-----------------------------------------------------------------------------------
void LoadChar(unsigned char user[8], unsigned char place); //加载自定义点阵信息
//-----------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------
// 等待函数
void Wait(void)
{
DatD=0x00; //设置为输入
CLE_RS;SET_RW;asm("nop");
SET_E;asm("nop");
while(DatI&0x80); //检测忙
DatD=0xFF; //设置为输出
}
//------------------------------------------------------------ // 向LCD写入命令或数据
void Write(unsigned char style,unsigned char data)
{
if(style) SET_RS;
else CLE_RS;
CLE_RW; asm("nop");
SET_E; asm("nop");
DatO=data;
CLE_E; asm("nop");
Wait();
}
//------------------------------------------------------------ // 移动光标
void Goto(unsigned char x, unsigned char y)
{
if(y==0)
Write(COMMAND,0x80|x);
if(y==1)
Write(COMMAND,0x80|(x-0x40));
}
//------------------------------------------------------------ // 设置显示模式
void SetDisplay(unsigned char DisplayMode)
{
Write(COMMAND, 0x08|DisplayMode);
}
//------------------------------------------------------------ // 设置输入模式
void SetInput(unsigned char InputMode)
{
Write(COMMAND, 0x04|InputMode);
}
//------------------------------------------------------------ // 移动光标或屏幕
void Move(unsigned char object, unsigned char direction)
{
if(object==CURSOR)
Write(COMMAND,0x10|direction);
if(object==SCREEN)
Write(COMMAND,0x18|direction);
}
//------------------------------------------------------------ // 将待显示的容写入LCD
void Print(unsigned char *str)
{
while(*str!='\0')
{
Write(DATA,*str);
str++;
}
}
//------------------------------------------------------------ // 向LCD初始化
void LCD_Initial(void)
{
DatD=0xFF;
ComD=0xFF;
CLE_E;;
Write(COMMAND,0x38);; //8位数据端口,2行显示,5*7点阵
Write(COMMAND,0x38);;
SetDisplay(SHOW|NO_CURSOR); //开启显示, 无光标
Write(COMMAND,CLEAR); //清屏
Goto(0,0); //回起点
SetInput(AC_UP|NO_MOVE); //AC递增, 画面不动
}
//------------------------------------------------------------ // 加载自定义点阵信息
void LoadChar(unsigned char user[8], unsigned char place)
{
unsigned char i;
Write(COMMAND,0x40|(place*8));
for(i=0; i<8; i++)
Write(DATA,user[i]);
}
#endif
#ifndef _key_H
#define _key_H
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
void init_adc_data(void)
{
data_count = 0;
old_data_count=0;
up_count=0;
T_count=0;
begin=0;
}
//-----------------------------------------------------------
// 键盘口定义 P1.3--91.7
#define keyOUT P1OUT //写
#define keyIN P1IN //读
#define keyDIR P1DIR //方向
//--------------------------------------------------------------------------
void show_rom()//unsigned int temp1,unsigned int temp2
{
unsigned char a[5]={0,'.','.','.','.'};
unsigned int voltage; //电压单位为(mV)
unsigned long value=0;
Write(COMMAND,CLEAR);
//ADC1 显示----------------------------------------------------- //计算temp1实际电压
value=max_data1;
voltage=((value*v_ref1)>>12);
a[0]=voltage/1000+0x30; a[1]=(voltage%1000)/100+0x30;
a[2]=(voltage%100)/10+0x30;
a[3]=(voltage%10)+0x30;
a[4]='\0';
Goto(0,0); Print(a);
//计算temp2实际电压
value=min_data1;
voltage=((value*v_ref1)>>12);
a[0]=voltage/1000+0x30;
a[1]=(voltage%1000)/100+0x30;
a[2]=(voltage%100)/10+0x30;
a[3]=(voltage%10)+0x30;
a[4]='\0';
Goto(6,0); Print(a);
//计算周期
if(ADC1_data[600]) //10mS以
{
voltage=ADC1_data[601];
a[0]=voltage/100+0x30;
a[1]='.';
a[2]=(voltage%100)/10+0x30;
a[3]=(voltage%10)+0x30;
}
else
{
voltage=ADC1_data[601];
a[0]=voltage/100+0x30;
a[1]=(voltage%100)/10+0x30; a[2]='.';
a[3]=(voltage%10)+0x30;
}
a[4]='\0';
Goto(12,0); Print(a);
//ADC0 显示----------------------------------------------------- //计算temp1实际电压
//计算temp1实际电压
value=max_data0-min_data0;// VPP
voltage=((value*v_ref2)>>13); // VPP/2
a[0]=voltage/1000;
if(a[0] > 10 ) a[0]=' ';
else a[0]+=0x30;
a[1]=(voltage%1000)/100+0x30;
a[2]=(voltage%100)/10+0x30;
a[3]=(voltage%10)+0x30;
a[4]='\0';
Goto(4,1); Print(a);
//计算周期
if(ADC0_data[600]) //10mS以
{
voltage= ADC0_data[601];
a[0]=voltage/100+0x30;
a[1]='.';
a[2]=(voltage%100)/10+0x30;
a[3]=(voltage%10)+0x30;
}
else
{
voltage= ADC0_data[601];
a[0]=voltage/100+0x30;
a[1]=(voltage%100)/10+0x30;
a[2]='.';
a[3]=(voltage%10)+0x30;
}
a[4]='\0';
Goto(12,1); Print(a);
}
//--------------------------------------------------------------------------
unsigned char key2_flag=0;
unsigned char key3_flag=0;
unsigned char key4_flag=0;
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
void get_key(void)
{
// unsigned char key_temp=0;
keyDIR = 0xf0;
keyOUT = 0XF0;
keyDIR = 0x00;
//读取键值
switch(keyIN & 0xf0)
{
//key1 ADC
// case 0xf0: key_temp=1; break;
//key2 存储
case 0xe0: //key_temp=2;
if(key2_flag)
{
adc_flag=1; //ADC 转换结束标志
Write(COMMAND,CLEAR);
SetDisplay(SHOW|NO_CURSOR);
Goto(2,0);
Print("saving data");
Goto(0,1);
Print("please wait");
key2_flag=0;
//等待ADC执行完毕之后写入IIC
TimerA_init_clr();
DAC_init_clr();
init_adc_data();
ADC_init();//初始化ADC
ADC12CTL0 |= ADC12SC; //启动ADC转换
while(adc_flag) asm("nop");//等待ADC结束
Write(COMMAND,CLEAR);
Goto(0,1);
Print("save ok");
deal_data();
//1602显示
show_ADC();
//show_max_data();
//------------------------------------------------------写入IIC if(key4_flag)
{
I2CWRBlock(0,602,ADC0_data); //写第一块
I2CWRBlock(1,602,ADC1_data); //写第二块
}
else
{
I2CWRBlock(2,602,ADC0_data); //写第三块
I2CWRBlock(3,602,ADC1_data); //写第四块
}
//if(key4_flag) //存第一通道
//else //存第二通道
DAC_init();//开启DAC
TimerA_init(96); //97个时钟中断
}
else
{
Write(COMMAND,CLEAR);
Goto(0,0);
Print("save channel");
Goto(0,1);
Print("choose: 1 2");
key2_flag=1; key4_flag=1;
Goto(8,1);
SetDisplay(SHOW|CURSOR);
delay_nms(5);
}
while(!(keyIN & 0x10)) asm("nop");//等待按键释放
break;
//key3 回放
case 0xd0: //key_temp=3;
if(key3_flag)
{
Write(COMMAND,CLEAR);
SetDisplay(SHOW|NO_CURSOR);
Goto(1,0);
Print("reading data");
Goto(0,1);
Print("please wait...");
key3_flag=0;
//--------------------------------------------------------读IIC if(key4_flag)
{
I2CRDBlock(0,602,ADC0_data); //写第一块
I2CRDBlock(1,602,ADC1_data); //写第一块
}
else
{
I2CRDBlock(2,602,ADC0_data); //写第一块
I2CRDBlock(3,602,ADC1_data); //写第一块
}
Write(COMMAND,CLEAR); //清屏
Goto(0,0);
Print("read ok");
Goto(1,1);
Print("output the data");
delay_nms(500);
int_adc0 = ADC0_data[0];
int_adc1 = ADC1_data[0];
deal_data();
//1602显示
show_rom();
//启动DAC 输出波形
//deal_data(); //显示信号参数
DAC_init();//开启DAC
TimerA_init(96); //97个时钟中断
}
else
{
Write(COMMAND,CLEAR);
Goto(3,0);
Print("reply channel");
Goto(0,1);
Print("choose: 1 2");
key3_flag=1; key4_flag=1;
Goto(8,1);
SetDisplay(SHOW|CURSOR);
//delay_nms(500);
}
while(!(keyIN & 0x20)) asm("nop");//等待按键释放 break;
//key4 上下选择
case 0xb0: //key_temp=4;
if(key4_flag)
{
Goto(11,1);
key4_flag=0;
// delay_nms(500);
}
else
{
Goto(8,1);
key4_flag=1;
// delay_nms(500);
}
while(!(keyIN & 0x40)) asm("nop");//等待按键释放 break;
//key5 取消
case 0x70:// key_temp=5;
ADC_init_clr();
TimerA_init_clr();
DAC_init_clr();
key2_flag=0;
key3_flag=0;
key4_flag=0;
init_adc_data();
Write(COMMAND,CLEAR);
SetDisplay(SHOW|NO_CURSOR);
Goto(2,0);
Print("welcome...");
while(!(keyIN & 0x80)) asm("nop");//等待按键释放 break;
//其他
default: break;
}
//return key_temp;
}
#endif
#include <msp430x26x.h>
#include "cry1602.h"
typedef unsigned char uchar;
typedef unsigned int uint;
/**************宏定义***************/
#define DataDir P4DIR
#define DataPort P4OUT
#define Busy 0x80
#define CtrlDir P3DIR
#define CLR_RS P3OUT&=~BIT0; //RS = P3.0
#define SET_RS P3OUT|=BIT0;
#define CLR_RW P3OUT&=~BIT1; //RW = P3.1
#define SET_RW P3OUT|=BIT1;
#define CLR_EN P3OUT&=~BIT2; //EN = P3.2
#define SET_EN P3OUT|=BIT2;
/***********************************************
函数名称:DispStr
功能:让液晶从某个位置起连续显示一个字符串
参数:x--位置的列坐标
y--位置的行坐标
ptr--指向字符串存放位置的指针
返回值:无
***********************************************/
void DispStr(uchar x,uchar y,uchar *ptr)
{
uchar *temp;
uchar i,n = 0;
temp = ptr;
while(*ptr++ != '\0') n++; //计算字符串有效字符的个数 for (i=0;i<n;i++)
{
Disp1Char(x++,y,temp[i]);
if (x == 0x0f)
{
x = 0;
y ^= 1;
}
}
}
/*******************************************
函数名称:DispNchar
功能:让液晶从某个位置起连续显示N个字符
参数:x--位置的列坐标
y--位置的行坐标
n--字符个数
ptr--指向字符存放位置的指针
返回值:无
********************************************/
void DispNChar(uchar x,uchar y, uchar n,uchar *ptr) {
uchar i;
for (i=0;i<n;i++)
{
Disp1Char(x++,y,ptr[i]);
if (x == 0x0f)
{
x = 0;
y ^= 1;
}
}
}
/*******************************************
函数名称:LocateXY
功能:向液晶输入显示字符位置的坐标信息
参数:x--位置的列坐标
y--位置的行坐标
返回值:无
********************************************/
void LocateXY(uchar x,uchar y)
{
uchar temp;
temp = x&0x0f;
y &= 0x01;
if(y) temp |= 0x40; //如果在第2行
temp |= 0x80;
LcdWriteCommand(temp,1);
}
/*******************************************
函数名称:Disp1Char
功能:在某个位置显示一个字符
参数:x--位置的列坐标
y--位置的行坐标
data--显示的字符数据
返回值:无
********************************************/
void Disp1Char(uchar x,uchar y,uchar data)
{
LocateXY( x, y );
LcdWriteData( data );
}
/*******************************************
函数名称:LcdReset
功能:对1602液晶模块进行复位操作
参数:无
返回值:无
********************************************/
void LcdReset(void)
{
CtrlDir |= 0x07; //控制线端口设为输出状态 DataDir = 0xFF; //数据端口设为输出状态 LcdWriteCommand(0x38, 0); //规定的复位操作
//Delay5ms();
LcdWriteCommand(0x38, 0);
//Delay5ms();
LcdWriteCommand(0x38, 0);
//Delay5ms();
LcdWriteCommand(0x38, 1); //显示模式设置
LcdWriteCommand(0x08, 1); //显示关闭
LcdWriteCommand(0x01, 1); //显示清屏
LcdWriteCommand(0x06, 1); //写字符时整体不移动
LcdWriteCommand(0x0c, 1); //显示开,不开游标,不闪烁}
/*******************************************
函数名称:LcdWriteCommand
功能:向液晶模块写入命令
参数:cmd--命令,
chk--是否判忙的标志,1:判忙,0:不判
返回值:无
********************************************/
void LcdWriteCommand(uchar cmd,uchar chk)
{
if (chk) WaitForEnable(); // 检测忙信号?
CLR_RS;
CLR_RW;
//_NOP();
DataPort = cmd; //将命令字写入数据端口
//_NOP();
SET_EN; //产生使能脉冲信号
//_NOP();
//_NOP();
CLR_EN;
}
/*******************************************
函数名称:LcdWriteData
功能:向液晶显示的当前地址写入显示数据
参数:data--显示字符数据
返回值:无
********************************************/
void LcdWriteData( uchar data )
{
WaitForEnable(); //等待液晶不忙
SET_RS;
CLR_RW;
//_NOP();
DataPort = data; //将显示数据写入数据端口 //_NOP();
SET_EN; //产生使能脉冲信号
//_NOP();
//_NOP();
CLR_EN;
}
/*******************************************
函数名称:WaitForEnable
功能:等待1602液晶完成部操作
参数:无
返回值:无
********************************************/
void WaitForEnable(void)
{
P4DIR &= 0x00; //将P4口切换为输入状态
CLR_RS;
SET_RW;
//_NOP();
SET_EN;
//_NOP();
//_NOP();
while((P4IN & Busy)!=0); //检测忙标志
CLR_EN;
P4DIR |= 0xFF; //将P4口切换为输出状态
}
/*******************************************
函数名称:Delay5ms
功能:延时约5ms
参数:无
返回值:无
********************************************/ void Delay5ms(void)
{
uint i=40000;
while (i != 0)
{
i--;
}
}
typedef unsigned char uchar;
typedef unsigned int uint;
//控制位的宏定义
#define Ctrl_Out P3DIR |= BIT3 + BIT6 + BIT7; #define Ctrl_0 P3OUT &= ~(BIT3 + BIT6 + BIT7) #define SRCLK_1 P3OUT |= BIT7
#define SRCLK_0 P3OUT &= ~BIT7
#define SER_1 P3OUT |= BIT6
#define SER_0 P3OUT &= ~BIT6
#define RCLK_1 P3OUT |= BIT3
#define RCLK_0 P3OUT &= ~BIT3
//板上资源配置函数
void BoardConfig(uchar cmd)
{
uchar i;
Ctrl_Out;
Ctrl_0;
for(i = 0; i < 8; i++)
{
SRCLK_0;
if(cmd & 0x80) SER_1;
else SER_0;
SRCLK_1;
cmd <<= 1;
}
RCLK_1;
_NOP();
RCLK_0;
}
***************************************
*项目:××××
*模块:I2C.c //I2C 程序模块
*说明:I2C 程序,SCL,及SDA 在主程序中定义为MCUIO
该模块共有:
1,I2CDelay();//延时程序,给I2C 总线提供必要的延时
2,I2CStart();//开始程序
3,I2CStop();//结束程序
4,I2CSendByte();//送一个字节
5,I2CReceiveByte();//接收一个字节
6,I2CReceiveACK();//接受应答信号
7,I2CAcknowledge();//发送应答信号
8,I2CSendWord();//送字
9,I2CPageRead();//接受字
10,I2CPageWrite();//发送页
11,I2CReceiveWords();//接收多字
使用MSP430F149 完成该功能,P3.0 作为SCL,P3.1 作为SDA *作者:DreamHW
*创建日期:2006.09.05
*修改日期:2006.9.14
***************************************/
#include "msp430x26x.h"
#include "iic.h"
//#define SDA P5.1。