基于DA转换模块的单片机仿真和C语言开发_第1页
基于DA转换模块的单片机仿真和C语言开发_第2页
基于DA转换模块的单片机仿真和C语言开发_第3页
基于DA转换模块的单片机仿真和C语言开发_第4页
基于DA转换模块的单片机仿真和C语言开发_第5页
已阅读5页,还剩27页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、武汉理工大学能力拓展课程设计说明书PAGE 武汉理工大学能力拓展课程设计说明书 1.总体设计思路波形发生器是一种常用的信号源,广泛地应用于电子电路、自动控制系统和教学实验等领域。函数信号发生器是一种能够产生多种波形,如三角波、锯齿波、矩形波(含方波)、正弦波的电路。函数信号发生器在电路实验和设备检测中具有十分广泛的用途。通过对函数波形发生器的原理以及构成分析,可设计一个能变换出三角波、正弦波、方波的函数波形发生器。目前使用的信号发生器大部分是函数信号发生器,且特殊波形发生器的价格昂贵。所以本设计使用的是DAC0832芯片构成的发生器,可产生三角波、方波、正弦波等多种特殊波形和任意波形,波形的频

2、率可用程序控制改变。在单片机上加外围器件距阵式键盘,通过键盘控制波形频率的增减以及波形的选择,并用了LCD显示频率大小。在单片机的输出端口接DAC0832进行D/A转换,再通过运放进行波形调整,最后输出波形接在示波器上显示。本设计具有线路简单、结构紧凑、价格低廉、性能优越等优点。本设计制作的波形发生器,可以输出多种标准波形,如方波、正弦波、三角波、锯齿波等,还可以输出任意波形,如用鼠标创建的一个周期的非规则波形或用函数描述的波形等,输出的波形的频率、幅度均可调,且能脱机输出。设计的人机界面不但清晰美观,而且操作方便。设计思路:课设需要各个波形的基本输出。如输出三角波、方波、正弦波。这些波形的实

3、现的具体步骤:锯齿波实现很简单,只需要一开始定义一个初值,然后不断的加1,当溢出后又重初值开始加起,就这样循环下去。三角波的实验过程是先加后减,实现方法是先是开始加1直到溢出后就执行减1操作,就这样不断调用这个循环。方波的实现方法是连续输出一个数,到某个时候就改变一下值,可以把值定义为正极性的,也可以是负极性。正弦波的实现是非常麻烦的。它的实现过程是通过定义一些数据,然后执行时直接输出定义的数据就可以了。元件选型:单片机AT89C51系统,DAC0832一片,PC机一台,运算放大器。2. 芯片简介2.1 DAC0832芯片介绍:0832采用双缓冲接口方式,其传送控制端接地,输入所存允许断ILE

4、与+5V电源相连,利用一个地址码进行二次输出操作,完成数据的传送和激动转换,第一次操作室P2.6为高电平,将P0口数据线上的数据锁存于DAC0832的输入寄存器中。第二次操作是写控制信号由效,传送控制端为低电平,将输入寄存器中的内容锁存入0832的DAC寄存器中,D/A转换器便开始对锁存于DAC寄存器的8位数据进行转换,约经过1/2时钟周期后,在输出端(IOUT2、IOUT1)建立稳定的电流输出。运放的作用是将0832输出的模拟电流信号转换为电压波形。DAC0832为一个8位D/A转换器,单电源供电,在+5+15V范围内均可正常工作。基准电压的范围为10V,电流建立时间为1s,CMOS工艺,低

5、功耗20mW。 DAC0832内部结构资料:芯片内有两级输入寄存器,使DAC0832具备双缓冲、单缓冲和直通三种输入方式,以便适于各种电路的需要(如要求多路D/A异步输入、同步转换等)。D/A转换结果采用电流形式输出。要是需要相应的模拟信号,可通过一个高输入阻抗的线性运算放大器实现这个供功能。运放的反馈电阻可通过RFB端引用片内固有电阻,还可以外接DI0DI7:数据输入线,TLL电平。 ILE:数据锁存允许控制信号输入线,高电平有效。 CS:片选信号输入线,低电平有效。 WR1:为输入寄存器的写选通信号。 XFER:数据传送控制信号输入线,低电平有效。 WR2:为DAC寄存器写选通输入线。 I

