数字信号处理与DSP器件:单片机的C语言-实例

上传人:博****1 文档编号:569739539 上传时间:2024-07-30 格式:PPT 页数:79 大小:3.23MB
返回 下载 相关 举报
数字信号处理与DSP器件:单片机的C语言-实例_第1页
第1页 / 共79页
数字信号处理与DSP器件:单片机的C语言-实例_第2页
第2页 / 共79页
数字信号处理与DSP器件:单片机的C语言-实例_第3页
第3页 / 共79页
数字信号处理与DSP器件:单片机的C语言-实例_第4页
第4页 / 共79页
数字信号处理与DSP器件:单片机的C语言-实例_第5页
第5页 / 共79页
点击查看更多>>
资源描述

《数字信号处理与DSP器件:单片机的C语言-实例》由会员分享,可在线阅读,更多相关《数字信号处理与DSP器件:单片机的C语言-实例(79页珍藏版)》请在金锄头文库上搜索。

1、一、基本示例分析:使用mega16的Port B连接8个LED,以产生流水灯的效果。连接好电路并且完成程序之后,您将可以看到8个LED依次轮流闪烁。 在这次练习中,您将学会如何使用I/O Port输出数据,以及如何使用循环实现时间延迟。 例1、LED的控制电路图/8位流水灯实验/外部晶振12M,接上J2跳线帽#include #include #define LED_ON PORTA.2=0;/主函数void main() unsigned char i=0; unsigned char led=0x01; /led=0xfe=11111110B,1-灭,0-亮 DDRB=0xff; /PB0

2、7,全部为输出状态 DDRA.2=1; /控制led亮灭的开关设为输出 LED_ON; /led控制打开 while(1) for(i=0;i8;i+) PORTB=led; /逐个PB口输出低电平 led=1; /led左移1位 if(0=led) led=0x01; delay_ms(300); /适当延迟 while(1) for(i=0;i8;i+) PORTB=led; /逐个PB口输出低电平 led=1; /led左移1位 if(0=led) led=0x01; delay_ms(300); /适当延迟 例2、4X4矩阵键盘的输入以及数码管显示 目的是使用mega16的Port B

3、连接到1个数码管,Port D则连接到4X4矩阵键盘,当用户按动开关时,数码管就会显示相应的16进制的数值。 在这次练习中,您将学会如何使用mega16输入数据,控制共阴七段数码管的显示。控制共阴七段数码管的显示。 例如,您要从Port D输入数据给变量temp时,可以执行temp=PIND; 电电路路图图#include #include LED7.h#include key16.h/全局变量:键盘结果unsigned char KeyResult; /标识所按下的按键void main() /主函数 LED7_IO_Init(); /数码管引脚初始化 while(1) Key_Scan()

