新概念51单片机C语言教程例题.doc
目录例2.2.1 编写程序,点亮第一个发光二极管(part2_1.c P27 )- 4 -例2.5.1利用for语句延时特性,编写第一个发光二极管以间隔1S亮灭闪动的程序(part2_3.c P42)- 5 -例2.6.1编写程序使第一个发光二极管以间隔500ms亮灭闪动。(part2_4.c P48)- 5 -例2.7.1编写程序使第一个二极管以亮200ms、灭800ms的方式闪动。part2_5.c P49- 6 -例2.8.3利用C51自带库_crol_,以间隔500ms,实现流水灯程序(part2_6.c P53)- 6 -例3.2.1编写程序使第一个数码管显示8(part2.1_.1c P59)- 7 -例3.2.2让实验板上6个数码管同时点亮,依次显示0到F,时间间隔为0.5ms,循环下去。(part2.1_2.c P61)- 8 -例3.3.1第一个数码管显示1,时间为0.5s,然后关闭它,立即让第二个数码管显示2,时间为0.5s,在关闭它一直到最后一个数码管显示6,时间同样为0.5s,关闭它之后再回来显示第一个数码管,一直循环下去。(part2.1_3.c P62)- 9 -例3.5.1利用定时器0工作方式1,在实验板上实现第一个发光管以1s亮灭闪烁。(part2.1.4.c P74)- 11 -例3.5.2用定时器0的方式1实现个第一发光二极管以200ms间隔闪烁,用定时器1的方式1实现数码管前两位59s循环计时。(part2.1_5.c P75)- 12 -例4.1.1用数码管前两位显示一个十进制数,变化范围为0059,开始时显示00,每按下S2键一次,数值加1;每按下S3键一次,数值减1;每按下S4键一次,数值归零;按下S5键一次,利用定时器功能使数值开始自动每秒加1,再次按下S5键,数值停止加1,保持显示原数。(part2.2_1.c P82)- 14 -例4.2.1实验班上电时,数码管不显示,顺序按下矩阵键盘后,数码管上依次显示0F,六个数码管同时静态显示即可。(part2.2_2.c P87)- 17 -例5.3.1用单片机控制ADC0804进行数模转换,当拧动实验板上A/D旁边的电位时,在数码管的前三位以十进制方式显示出A/D转换后的数字量(8位A/D转换后数值在0255变化)。(part2.3_1.c P107)- 21 -例5.5.1用单片机控制DAC0832芯片输出电流,让发光二级管D12由灭均匀变到最亮,再由最亮均匀熄灭。在最亮和最暗时使用蜂鸣器分别警报一声,完成整个周期时间控制在5S左右,循环变化。(part2.3_2.c P121)- 23 -例6.5.1在上位机上用串口调试助手发送一个字符X,单片机收到字符后返回给上位机“I get X”,串口波特率设为9600bps。(part2.4_1.c P137)- 25 -例6.6.1单片机上电后等待从上位机串口发来的命令,同时在数码管的前三位以十进制方式显示A/D采集的数值,在未收到上位机发送来的启动A/D转换命令之前数码管始终显示000。当收到上位机以十六进制发送来的01后,向上位机发送字符串“Turn on ad”同时间隔1s读取一次A/D的值,然后把A/D采集回来的8位二进制转换成十进制表示的实际电压浮点数,并且从串口发送给上位机,形式如“The voltage is 3.398438V”,发送周期也是一秒一次,同时在数码管上也要每秒刷新现实的数值。当收到上位机以十六进制发送过来的02后,向上位机发送字符串“Turn off ad”,然后停止发送电压值,数码管上显示上次结束时保持的值。当收到上位机发来的其他任何数时,向上位机发送字符串“Error”。- 27 -例7.2.1实现1602液晶的第一行显示“I LOVE MCU”,在第二行显示。- 31 -例7.2.2实现1602第一行从左侧移入“Hello everyone”同时第二行从右侧移入“Welcome to here”,移入速度自定,然后停留在屏幕上。(part2.5_2.c P154)- 33 -例7.3.1实现12232液晶的第一行显示“I LOVE MCU”,第二行显示“我爱单片机”。(part2.5_3.c P160)- 34 -例7.3.2实现12232液晶第一行从右侧移入“Hello everyone”,同时第二行从右侧移入“欢迎大家来学习”移入速度自定,最后停留在屏幕上。(part2.5_4.c P163)- 37 -例7.4.1实现在12864液晶上第一行显示“0123456789”,并且让每一位数字随机变化,第二行显示“”,第三行显示“天祥电子”,第四行对应第三行显示出下划线。(part2.5_5.c P173)- 40 -知识点生成随机数(part2.5_512232suiji.c P176)- 44 -例8.3.1利用定时器产生一个099秒变化的秒表,并且显示在数码管上,每过一秒将这个变化的数写入板上AT24C02内部。当关闭实验板电源,并再次打开实验板电源时,单片机先从AT24C02中将原来写入的数读取出来,接着此数继续变化并显示在数码管上。(part2.6_1.c P188)- 48 -例10.1.1利用定时器0工作方式0,在实验板上实现第一个发光管以1s亮灭闪烁。(part3.1.1.c P203)- 53 -例10.2.1利用定时器0工作方式2,在实验板上实现第一个发光管以1s亮灭闪烁。(part3.1.2.c P204)- 54 -例10.3.1利用定时器工作方式3,在实验板上实现用TL0计数器对应的8位定时器实现第一个发光管以1s亮灭闪烁,用TH0计数器对应的8位定时器实现第二个发光管以0.5s亮灭闪烁。(part3.1.3.c P206)- 54 -例10.5.1利用计数器0工作方式1,在实验板上实现用一根导线一端连接GND引脚,另一端去接触T0P3.4引脚,每接触一下,计数器计一次数,将所计的数值实时显示在数码管的前两位,计满100时清0,再从头计起。(part3.1.4.c P214)- 55 -例11.1.1设置单片机串行口的工作模式0,间隔循环发送十六进制数0 xAA,然后用双路示波器观察P3.0和P3.1口波形。(- 58 -例11.3.1用交叉串口线连接两块实验板,或直接用短线交叉线连接连个单片机的P3.0和P3.1口(共地)。在一块板上编写矩阵键盘扫描程序,当扫描到有键按下时,将键值通过串口发送出去,另一块板上单片机收到串口发送来的键值后,将对应键值以0F方式显示在数码管上。- 60 -例11.4.1程序分为主机程序和从机程序,约定一次传送的数据为16B,以02H地址的从机为例。图11.4.2为多机通信主机程序流程图- 65 -图11.4.3为多机通信从机程序流程图。- 68 -从机程序代码(part3.2.6.c P234)- 68 -例12.8.1指针使用例程(point.c P264)- 71 -例13.1.1编写程序实现开启两个外部中断,设置低电平触发中断,用定时器计数并且显示在数码管的前两位,当计数到5时,使单片机进入空闲(休眠)模式,同时关闭定时器,当单片机响应外部中断后,从空闲(休眠)模式返回,同时开启定时器。(- 72 -例13.2.1实验板上实现如下描述程序启动后设定看门狗溢出时间为2s,然后点亮第一个发光二极管,稍延时一会,然后熄灭发光二极管,使程序进入等待死循环状态,并且在死循环中大约每隔1s喂狗一次,看程序运行是否正常。- 74 -例13.6.1.在实验板上实现操作STC单片机自带的E2PROM,存储一组按秒递增的两位数据,并且将数据实时显示在数码管上,数据每变化一次就往E2PROM中写入一次,当关闭实验板电源并再次开启电源时,从E2PROM中读取先前存储的数据,接着递增显示。- 77 -例13.7.1STC89LE516AD/X2系列单片机的A/D转换功能。时钟11.0592MHz,转换结果以16进制形式输出到串行口,可以用串行口调试程序,观察输出结果(本代码摘自宏晶科技芯片手册,经作者调试可正常运行)。- 80 -例13.8.1给出一个STC12C5412AD应用的参考程序。(part3.4.6.c P287)- 82 -程序14.3.1利用51单片机的定时器设计一个时钟。- 89 -程序15.5.1使用DS12C887时钟芯片设计高精度时钟。- 97 -程序16.3.1使用TX-1C实验板上的DS18B20温度传感器设计温控系统C语言源代码(part4.3 P349)- 108 -程序17.3.1太阳能充/放电控制器C语言源代码- 114 -ISD400 x系列语音芯片C语言参考程序- 134 -例21.1.1使用TX-1C实验板上两个独立按键调节直流电机的转速,同时在实验板的数码管上象征性的显示相应的转速值。通过控制单片机输出不同占空比的PWM信号来控制直流电机的转速(感性认识)。(part5.3 P434)- 138 -例21.2.1步进电机应用C语言程序设计(part3.2 P444)- 142 -例21.3.1舵机应用C语言程序设计实例开机时舵机角度自动转为0度,通过实验板上的独立按键调节舵机的角度转动,并且在实验板数码管上显示相应的角度。本例仅演示5个角度的控制,若想实现任意角度控制请大家自行编程实验。程序代码如下(part5.3 P453)- 145 -调节舵机使之转动5个角度 0 45 90 135 180 PWM信号周期为20ms,- 145 -控制高电平的持续时间即可控制舵机停止制动的角度,0.5ms-0度 1-45 1.5-90 2-135 2.5-180- 145 -程序流程是开机时舵机角度自动转为0度,按下 P3.7则转到45度,以后就根据两个按键的按下而转动- 145 -例2.2.1 编写程序,点亮第一个发光二极管(part2_1.c P27 )include reg52.h 52系列单片机头文件sbit led1P10; 声明单片机P1口的第一位void main 主函数led10; /*点亮第一个发光二极管*/例2.2.2 编写程序,点亮P1口的若干二极管(part2_2.c P39 )include reg52.h 52系列单片机头文件void main 主函数P10 xaa; while1; 例2.5.1利用for语句延时特性,编写第一个发光二极管以间隔1S亮灭闪动的程序(part2_3.c P42)include reg52.h 52系列单片机头文件define uint unsigned int 宏定义sbit led1P10; 声明单片机P1口的第一位uint i,j;void main 主函数while1 大循环led10;/*点亮第一个发光二极管*/fori1;i0;i延时forj110;j0;j;led11;/*关闭第一个发光二极管*/fori1000;i0;i延时forj110;j0;j;例2.6.1编写程序使第一个发光二极管以间隔500ms亮灭闪动。(part2_4.c P48)include reg52.h 52系列单片机头文件define uint unsigned int 宏定义sbit led1P10; 声明单片机P1口的第一位void delay1s;声明子函数void main 主函数while1 大循环led10;/*点亮第一个发光二极管*/delay1s;调用延时子函数led11;/*关闭第一个发光二极管*/delay1s;调用延时子函数void delay1s子函数体uint i,j;fori500;i0;iforj110;j0;j;例2.7.1编写程序使第一个二极管以亮200ms、灭800ms的方式闪动。part2_5.c P49include reg52.h 52系列单片机头文件define uint unsigned int 宏定义sbit led1P10; 声明单片机P1口的第一位void delaymsuint;声明子函数void main 主函数while1 大循环led10;/*点亮第一个发光二极管*/delayms200;延时200毫秒led11;/*关闭第一个发光二极管*/delayms800;延时800毫秒void delaymsuint xmsuint i,j;forixms;i0;i ixms即延时约xms毫秒forj110;j0;j;例2.8.3利用C51自带库_crol_,以间隔500ms,实现流水灯程序(part2_6.c P53)include reg52.h 52系列单片机头文件include intrins.hdefine uint unsigned int 宏定义define uchar unsigned charvoid delaymsuint;声明子函数uchar aa;void main 主函数aa0 xfe;赋初值11111110 while1 大循环P1aa;delayms500; 延时500毫秒aa_crol_aa,1; 将aa循环左移1位后再赋给aavoid delaymsuint xmsuint i,j;forixms;i0;i ixms即延时约xms毫秒forj110;j0;j;例3.2.1编写程序使第一个数码管显示8(part2.1_.1c P59)include reg52.h 52系列单片机头文件sbit dulaP26; 申明U1锁存器的锁存端sbit welaP27; 申明U2锁存器的锁存端void mainwela1; 打开U2锁存器P00 xFE; 送入位选信号wela0; 关闭U2锁存器dula1; 打开U1锁存器P00 x7F; 送入段选信号dula0; 关闭U2锁存器while1; 程序停止到这里例3.2.2让实验板上6个数码管同时点亮,依次显示0到F,时间间隔为0.5ms,循环下去。(part2.1_2.c P61)include reg52.h 52系列单片机头文件define uchar unsigned chardefine uint unsigned intsbit dulaP26; 申明U1锁存器的锁存端sbit welaP27; 申明U2锁存器的锁存端uchar num;unchar code table0 x3f,0 x06,0 x5b,0 x4f,0 x66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f,0 x77,0 x7c,0 x39,0 x5e,0 x79,0 x71;void delaymsuint;void mainwela1; 打开U2锁存端P00 xco; 送入位选信号wela0; 关闭U2锁存端while1fornum0;num16;num 16个数循环显示dula1; 打开U1锁存端P0tablenum; 送入段选信号dula0; 关闭U1锁存端delay500; 延时0.5秒void delaymsuint xmsuint i,j;forixms;i0;i ixms即延时约xms毫秒forj110;j0;j;例3.3.1第一个数码管显示1,时间为0.5s,然后关闭它,立即让第二个数码管显示2,时间为0.5s,在关闭它一直到最后一个数码管显示6,时间同样为0.5s,关闭它之后再回来显示第一个数码管,一直循环下去。(part2.1_3.c P62)include reg52.h 52系列单片机头文件define uchar unsigned chardefine uint unsigned intsbit dulaP26; 申明U1锁存器的锁存端sbit welaP27; 申明U2锁存器的锁存端uchar num;unchar code table0 x3f,0 x06,0 x5b,0 x4f,0 x66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f,0 x77,0 x7c,0 x39,0 x5e,0 x79,0 x71;void delaymsuint;void mainwhile1 dula1; P0table1; 送段选数据 dula0; P00 xff; 送位选数据前关闭所有显示,防止打开位选锁存时 wela1; 原来段选数据通过位选锁存器造成混乱 P00 xfe; 送位选数据 wela0; delayms500; 延时dula1; P0table2; 送段选数据 dula0; P00 xff; 送位选数据前关闭所有显示,防止打开位选锁存时 wela1; 原来段选数据通过位选锁存器造成混乱 P00 xfd; 送位选数据 wela0; delayms500; 延时dula1; P0table3; 送段选数据 dula0; P00 xff; 送位选数据前关闭所有显示,防止打开位选锁存时 wela1; 原来段选数据通过位选锁存器造成混乱 P00 xfb; 送位选数据 wela0; delayms500; 延时dula1; P0table4; 送段选数据 dula0; P00 xff; 送位选数据前关闭所有显示,防止打开位选锁存时 wela1; 原来段选数据通过位选锁存器造成混乱 P00 xf7; 送位选数据 wela0; delayms500; 延时dula1; P0table5; 送段选数据 dula0; P00 xff; 送位选数据前关闭所有显示,防止打开位选锁存时 wela1; 原来段选数据通过位选锁存器造成混乱 P00 xef; 送位选数据 wela0; delayms500; 延时dula1; P0table6; 送段选数据 dula0; P00 xff; 送位选数据前关闭所有显示,防止打开位选锁存时 wela1; 原来段选数据通过位选锁存器造成混乱 P00 xdf; 送位选数据 wela0; delayms500; 延时void delaymsuint xms uinti,j; forixms;i0;i ixms即延时约xms毫秒 forj110;j0;j;例3.5.1利用定时器0工作方式1,在实验板上实现第一个发光管以1s亮灭闪烁。(part2.1.4.c P74)includereg52.h 52系列单片机头文件define uchar unsigned chardefine uint unsigned intsbit led1P10;uchar num;void mainTMOD0 x01; 设置定时器0为工作方式1(M1M0为01)TH065536-45872/256; 装初值11.0592M晶振定时50ms数为45872TL065536-45872256; EA1; 开总中断ET01; 开定时器0中断TR01; 启动定时器0while1; 程序停止在这里等待中断中断发生void T0_time interrupt 1TH065536-45872/256; 重装初值TL065536-45872256;num; num每加1次判断一次是否到20次ifnum20 如果到了20次,说明1秒时间到 num0; 然后把num清0重新再计20次 led1led1; 让发光管状态取反3.5.2用定时器0的方式1实现第一个发光二极管以200ms间隔闪烁,用定时器1的方式1实现数码管前两位59s循环计时。(part2.1_5.c P75)include reg52.h 52系列单片机头文件define uchar unsigned chardefine uint unsigned intsbit dulaP26; 申明U1锁存器的锁存端sbit welaP27; 申明U2锁存器的锁存端sbit led1P10;unchar code table0 x3f,0 x06,0 x5b,0 x4f,0 x66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f,0 x77,0 x7c,0 x39,0 x5e,0 x79,0 x71;void delaymsuint;void displayuchar,uchar;uchar num,num1,num2,shi,ge;void mainTMOD0 x11; 设置定时器0为工作方式1(M1M0为11)TH065536-45872/256; 装初值11.0592M晶振定时50ms数为45872TL065536-45872256; TH165536-45872/256; 装初值11.0592M晶振定时50ms数为45872TL165536-45872256; EA1; 开总中断ET01; 开定时器0中断ET11; 开定时器1中断TR01; 启动定时器0TR11; 启动定时器1while1; 程序停止在这里等待中断中断发生 displayshi,ge;void displayuchar shi,uchar ge 显示子函数 dula1; P0tableshi; 送段选数据 dula0; P00 xff; 送位选数据前关闭所有显示,防止打开位选锁存时 wela1; 原来段选数据通过位选锁存器造成混乱 P00 xfe; 送位选数据 wela0; delayms5; 延时dula1; P0tablege;送段选数据 dula0; P00 xff; 送位选数据前关闭所有显示,防止打开位选锁存时 wela1; 原来段选数据通过位选锁存器造成混乱 P00 xfd; 送位选数据 wela0; delayms5; 延时void delaymsuint xmsuint i,j;forixms;i0;i ixms即延时约xms毫秒 forj110;j0;j;void T0_time interrupt 1 TH065536-45872/256; 重装初值TL065536-45872256;num;ifnum14 如果到了4次,说明200ms时间到 num10; 然后把num1清0重新再计4次 led1led1; 让发光管状态取反void T1_time interrupt 3 TH165536-45872/256; 重装初值TL165536-45872256;num2;ifnum220 如果到了20次,说明1秒刷新时间到 num20; 然后把num2清0重新再计4次 num;ifnum60 这个数用来送数码管显示,到60后归0num0;shinum/10; 把一个2位数分离后分别送数码管显示genum10; 十位和个位例4.1.1用数码管前两位显示一个十进制数,变化范围为0059,开始时显示00,每按下S1键一次,数值加1;每按下S2键一次,数值减1;每按下S3键一次,数值归零;按下S4键一次,利用定时器功能使数值开始自动每秒加1,再次按下S4键,数值停止加1,保持显示原数。(part2.2_1.c P82)include reg52.h 52系列单片机头文件define uchar unsigned chardefine uint unsigned int sbit key1P34;sbit key2P35;sbit key3P36;sbit key4P37;sbit dulaP26;申明U1锁存器的锁存端sbit welaP27;申明U2锁存器的锁存端uchar code table0 x3f,0 x06,0 x5b,0 x4f,0 x66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f,0 x77,0 x7c,0 x39,0 x5e,0 x79,0 x71;void delaymsuint;uchar numt0,num;void displayuchar numdis 显示子函数uchar shi,ge; 分离两个分别要显示的数shinumdis/10;genumdis10; dula1;P0tableshi; 送十位段选数据dula0;P00 xff;送位选数据前关闭所有显示,防止打开位选锁存时wela1;原来段选数据通过位选锁存器造成混乱P00 xfe;送位选数据wela0;delayms5;延时dula1;P0tablege; 送个位段选数据dula0;P00 xff;wela1;P00 xfd;wela0;delayms5;void delaymsuint xmsuint i,j;forixms;i0;i ixms即延时约xms毫秒forj110;j0;j;void init 初始化函数TMOD0 x01;设置定时器0为工作方式10000 0001TH065536-45872/256;装初值50ms一次中断TL065536-45872256;EA1; 开总中断ET01; 开定时器0中断void keyscanifkey10delayms10;ifkey10num;ifnum60当到60时重新归0num0;whilekey1;等待按键释放ifkey20delayms10;ifkey20ifnum0当到0时重新归60num60;num;whilekey2;ifkey30delayms10;ifkey30num0; 清0whilekey3;ifkey40delayms10;ifkey40whilekey4;TR0TR0;启动或停止定时器0void maininit;初始化函数while1 keyscan;displaynum;void T0_time interrupt 1TH065536-45872/256;重装初值TL065536-45872256;numt0;ifnumt020如果到了20次,说明1秒时间到numt00;然后把num清0重新再计20次num;ifnum60num0;例4.2.1实验班上电时,数码管不显示,顺序按下矩阵键盘后,数码管上依次显示0F,六个数码管同时静态显示即可。(part2.2_2.c P87)include reg52.h 52系列单片机头文件define uchar unsigned chardefine uint unsigned int sbit dulaP26;申明U1锁存器的锁存端sbit welaP27;申明U2锁存器的锁存端uchar code table0 x3f,0 x06,0 x5b,0 x4f,0 x66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f,0 x77,0 x7c,0 x39,0 x5e,0 x79,0 x71;void delaymsuint xmsuint i,j;forixms;i0;i ixms即延时约xms毫秒forj110;j0;j;void displayuchar numP0tablenum; 显示函数只送段选数据dula1;dula0;void matrixkeyscanuchar temp,key; P30 xfe; tempP3; temptemp iftemp0 xf0 delayms10; tempP3; temptemp iftemp0 xf0 tempP3; switchtemp case 0 xee key0;