6、out1:电流输出线。当输入全为1时Iout1最大。 Iout2: 电流输出线。其值与Iout1之和为一常数。 Rfb:反馈信号输入线,芯片内部有反馈电阻。 Vcc:电源输入线 (+5v+15v) 。Vref:基准电压输入线 (-10v+10v) 。AGND:模拟地,摸拟信号和基准电源的参考地。DGND:数字地,两种地线在基准电源处共地比较好。2.2 AT89C52管脚说明:图2.1AT89C52引脚图VCC:供电电压。 GND:接地。 P0口:P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。当P1口的管脚第一次写1时,被定义为高阻输入。P0能够用于外部程序数据存储器,它可以被

7、定义为数据/地址的第八位。在FIASH编程时,P0 口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。 P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在FLASH编程和校验时,P1口作为第八位地址接收。 P2口:P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。并因此作为输入时,P2口的管脚被外部拉低,将输出电流

8、。这是由于内部上拉的缘故。P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。P2口在FLASH编程和校验时接收高八位地址信号和控制信号。 P3口:P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL门电流。当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故。RST:复位输入。当振荡器复位器件时,要保持RST脚两个机器周期的高电平时间。 ALE/PRO

9、G:当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的地位字节。在FLASH编程期间,此引脚用于输入编程脉冲。在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。因此它可用作对外部输出的脉冲或用于定时目的。然而要注意的是:每当用作外部数据存储器时,将跳过一个ALE脉冲。如想禁止ALE的输出可在SFR8EH地址上置0。此时, ALE只有在执行MOVX,MOVC指令是ALE才起作用。另外,该引脚被略微拉高。如果微处理器在外部执行状态ALE禁止,置位无效。 /PSEN:外部程序存储器的选通信号。在由外部程序存储器取指期间,每个机器周期两次/PSEN有效。但在访问外部数据

10、存储器时,这两次有效的/PSEN信号将不出现。 /EA/VPP:当/EA保持低电平时,则在此期间外部程序存储器(0000H-FFFFH),不管是否有内部程序存储器。注意加密方式1时,/EA将内部锁定为RESET;当/EA端保持高电平时,此间内部程序存储器。在FLASH编程期间,此引脚也用于施加12V编程电源(VPP)。 XTAL1:反向振荡放大器的输入及内部时钟工作电路的输入。 XTAL2:来自反向振荡器的输出。3. 原理图设计及仿真结果3.1. 总体硬件原理图:图3.1总体硬件原理图3.2 方波产生原理及波形此波形的实现更加简单,只需开始的时候设置一个初值然后直接输出这个值就行了,输出一段时

11、间后,然后再重新置一个数据,然后再输出这个数据一段时间,但是此时的时间一定要等于前面那段时间。这样才是一个方波,如果两个时间不相同,那就相当于一个脉冲波了。流程图如下图所示:开 始循环开始 给p0赋值0 x00延时给p0赋值0 xff延时判断按键是否为0图3.2 方波产生流程图仿真结果图:图3.3方波仿真结果3.3 正弦波产生原理及波形正弦波的实现则相对比较复杂,因为正弦波的实现是输出各个点的值就行了,可是各个点值则要通过正弦函数来求出。输出的数据刚好是256个数据,这样则可以直接相加就行了流程图如下图所示:定义变量i循环开始 如果i=0;+i=128把p0定义为数组tab【i判断按键是否为0