4、; /键盘扫描函数 Number_Show(KeyResult); /数码管显示函数 /4X4矩阵键盘的输入及数码管显示程序/键盘按下判断函数unsigned char Key_Press(void) unsigned char KeyRead=0x00; DDRD=0xf0; /PD03为带上拉输入, /P47输出低电平 PORTD=0x0f; KeyRead=PIND; /读取PD的结果 KeyRead&=0x0f; /屏蔽高四位 if(KeyRead!=0x0f) /手否有按下键呢? return 1; /是 else return 0; /不是/键盘扫描函数void Key_Scan(

5、void) if(Key_Press() /如果有按下键 delay_ms(10); /消抖 C1_Scan(); /扫描列1 C2_Scan(); /扫描列2 C3_Scan(); /扫描列3 C4_Scan(); /扫描列4 while(Key_Press(); /判断是否已经释放手 /扫描列1函数void C1_Scan(void) unsigned char KeyRead; DDRD=0xf0; /PD03为带上拉输入,/P47输出低电平 PORTD=0xef; /PD4输出低电平,其余高四位输出高电平。低四位为带上拉输入 DDRD=0x00; /PD口全部输入 KeyRead=PI

6、ND; /读取PD口的值 switch (KeyRead) /判断 case 0xee: KeyResult=0; break; /(1,1) case 0xed: KeyResult=1; break; /(2,1) case 0xeb: KeyResult=2; break; /(3,1) case 0xe7: KeyResult=3; break; /(4,1) 一个共阴七段数码管的外观和引脚如图所示。这个共阴七段数码管的引脚分别通过锁存器连接到mega16的Port B引脚。PB6PB5PB4PB3PB0PB1PB2PB7GND电路图电路图通过锁存器把6个数码管连接到mega16的Po

7、rt B引脚,可以控制6个数码管的显示。 共阴七段数码管有一共同接点连接到地,其余的引脚分别连到PORTB口; 因此如果要让所指定的LED发光时,就必须输出1,反之则输出0,所以我们可以用下表排列出所要显示字符和必须输出的信号。七段数码管码表#include LED7.h/数组声明并定义在存储数据区/0funsigned char const Number= 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71 ;例2、数码管动态显示例3、步进电机步进电机是将电脉冲信号转变为角位移或

8、线位移的开环控制元步进电机件。在非超载的情况下,电机的转速、停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响,当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定的方向转动一个固定的角度,称为“步距角”,它的旋转是以固定的角度一步一步运行的。可以通过控制脉冲个数来控制角位移量,从而达到准确定位的目的;同时可以通过控制脉冲频率来控制电机转动的速度和加速度,从而达到调速的目的。步进电机工作原理步进电机能将脉冲信号转换成角位移,每个步距对应一个脉冲,步距角值是精确的,误差不会累积。下图所示为三相步进电机简化模型图,定子上有三对凸起磁极,定子上相对的磁极绕有同一线圈。转子为磁场良导体,

9、上有四个凸齿。当定子磁极上的线圈中通有电流时,磁极感生磁场将经由转子传导。此时磁通将根据磁阻最小的路径原则闭合,结果将导致磁场在转子上产生力矩,使其某一对凸齿尽量正对定子上通电的磁极。绕线情况A相通电时平衡位置三相步进电机单三拍方式驱动设启动时转子1、3齿在A极附近,则第一个脉冲通过A极后,由于磁通企图沿最小磁阻路径闭合,产生的磁场力导致1、3齿要转动到与A极对齐。同样,下一个脉冲经过B极,同样驱使2、4齿转动到与B极对齐,以此类推。通电顺序ABCAB时,电机正转;通电顺序ACBAC时,电机反转。三相步进电机六拍方式驱动在单三拍驱动方式下,电机运行时有3个稳定位置,每改 变 一 次 通 电 状

10、 态 , 转 子 转 动 30; 若 按 照AABBBCCCAA的顺序通电,则运行时有6个稳定位置,每改变一次通电状态,转子顺时针方向转15。若通电顺序相反,同样导致电机反转。如果A相和B相的电流按照某一规律变化,则可以在AB之间获得更多的稳定状态,同样技术施于BC和CA间,即可做到更小的步距角,实现更加精确的位移。步进电机驱动器步进电机电路图步进电机实物图: 常用的四相步进电机原理图:#include #include #define uchar unsigned charflash uchar F_Rotation4=0x01,0x02,0x04,0x08; /正转表格,换算成二进制 00

11、00 0001,0000 0010,0000 0100,0000 1000flash uchar B_Rotation4=0x08,0x04,0x02,0x01; /反转表格/步进电机控制程序void main() uchar i,j; DDRB=0xff; /PB0-PB2设置为输出状态 while(1) for(j=0;j255;j+) for(i=0;i4;i+) /4相 PORTB=F_Rotationi; /输出对应的相 ,使步进电机正转 delay_ms(5); /改变这个参数可以调整电机转速 ,数字越小,转速越大 delay_ms(1000); /暂停1s for(j=0;j25

12、5;j+) for(i=0;i4;i+) /4相 PORTB=B_Rotationi; /输出对应的相 ,使步进电机反转 delay_ms(5); /改变这个参数可以调整电机转速 ,数字越小, 转速越大 delay_ms(1000); /暂停1s 例4、红外遥控以及LCD显示 本例子主要利用红外接收头TL1838解码,在液晶上显示由遥控器发来的4组编码,并且在接收到正确编码时,蜂鸣器会鸣响一下。 在这次练习中,您将学会如何使用mega16进行红外解码,定时器和外部中断的使用,LCD的显示以及蜂鸣器的使用。 红外线的光谱位于红色光之外, 波长是0.761.5m,比红光的波长还长。红外遥控是利用红

13、外线进行传递信息的一种控制方式,红外遥控具有抗干扰,电路简单,容易编码和解码,功耗小,成本低的优点。红外遥控几乎适用所有家电的控制。 红外遥控系统的主要部分为调制、发射和接收,如下左图所示:红外线接收头红外接收头TL1838 上图为一个典型的红外接收器模块图,红外信号由接收器的检波二极管接收,依次经过放大,限幅,带通滤波器,检波,积分和比较的处理。 当你对此图表模块的描述不了解时,请不要慌张,因为所有这些功能模块都集成到单一的电子器件(红外接收头)。红外遥控编码格式常用的编码格式协议格式:NEC协议格式NEC格式的特征:1:使用 38 kHz 载波频率 2:引导码间隔是 9 ms + 4.5

14、ms (为了方便解码) 3:使用 16位客户代码 4:使用 8位数据代码和 8位取反的数据代码 NEC 协议通过脉冲串之间的时间间隔来实现信号的调制(英文简写PPM)红外遥控编码格式NEC 协议 逻辑“0”是由0.56ms的38KHZ载波和0.560ms的无载波间隔组成;逻辑“1”是由0.56ms的38KHZ载波和1.68ms的无载波间隔组成;结束位是0.56ms的38K载波。红外遥控编码格式NEC 协议上图所示为NEC协议的典型脉冲链。 协议规定低位首先发送,每次发送的信息首先是引导码,接下来便是地址码和命令码。地址码和命令码发送两次,第二次发送的是反码,用于验证接收的信息的准确性。因为每位

15、都发送一次它的反码,所以总体的发送时间是恒定的。红外遥控编码格式NEC 协议 尽管你一直按住那个按键,一串信息只能发送一次。如果一直按着按键,发送的则是以110ms为周期的重复码,重复码是由9ms的高电平和2.25ms的低电平及一个560us的高电平组成。红外遥控系统电路图#include #include #include /包含1602液晶库函数#include /包含蜂鸣器库函数#define uchar unsigned char#define uint unsigned int#define IR PIND.2 /PD2接口与TL1838相连,定义 /IR读取数据uchar Titl

16、e=IR Code:; /标题uchar LowTime,HighTime; /分别储存高、低电平的宽度uchar IrCode4; /处理后的红外码: /客户码,客户码反码,数据 /码,数据码反码/* 主函数 */*/void main(void) DDRD.2=0; /TL1838对应引脚输入状态 PORTD.2=1; /内部上拉电阻有效 lcd_init(); /液晶初始化 lcd_puts(Title); /在第一行显示标题 TIME0_Init(); /定时器0初始化 EXT0_Init(); /外部中断0初始化 #asm(sei); /使能全局中断 while(1); /等待红外编

17、码接收/* 外部中断0初始化 */*/void EXT0_Init(void) GICR |= 0x40; /打开外部中断0 MCUCR &= 0xfc; /ISC01:0=10b,下降沿触发 MCUCR |= 0x02;/*/* 外部中断0函数 */interrupt EXT_INT0 void ex0_isr (void) /外部中断0服务函数 GICR &= 0xbf; /关闭外中断0,不再接收二次红外信号 TCNT0 = 0x00; /定时器T0清0 TIMSK |= 0x01; /开启定时器T0 while(IR=0); /如果是低电平就等待,给引导码低电平计时 TIMSK &= 0

18、xfe; /关闭定时器T0 LowTime = TCNT0; /保存引导码低电平时间 TCNT0 = 0x00; /定时器T0清0 TIMSK |= 0x01; while(IR=1); /如果是高电平就等待,给引导码高电平计时 TIMSK &= 0xfe; HighTime = TCNT0; /保存引导码高电平时间if(LowTime100)&(LowTime45)&(HighTime55) /如果是引导码,就开始解码,否则放弃(计算如下) if(DeCode()=1) /执行遥控解码功能 disp_code(); /解码成功,调用1602LCD显示函数 beep(); /蜂鸣器响一声 提示

19、解码成功 GICR |= 0x40; /开启外中断0/*uchar DeCode(void) uchar i,j; uchar temp; /储存解码出的数据 for(i=0;i4;i+) /连续读取4个用户码和键数据码 temp=0; /必须在此时对temp清零 for(j=0;j=1; /temp中的各数据位右移一位, TCNT0=0x00; /定时器清0 TIMSK |= 0x01; /开启定时器T0 while(IR=0); /低电平就等待(计低电平时间) TIMSK &= 0xfe; /定时器T0停止计时 LowTime = TCNT0; /保存低电平时间 TCNT0 = 0x00;

20、 TIMSK |= 0x01; while(IR=1); /高电平就等待(计高电平时间) TIMSK &= 0xfe; HighTime = TCNT0; if(LowTime10) return 0; /如果低电平长度不在合理范围,则认为出错,停止解码 else if(HighTime=4)&(HighTime=16)&(HighTime4; /右移四位得到高四位码 if(temp=0x09) /0-9则显示对应ASCII码 lcd_putchar(temp+0x30); else /A-F则显示对应ASCII码 lcd_putchar(temp-0x09+0x40); temp=data&

21、0x0f; if(temp=0x09) /与0x0f相与取低四位码 lcd_putchar(temp+0x30); else lcd_putchar(temp-0x09+0x40); lcd_putchar(H); /显示字符H/*/* 显示4组红外码 */*/void disp_code(void) uchar i; lcd_gotoxy(0,1); /定位液晶第二行 for(i=0;i100)&(LowTime45)&(HighTime55) /如果是引导码,就开始解码,否则放弃(计算如下) if(DeCode()=1) /执行遥控解码功能 disp_code(); /解码成功,调用160

22、2LCD显示函数 beep(); /蜂鸣器响一声 提示解码成功 GICR |= 0x40; /开启外中断0/*例5、 DS18B20温度传感器使用 本例子主要利用mega16读取DS18B20温度传感器测得的数据,然后通过LCD来显示。 在这次练习中,您将学会如何使用mega16和温度传感器对温度进行测量并显示,学习1wire总线的使用。 DS18B20温度传感器电路图 1-wire总线是一种具有一共主机和多个从机的系统,本例中mega16为主机,DS18B20为从机。 通过1-wire对DS18B20进行初始化、写数据和读数据都要有严格的时序。对DS18B20写数据时必须处在写时隙(writ

23、e time slots)中,读数据时必须处在读时隙(read time slots)中。请结合程序理解时序的操作。#define DQ_0 PORTA.5=0#define DQ_1 PORTA.5=1#define DQ_OUTDDRA.5=1#define DQ_IN DDRA.5=0#define DQ PINA.5 初始化:通过1-wire从主机上发出一个复位脉冲,接着由从属器件发回存在脉冲。时序图如下: 发送复位脉冲的方法是拉低1-wire总线电平,时间至少480us。之后总线主控会释放总线并进入接收模式(Rx)。当释放总线时,5K的上拉电阻会拉高电平,DS18B20检测到这个上升

24、沿时,会等待15-60us之后发送一个存在脉冲回来。因此为了确保DS18B20能发回脉冲,我们要在程序里手动延迟60us以上。/DS18B20复位函数void DS18B20_Reset() DQ_OUT; /DQ为输出状态 DQ_0; /输出低电平 delay_us(500); / 延迟500微妙 DQ_1; /释放总线 delay_us(60); /延迟60微妙 DQ_IN; /DQ位输入状态 while(DQ); /等待从机DS18B20应答(低电平有效) while(!DQ); /等待从机DS18B20释放总线#define DQ_0 PORTA.5=0#define DQ_1 POR

25、TA.5=1#define DQ_OUTDDRA.5=1#define DQ_IN DDRA.5=0#define DQ PINA.5 写时隙:分为写0时隙和写1时隙,即总线使用写0时隙对DS18B20写入逻辑0,使用写1时隙对DS18B20写入逻辑1。 所有写时隙过程都至少持续60us,且在两个写时隙之间至少延迟1us。两种写时隙的初始化都由拉低电平实现。 DS18B20采集总线数据是初始化之后的15us-60us之间(如图),在这段时间内,总线电平1则采集到逻辑1,电平为0则采集到逻辑0。因此,形成一个写0时隙要拉低电平,并保持低电平至少60us。而形成一个写1时隙要在拉低电平后的15us

26、之内释放总线。void DS18B20_Write(unsigned char Data)/ DS18B20写字节函数 unsigned char i; DQ_OUT; /DQ为输出 for(i=0;i=1; 读时隙:与写时隙类似,分为读0时隙和读1时隙。 DS18B20只有在主机处于读时隙时才能传送数据,因此总线必须在写入Read Scratchpad BEh指令之后立即进入读时隙。 初始化读时隙也是通过拉低电平实现,初始化后DS18B20会向总线传送逻辑1或0,且在初始化后的15us之内是有效的,因此主机必须在这段时间内拉高电平并且开始采集总线数据。/ DS18B20读字节函数unsign

27、ed char DS18B20_Read() unsigned char i,Temp=0; for(i=0;i=1; /数据右移 DQ_OUT; ; /DQ为输出状态 DQ_0; ; /拉低总线,启动输入 DQ_1; /释放总线DQ_IN; /DQ为输入状态if(DQ) Temp|=0x80;delay_us(45); /延迟45微妙(最大45微妙)return Temp; 对DS18B20的控制通过使用1-wire写指令来实现。包括5个ROM指令和6个功能指令。本程序中,由于硬件接法,所以只用到了以下三个指令: SKIP ROM CCh:主机可以通过这个指令可以同时命令总线上所有器件,而不

28、发送任何ROM代码信息。 CONVERT T 44h:启动温度转换。产生9位数据。8位数据和最后一位校验位(CRC)。 READ SCRATCHPADBEh:读取暂存器内容,每次读一位,直到第9位(byte-8,CRC)。 其余指令可下载PDF查看详细介绍,另包括DS18B20内部流程。#include #include #include 1602LCD.h#include DS18B20.hunsigned char buff=Temperature:; / 字符串/主函数void main() lcd_init(); /调用IO口初始化函数while(1) Display_temperat

29、ure(Read_Temperature();delay_ms(500);/稍微延迟/读温度函数unsigned int Read_Temperature()unsigned int Temp1,Temp2;DS18B20_Reset(); /DS1302复位DS18B20_Write(0xCC); /跳过ROMDS18B20_Write(0x44); /温度转换DS18B20_Reset(); /DS1302复位DS18B20_Write(0xCC); /跳过ROMDS18B20_Write(0xbe); /读取RAMTemp1=DS18B20_Read(); /读低八位,LS Byte,

30、RAM0Temp2=DS18B20_Read(); /读高八位,MS Byte, RAM1DS18B20_Reset(); /DS1302复位,表示读取结束return (Temp28)|Temp1)*6.25);/0.0625=xx, 0.625=xx.x, 6.25=xx.xxvoid Display_temperature(unsigned int Temp) /显示温度unsigned char ten,one,dat,dat1;lcd_gotoxy(0,0); lcd_puts(buff);lcd_gotoxy(5,1);/第二行第六列 ten=Temp/1000+0x30;one=

31、Temp%1000/100+0x30;dat=Temp%100/10+0x30;dat1=Temp%10+0x30;lcd_putchar(ten); lcd_putchar(one);lcd_putchar(0x2e); lcd_putchar(dat); lcd_putchar(dat1);例6、 DS1302时钟模块的使用 本例子主要利用mega16结合DS1302时钟芯片来产生实时时钟,并通过按键来对时钟进行设定,然后通过LCD来显示。 在这次练习中,您将学会如何使用mega16和时钟芯片来产生和显示时间。DS1302时钟模块电路图void main()/主函数 unsigned ch

32、ar i=0; /同步Timer和Buffer时使用 lcd_init(); /lcd初始化 DS1302_Init(); /1302初始化 Unprotect(); /DS1302寄存器解保护 DS1302_Set_Timer(Timer); /写入初始的时间 Protect(); /对DS1302的寄存器进行保护 while(1) if(Key_Press() /是否有键被按下 Key_Scan(); /扫描键盘 if(15=KeyResult) /按下(4,4)则更改为设置时间模式 model=1; else model=0; /显示时间模式 else model=0; if(!mode

33、l) /显示时间模式 Unprotect(); /DS1302寄存器解保护 DS1302_Get_Timer(Buffer); /获取当前时间 Protect(); /对DS1302的寄存器进 /行保护 display_timer(Buffer); /显示当前时间 else /设置时间模式 for(i=0;i=3) i=0; for(i=0;i=2;i+) for(j=0;j=250;j+) Number_Show(Table2i); /显示读取的结果 期中检查要求(占总评期中检查要求(占总评20%左右),左右),11月月26号之前检号之前检查,逾期作废,查,逾期作废,实现实现DEMO板基本功

34、能(每组至多板基本功能(每组至多2人),人),可以周末或平时去实验室交作品(只交电路板,可以周末或平时去实验室交作品(只交电路板,不需交电源),之后,再统一发放,请在自己的电路不需交电源),之后,再统一发放,请在自己的电路板贴标签标明自己的姓名:板贴标签标明自己的姓名:平时分(总共40分)的20分用来考察课余制作: 实现MEGA16的制作与基本功能演示可以获得12分(包括 LED在按键控制下的闪烁功能、LCD的现实功能、 AD 转换器的功能 等); 实现DS1302时钟功能、Ds18B20温度测量;实现通过AD口采集方波信号(可以用另外一个MEGA16单片机产生方波),展现FIR滤波器或者IIR滤波器功能,可以同时考虑FFT或者DFT功能的实现,可以获得满分); 根据自己的兴趣拓展功能给负责考核的师兄或者师姐看,不拘一格都可以考虑加分。

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 高等教育 > 研究生课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号