
p89v51rd2单片机综合实验.pdf
32页中国地质大学(北京) 本 科 课 程 报 告 2017 年 11 月 24 日 中国地质大学(北京) 课课 程程 名名 称称单片机原理及应用 实实 验验 名名 称称P89V51RD2 单片机综合实验 学学 生生 姓姓 名名衡 星 院 ( 系 )院 ( 系 )地球物理与信息技术学院 专专业业测控技术与仪器 学学号号1010152213 姓名:衡星学号:1010152213成绩: 目录 1 实验目的.-1- 2 实验内容和步骤.-1- 3 实验设备及软件.-2- 4 实验程序框图.-2- 5 程序源代码.-2- 6 调试结果.-16- 7 存在的问题及体会.-21- 附录 Lcd12864.c程序-22- 姓名:衡星学号:1010152213成绩: - 1 - 1 实验目的 (1) 锻炼学生的动手操作能力,在实践中深入理解单片机内部结构 (2) 在实验中理解并运用所学的理论知识,加深对基础内容的理解 (3) 掌握利用 Keil 软件 C 语言编程技巧,加强对程序的调试能力 (4) 锻炼学生分析问题、解决问题的能力 2 实验内容和步骤 实验内容: 单片机上电后显示主菜单: 选择 1 键后,程序功能和实验二相同。
选择 2 键后,出现串口测试子菜单,可选择发送功能和接收功能测试: 发送功能—按 0-9 键后,从串口发出相应按键的 ASCII 码; 接收功能—LCD 屏显示接收到的 ASCII 码字符或字符串或汉字 选择 3 键后,出现数模转换功能测试子菜单,用户可进一步选择输出波形:锯齿波、三 角波、正弦波,用户可以通过按键改变输出波形的频率,7 段数码管显示当前信号的频率 实验步骤: (1) 完成实验二内容 1) 使用定时器,实现 LED 灯的定时移动功能; 2) 利用外部中断,通过 INT0 按键改变流水灯点亮时间; 3) 加入数码管显示功能,通过定时器实现 4 位数码管动态显示当前点亮时间 (2) 实现程序流程控制 1) 实现 LCD 显示,通过 LCD 查看当前程序所在界面及功能; 2) 实现按键扫描,通过键盘控制程序功能切换 (3) 加入串口测试功能 1) 串口发送:通过键盘扫描程序获得当前按键值,然后将按键值发送至 PC 机; 2) 串口接收:实现接收 PC 机发送的字符串功能,并通过 LCD 显示 (4) 数模转换功能 1) 实现三种波形的转换输出; 2) 使用定时器功能,实现波形频率的输出; 3) 加入外部中断,通过 INT0 按键改变输出频率; 4) 加入 LCD。
1 流水灯测试 2 串口功能测试 3 D/A 功能测试 姓名学号 姓名:衡星学号:1010152213成绩: - 2 - 3 实验设备及软件 P89V51RD2 单片机学习板、Keil 软件、stc-isp-15xx-v6.86G 软件等 4 实验程序框图 5 程序源代码 #include #include #include 开始 主菜单 1 键?3 键?2 键? 流水灯测试 频率等于 500Hz INT0? =8) i=0; } void Timer0_INT(void) interrupt 1//定时器 T0 方式 1 中断 { static unsigned int count=0; static unsigned int count_2ms=0; static unsigned int CntKeyJitter=0; if(FlagKeyPressing)//貌似 INT0 键被按下 { if(++CntKeyJitter = 20)//延时 20ms 后再读按键,防抖动 { CntKeyJitter = 0; 姓名:衡星学号:1010152213成绩: - 5 - if(KEY_INT == 0)//读 INT0 引脚,为 0:键正被按下 { FlagKeyPressed = 1; FlagKeyPressing = 0; } else//读 INT0 引脚,为 1:无键按下 { FlagKeyPressed = 0; FlagKeyPressing = 0; } } } TF0=0; if((++count)=dispcount)//LED 移位时间 { count=0; FlagLEDChange=1; } if((++count_2ms)=2)//数码管 2ms 延时 { count_2ms=0; Flag2msOK=1; } TH0=th0; TL0=tl0; } void EInt0_Init(void) { TR0 = 1; IT0 = 1; } void Handle_Key(void)//处理 INTO 按键 { dispcount=dispcount-10; if(dispcount=129) P0=2*(256-NUM++); break; case 3://3 时为锯齿波,只累加 P0=NUM++; break; } DAC_ILE=0; if(NUM=256) NUM=0; } void Handle_Key1(void)// INT0 按键处理 { FREQ=FREQ+1; if(FREQ=100) FREQ=10; 姓名:衡星学号:1010152213成绩: - 10 - calculate_F(); FREQ_LCD[0]=FREQ/10+'0'; FREQ_LCD[1]=FREQ%10+'0'; Lcd_WriteStr(0,3,FREQ_LCD); } void zhengxian(void) { T_Init1(); EInt0_Init(); EA=1; while(1) { if(FlagKeyPressed) { FlagKeyPressed = 0; Handle_Key1(); } } } /********************************LCD 屏显示***********************************/ void Lcd1() { unsigned char code Seg_Lcd1[]={“1 流水灯测试“}; unsigned char code Seg_Lcd2[]={“2 串口功能测试“}; unsigned char code Seg_Lcd3[]={“3 D/A功能测试“}; unsigned char code Seg_Lcd4[]={“1010152213 衡星“}; Lcd_WriteStr(0,0,Seg_Lcd1); Lcd_WriteStr(0,1,Seg_Lcd2); Lcd_WriteStr(0,2,Seg_Lcd3); Lcd_WriteStr(0,3,Seg_Lcd4); } void Lcd2() { unsigned char code Seg_Lcd1[]={“流水灯测试“}; unsigned char code Seg_Lcd3[]={“按 INTO 键改变频率“}; Lcd_WriteStr(0,0,Seg_Lcd1); Lcd_WriteStr(0,2,Seg_Lcd3); } void Lcd3() { 姓名:衡星学号:1010152213成绩: - 11 - unsigned char code Seg_Lcd1[]={“1 发送数据“}; unsigned char code Seg_Lcd2[]={“2 接收功能“}; unsigned char code Seg_Lcd3[]={“串口功能测试“}; Lcd_WriteStr(0,0,Seg_Lcd3); Lcd_WriteStr(0,2,Seg_Lcd1); Lcd_WriteStr(0,3,Seg_Lcd2); } void Lcd4() { unsigned char code Seg_Lcd1[]={“发送功能“}; unsigned char code Seg_Lcd2[]={“按 0--9 键发送“}; Lcd_WriteStr(0,0,Seg_Lcd1); Lcd_WriteStr(0,2,Seg_Lcd2); } void Lcd5() { unsigned char code Seg_Lcd1[]={“请发送字符串“}; Lcd_WriteStr(0,0,Seg_Lcd1); } void Lcd6() { unsigned char code Seg_Lcd1[]={“请发送字符串“}; unsigned char code Seg_Lcd3[]={“接收到的字符串:“}; Lcd_WriteStr(0,0,Seg_Lcd1); Lcd_WriteStr(0,2,Seg_Lcd3); Lcd_WriteStr(0,3,receive_number); } void Lcd7() { unsigned char code Seg_Lcd1[]={“1 sinx“};//“正弦波”字体乱码 unsigned char code Seg_Lcd2[]={“2 triangle“};//“三角波”字体乱码 unsigned char code Seg_Lcd3[]={“3 锯齿波“}; Lcd_WriteStr(0,0,Seg_Lcd1); Lcd_WriteStr(0,1,Seg_Lcd2); Lcd_WriteStr(0,2,Seg_Lcd3); } void Lcd8() { unsigned char code Seg_Lcd1[]={“1 sinx“}; 姓名:衡星学号:1010152213成绩: - 12 - unsigned char code Seg_Lcd2[]={“按 INT0 键改变频率“}; unsigned char code Seg_Lcd3[]={“当前频率“}; unsigned char code Seg_Lcd4[]={“10Hz“}; Lcd_WriteStr(0,0,Seg_Lcd1); Lcd_WriteStr(0,1,Seg_Lcd2); Lcd_WriteStr(0,2,Seg_Lcd3); Lcd_WriteStr(0,3,Seg_Lcd4); } void Lcd9() { unsigned char code Seg_Lcd1[]={“2 triangle“}; unsigned char code Seg_Lcd2[]={“按 INT0 键改变频率“}; unsigned char code Seg_Lcd3[]={“当前频率:“}; unsigned char code Seg_Lcd4[]={“10Hz“}; Lcd_WriteStr(0,0,Seg_Lcd1); Lcd_WriteStr(0,1,Seg_Lcd2); Lcd_WriteStr(0,2,Seg_Lcd3); Lcd_WriteStr(0,3,Seg_Lcd4); } void Lcd10() { unsigned char code Seg_Lcd1[]={“3 锯齿波“}; unsigned char code Seg_Lcd2[]={“按 INT0 键改变频率“}; unsigned char code Seg_Lcd3[]={“当前频率“}; unsigned char code Seg_Lcd4[]={“10Hz“}; Lcd_WriteStr(0,0,Seg_Lcd1); Lcd_WriteStr(0,1,Seg_Lcd2); Lcd_WriteStr(0,2,Seg_Lcd3); Lcd_WriteStr(0,3,Seg_Lcd4); } /************************************键盘扫描*********************************/ void Uart_Init(void); void Send_Byte(unsigned char val); void delay(void)//延时 { unsigned char。