12、延时为0则终止 图3.3 正弦波产生流程图仿真结果图:图3.4正弦波仿真结果3.4三角波产生原理及波形三角波的实现是设置一个初值,然后进行加数,同样是加到某个数之后再行减数,减到初值之后就再返回到先前的操作,这个操作跟锯齿波的实现是相似的。此程序输入的VREF的电压是5V,因此该波形输出的最大频率是初值为0和最终值为256,这样输出的波形是最大的。流程图如下图所示:定义变量iuchar ifor(i=0;i0;i-)判断p0是否已满否是延时否/是开 始判断按键是否为0图3.5正弦波产生流程图仿真结果图:图3.6三角波仿真结果4.其他模块及拓展部分4.1 通过开关实现波形的切换及调频通过开关实现

13、波形的切换比较简单只需通过输出波形后不断返回到检测开关的子程序中,判断是否有别的开关拨动,如果有别的开关拨动则执行别的程序,否则输出原来的波形,不过如果要能够识别别的开关发生变化,必须将此开关关掉否则会识别不了别的键按下。当然开关的调频和调幅的实现也一样,不过首先先输出一个波形,然后再检测开关是否需要调频或者调幅,如果需要则转入到相应的程序中,最后再重新输出波形。电路模块实现:图4.1波形的切换及调频电路4.2 运算放大器模块大多数常用的D/A转换器的数字输入时二进制或BCD码形式,输出可以是电流也可以使电压,而多数是电流。因此,在多数电路中,D/A转换器的输出需要用运算放大器组成的I/V转换

14、器将电流输出转换成电压输出4.3 扩展功能简介电位器RV1用于调整输入的I/V转换系数。调节可变电阻RV1可以调整电压,电流转化比例。该电压,电流成正比变化,当可变电阻变大时,输出波形随输出电压增大而增大;当可变电阻变小时,输出波形随输出电压变小而变小。通过电阻调节,可显示电压的变化,如图所示:图4.2波形幅度控制电路输出波形可随电压值变化而变化图4.3不同幅值的波形比较该LED模块可显示1. 波形选择提示 2. 可显示通过按键调节的增大或减小的频率。LED通过接AT89C52的P0口和排阻,实现数据传输和显示功能。图4.4 LED显示电路5.心得体会本次的设计中利用AT89C52和DAC08

15、32以及放大器完成电路的设计,用开关来控制各种波形的发生及转换,用单片机输出后,经过模数转换器生成波形,最终可以通过示波器观察。在这次的软件设计中,程序设计采用的是C语言。C语言具有速度快,可以直接对硬件进行操作的优点,它可以极好的发挥硬件的功能。并且C语言编写的代码非常容易理解,但存在不好维护,很容易产生 bug,难于调试的缺点。因此,在大型程序的设计中,多采用C语言进行程序编译。C语言简洁高效,是最贴近硬件的高级编程语言,经过多年的发展,现在已成熟为专业水平的高级语言。而且,现在单片机产品推出时纷纷配套了C语言编译器,应用广泛。就本次课程设计来说,C语言完全适用本次课设的。由于真正意义上的

16、程序设计还不多,因此还不是很得心应手,所以在设计中遇到一些问题和一些难点。比如:在程序设计中如何实现程序结构的最优化,以达到较高的质量。这是以后设计中要注意的问题。 通过这次课程设计,我进一步了解了波形发生器的原理,在实际动手操作过程中,使我接触了许多我以前没接触过的元件,而且重新温习了学了已久的C语言,使我学得了许多知识,使我获益匪浅。这次课程设计,使我的动手能力得到了很大的提高,更使我们懂得理论知识的重要性,没有理论的指导一切实际行动都是盲目的,且实际操作是我们得到的理论知识得到验证,更能增加对理论知识的理解。虽然在这次设计的过程中,困难不少,但是正是在自己的努力,同学们的帮助下,自己能够

