147 -郭天祥目录例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用数码管前两位显示一个十进制数,变化范围为00~59,开始时显示00,每按下S2键一次,数值加1;每按下S3键一次,数值减1;每按下S4键一次,数值归零;按下S5键一次,利用定时器功能使数值开始自动每秒加1,再次按下S5键,数值停止加1,保持显示原数part2.2_1.c P82) - 14 -例4.2.1实验班上电时,数码管不显示,顺序按下矩阵键盘后,数码管上依次显示0~F,六个数码管同时静态显示即可part2.2_2.c P87) - 17 -例5.3.1用单片机控制ADC0804进行数模转换,当拧动实验板上A/D旁边的电位时,在数码管的前三位以十进制方式显示出A/D转换后的数字量(8位A/D转换后数值在0~255变化)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”,串口波特率设为9600bpspart2.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!”,在第二行显示WWW.TXMCU.COM - 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利用定时器产生一个0~99秒变化的秒表,并且显示在数码管上,每过一秒将这个变化的数写入板上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引脚,另一端去接触T0(P3.4)引脚,每接触一下,计数器计一次数,将所计的数值实时显示在数码管的前两位,计满100时清0,再从头计起part3.1.4.c P214) - 55 -例11.1.1设置单片机串行口的工作模式0,间隔循环发送十六进制数0xAA,然后用双路示波器观察P3.0和P3.1口波形。
- 58 -例11.3.1用交叉串口线连接两块实验板,或直接用短线交叉线连接连个单片机的P3.0和P3.1口(共地)在一块板上编写矩阵键盘扫描程序,当扫描到有键按下时,将键值通过串口发送出去,另一块板上单片机收到串口发送来的键值后,将对应键值以0~F方式显示在数码管上 - 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 -ISD400x系列语音芯片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 //52系列单片机头文件sbit led1=P1^0; //声明单片机P1口的第一位void main() //主函数{ led1=0; /*点亮第一个发光二极管*/ }例2.2.2 编写程序,点亮P1口的若干二极管(part2_2.c P39 )#include //52系列单片机头文件void main() //主函数{ P1=0xaa; //while(1); }例2.5.1利用for语句延时特性,编写第一个发光二极管以间隔1S亮灭闪动的程序(part2_3.c P42)#include //52系列单片机头文件#define uint unsigned int //宏定义sbit led1=P1^0; //声明单片机P1口的第一位uint i,j;void main() //主函数{ while(1) //大循环 { led1=0; /*点亮第一个发光二极管*/ for(i=1;i>0;i--) //延时 for(j=110;j>0;j--); led1=1; /*关闭第一个发光二极管*/ for(i=1000;i>0;i--) //延时 for(j=110;j>0;j--); } }例2.6.1编写程序使第一个发光二极管以间隔500ms亮灭闪动。
part2_4.c P48)#include //52系列单片机头文件#define uint unsigned int //宏定义sbit led1=P1^0; //声明单片机P1口的第一位void delay1s(); //声明子函数void main() //主函数{ while(1) //大循环 { led1=0; /*点亮第一个发光二极管*/ delay1s(); //调用延时子函数 led1=1; /*关闭第一个发光二极管*/ delay1s(); //调用延时子函数 } }void delay1s() //子函数体{ uint i,j; for(i=500;i>0;i--) for(j=110;j>0;j--);}例2.7.1编写程序使第一个二极管以亮200ms、灭800ms的方式闪动part2_5.c P49)#include //52系列单片机头文件#define uint unsigned int //宏定义sbit led1=P1^0; //声明单片机P1口的第一位void delayms(uint); //声明子函数void main() //主函数{ while(1) //大循环 { led1=0; /*点亮第一个发光二极管*/ delayms(200); //延时200毫秒 led1=1; /*关闭第一个发光二极管*/ delayms(800); //延时800毫秒 } }void delayms(uint xms) { uint i,j; for(i=xms;i>0;i--) //i=xms即延时约xms毫秒 for(j=110;j>0;j--);}例2.8.3利用C51自带库_crol_(),以间隔500ms,实现流水灯程序(part2_6.c P53)#include //52系列单片机头文件#include #define uint unsigned int //宏定义#define uchar unsigned charvoid delayms(uint); //声明子函数uchar aa;void main() //主函数{ aa=0xfe; //赋初值11111110 while(1) //大循环 { P1=aa; delayms(500); //延时500毫秒 aa=_crol_(aa,1); //将aa循环左移1位后再赋给aa } }void delayms(uint xms) { uint i,j; for(i=xms;i>0;i--) //i=xms即延时约xms毫秒 for(j=110;j>0;j--);}例3.2.1编写程序使第一个数码管显示8(part2.1_.1c P59)#include //52系列单片机头文件sbit dula=P2^6; //申明U1锁存器的锁存端sbit wela=P2^7; //申明U2锁存器的锁存端void main(){wela=1; //打开U2锁存器P0=0xFE; //送入位选信号wela=0; //关闭U2锁存器dula=1; //打开U1锁存器P0=0x7F; //送入段选信号dula=0; //关闭U2锁存器while(1); //程序停止到这里}例3.2.2让实验板上6个数码管同时点亮,依次显示0到F,时间间隔为0.5ms,循环下去。
part2.1_2.c P61)#include //52系列单片机头文件#define uchar unsigned char#define uint unsigned intsbit dula=P2^6; //申明U1锁存器的锁存端sbit wela=P2^7; //申明U2锁存器的锁存端uchar num;unchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};void delayms(uint);void main(){ wela=1; //打开U2锁存端 P0=0xco; //送入位选信号 wela=0; //关闭U2锁存端 while(1) { for(num=0;num<16;num++) //16个数循环显示 { dula=1; //打开U1锁存端 P0=table[num]; //送入段选信号 dula=0; //关闭U1锁存端 delay(500); //延时0.5秒 } }}void delayms(uint xms){ uint i,j; for(i=xms;i>0;i--) //i=xms即延时约xms毫秒 for(j=110;j>0;j--); }例3.3.1第一个数码管显示1,时间为0.5s,然后关闭它,立即让第二个数码管显示2,时间为0.5s,在关闭它……一直到最后一个数码管显示6,时间同样为0.5s,关闭它之后再回来显示第一个数码管,一直循环下去。
part2.1_3.c P62)#include //52系列单片机头文件#define uchar unsigned char#define uint unsigned intsbit dula=P2^6; //申明U1锁存器的锁存端sbit wela=P2^7; //申明U2锁存器的锁存端uchar num;unchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};void delayms(uint);void main(){while(1){ dula=1; P0=table[1]; //送段选数据 dula=0; P0=0xff; //送位选数据前关闭所有显示,防止打开位选锁存时 wela=1; //原来段选数据通过位选锁存器造成混乱 P0=0xfe; //送位选数据 wela=0; delayms(500); //延时dula=1; P0=table[2]; //送段选数据 dula=0; P0=0xff; //送位选数据前关闭所有显示,防止打开位选锁存时 wela=1; //原来段选数据通过位选锁存器造成混乱 P0=0xfd; //送位选数据 wela=0; delayms(500); //延时dula=1; P0=table[3]; //送段选数据 dula=0; P0=0xff; //送位选数据前关闭所有显示,防止打开位选锁存时 wela=1; //原来段选数据通过位选锁存器造成混乱 P0=0xfb; //送位选数据 wela=0; delayms(500); //延时dula=1; P0=table[4]; //送段选数据 dula=0; P0=0xff; //送位选数据前关闭所有显示,防止打开位选锁存时 wela=1; //原来段选数据通过位选锁存器造成混乱 P0=0xf7; //送位选数据 wela=0; delayms(500); //延时dula=1; P0=table[5]; //送段选数据 dula=0; P0=0xff; //送位选数据前关闭所有显示,防止打开位选锁存时 wela=1; //原来段选数据通过位选锁存器造成混乱 P0=0xef; //送位选数据 wela=0; delayms(500); //延时dula=1; P0=table[6]; //送段选数据 dula=0; P0=0xff; //送位选数据前关闭所有显示,防止打开位选锁存时 wela=1; //原来段选数据通过位选锁存器造成混乱 P0=0xdf; //送位选数据 wela=0; delayms(500); //延时}}void delayms(uint xms){ uinti,j; for(i=xms;i>0;i--) //i=xms即延时约xms毫秒 for(j=110;j>0;j--);}例3.5.1利用定时器0工作方式1,在实验板上实现第一个发光管以1s亮灭闪烁。
part2.1.4.c P74)#include //52系列单片机头文件#define uchar unsigned char#define uint unsigned intsbit led1=P1^0;uchar num;void main(){TMOD=0x01; //设置定时器0为工作方式1(M1M0为01)TH0=(65536-45872)/256; //装初值11.0592M晶振定时50ms数为45872TL0=(65536-45872)%256; EA=1; //开总中断ET0=1; //开定时器0中断TR0=1; // 启动定时器0while(1); //程序停止在这里等待中断中断发生}void T0_time() interrupt 1{TH0=(65536-45872)/256; //重装初值TL0=(65536-45872)%256;num++; //num每加1次判断一次是否到20次if(num==20) //如果到了20次,说明1秒时间到{ num=0; //然后把num清0重新再计20次 led1=~led1; //让发光管状态取反}}例3.5.2用定时器0的方式1实现第一个发光二极管以200ms间隔闪烁,用定时器1的方式1实现数码管前两位59s循环计时。
part2.1_5.c P75)#include //52系列单片机头文件#define uchar unsigned char#define uint unsigned intsbit dula=P2^6; //申明U1锁存器的锁存端sbit wela=P2^7; //申明U2锁存器的锁存端sbit led1=P1^0;unchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};void delayms(uint);void display(uchar,uchar);uchar num,num1,num2,shi,ge;void main(){TMOD=0x11; //设置定时器0为工作方式1(M1M0为11)TH0=(65536-45872)/256; //装初值11.0592M晶振定时50ms数为45872TL0=(65536-45872)%256; TH1=(65536-45872)/256; //装初值11.0592M晶振定时50ms数为45872TL1=(65536-45872)%256; EA=1; //开总中断ET0=1; //开定时器0中断ET1=1; //开定时器1中断TR0=1; // 启动定时器0TR1=1; // 启动定时器1while(1); //程序停止在这里等待中断中断发生{ display(shi,ge);}}void display(uchar shi,uchar ge) //显示子函数{ dula=1; P0=table[shi]; //送段选数据 dula=0; P0=0xff; //送位选数据前关闭所有显示,防止打开位选锁存时 wela=1; //原来段选数据通过位选锁存器造成混乱 P0=0xfe; //送位选数据 wela=0; delayms(5); //延时dula=1; P0=table[ge];//送段选数据 dula=0; P0=0xff; //送位选数据前关闭所有显示,防止打开位选锁存时 wela=1; //原来段选数据通过位选锁存器造成混乱 P0=0xfd; //送位选数据 wela=0; delayms(5); //延时}void delayms(uint xms){uint i,j;for(i=xms;i>0;i--) //i=xms即延时约xms毫秒 for(j=110;j>0;j--);}void T0_time() interrupt 1{ TH0=(65536-45872)/256; //重装初值TL0=(65536-45872)%256;num++;if(num1==4) //如果到了4次,说明200ms时间到{ num1=0; //然后把num1清0重新再计4次 led1=~led1; //让发光管状态取反}}void T1_time() interrupt 3{ TH1=(65536-45872)/256; //重装初值TL1=(65536-45872)%256;num2++;if(num2==20) //如果到了20次,说明1秒刷新时间到{ num2=0; //然后把num2清0重新再计4次 num++;if(num==60) //这个数用来送数码管显示,到60后归0num=0;shi=num/10; //把一个2位数分离后分别送数码管显示ge=num%10; //十位和个位}}例4.1.1用数码管前两位显示一个十进制数,变化范围为00~59,开始时显示00,每按下S2键一次,数值加1;每按下S3键一次,数值减1;每按下S4键一次,数值归零;按下S5键一次,利用定时器功能使数值开始自动每秒加1,再次按下S5键,数值停止加1,保持显示原数。
part2.2_1.c P82)#include //52系列单片机头文件#define uchar unsigned char#define uint unsigned int sbit key1=P3^4;sbit key2=P3^5;sbit key3=P3^6;sbit key4=P3^7;sbit dula=P2^6; //申明U1锁存器的锁存端sbit wela=P2^7; //申明U2锁存器的锁存端uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};void delayms(uint);uchar numt0,num;void display(uchar numdis) //显示子函数{ uchar shi,ge; //分离两个分别要显示的数 shi=numdis/10; ge=numdis%10; dula=1; P0=table[shi]; //送十位段选数据 dula=0; P0=0xff; //送位选数据前关闭所有显示,防止打开位选锁存时 wela=1; //原来段选数据通过位选锁存器造成混乱 P0=0xfe; //送位选数据 wela=0; delayms(5); //延时 dula=1; P0=table[ge]; //送个位段选数据 dula=0; P0=0xff; wela=1; P0=0xfd; wela=0; delayms(5);}void delayms(uint xms) { uint i,j; for(i=xms;i>0;i--) //i=xms即延时约xms毫秒 for(j=110;j>0;j--);}void init() //初始化函数{ TMOD=0x01;//设置定时器0为工作方式1(0000 0001) TH0=(65536-45872)/256;//装初值50ms一次中断 TL0=(65536-45872)%256; EA=1; //开总中断 ET0=1; //开定时器0中断 }void keyscan(){ if(key1==0) { delayms(10); if(key1==0) { num++; if(num==60)//当到60时重新归0 num=0; while(!key1);//等待按键释放 } } if(key2==0) { delayms(10); if(key2==0) { if(num==0)//当到0时重新归60 num=60; num--; while(!key2); } } if(key3==0) { delayms(10); if(key3==0) { num=0; //清0 while(!key3); } } if(key4==0) { delayms(10); if(key4==0) { while(!key4); TR0=~TR0;//启动或停止定时器0 } }}void main(){ init();//初始化函数 while(1) { keyscan(); display(num); }}void T0_time() interrupt 1{ TH0=(65536-45872)/256;//重装初值 TL0=(65536-45872)%256; numt0++; if(numt0==20) //如果到了20次,说明1秒时间到 { numt0=0; //然后把num清0重新再计20次 num++; if(num==60) num=0; } }例4.2.1实验班上电时,数码管不显示,顺序按下矩阵键盘后,数码管上依次显示0~F,六个数码管同时静态显示即可。
part2.2_2.c P87)#include //52系列单片机头文件#define uchar unsigned char#define uint unsigned int sbit dula=P2^6; //申明U1锁存器的锁存端sbit wela=P2^7; //申明U2锁存器的锁存端uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};void delayms(uint xms) { uint i,j; for(i=xms;i>0;i--) //i=xms即延时约xms毫秒 for(j=110;j>0;j--);}void display(uchar num){ P0=table[num]; //显示函数只送段选数据 dula=1; dula=0;}void matrixkeyscan(){ uchar temp,key; P3=0xfe; temp=P3; temp=temp&0xf0; if(temp!=0xf0) { delayms(10); temp=P3; temp=temp&0xf0; if(temp!=0xf0) { temp=P3; switch(temp) { case 0xee: key=0; break; case 0xde: key=1; break; case 0xbe: key=2; break; case 0x7e: key=3; break; } while(temp!=0xf0) { temp=P3; temp=temp&0xf0; } display(key); } } P3=0xfd; temp=P3; temp=temp&0xf0; if(temp!=0xf0) { delayms(10); temp=P3; temp=temp&0xf0; if(temp!=0xf0) { temp=P3; switch(temp) { case 0xed: key=4; break; case 0xdd: key=5; break; case 0xbd: key=6; break; case 0x7d: key=7; break; } while(temp!=0xf0) { temp=P3; temp=temp&0xf0; } display(key); } } P3=0xfb; temp=P3; temp=temp&0xf0; if(temp!=0xf0) { delayms(10); temp=P3; temp=temp&0xf0; if(temp!=0xf0) { temp=P3; switch(temp) { case 0xeb: key=8; break; case 0xdb: key=9; break; case 0xbb: key=10; break; case 0x7b: key=11; break; } while(temp!=0xf0) { temp=P3; temp=temp&0xf0; } display(key); } } P3=0xf7; temp=P3; temp=temp&0xf0; if(temp!=0xf0) { delayms(10); temp=P3; temp=temp&0xf0; if(temp!=0xf0) { temp=P3; switch(temp) { case 0xe7: key=12; break; case 0xd7: key=13; break; case 0xb7: key=14; break; case 0x77: key=15; break; } while(temp!=0xf0) { temp=P3; temp=temp&0xf0; } display(key); } }}void main(){ P0=0; //关闭所有数码管段选 dula=1; dula=0; P0=0xc0;//位选中所有数码管 wela=1; wela=0; while(1) { matrixkeyscan();//不停调用键盘扫描程序 }}例5.3.1用单片机控制ADC0804进行数模转换,当拧动实验板上A/D旁边的电位时,在数码管的前三位以十进制方式显示出A/D转换后的数字量(8位A/D转换后数值在0~255变化)。
part2.3_1.c P107)#include //52系列单片机头文件#include #define uchar unsigned char#define uint unsigned int sbit dula=P2^6; //申明U1锁存器的锁存端sbit wela=P2^7; //申明U2锁存器的锁存端sbit adwr=P3^6; //定义AD的WR端口sbit adrd=P3^7; //定义AD的RD端口uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};void delayms(uint xms) { uint i,j; for(i=xms;i>0;i--) //i=xms即延时约xms毫秒 for(j=110;j>0;j--);}void display(uchar bai,uchar shi,uchar ge) //显示子函数{ dula=1; P0=table[bai]; //送段选数据 dula=0; P0=0xff; //送位选数据前关闭所有显示,防止打开位选锁存时 wela=1; //原来段选数据通过位选锁存器造成混乱 P0=0x7e; //送位选数据 wela=0; delayms(5); //延时 dula=1; P0=table[shi]; dula=0; P0=0xff; wela=1; P0=0x7d; wela=0; delayms(5); dula=1; P0=table[ge]; dula=0; P0=0xff; wela=1; P0=0x7b; wela=0; delayms(5);}void main() // 主程序{ uchar a,A1,A2,A3,adval; wela=1; P0=0x7f; //置CSAD为0,选通ADCS 以后不必再管ADCS wela=0; while(1) { adwr=1; _nop_(); adwr=0; //启动AD转换 _nop_(); adwr=1; for(a=10;a>0;a--) //TX-1C实验板AD工作频率较低,所以启动转换后要多留点时间用来转换 { //这里把显示部分放这里的原因也是为了延长转换时间 display(A1,A2,A3); } P1=0xff; //读取P1口之前先给其写全1 adrd=1; //选通ADCS _nop_(); adrd=0; //AD读使能 _nop_(); adval=P1; //AD数据读取赋给P1口 adrd=1; A1=adval/100; //分出百,十,和个位 A2=adval%100/10; A3=adval%10; }}例5.5.1用单片机控制DAC0832芯片输出电流,让发光二级管D12由灭均匀变到最亮,再由最亮均匀熄灭。
在最亮和最暗时使用蜂鸣器分别警报一声,完成整个周期时间控制在5S左右,循环变化part2.3_2.c P121)#include #define uchar unsigned char#define uint unsigned intsbit dula=P2^6; //申明U1锁存器的锁存端sbit wela=P2^7; //申明U2锁存器的锁存端sbit dawr=P3^6; //定义DA的WR端口sbit dacs=P3^2; //定义DA的CS端口sbit beep=P2^3; //定义蜂鸣器端口void delayms(uint xms) { uint i,j; for(i=xms;i>0;i--) //i=xms即延时约xms毫秒 for(j=110;j>0;j--);}void main(){ uchar val,flag; dula=0; wela=0; dacs=0; dawr=0; P0=0; while(1) { if(flag==0) { val+=5; P0=val; //通过P0口给DA数据口赋值 if(val==255) { flag=1; 。