17、顺利的完成,确实还是蛮欣慰的。感谢这次课程设计给了自己锻炼的机会,自己在今后的学 习和生活中,会更加的努力,争取更大的进步!6.仿真程序#include#define uchar unsigned char#define uint unsigned int/#define Fosc 24000000/12000000 /12分频后的频率#define DAdata P0/DA数据端口sbit DA_S1= P20; / 控制DAC0832的8位输入寄存器,仅当都为0时,可以输出数据(处于直通状态),否则,输出将被锁存sbit DA_S2= P21; / 控制DAC0832的8位DAC寄存器,仅

18、当都为0时,可以输出数据(处于直通状态),否则,输出将被锁存sbit key= P32;uchar wavecount; /抽点计数uchar THtemp,TLtemp;/传递频率的中间变量/uint T_temp;uchar judge=1; /在方波输出函数中用于简单判别作用uchar waveform; /当其为0、1、2时,分别代表三种波uchar code freq_unit3=10,50,200; /三种波的频率单位uchar idata wavefreq3=1,1,1; /给每种波定义一个数组单元,用于存放单位频率的个数uchar code lcd_hang1=Sine Wav

19、e Triangle Wave Square Wave Select Wave: press No.1 key! ;uchar idata lcd_hang216=f= Hz ;/*uchar code wave_freq_adjust= /频率调整中间值 0 xff,0 xb8,0 x76,0 x56,0 x43,0 x37,0 x2e,0 x26,0 x20,0 x1c, /正弦波频率调整中间值0 xff,0 x8e,0 x5a,0 x41,0 x32,0 x28,0 x20,0 x1b,0 x17,0 x0e,/三角波频率调整中间值0 xff,0 x8e,0 x5a,0 x41,0 x3

20、2,0 x28,0 x20,0 x1b,0 x17,0 x0e; uint code wave_freq_adjust= /频率调整中间值 380,184,118,86,67,55,46,28,38,32,295,142, 90,65,50,40,32,27,23,14,295,142, 90,65,50,40,32,27,23,14; */*uchar code waveTH= 0 xfc,0 xfe,0 xfe,0 xff,0 xff,0 xff,0 xff,0 xff,0 xff,0 xff,0 xfc,0 xfe,0 xfe,0 xff,0 xff,0 xff,0 xff,0 xff,

21、0 xff,0 xff,0 xff,0 xff,0 xff,0 xff,0 xff,0 xff,0 xff,0 xff,0 xff,0 xff;uchar code waveTL= 0 xf2,0 x78,0 xfb,0 x3c,0 x63,0 x7d,0 x8f,0 x9d,0 xa8,0 xb1,0 x17,0 x0b,0 xb2,0 x05,0 x37,0 x58,0 x70,0 x82,0 x90,0 x9b, 0 x4d,0 xa7,0 xc4,0 xd3,0 xdc,0 xe2,0 xe6,0 xea,0 xec,0 xee;*/*这两组数组很重要,需要根据波形来调试,选择合适的值

22、,使输出波形达到频率要求*/uchar code waveTH= 0 xfd,0 xfe,0 xff,0 xff,0 xff,0 xff,0 xff,0 xff,0 xff,0 xff,0 xfd,0 xfe,0 xff,0 xff,0 xff,0 xff,0 xff,0 xff,0 xff,0 xff,0 xec,0 xf6,0 xf9,0 xfb,0 xfc,0 xfc,0 xfd,0 xfd,0 xfd,0 xfe;uchar code waveTL= 0 x06,0 x8a,0 x10,0 x4e,0 x78,0 x93,0 xa8,0 xb3,0 xbe,0 xc6, /正弦波频率调

23、整中间值0 xac,0 xde,0 x48,0 x7a,0 x99,0 xaf,0 xbb,0 xc8,0 xd0,0 xde,/三角波频率调整中间值0 x88,0 x50,0 x90,0 x32,0 x34,0 xbe,0 x4a,0 xa3,0 xe5,0 x2c; /*/uchar code triangle_tab= /每隔数字8,采取一次0 x00,0 x08,0 x10,0 x18,0 x20,0 x28,0 x30,0 x38,0 x40,0 x48,0 x50,0 x58,0 x60,0 x68,0 x70,0 x78,0 x80,0 x88,0 x90,0 x98,0 xa0

24、,0 xa8,0 xb0,0 xb8,0 xc0,0 xc8,0 xd0,0 xd8,0 xe0,0 xe8,0 xf0,0 xf8,0 xff,0 xf8,0 xf0,0 xe8,0 xe0,0 xd8,0 xd0,0 xc8,0 xc0,0 xb8,0 xb0,0 xa8,0 xa0,0 x98,0 x90,0 x88,0 x80,0 x78,0 x70,0 x68,0 x60,0 x58,0 x50,0 x48,0 x40,0 x38,0 x30,0 x28,0 x20,0 x18,0 x10,0 x08,0 x00;uchar code sine_tab256=/输出电压从0到最大值(

25、正弦波1/4部分)0 x80,0 x83,0 x86,0 x89,0 x8d,0 x90,0 x93,0 x96,0 x99,0 x9c,0 x9f,0 xa2,0 xa5,0 xa8,0 xab,0 xae,0 xb1,0 xb4,0 xb7,0 xba,0 xbc,0 xbf,0 xc2,0 xc5,0 xc7,0 xca,0 xcc,0 xcf,0 xd1,0 xd4,0 xd6,0 xd8,0 xda,0 xdd,0 xdf,0 xe1,0 xe3,0 xe5,0 xe7,0 xe9,0 xea,0 xec,0 xee,0 xef,0 xf1,0 xf2,0 xf4,0 xf5,0 x

26、f6,0 xf7,0 xf8,0 xf9,0 xfa,0 xfb,0 xfc,0 xfd,0 xfd,0 xfe,0 xff,0 xff,0 xff,0 xff,0 xff,0 xff,/输出电压从最大值到0(正弦波1/4部分)0 xff,0 xff,0 xff,0 xff,0 xff,0 xff,0 xfe,0 xfd,0 xfd,0 xfc,0 xfb,0 xfa,0 xf9,0 xf8,0 xf7,0 xf6,0 xf5,0 xf4,0 xf2,0 xf1,0 xef,0 xee,0 xec,0 xea,0 xe9,0 xe7,0 xe5,0 xe3,0 xe1,0 xde,0 xdd,

27、0 xda,0 xd8,0 xd6,0 xd4,0 xd1,0 xcf,0 xcc,0 xca,0 xc7,0 xc5,0 xc2,0 xbf,0 xbc,0 xba,0 xb7,0 xb4,0 xb1,0 xae,0 xab,0 xa8,0 xa5,0 xa2,0 x9f,0 x9c,0 x99 ,0 x96,0 x93,0 x90,0 x8d,0 x89,0 x86,0 x83,0 x80,/输出电压从0到最小值(正弦波1/4部分)0 x80,0 x7c,0 x79,0 x76,0 x72,0 x6f,0 x6c,0 x69,0 x66,0 x63,0 x60,0 x5d,0 x5a,0

28、x57,0 x55,0 x51,0 x4e,0 x4c,0 x48,0 x45,0 x43,0 x40,0 x3d,0 x3a,0 x38,0 x35,0 x33,0 x30,0 x2e,0 x2b,0 x29,0 x27,0 x25,0 x22,0 x20,0 x1e,0 x1c,0 x1a,0 x18,0 x16 ,0 x15,0 x13,0 x11,0 x10,0 x0e,0 x0d,0 x0b,0 x0a,0 x09,0 x08,0 x07,0 x06,0 x05,0 x04,0 x03,0 x02,0 x02,0 x01,0 x00,0 x00,0 x00,0 x00,0 x00,0

29、 x00,/输出电压从最小值到0(正弦波1/4部分)0 x00,0 x00,0 x00,0 x00,0 x00,0 x00,0 x01,0 x02 ,0 x02,0 x03,0 x04,0 x05,0 x06,0 x07,0 x08,0 x09,0 x0a,0 x0b,0 x0d,0 x0e,0 x10,0 x11,0 x13,0 x15 ,0 x16,0 x18,0 x1a,0 x1c,0 x1e,0 x20,0 x22,0 x25,0 x27,0 x29,0 x2b,0 x2e,0 x30,0 x33,0 x35,0 x38,0 x3a,0 x3d,0 x40,0 x43,0 x45,0

30、x48,0 x4c,0 x4e,0 x51,0 x55,0 x57,0 x5a,0 x5d,0 x60,0 x63,0 x66 ,0 x69,0 x6c,0 x6f,0 x72,0 x76,0 x79,0 x7c,0 x80; void delay(uchar z) uint x,y;for(x=z;x0;x-)for(y=110;y0;y-);void triangle_out()/三角波输出 DAdata=triangle_tabwavecount+;if(wavecount64) wavecount=0;DA_S1=0; /打开8位输入寄存器DA_S1=1; /关闭8位输入寄存器void

31、 sine_out() /正弦波输出 DAdata=sine_tabwavecount+;DA_S1=0; /打开8位输入寄存器DA_S1=1; /关闭8位输入寄存器void square_out() /方波输出 judge=judge; if(judge=1) DAdata=0 xff;else DAdata=0 x00;DA_S1=0; /打开8位输入寄存器DA_S1=1; /关闭8位输入寄存器/*1602液晶的相关函数*/#define lcd_ports P1sbit rs=P22;sbit rw=P23;sbit lcden=P24;void write_com(uchar com)

32、rs=0;/置零,表示写指令lcden=0;lcd_ports=com;delay(5);lcden=1;delay(5);lcden=0;void write_date(uchar date)rs=1;/置1,表示写数据(在指令所指的地方写数据)lcden=0;lcd_ports=date;delay(5);lcden=1;delay(5);lcden=0;void disp_lcd(uchar addr,uchar *temp1)uchar num;write_com(addr);delay(1); /延时一会儿?for(num=0;num16;num+)write_date(temp1n

33、um);/或者这样写write_date(*(temp1+num);delay(1);void init_lcd()/uchar num;lcden=0; /可有可无?rw=0; /初始化一定要设置为零,表示写数据write_com(0 x38); /使液晶显示点阵,为下面做准备write_com(0 x0c); /初始设置write_com(0 x06); /初始设置write_com(0 x01); /清零write_com(0 x80); /使指针指向第一行第一格 disp_lcd(0 x80,&lcd_hang13*16); /在第一行显示 disp_lcd(0 xc0,&lcd_ha

34、ng14*16); /在第二行显示/*for(num=0;num16;num+)write_date(tablenum);delay(5);write_com(0 x80+0 x40); /给指针重新赋值,使之指向第二行第一格for(num=0;num2) waveform=0; break; case 0 xd0: /频率按规定单位依次增加 wavefreqwaveform+; if(wavefreqwaveform10) wavefreqwaveform=1; / /*这边要用“10”,因为它比“=11”可靠 break; / 性更高,使加数有个上限,不会一直加下去*/ case 0 xb

35、0: /频率按规定单位依次衰减 wavefreqwaveform-; if(wavefreqwaveform1) wavefreqwaveform=10; /这边要用“1”,因为它比“=0”可靠性更高 break; case 0 x70: /TTL输出 DA_S2=1; /使DAC寄存器关闭 break; THtemp=waveTHwaveform*10+(wavefreqwaveform-1); /方括号中选取第几个数后,并把该值赋给T_tempTLtemp=waveTLwaveform*10+(wavefreqwaveform-1); total_freq= wavefreqwavefor

36、m * freq_unitwaveform; /求输出频率(个数*单位) lcd_hang25=total_freq%10+0 x30; /在液晶中显示个位,(0 x30 在液晶显示中表示数字0) total_freq/=10; lcd_hang24=total_freq%10+0 x30; /在液晶中显示时十位 total_freq/=10; lcd_hang23=total_freq%10+0 x30; /在液晶中显示时百位 total_freq/=10; lcd_hang22=total_freq%10+0 x30; /在液晶中显示时千位 disp_lcd(0 x80,&lcd_hang

37、1waveform*16); /在第一行显示 disp_lcd(0 xc0,lcd_hang2); /在第二行显示wavecount=0; /抽点计数清零while(!key);EA=1; TR0=1; /开启总中断与定时器参考文献1 朱定华,马爱梅,林卫. 微机应用系统设计M. 武汉:华中科技大学出版社,1999:130-1332 顾德英,张健,马淑华. 计算机控制技术M. 北京:北京邮电大学出版社,2006:64-703 朱定华,戴汝平等,单片微机原理与应用M.北京交通大学出版社,清华大学出版社.4 彭介华.电子技术课程设计指导J.北京:高等教育出版社,1997.5彭楚武. 微计原理与接口

38、技术M. 长沙:湖南大学出版社6 HYPERLINK /search?channel=search&sw=(美)Richard&Field=2 t _blank (美)Richard HYPERLINK /search?channel=search&sw=Blum&Field=2 t _blank Blum著 HYPERLINK /search?channel=search&sw=;马朝晖&Field=2 t _blank ;马朝晖等译;C语言程序设计M 北京市:机械工业出版社附录资料:不需要的可以自行删除SHA算法的实现C语言程序:#include #include /定义vector数组

39、#include /记录消息using namespace std; const int NUM = 8; /一个字由32比特(或者8个16进制数)const int BIT = 512; /消息认证码要以512比特一组 /字常量 string H0 = 67452301; string H1 = EFCDAB89; string H2 = 98BADCFE; string H3 = 10325476; string H4 = C3D2E1F0; /定义SHA1(安全哈希算法)类 class SHA1 public: /将一个字符串形式的字转化为vector数组 vector hex_into

40、_dec(string word); /将vector转化为string字符串形式 string num_into_message(vector A); /两个字X和Y的逻辑和 vector word_AND(vector A,vector B); /两个字X和Y的逻辑或 vector word_OR(vector A,vector B); /两个字X和Y的逻辑异或 vector word_XOR(vector A,vector B); /两个字X和Y的逻辑补 vector word_COMPLEMENT(vector A); /两个字X和Y的摸232整数加 vector word_ADD(v

41、ector A,vector B); /将字X循环左移s个位置 vector ROTL(vector A,int s); /SHA-1的填充方案,我们设定msg由ASCII码组成 vectorvector SHA_1_PAD(string msg); /将SHA-1压成以字为单位 vectorvectorvector compress(vectorvector result); /定义ft函数,每个ft函数都有B,C,D三个字作为输入,并产生一个字作为输出 vector Ft(int t,vector B,vector C,vector D); /定义字常数K vector K(int t);

42、 /开始进行SHA-1(安全Hash算法)的加密 vectorvector SHA_1(string msg); ; /将vector转化为string字符串形式 string SHA1:num_into_message(vector A) int i; string msg = ; for(i = 0;i = 0 & Ai = 10 & Ai = 15) msg += A + (Ai - 10); return msg; /将一个字符串形式的字转化为vector数组 vector SHA1:hex_into_dec(string word) int i; vector result(NUM,

43、0); for(i = 0;i = 0 & wordi = A & wordi = F) resulti = 10 + wordi - A; return result; /两个字X和Y的逻辑和 vector SHA1:word_AND(vector A,vector B) vector result(NUM,0); int i; for(i = 0;i NUM;i+) resulti = Ai & Bi; return result; /两个字X和Y的逻辑或 vector SHA1:word_OR(vector A,vector B) vector result(NUM,0); int i;

44、 for(i = 0;i NUM;i+) resulti = Ai | Bi; return result; /两个字X和Y的逻辑异或 vector SHA1:word_XOR(vector A,vector B) vector result(NUM,0); int i; for(i = 0;i NUM;i+) resulti = Ai Bi; return result; /两个字X和Y的逻辑补 vector SHA1:word_COMPLEMENT(vector A) vector result(NUM,0); int i; for(i = 0;i NUM;i+) resulti = 15

45、 - Ai; return result; /两个字X和Y的摸232整数加 vector SHA1:word_ADD(vector A,vector B) vector result(NUM,0); int i; for(i = NUM - 1;i = 0;i-) resulti = Ai + Bi; if(i != 0) int temp = resulti / 16; resulti-1 += temp; resulti %= 16; return result; /将字X循环左移s个位置 vector SHA1:ROTL(vector A,int s) vector result = A

46、; vector temp(NUM,0); int i,j; for(i = 0;i = 0;j-) if(resultj / 8 = 1) tempj = 1; resultj = 1; resultj %= 16; if(j NUM - 1) resultj += tempj + 1; else if(resultj / 8 = 0) tempj = 0; resultj = 1; resultj %= 16; resultNUM - 1 += temp0; return result; /SHA-1的填充方案,我们设定msg由ASCII码组成 vectorvector SHA1:SHA_

47、1_PAD(string msg) int len = msg.length(); int bit_num = len * 8; int i,j; int num,lest = bit_num % 512; if(lest != 0) /看消息长度是否超过512字节,我们需要将它补成512的倍数 num = bit_num / 512 + 1; else num = bit_num / 512; /首先我们以8位字节为一组保存到vector里面,512比特为一组,即一组里面有64位元素 vectorvector result; result.resize(num); for(i = 0;i n

48、um;i+) resulti.resize(64); for(i = 0;i num;i+) for(j = 0;j 64 & i * 64 + j len;j+) resultij = msgi * 64 + j; /下面开始为未够512比特的消息分组进行补长度操作 if(lest != 0) int x = num - 1,last_len = lest / 8; resultxlast_len = 128; /先补一个1 for(i = last_len + 1;i = 56) resultxj = last_l % 128; last_l /= 128; j-; return resu

49、lt; /将SHA-1压成以字为单位(三维数组有点复杂) vectorvectorvector SHA1:compress(vectorvector result) vectorvector rr; rr.resize(result.size(); int i,j; for(i = 0;i rr.size();i+) rri.resize(128); for(i = 0;i result.size();i+) for(j = 0;j resulti.size();j+) rri2 * j = resultij / 16; rri2 * j + 1 = resultij % 16; vector

50、vectorvector rrr; rrr.resize(result.size(); for(i = 0;i rrr.size();i+) rrri.resize(16); for(i = 0;i rrr.size();i+) for(j = 0;j 16;j+) rrrij.resize(8); for(i = 0;i rr.size();i+) for(j = 0;j rri.size();j+) rrrij / 8j % 8 = rrij; return rrr; /定义ft函数,每个ft函数都有B,C,D三个字作为输入,并产生一个字作为输出 vector SHA1:Ft(int t,

51、vector B,vector C,vector D) vector result; if(t = 0 & t = 19) vector a1 = word_AND(B,C); vector a2 = word_AND(word_COMPLEMENT(B),D); result = word_OR(a1,a2); else if(t = 20 & t = 60 & t = 79) vector a1 = word_XOR(B,C); result = word_XOR(a1,D); else if(t = 40 & t = 59) vector a1 = word_AND(B,C); vect

52、or a2 = word_AND(B,D); vector a3 = word_AND(C,D); vector a4 = word_OR(a1,a2); result = word_OR(a4,a3); return result; /定义字常数K vector SHA1:K(int t) vector result; if(t = 0 & t = 20 & t = 40 & t = 60 & t = 79) result = hex_into_dec(CA62C1D6); return result; /开始进行SHA-1(安全Hash算法)的加密 vectorvector SHA1:SHA_1(string msg) vector h0 = hex_into_dec(H0); vector h1 = hex_into_dec(H1); vector h2 = hex_into_dec(H2); vector h3 = hex_into_dec(H3); vector h4 = hex_into_dec(H4); vectorvector resul

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论