第一篇:51单片机程序设计实训100例
《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例
《单片机C语言程序设计实训100例—基于8051+Proteus仿真》案例
第 01 篇 基础程序设计
01 闪烁的LED
/* 名称:闪烁的LED */ #include
void DelayMS(uint x){ uchar i;while(x--){ 说明:LED按设定的时间间隔闪烁
for(i=0;i<120;i++);} } //主程序 void main(){
} while(1){
} LED=~LED;DelayMS(150);
02 从左到右的流水灯
/* 名称:从左到右的流水灯
说明:接在P0口的8个LED从左到右循环依次点亮,产生走马灯效果 */ #include
//延时
void DelayMS(uint x){
uchar i;while(x--){ for(i=0;i<120;i++);} } //主程序 void main(){ P0=0xfe;
}
03 8只LED左右来回点亮
/* 名称:8只LED左右来回点亮
说明:程序利用循环移位函数_crol_和_cror_形成来回滚动的效果 */ #include
void DelayMS(uint x){ uchar i;
while(x--){ } for(i=0;i<120;i++);while(1){ P0=_crol_(P0,1);//P0的值向左循环移动
DelayMS(150);} } //主程序 void main(){
uchar i;P2=0x01;while(1){ 上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例
}
} for(i=0;i<7;i++){ P2=_crol_(P2,1);//P2的值向左循环移动 DelayMS(150);} for(i=0;i<7;i++){ P2=_cror_(P2,1);//P2的值向右循环移动
} DelayMS(150);04 花样流水灯
/* 名称:花样流水灯
说明:16只LED分两组按预设的多种花样变换显示 */ #include
0xfc,0xf9,0xf3,0xe7,0xcf,0x9f,0x3f,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xe7,0xdb,0xbd,0x7e,0xbd,0xdb,0xe7,0xff,0xe7,0xc3,0x81,0x00,0x81,0xc3,0xe7,0xff, 0xaa,0x55,0x18,0xff,0xf0,0x0f,0x00,0xff,0xf8,0xf1,0xe3,0xc7,0x8f,0x1f,0x3f,0x7f, 0x7f,0x3f,0x1f,0x8f,0xc7,0xe3,0xf1,0xf8,0xff,0x00,0x00,0xff,0xff,0x0f,0xf0,0xff,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe, 0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe, 0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff };uchar code Pattern_P2[]= { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfc,0xf9,0xf3,0xe7,0xcf,0x9f,0x3f,0xff, 0xe7,0xdb,0xbd,0x7e,0xbd,0xdb,0xe7,0xff,0xe7,0xc3,0x81,0x00,0x81,0xc3,0xe7,0xff, 0xaa,0x55,0x18,0xff,0xf0,0x0f,0x00,0xff,0xf8,0xf1,0xe3,0xc7,0x8f,0x1f,0x3f,0x7f, 0x7f,0x3f,0x1f,0x8f,0xc7,0xe3,0xf1,0xf8,0xff,0x00,0x00,0xff,0xff,0x0f,0xf0,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f, 0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x00, 0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例
0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff };//延时
void DelayMS(uint x){
uchar i;while(x--){ } for(i=0;i<120;i++);} //主程序 void main(){
uchar i;while(1){ //从数组中读取数据送至P0和P2口显示
} for(i=0;i<136;i++){
} P0=Pattern_P0[i];P2=Pattern_P2[i];DelayMS(100);}
05 LED模拟交通灯
/* 名称:LED模拟交通灯
说明:东西向绿灯亮若干秒,黄灯闪烁5次后红灯亮,红灯亮后,南北向由红灯变为绿灯,若干秒后南北向黄灯闪烁5此后变红灯,东西向变绿灯,如此重复。*/ #include
//东西向灯 sbit YELLOW_A=P0^1;sbit GREEN_A=P0^2;sbit RED_B=P0^3;
//南北向灯
sbit YELLOW_B=P0^4;sbit GREEN_B=P0^5;uchar Flash_Count=0,Operation_Type=1;//闪烁次数,操作类型变量 上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例
//延时
void DelayMS(uint x){ uchar i;while(x--)for(i=0;i<120;i++);} //交通灯切换 void Traffic_Light(){ switch(Operation_Type){
case 1: //东西向绿灯与南北向红灯亮
RED_A=1;YELLOW_A=1;GREEN_A=0;
RED_B=0;YELLOW_B=1;GREEN_B=1;
DelayMS(2000);
Operation_Type=2;
break;
case 2: //东西向黄灯闪烁,绿灯关闭
DelayMS(300);
YELLOW_A=~YELLOW_A;GREEN_A=1;
if(++Flash_Count!=10)return;//闪烁5次
Flash_Count=0;
Operation_Type=3;
break;
case 3: //东西向红灯,南北向绿灯亮
RED_A=0;YELLOW_A=1;GREEN_A=1;
RED_B=1;YELLOW_B=1;GREEN_B=0;
DelayMS(2000);
Operation_Type=4;
break;
case 4: //南北向黄灯闪烁5次
DelayMS(300);
YELLOW_B=~YELLOW_B;GREEN_B=1;
if(++Flash_Count!=10)return;
Flash_Count=0;
Operation_Type=1;} } //主程序 void main(){ while(1)Traffic_Light();}
06 单只数码管循环显示0~9 上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例
/* 名称:单只数码管循环显示0~9 */ #include
void DelayMS(uint x){ uchar t;while(x--)for(t=0;t<120;t++);} //主程序 void main(){
} uchar i=0;P0=0x00;while(1){
} P0=~DSY_CODE[i];i=(i+1)%10;DelayMS(300);说明:主程序中的循环语句反复将0~9的段码送至P0口,使数字0~9循环显示
07 8只数码管滚动显示单个数字
/* 名称:8只数码管滚动显示单个数字
说明:数码管从左到右依次滚动显示0~7,程序通过每次仅循环选通一只数码管 */ #include
void DelayMS(uint x){ uchar t;while(x--)for(t=0;t<120;t++);上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例
} //主程序 void main(){ uchar i,wei=0x80;while(1){
for(i=0;i<8;i++)
{
P2=0xff;
//关闭显示
wei=_crol_(wei,1);
P0=DSY_CODE[i];//发送数字段码
P2=wei;
//发送位码
DelayMS(300);
} } }
08 8只数码管动态显示多个不同字符
电路如上图
/* 名称:8只数码管动态显示多个不同字符
说明:数码管动态扫描显示0~7。*/ #include
void DelayMS(uint x){ uchar t;while(x--)for(t=0;t<120;t++);} //主程序 void main(){ uchar i,wei=0x80;while(1){
for(i=0;i<8;i++)
{
P0=0xff;
P0=DSY_CODE[i];//发送段码 wei=_crol_(wei,1);上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例
P2=wei;
//发送位码
DelayMS(2);
} } }
09 8只数码管闪烁显示数字串
电路如上图
/* 名称:8只数码管闪烁显示数字串
说明:数码管闪烁显示由0~7构成的一串数字
本例用动态刷新法显示一串数字,在停止刷新时所有数字显示消失。
*/ #include
uchar code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//位码表
uchar code DSY_IDX[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//延时
void DelayMS(uint x){ uchar t;while(x--)for(t=0;t<120;t++);} //主程序 void main(){ uchar i,j;while(1){
for(i=0;i<30;i++)
{
for(j=0;j<8;j++)
{
P0=0xff;
P0=DSY_CODE[j];//发送段码
P2=DSY_IDX[j];//发送位码
DelayMS(2);
}
}
P2=0x00;
//关闭所有数码管并延时
DelayMS(1000);} } 上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例 8只数码管滚动显示数字串
电路如上图
/* 名称:8只数码管滚动显示数字串 说明:数码管向左滚动显示3个字符构成的数字串 */ #include
uchar code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};//下面数组看作环形队列,显示从某个数开始的8个数(10表示黑屏)uchar Num[]={10,10,10,10,10,10,10,10,2,9,8};//延时
void DelayMS(uint x){ uchar t;while(x--)for(t=0;t<120;t++);} //主程序 void main(){ uchar i,j,k=0,m=0x80;while(1){ //刷新若干次,保持一段时间的稳定显示
for(i=0;i<15;i++)
{
for(j=0;j<8;j++)
{ //发送段码,采用环形取法,从第k个开始取第j个
P0=0xff;
P0=DSY_CODE[Num[(k+j)%11]];
m=_crol_(m,1);
P2=m;//发送位码
DelayMS(2);
}
}
k=(k+1)%11;//环形队列首支针k递增,Num下标范围0~10,故对11取余
} } K1-K4 控制LED移位
/* 名称:K1-K4 控制LED移位 说明:按下K1时,P0口LED上移一位;
上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例
*/
按下K2时,P0口LED下移一位;
按下K3时,P2口LED上移一位;
按下K4时,P2口LED下移一位;
#include
void DelayMS(uint x){ uchar i;while(x--)for(i=0;i<120;i++);}
//根据P1口的按键移动LED void Move_LED(){
if
((P1&0x10)==0)P0=_cror_(P0,1);//K1 else if((P1&0x20)==0)P0=_crol_(P0,1);//K2 else if((P1&0x40)==0)P2=_cror_(P2,1);//K3
//K4 else if((P1&0x80)==0)P2=_crol_(P2,1);} //主程序
void main(){ uchar Recent_Key;//最近按键
} P0=0xfe;P2=0xfe;P1=0xff;Recent_Key=0xff;while(1){
} if(Recent_Key!=P1){
} Recent_Key=P1;
//保存最近按键 Move_LED();DelayMS(10);K1-K4 按键状态显示 上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例
/* 名称:K1-K4 按键状态显示
说明:K1、K2按下时LED点亮,松开时熄灭,*/ #include
void DelayMS(uint x){ uchar i;while(x--)for(i=0;i<120;i++);
K3、K4按下并释放时LED点亮,再次按下并释放时熄灭;
} //主程序 void main(){
} K1-K4 分组控制LED 上海师范大学信息与机电工程学院—倪继锋 P0=0xff;P1=0xff;while(1){
} LED1=K1;LED2=K2;if(K3==0){ while(K3==0);} LED3=~LED3;if(K4==0){
} while(K4==0);LED4=~LED4;DelayMS(10);《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例
/* 名称:K1-K4 分组控制LED 说明:每次按下K1时递增点亮一只LED,全亮时再次按下则再次循环开始,K2按下后点亮上面4只LED,K3按下后点亮下面4只LED,K4按下后关闭所有LED */ #include
void DelayMS(uint x){ uchar i;while(x--)for(i=0;i<120;i++);} //主程序 void main(){
uchar k,t,Key_State;P0=0xff;P1=0xff;while(1){
t=P1;if(t!=0xff){
DelayMS(10);if(t!=P1)continue;//取得4位按键值,由模式XXXX1111(X中有一位为0,其他均为1)//变为模式0000XXXX(X中有一位为1,其他均为0)Key_State=~t>>4;k=0;//检查1所在位置,累加获取按键号k while(Key_State!=0){ k++;Key_State>>=1;} //根据按键号k进行4种处理 switch(k){
case 1:
if(P0==0x00)P0=0xff;P0<<=1;DelayMS(200);break;P0=0xf0;break;case 2:
上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例
}
}
}
} case 3: case 4: P0=0x0f;break;P0=0xff;14 K1-K4 控制数码管移位显示
/* 名称:K1-K4 控制数码管移位显示
说明:按下K1时加1计数并增加显示位,按下K2时减1计数并减少显示位,按下K3时清零。
*/ #include
uchar code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};//位码
uchar code DSY_Index[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};//待显示到各数码管的数字缓冲(开始仅在0位显示0,其他黑屏)uchar Display_Buffer[]={0,10,10,10,10,10,10,10};//延时
void DelayMS(uint x){ uchar i;while(x--)for(i=0;i<120;i++);}
void Show_Count_ON_DSY(){ uchar i;for(i=0;i<8;i++)
{ P0=0xff;P0=DSY_CODE[Display_Buffer[i]];
} P2=DSY_Index[i];DelayMS(2);} //主程序 void main(){ uchar i,Key_NO,Key_Counts=0;上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例
P0=0xff;P1=0xff;P2=0x00;while(1){
} Show_Count_ON_DSY();P1=0xff;Key_NO=P1;//P1口按键状态分别为K1-0xfe,K2-0xfd,K3-0xfb switch(Key_NO){
case 0xfe:
Key_Counts++;if(Key_Counts>8)Key_Counts=8;Display_Buffer[Key_Counts-1]=Key_Counts;break;if(Key_Counts>0)Display_Buffer[--Key_Counts]=10;break;Display_Buffer[0]=0;for(i=1;i<8;i++)Display_Buffer[i]=10;Key_Counts=0;case 0xfd:
case 0xfb:
} //若键未释放则仅刷新显示,不进行键扫描 while(P1!=0xff)Show_Count_ON_DSY();} K1-K4 控制数码管加减演示
/* 名称:K1-K4 控制数码管加减演示
说明:按下K1后加1计数,按下K2后减1计数,按下K3后清零。*/ #include
uchar code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};//待显示的3位缓冲 uchar Num_Buffer[]={0,0,0};//按键代码,按键计数 uchar Key_Code,Key_Counts=0;//延时
void DelayMS(uint x){ 上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例
uchar i;while(x--)for(i=0;i<120;i++);}
//显示函数
void Show_Counts_ON_DSY(){ uchar i,j=0x01;Num_Buffer[2]=Key_Counts/100;Num_Buffer[1]=Key_Counts/10%10;Num_Buffer[0]=Key_Counts%10;for(i=0;i<3;i++){
j=_cror_(j,1);
P0=0xff;
P0=DSY_CODE[Num_Buffer[i]];
P2=j;DelayMS(1);} } //主程序 void main(){ uchar i;P0=0xff;P1=0xff;P2=0x00;Key_Code=0xff;while(1){
Show_Counts_ON_DSY();
P1=0xff;
Key_Code=P1;
//有键按下时,数码管刷新显示30次,该行代码同时起到延时作用
if(Key_Code!=0xff)
for(i=0;i<30;i++)Show_Counts_ON_DSY();
switch(Key_Code)
{
case 0xfe: if(Key_Counts<255)Key_Counts++;
break;
case 0xfd: if(Key_Counts>0)Key_Counts--;
break;
case 0xfb: Key_Counts=0;
}
Key_Code=0xff;} 上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例
} 4X4矩阵键盘控制条形LED显示
/* 名称:4X4矩阵键盘控制条形LED显示
说明:运行本例时,按下的按键值越大点亮的LED越多。*/ #include
uchar code KeyCodeTable[]={0x11,0x12,0x14,0x18,0x21, 0x22,0x24,0x28,0x41,0x42,0x44,0x48,0x81,0x82,0x84,0x88};//延时
void DelayMS(uint x){ uchar i;while(x--)for(i=0;i<120;i++);}
//键盘扫描
uchar Keys_Scan(){ uchar sCode,kCode,i,k;//低4位置0,放入4行
P1=0xf0;//若高4位出现0,则有键按下 if((P1&0xf0)!=0xf0){
DelayMS(2);if((P1&0xf0)!=0xf0){
sCode=0xfe;{
//行扫描码初值
for(k=0;k<4;k++)//对4行分别进行扫描
P1=sCode;if((P1&0xf0)!=0xf0){
kCode=~P1;for(i=0;i<16;i++)//查表得到按键序号并返回 if(kCode==KeyCodeTable[i])上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例
}
}
return(i);else sCode=_crol_(sCode,1);} }
return(-1);} //主程序
void main(){ uchar i,P2_LED,P3_LED;uchar KeyNo=-1;//按键序号,-1表示无按键
} while(1){ KeyNo=Keys_Scan();//扫描键盘获取按键序号KeyNo
if(KeyNo!=-1){
}
} P2_LED=0xff;P3_LED=0xff;for(i=0;i<=KeyNo;i++)//键值越大,点亮的LED越多 { if(i<8)P3_LED>>=1;else P2_LED>>=1;} P3=P3_LED;//点亮条形LED P2=P2_LED;数码管显示4X4矩阵键盘按键号
/* 名称:数码管显示4X4矩阵键盘按键号
说明:按下任意键时,数码管都会显示其键的序号,扫描程序首先判断按键发生在哪一列,然后根据所发生的行附加不同的值,从而得到按键的序号。*/ 上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例
#include
uchar code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90, 0x88,0x83,0xc6,0xa1,0x86,0x8e,0x00};sbit BEEP=P3^7;//上次按键和当前按键的序号,该矩阵中序号范围0~15,16表示无按键 uchar Pre_KeyNo=16,KeyNo=16;//延时
void DelayMS(uint x){ uchar i;while(x--)for(i=0;i<120;i++);}
//矩阵键盘扫描 void Keys_Scan(){
uchar Tmp;P1=0x0f;//高4位置0,放入4行
DelayMS(1);Tmp=P1^0x0f;//按键后0f变成0000XXXX,X中一个为0,3个仍为1,通过异或把3个1变为0,唯一的0变为1 switch(Tmp)//判断按键发生于0~3列的哪一列
{
case 1: KeyNo=0;break;case 2: KeyNo=1;break;case 4: KeyNo=2;break;case 8: KeyNo=3;break;default:KeyNo=16;//无键按下
} P1=0xf0;
//低4位置0,放入4列
DelayMS(1);Tmp=P1>>4^0x0f;//按键后f0变成XXXX0000,X中有1个为0,三个仍为1;高4位转移到低4位并异或得到改变的值
switch(Tmp)//对0~3行分别附加起始值0,4,8,12 {
} case 1: case 2: case 4: case 8: KeyNo+=0;break;KeyNo+=4;break;KeyNo+=8;break;KeyNo+=12;} //蜂鸣器 void Beep()上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例
{
uchar i;for(i=0;i<100;i++){
} DelayMS(1);BEEP=~BEEP;BEEP=0;} //主程序 void main(){ P0=0x00;
} BEEP=0;while(1){
} P1=0xf0;if(P1!=0xf0)Keys_Scan();//获取键序号 if(Pre_KeyNo!=KeyNo){
} P0=~DSY_CODE[KeyNo];Beep();Pre_KeyNo=KeyNo;DelayMS(100);18 开关控制LED
/* 名称:开关控制LED 说明:开关S1和S2分别控制LED1和LED2。*/ #include
while(1){ LED1=S1;上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例
} } LED2=S2;19 继电器控制照明设备
/* 名称:继电器控制照明设备
说明:按下K1灯点亮,再次按下时灯熄灭 */ #include
void DelayMS(uint ms){ uchar t;while(ms--)for(t=0;t<120;t++);} //主程序 void main(){
} 数码管显示拨码开关编码
/* 名称:数码管显示拨码开关编码
*/ #include
} if(K1==0){
} while(K1==0);RELAY=~RELAY;DelayMS(20);说明:系统显示拨码开关所设置的编码000~255 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例
#define uint unsigned int //各数字的数码管段码(共阴)
uchar code DSY_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//显示缓冲
uchar DSY_Buffer[3]={0,0,0};//延时
void DelayMS(uint ms){ uchar t;while(ms--)for(t=0;t<120;t++);} //主程序 void main(){
} uchar i,m,Num;P0=0xff;P2=0xff;while(1){
} m=0xfe;Num=P1;//读取拨码开关的值 DSY_Buffer[0]=Num/100;DSY_Buffer[1]=Num/10%10;DSY_Buffer[2]=Num%10;for(i=0;i<3;i++)//刷新显示在数码管上 {
} m=_crol_(m,1);P2=m;P0=DSY_CODE[DSY_Buffer[i]];DelayMS(10);开关控制报警器
/* 名称:开关控制报警器 说明:用K1开关控制报警器,程序控制P1.0输出两种不同频率的声音,模拟很逼真的报警效果 */ #include
void Alarm(uchar t){
} void main(){
} 按键发音
/* 名称:按键发音
说明:按下不同的按键会是SOUNDER发出不同频率的声音。本例使用延时函数实现不同频率的声音输出,以后也可使用定时器 */ #include
void DelayMS(uint x){ uchar t;SPK=0;while(1){
} if(K1==1){
} Alarm(90);Alarm(120);uchar i,j;for(i=0;i<200;i++){
} SPK=~SPK;for(j=0;j while(x--)for(t=0;t<120;t++);} //按周期t发音 void Play(uchar t){ 上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例 uchar i;for(i=0;i<100;i++){ BEEP=~BEEP; DelayMS(t);} BEEP=0;} void main(){ P1=0xff;BEEP=0;while(1){ if(K1==0)Play(1); if(K2==0)Play(2); if(K3==0)Play(3); if(K4==0)Play(4);} } 播放音乐 /* 名称:播放音乐 说明:程序运行时播放生日快乐歌,未使用定时器中断,所有频率完全用延时实现 */ #include uchar code SONG_TONE[]={212,212,190,212,159,169,212,212,190,212,142,159,212,212,106,126,159,169,190,119,119,126,159,142,159,0};//生日快乐歌节拍表,节拍决定每个音符的演奏长短 uchar code SONG_LONG[]={9,3,12,12,12,24,9,3,12,12,12,24,9,3,12,12,12,12,12,9,3,12,12,12,24,0};//延时 void DelayMS(uint x){ uchar t;while(x--)for(t=0;t<120;t++);} //播放函数 void PlayMusic(){ 上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例 } uint i=0,j,k;while(SONG_LONG[i]!=0||SONG_TONE[i]!=0){ //播放各个音符,SONG_LONG为拍子长度 } for(j=0;j } DelayMS(10);i++;BEEP=~BEEP;//SONG_TONE延时表决定了每个音符的频率 for(k=0;k } BEEP=0;while(1){ } PlayMusic();//播放生日快乐 DelayMS(500);//播放完后暂停一段时间 INT0中断计数 /* 名称:INT0中断计数 说明:每次按下计数键时触发INT0中断,中断程序累加计数,计数值显示在3只数码管上,按下清零键时数码管清零 */ #include uchar code DSY_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};//计数值分解后各个待显示的数位 uchar DSY_Buffer[]={0,0,0};uchar Count=0;sbit Clear_Key=P3^6;//数码管上显示计数值 void Show_Count_ON_DSY(){ DSY_Buffer[2]=Count/100;//获取3个数 上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例 DSY_Buffer[1]=Count%100/10;DSY_Buffer[0]=Count%10;if(DSY_Buffer[2]==0) //高位为0时不显示 { } P0=DSY_CODE[DSY_Buffer[0]];P1=DSY_CODE[DSY_Buffer[1]];DSY_Buffer[2]=0x0a;if(DSY_Buffer[1]==0) //高位为0,若第二位为0同样不显示 DSY_Buffer[1]=0x0a;P2=DSY_CODE[DSY_Buffer[2]];} //主程序 void main(){ P0=0x00;P1=0x00;P2=0x00;IE=0x81;//允许INT0中断 IT0=1;//下降沿触发 while(1){ if(Clear_Key==0)Count=0;//清0 Show_Count_ON_DSY();} } //INT0中断函数 void EX_INT0()interrupt 0 { Count++;//计数值递增 } 外部INT0中断控制LED /* 名称:外部INT0中断控制LED 说明:每次按键都会触发INT0中断,中断发生时将LED状态取反,产生LED状态由按键控制的效果 */ #include { LED=1;EA=1;EX0=1;IT0=1;while(1);} //INT0中断函数 void EX_INT0()interrupt 0 { } INT0及INT1中断计数 /* 名称:INT0及INT1中断计数 说明:每次按下第1个计数键时,第1组计数值累加并显示在右边3只数码管上,每次按下第2个计数键时,第2组计数值累加并显示在左边3只数码管上,后两个按键分别清零。*/ #include uchar code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};uchar code DSY_Scan_Bits[]={0x20,0x10,0x08,0x04,0x02,0x01};//2组计数的显示缓冲,前3位一组,后3位一组 uchar data Buffer_Counts[]={0,0,0,0,0,0};uint Count_A,Count_B=0;//延时 void DelayMS(uint x){ uchar t;while(x--)for(t=0;t<120;t++);LED=~LED;//控制LED亮灭 } //数据显示 void Show_Counts(){ uchar i;Buffer_Counts[2]=Count_A/100;Buffer_Counts[1]=Count_A%100/10;Buffer_Counts[0]=Count_A%10;上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例 if(Buffer_Counts[2]==0){ Buffer_Counts[2]=0x0a;if(Buffer_Counts[1]==0) Buffer_Counts[1]=0x0a;} Buffer_Counts[5]=Count_B/100;Buffer_Counts[4]=Count_B%100/10;Buffer_Counts[3]=Count_B%10;if(Buffer_Counts[5]==0){ Buffer_Counts[5]=0x0a; if(Buffer_Counts[4]==0) Buffer_Counts[4]=0x0a;} for(i=0;i<6;i++){ P2=DSY_Scan_Bits[i]; P1=DSY_CODE[Buffer_Counts[i]];DelayMS(1);} } //主程序 void main(){ IE=0x85;PX0=1;//中断优先 IT0=1;IT1=1;while(1){ if(K3==0)Count_A=0; if(K4==0)Count_B=0; Show_Counts();} } //INT0中断函数 void EX_INT0()interrupt 0 { Count_A++; } //INT1中断函数 void EX_INT1()interrupt 2 { Count_B++; 上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例 } 定时器控制单只LED /* 名称:定时器控制单只LED 说明:LED在定时器的中断例程控制下不断闪烁。*/ #include void main(){ TMOD=0x00; //定时器0工作方式0 TH0=(8192-5000)/32;//5ms定时 TL0=(8192-5000)%32;IE=0x82;//允许T0中断 TR0=1;while(1);} //T0中断函数 void LED_Flash()interrupt 1 { } TH0=(8192-5000)/32;//恢复初值 TL0=(8192-5000)%32;if(++T_Count==100)//0.5s开关一次LED { } LED=~LED;T_Count=0;TIMER0控制流水灯 /* 名称:TIMER0控制流水灯 说明:定时器控制P0、P2口的LED滚动显示,本例未使用中断函数。*/ #include //主程序 void main(){ uchar T_Count=0;P0=0xfe;P2=0xfe;TMOD=0x01; TH0=(65536-40000)/256; //定时器0工作方式1 //40ms定时 TL0=(65536-40000)%256;TR0=1; //启动定时器 while(1){ if(TF0==1) { } TF0=0;TH0=(65536-40000)/256;//恢复初值 TL0=(65536-40000)%256;if(++T_Count==5){ } P0=_crol_(P0,1);P2=_crol_(P2,1);T_Count=0;} } 定时器控制4个LED滚动闪烁 /* 名称:定时器控制4个LED滚动闪烁 说明:4只LED在定时器控制下滚动闪烁。*/ #include 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例 TMOD=0x02; TH0=256-200;TL0=256-200;IE=0x82;TR0=1;//定时器0工作方式2 //200us定时 //启动定时器 while(1);} //T0中断函数 void LED_Flash_and_Scroll()interrupt 1 { if(++k<35)k=0;switch(i){ case 0: case 1: case 2: B1=~B1;break;G1=~G1;break;R1=~R1;break;return; //定时中断若干次后执行闪烁 case 3: Y1=~Y1;break;default:i=0;} if(++j<300)return;//每次闪烁持续一段时间 j=0;P0=0xff;//关闭显示 i++;//切换到下一个LED } T0控制LED实现二进制计数 /* 名称:T0控制LED实现二进制计数 说明:本例对按键的计数没有使用查询法,没有使用外部中断函数,没有使用定时或计数中断函数。而是启用了计数器,连接在T0引脚的按键每次按下时,会使计数寄存器的值递增,其值通过LED以二进制形式显示 */ #include void main(){ TMOD=0x05;//定时器0为计数器,工作方式1,最大计数值65535 TH0=0;//初值为0 TL0=0;TR0=1;while(1)上海师范大学信息与机电工程学院—倪继锋 //启动定时器 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例 { } P1=TH0;P2=TL0;} TIMER0与TIMER1控制条形LED /* 名称:TIMER0与TIMER1控制条形LED 说明:定时器T0定时控制上一组条形LED,滚动速度较快 定时器T1定时控制下一组条形LED,滚动速度较慢 */ #include TH0=(65536-15000)/256; //定时器0:15ms //定时器1:50ms TL0=(65536-15000)%256;TH1=(65536-50000)/256;TL1=(65536-50000)%256;IE=0x8a;TR0=1;//启动定时器 TR1=1;while(1);} //T0中断函数 void Time0()interrupt 1 { TH0=(65536-15000)/256; //恢复定时器0初值 TL0=(65536-15000)%256;if(++tc0==10) //150ms转换状态 { tc0=0;P0=_crol_(P0,1);} } //T1中断函数 上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例 void Time1()interrupt 3 { TH0=(65536-50000)/256; } 10s的秒表 //恢复定时器1初值 TL0=(65536-50000)%256;if(++tc1==10) //500ms转换状态 { } tc1=0;P2=_crol_(P2,1); /* 名称:10s的秒表 说明:首次按键计时开始,再次按键暂停,第三次按键清零。*/ #include void DelayMS(uint ms){ uchar t;while(ms--)for(t=0;t<120;t++);} //处理按键事件 void Key_Event_Handle(){ if(Key_State==0){ Key_Flag_Idx=(Key_Flag_Idx+1)%3;switch(Key_Flag_Idx){ } case 1: case 2: case 0: EA=1;ET0=1;TR0=1;break;EA=0;ET0=0;TR0=0;break;P0=0x3f;P2=0x3f;i=0;Second_Counts=0; 上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例 } } //主程序 void main(){ P0=0x3f;//显示00 P2=0x3f;i=0;Second_Counts=0; Key_Flag_Idx=0; //按键次数(取值0,1,2,3) Key_State=1; //按键状态 TMOD=0x01;//定时器0方式1 TH0=(65536-50000)/256; //定时器0:15ms TL0=(65536-50000)%256;while(1){ if(Key_State!=K1) { DelayMS(10); Key_State=K1; Key_Event_Handle();} } } //T0中断函数 void DSY_Refresh()interrupt 1 { TH0=(65536-50000)/256;//恢复定时器0初值 TL0=(65536-50000)%256;if(++i==2) //50ms*2=0.1s转换状态 { i=0; Second_Counts++; P0=DSY_CODE[Second_Counts/10]; P2=DSY_CODE[Second_Counts%10]; if(Second_Counts==100)Second_Counts=0; //满100(10s)后显示00 } } 用计数器中断实现100以内的按键计数 /* 名称:用计数器中断实现100以内的按键计数 说明:本例用T0计数器中断实现按键技术,由于计数寄存器初值为1,因此 P3.4引脚的每次负跳变都会触发T0中断,实现计数值累加。 计数器的清零用外部中断0控制。 上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例 */ #include code DSY_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};uchar Count=0;//主程序 void main(){ P0=0x00; //计数器T0方式2 //计数值为1 //允许T0中断 //允许INT0中断 //允许CPU中断 P2=0x00;TMOD=0x06;TH0=TL0=256-1;ET0=1; EX0=1; EA=1; IP=0x02;IT0=1;TR0=1;while(1){ //设置优先级,T0高于INT0 //INT0中断触发方式为下降沿触发 //启动T0 P0=DSY_CODE[Count/10];P2=DSY_CODE[Count%10];} } //T0计数器中断函数 void Key_Counter()interrupt 1 { Count=(Count+1)%100;//因为只有两位数码管,计数控制在100以内(00~99)} //INT0中断函数 void Clear_Counter()interrupt 0 { } Count=0; 上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例 100 000s以内的计时程序 /* 名称:100 000s以内的计时程序 说明:在6只数码管上完成0~99 999.9s。*/ #include code DSY_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//6只数码管上显示的数字 uchar Digits_of_6DSY[]={0,0,0,0,0,0};uchar Count;sbit Dot=P0^7;//延时 void DelayMS(uint ms){ uchar t;while(ms--)for(t=0;t<120;t++);} //主程序 void main(){ uchar i,j;P0=0x00;P3=0xff; Count=0;TMOD=0x01; TH0=(65536-50000)/256; //计数器T0方式1 //50ms定时 TL0=(65536-50000)%256;IE=0x82;TR0=1; //启动T0 while(1){ j=0x7f;//显示Digits_of_6DSY[5]~Digits_of_6DSY[0]的内容 //前面高位,后面低位,循环中i!=-1亦可写成i!=0xff for(i=5;i!=-1;i--){ j=_crol_(j,1); 上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例 P3=j;P0=DSY_CODE[Digits_of_6DSY[i]];if(i==1)Dot=1;//加小数点 DelayMS(2); } } } //T0中断函数 void Timer0()interrupt 1 { uchar i;TH0=(65536-50000)/256;TL0=(65536-50000)%256;if(++Count!=2)return;Count=0;Digits_of_6DSY[0]++;//0.1s位累加 for(i=0;i<=5;i++)//进位处理 { if(Digits_of_6DSY[i]==10){ Digits_of_6DSY[i]=0;if(i!=5)Digits_of_6DSY[i+1]++; //如果0~4位则分别向高一位进位 //若某低位没有进位,怎循环提前结束 //恢复初值 } else break;} } 定时器控制数码管动态显示 /* 名称:定时器控制数码管动态显示 说明:8个数码管上分两组动态显示年月日与时分秒,本例的位显示延时用定时器实现。*/ #include uchar code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf};//待显示的数据:09-12-25与23-59-58(分两组显示) uchar code Table_of_Digits[][8]={{0,9,10,1,2,10,2,5},{2,3,10,5,9,10,5,8}};uchar i,j=0; 上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例 uint t=0;//主程序 void main(){ P3=0x80; //位码初值 TMOD=0x00; //计数器T0方式0 TH0=(8192-4000)/32;//4ms定时 TL0=(8192-4000)%32;IE=0x82;TR0=1; //启动T0 while(1);} //T0中断函数控制数码管刷新显示 void DSY_Show()interrupt 1 { TH0=(8192-4000)/32;//恢复初值 TL0=(8192-4000)%32;P0=0xff; //输出位码和段码 P0=DSY_CODE[Table_of_Digits[i][j]];P3=_crol_(P3,1); j=(j+1)%8; //数组第i行的下一字节索引 if(++t!=350)return;//保持刷新一段时间 t=0;i=(i+1)%2; //数组行i=0时显示年月日,i=1时显示时分秒 } 8X8LED点阵显示数字 /* 名称:8X8LED点阵显示数字 说明:8X8LED点阵屏循环显示数字0~9,刷新过程由定时器中断完成。*/ #include 0x00,0x3e,0x41,0x41,0x41,0x3e,0x00,0x00, 0x00,0x00,0x00,0x21,0x7f,0x01,0x00,0x00, 0x00,0x27,0x45,0x45,0x45,0x39,0x00,0x00, 0x00,0x22,0x49,0x49,0x49,0x36,0x00,0x00, 0x00,0x0c,0x14,0x24,0x7f,0x04,0x00,0x00,//0 //1 //2 //3 //4 上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例 0x00,0x72,0x51,0x51,0x51,0x4e,0x00,0x00, 0x00,0x3e,0x49,0x49,0x49,0x26,0x00,0x00, 0x00,0x40,0x40,0x40,0x4f,0x70,0x00,0x00, 0x00,0x36,0x49,0x49,0x49,0x36,0x00,0x00,//5 //6 //7 //8 //9 0x00,0x32,0x49,0x49,0x49,0x3e,0x00,0x00 };uchar i=0,t=0,Num_Index;//主程序 void main(){ P3=0x80; Num_Index=0;TMOD=0x00; //从0开始显示 //T0方式0 //2ms定时 TH0=(8192-2000)/32;TL0=(8192-2000)%32;IE=0x82;TR0=1; //启动T0 while(1);} //T0中断函数 void LED_Screen_Display()interrupt 1 { TH0=(8192-2000)/32;//恢复初值 } 按键控制8X8LED点阵屏显示图形 /* 名称:按键控制8X8LED点阵屏显示图形 说明:每次按下K1时,会使8X8LED点阵屏循环显示不同图形。 本例同时使用外部中断和定时中断。*/ #include 上海师范大学信息与机电工程学院—倪继锋 TL0=(8192-2000)%32;P0=0xff; //输出位码和段码 P0=~Table_of_Digits[Num_Index*8+i];P3=_crol_(P3,1); if(++i==8)i=0; //每屏一个数字由8个字节构成 if(++t==250){ } //每个数字刷新显示一段时间 t=0;if(++Num_Index==10)Num_Index=0;//显示下一个数字 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例 #include uchar code M[][8]= { {0x00,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x00}, //图1 {0x00,0x38,0x44,0x54,0x44,0x38,0x00,0x00}, //图2 {0x00,0x20,0x30,0x38,0x3c,0x3e,0x00,0x00} //图3 };uchar i,j;//主程序 void main(){ P0=0xff;P1=0xff; TMOD=0x01; //T0方式1 TH0=(65536-2000)/256;//2ms定时 TL0=(65536-2000)%256;IT0=1; //下降沿触发 IE=0x83; //允许定时器0、外部0中断 i=0xff;//i的初值设为0xff,加1后将从0开始 while(1);} //T0中断控制点阵屏显示 void Show_Dot_Matrix()interrupt 1 { TH0=(65536-2000)/256;//恢复初值 TL0=(65536-2000)%256;P0=0xff; //输出位码和段码 P0=~M[i][j];P1=_crol_(P1,1); j=(j+1)%8;} //INT0中断(定时器由键盘中断启动)void Key_Down()interrupt 0 { P0=0xff;P1=0x80;j=0;i=(i+1)%3; //i在0,1,2中取值,因为只要3个图形 TR0=1;} 用定时器设计的门铃 上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例 /* 名称:用定时器设计的门铃 */ #include DoorBell=0;TMOD=0x00;//T0方式0 说明:按下按键时蜂鸣器发出叮咚的门铃声。 TH0=(8192-700)/32;//700us定时 TL0=(8192-700)%32;IE=0x82;while(1){ if(Key==0){ //按下按键启动定时器 TR0=1;while(Key==0); } } } //T0中断控制点阵屏显示 void Timer0()interrupt 1 { DoorBell=~DoorBell;p++;if(p<400) //若需要拖长声音,可以调整400和800 { } { } else { TR0=0; 上海师范大学信息与机电工程学院—倪继锋 TH0=(8192-700)/32;//700us定时 TL0=(8192-700)%32; else if(p<800)TH0=(8192-1000)/32;//1ms定时 TL0=(8192-1000)%32;《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例 } } p=0;39 演奏音阶 /* 名称:演奏音阶 说明:本例使用定时器演奏一段音阶,播放由K1控制。*/ #include //音符索引 //14个音符放在方式2下的定时寄存器(TH0,TL0) uchar code HI_LIST[]={0,226,229,232,233,236,238,240,241,242,244,245,246,247,248};uchar code LO_LIST[]={0,4,13,10,20,3,8,6,2,23,5,26,1,4,3};//定时器0中断函数 void T0_INT()interrupt 1 { TL0=LO_LIST[i];TH0=HI_LIST[i];SPK=~SPK;} //延时 void DelayMS(uint ms){ uchar t;while(ms--)for(t=0;t<120;t++);} //主程序 void main(){ TMOD=0x00;IE=0x82;SPK=0;while(1){ //T0方式0 while(K1==1);while(K1==0);for(i=1;i<15;i++){ //未按键等待 //等待释放 上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例 } } } TR0=1; DelayMS(500);TR0=0;DelayMS(50); //播放一个音符 //播放延时 按键控制定时器选播多段音乐 /* 名称:按键控制定时器选播多段音乐 说明:本例内置3段音乐,K1可启动停止音乐播放,K2用于选择音乐段。*/ #include sbit SPK=P3^7;//播放和停止键 //蜂鸣器 //当前音乐段索引,音符索引 uchar Song_Index=0,Tone_Index=0;//数码管段码表 uchar code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//标准音符频率对应的延时表 uchar code HI_LIST[]={0,226,229,232,233,236,238,240,241,242,244,245,246,247,248};uchar code LO_LIST[]={0,4,13,10,20,3,8,6,2,23,5,26,1,4,3};//三段音乐的音符 uchar code Song[][50]= { {1,2,3,1,1,2,3,1,3,4,5,3,4,5,5,6,5,3,5,6,5,3,5,3,2,1,2,1,-1}, {3,3,3,4,5,5,5,5,6,5,3,5,3,2,1,5,6,53,3,2,1,1,-1}, {3,2,1,3,2,1,1,2,3,1,1,2,3,1,3,4,5,3,4,5,5,6,5,3,5,3,2,1,3,2,1,1,-1} };//三段音乐的节拍 uchar code Len[][50]= { {1,1,1,1,1,1,1,1,1,1,2,1,1,2,1,1,1,1,1,1,1,1,1,1,1,2,1,2,-1}, {1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,2,2,-1}, {1,1,2,1,1,2,1,1,1,1,1,1,1,1,1,1,2,1,1,2,1,1,1,1,1,1,1,2,1,1,2,2,-1} };//外部中断0 void EX0_INT()interrupt 0 { TR0=0;//播放结束或者播放中途切换歌曲时停止播放 Song_Index=(Song_Index+1)%3;//跳到下一首的开头 上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例 Tone_Index=0;P2=DSY_CODE[Song_Index]; //数码管显示当前音乐段号 } //定时器0中断函数 void T0_INT()interrupt 1 { TL0=LO_LIST[Song[Song_Index][Tone_Index]];TH0=HI_LIST[Song[Song_Index][Tone_Index]];SPK=~SPK;} //延时 void DelayMS(uint ms){ uchar t;while(ms--)for(t=0;t<120;t++);} //主程序 void main(){ P2=0xc0;SPK=0;TMOD=0x00; //T0方式0 IE=0x83;IT0=1;IP=0x02;while(1){ while(K1==1);//未按键等待 while(K1==0); //等待释放 TR0=1; //开始播放 Tone_Index=0;//从第0个音符开始 //播放过程中按下K1可提前停止播放(K1=0)。 //若切换音乐段会触发外部中断,导致TR0=0,播放也会停止 while(Song[Song_Index][Tone_Index]!=-1&&K1==1&&TR0==1) { DelayMS(300*Len[Song_Index][Tone_Index]);//播放延时(节拍) Tone_Index++;//当前音乐段的下一音符索引 } TR0=0; //停止播放 while(K1==0);//若提前停止播放,按键未释放时等待 } } 定时器控制交通指示灯 上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例 /* 名称:定时器控制交通指示灯 说明:东西向绿灯亮5s后,黄灯闪烁,闪烁5次亮红灯,红灯亮后,南北向由红灯变成绿灯,5s后南北向黄灯闪烁,闪烁5次后亮红灯,东西向绿灯亮,如此往复。 */ #include uchar Time_Count=0,Flash_Count=0,Operation_Type=1;//定时器0中断函数 void T0_INT()interrupt 1 { TL0=-50000/256;TH0=-50000%256;switch(Operation_Type){ case 1: //东西向绿灯与南北向红灯亮5s RED_A=0;YELLOW_A=0;GREEN_A=1;RED_B=1;YELLOW_B=0;GREEN_B=0;if(++Time_Count!=100)return;//5s(100*50ms)切换 Time_Count=0;Operation_Type=2;break;//东西向黄灯开始闪烁,绿灯关闭 if(++Time_Count!=8)return;Time_Count=0;YELLOW_A=~YELLOW_A;GREEN_A=0;if(++Flash_Count!=10)return;//闪烁 Flash_Count=0;Operation_Type=3;break; //东西向红灯与南北向绿灯亮5s RED_A=1;YELLOW_A=0;GREEN_A=0;RED_B=0;YELLOW_B=0;GREEN_B=1;if(++Time_Count!=100)return;//5s(100*50ms)切换 Time_Count=0;Operation_Type=4; 上海师范大学信息与机电工程学院—倪继锋 case 2: case 3: 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例 } case 4: break;//南北向黄灯开始闪烁,绿灯关闭 if(++Time_Count!=8)return;Time_Count=0;YELLOW_B=~YELLOW_B;GREEN_A=0;if(++Flash_Count!=10)return;//闪烁 Flash_Count=0;Operation_Type=1;break; } //主程序 void main(){ } 报警与旋转灯 /* 名称:报警与旋转灯 说明:定时器控制报警灯旋转显示,并发出仿真警报声。*/ #include void DelayMS(uint ms){ } //INT0中断函数 void EX0_INT()interrupt 0 { TR0=~TR0;//开启或停止两定时器,分别控制报警器的声音和LED旋转 TR1=~TR1;if(P2==0x00) 上海师范大学信息与机电工程学院—倪继锋 TMOD=0x01;IE=0x82;TR0=1;while(1); //T0方式1 uchar i;while(ms--)for(i=0;i<120;i++);《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例 P2=0xe0;//开3个旋转灯 else P2=0x00;//关闭所有LED } //定时器0中断 void T0_INT()interrupt 1 { TH0=0xfe;TL0=FRQ;SPK=~SPK;} //定时器1中断 void T1_INT()interrupt 3 { TH1=-45000/256;TL1=-45000%256;P2=_crol_(P2,1);} //主程序 void main(){ } 串行数据转换为并行数据 /* 名称:串行数据转换为并行数据 说明:串行数据由RXD发送给串并转换芯片74164,TXD则用于输出移位时钟脉冲,74164将串行输入的1字节转换为并行数据,并将转换的数据通过8只LED显示出来。本例串口工作模式0,即移位寄存器I/O模式。*/ 上海师范大学信息与机电工程学院—倪继锋 P2=0x00;SPK=0x00;TMOD=0x11;TH0=0x00;TL0=0xff;IT0=1;IE=0x8b;IP=0x01;TR0=0;TR1=0;while(1){ } FRQ++;DelayMS(1);//T0、T1方式1 //开启0,1,3号中断 //INT0设为最高优先 //定时器启停由INT0控制,初始关闭 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例 #include void DelayMS(uint ms){ uchar i;while(ms--)for(i=0;i<120;i++);} //主程序 void main(){ } uchar c=0x80;SCON=0x00;TI=1;while(1){ } c=_crol_(c,1);SBUF=c;while(TI==0);TI=0; DelayMS(400);//串口模式0,即移位寄存器输入/输出方式 //等待发送结束 //TI软件置位 并行数据转换为串行数据 /* 名称:并行数据转换为串行数据 说明:切换连接到并串转换芯片74LS165的拨码开关,该芯片将并行数据以串行方式发送到8051的RXD引脚,移位脉冲由TXD提供,显示在P0口。*/ #include void DelayMS(uint ms){ 上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例 uchar i;while(ms--)for(i=0;i<120;i++);} //主程序 void main(){ SCON=0x10; } while(1){ } SPL=0;//置数(load),读入并行输入口的8位数据 //串口模式0,允许串口接收 SPL=1;//移位(shift),并口输入被封锁,串行转换开始 while(RI==0);//未接收1字节时等待 RI=0; //RI软件置位 //接收到的数据显示在P0口,显示拨码开关的值 P0=SBUF;DelayMS(20); 甲机通过串口控制乙机LED /* 名称:甲机发送控制命令字符 说明:甲单片机负责向外发送控制命令字符“A”、“B”、“C”,或者停止发送,乙机根据所接收到的字符完成LED1闪烁、LED2闪烁、双闪烁、或停止闪烁。*/ #include sbit LED2=P0^3;sbit K1=P1^0;//延时 void DelayMS(uint ms){ uchar i;while(ms--)for(i=0;i<120;i++);} //向串口发送字符 void Putc_to_SerialPort(uchar c){ SBUF=c;while(TI==0);TI=0; 上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例 } //主程序 void main(){ uchar Operation_No=0;SCON=0x40;//串口模式1 TMOD=0x20;//T1工作模式2 PCON=0x00;//波特率不倍增 TH1=0xfd;TL1=0xfd;TI=0;TR1=1;while(1){ if(K1==0)//按下K1时选择操作代码0,1,2,3 { while(K1==0); Operation_No=(Operation_No+1)%4; } switch(Operation_No)//根据操作代码发送A/B/C或停止发送 { case 0: LED1=LED2=1; break; case 1: Putc_to_SerialPort('A'); LED1=~LED1;LED2=1; break; case 2: Putc_to_SerialPort('B'); LED2=~LED2;LED1=1; break; case 3: Putc_to_SerialPort('C'); LED1=~LED1;LED2=LED1; break; } DelayMS(100);} } /* 名称:乙机程序接收甲机发送字符并完成相应动作 说明:乙机接收到甲机发送的信号后,根据相应信号控制LED完成不同闪烁动作。*/ #include sbit LED2=P0^3;上海师范大学信息与机电工程学院—倪继锋 《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例 //延时 void DelayMS(uint ms){ uchar i;while(ms--)for(i=0;i<120;i++);} //主程序 void main(){ } SCON=0x50;TMOD=0x20;PCON=0x00;TH1=0xfd;TL1=0xfd;RI=0;TR1=1;LED1=LED2=1;while(1){ if(RI) } { //串口模式1,允许接收 //T1工作模式2 //波特率不倍增 //波特率9600 //如收到则LED闪烁 RI=0;switch(SBUF)//根据所收到的不同命令字符完成不同动作 { } //关闭LED case 'A': LED1=~LED1;LED2=1;break;case 'B': LED2=~LED2;LED1=1;break;case 'C': LED1=~LED1;LED2=LED1; //LED1闪烁 //LED2闪烁 //双闪烁 } else LED1=LED2=1;DelayMS(100); 单片机之间双向通信 /* 名称:甲机串口程序 说明:甲机向乙机发送控制命令字符,甲机同时接收乙机发送的数字,并显示在数码管上。*/ #include 上海师范大学信息与机电工程学院—倪继锋 单片机应用课程设计教学大纲 开课学院:机电工程学院 适用专业:电子科学与技术 课程编号:2009404 课程英文名称:Single-chip Microcomputer Application System Design 实验课程总学时:36 实验课程总学分:1 一、课程性质和目的: 单片机原理及应用是一门技术性、应用性很强的学科,实验教学是它的一个极为重要的教学环节,除实验教学环节,单片机课程设计也是重要的实践教学环节,通过这一环节可使学生不但能够将课堂上学到的理论知识与实践应用结合起来,而且能够对电子电路、电子元器件、印制电路板等方面的知识进一步加深认识,同时在软件编程、排错调试、相关仪器设备的使用技能等方面得到较全面的锻炼和提高,为今后能独立进行单片机应用系统的开发设计工作打良好的基础。 二、本课程与其它课程的联系与分工 先修课程:电路分析、模拟电路、数字电路、微机原理、单片机、电子线路常用软件 后续课程:传感器技术、数字信号处理等 三、单片机课程设计的基本要求 1、原则上每生一项设计,不能重复设计。 2、项目大的可多人从事,但每人必须承担足够的设计任务。 3、项目结题需要提供电路图、程序清单、设计说明书等资料,还要提供实物作品,运行照片等。 4、参加科技节展出及评奖的作品,要给与适量的加分。优秀的设计人员优先推荐参加省机电大赛或电子大赛。 5、整个课程设计过程中,严格执行考核制度,对于无故旷课、扰乱课堂秩序、玩游戏、玩手机、不从事设计和制作的行为给予严肃处理。 6、对于课堂表现好的同学,进行加分奖励。 四、课程设计的实施过程 1、基本开发工具的使用 电路设计及仿真运行工具Proteus软件、编程及编译环境Keil uVision软件、程序烧写器的使用及驱动程序的安装。 2、单片机应用系统的搭建方法 电源的设计、振荡电路参数的选择、复位电路的设计、内置及外置程序程序存储器的选择,各端口的驱动能力及接口方法。 3、学生实践能力的摸底测试 通过简单的单片机应用设计,如:流水灯、数码显示、键盘控制等,进行软环境编程测试及硬环境测试。 软环境测试:利用Proteus、Keil C51 进行仿真测试。硬环境测试:搭建具体电路,利用编程器烧写程序,进行调试。 4、选择设计题目 学生可根据自身能力和爱好,选择或自拟设计题目,并进行系统的分析和调研、可行性分析、性价比分析,形成设计任务书。指导教师处备案。 5、确定实施方案 经过方案论证,找出最优化的实施方案。以此评价开发思路。 6、加强指导 指导教师对学生的共性问题进行集中指导,对零散问题进行分别指导。 7、硬件电路设计 根据实施方案,利用Proteus软件设计原理图。原理图的质量作为考核依据。 8、软件设计 根据系统工作过程画出各部分流程图,根据流程图编写程序并进行整合,程序和流程图的质量作为考核依据。 9、仿真调试 编译后的程序加载到原理图上进行仿真,调试,调试成功后的仿真图片作为考核的依据。 10、电路搭建 根据电路原理图设计,进行布线图设计。购买电子元件,焊接线路板,线路板的焊接质量作为考核依据。 11、系统调试 系统调试成功之后,考察功能实现情况,作为考核依据。 12、撰写课程设计论文 要求从选题、论证、设计、仿真、调试、形成作品到感想写入论文内,要符合正规论文格式。 五、考核方案 1、考核分四部分进行:实物作品、课程设计论文、平时成绩、课堂表现 2、实物作品从实现功能和焊接质量进行评分,占总成绩的40%。 3、课程设计论文从论文的规格、要求进行评分,占总成绩的30%。 4、平时成绩就是平时阶段性的检查成绩,占总成绩的20%。 5、课堂表现指出勤、课堂纪律,占总成绩的10%。 6、科技节加分:一等奖5分、二等奖4分、三等奖3分、参展2分。 六、单片机课程设计题目(备选) 1、基于单片机的智能电压表设计 2、基于单片机的LED流水灯系统设计 3、基于单片机的智能船模设计 4、基于单片机的电梯控制模型设计 5、基于单片机的水位控制系统设计 6、基于单片机的多路数据采集系统设计 7、基于单片机的抢答器设计 8、基于单片机的数字温度计设计 9、基于单片机的智能小车设计 10、基于单片机的遥控器设计 11、基于单片机的串行通信发射机设计 12、基于单片机的简易智能电动车设计 13、基于单片机的太阳能热水器控制器设计 14、MCS-51单片机温度控制系统的设计 15、直流电动机的转速检测与脉宽调速 16、基于单片机的智能机器人的设计 17、基于单片机的简易无线竞赛系统的设计 18、基于单片机的车辆闯红灯监控系统设计 19、基于单片机控制的井下瓦斯监控系统设计 20、基于单片机的煤气泄漏检测报警装置设计 21、基于单片机的井式渗碳炉控制系统设计 22、基于单片机的蔬菜大棚温湿度智能控制系统设计 23、基于单片机的电子钟设计 24、基于单片机的液位控制器设计(8051) 25、基于单片机的点阵电子显示屏设计 26、基于单片机的智能寻迹避障小车设计 27、基于单片机的热敏电阻测温系统设计 28、基于单片机的智能型电话远程遥控器设计 29、基于单片机的数控直流电源设计 30、基于单片机的电子万年历设计 31、基于单片机的红外防盗报警器设计 32、基于单片机的花卉温室控温系统设计 33、基于单片机的焊机温度控制系统设计 34、基于单片机的路灯控制器设计 35、基于单片机的车床刀架控制系统设计 36、基于单片机的电机智能综合保护装置设计 37、基于单片机的太阳能热水器控制器设计 38、基于单片机的智能型矿用磁力启动器设计 39、基于单片机的无氧退火炉温控系统设计 40、基于单片机的电厂锅炉过热蒸汽温度监测系统设计 41、基于单片机的摩托车里程表研制 42、基于单片机的自动车库门的设计 43、基于单片机的自动滴灌控制系统的设计 44、基于单片机的预付费电度表设计 45、基于单片机的智能电子秤设计 46、基于单片机的油井巡视定位系统设计 47、基于单片机的照明控制系统 48、基于单片机的锅炉液位控制系统设计 49、基于单片机的洗衣机设计 50、基于单片机的锅炉汽包水位控制系统设计 51、基于单片机的多功能秒表设计 52、基于单片机的无线监护系统的设计 53、基于串行通信的红外线智能家电控制系统 54、基于单片机的智能遥控器设计 56、基于单片机的公用电话网远程控制器的设计 57、基于单片机的多功能节能微波炉控制器设计 58、基于单片机的多功能数显表设计(气压、冲击频率) 59、基于单片机的仓库温湿度测量仪设计 60、基于单片机的自动加料系统 62、基于单片机的远程温度显示系统 63、基于89C51单片机的传感器水位测量系统 64、基于51单片机的广告灯设计 65、基于单片机的水箱水位控制系统设计 66、动态电子秤设计 67、基于单片机的非接触式热量测量系统设计 68、基于单片机的非接触式位移传感器设计 69、基于单片机的非接触式温度测试仪设计 70、基于单片机的工业电加热炉的微机控制系统设计 71、基于单片机的户用超声波热量表设计 72、基于单片机的火灾自动探测报警系统设计 73、基于单片机的住宅智能化险情报警系统设计 74、基于单片机的数字温度测量及显示系统设计 75、火灾自动报警系统设计 76、基于GSM短信模块的家庭防盗报警系统 77、基于GSM模块的车载防盗系统设计 78、基于单片机的16×16点阵(滚动显示)79、基于单片机的仓库温湿度的监测系统 80、基于单片机的点阵电子显示屏设计 81、基于单片机的电子密码锁设计 82、基于单片机的温度远程显示实现 83、基于单片机的直流电机控制系统 84、基于单片机的自动加料机控制系统 85、数控直流稳压电源设计 86、智能型充电器的电源和显示的设计 87、基于CPLD的出租车计价器设计 88、基于IC卡的楼宇门禁系统的设计 89、基于SPCE061A的语音遥控小车设计 90、基于单片机的短信收发系统设计 91、智能机器人的研究与设计(自动循轨和语音控制的实现)92、PC机与单片机的串口通信 93、基于单片机的红外线防盗报警系统 94、基于单片机的转速测量系统设计 95、基于单片机的电梯控制模型设计与仿真 学习参考资料: 1、谢维成 杨加国:《单片机原理与应用及C51程序设计》,清华大学出版社,2009年7月第2版 2、彭伟主编:《单片机C语言程序设计实训100例——基于8051+Proteus仿真》,电子工业出版社,2009年6月第1版 3、周兴华主编:《手把手教你学单片机C程序设计》,北京航空航天大学出版社,2007年10月 第1版 学习参考网站: http://xxgcxy.qdbhu.edu.cn/jsjdlzzsx/index.html http://www.xiexiebang.com 执笔人:陈振军 编写日期:2013年3月5日 审核人: 电气1001班综合实训任务(单片机控制系统运行与维护) 第1题 模拟交通灯 任务要求: 1、主干道绿灯40秒,支干道绿灯20秒,黄灯都是5秒; 2、要求用定时器实现定时时间; 3、要求显示器同步显示主干道时间的倒计时; 4、如果有按键按下,表示有紧急车辆通过(救火车等),2路都亮红灯,蜂鸣器响,如果另外一个按键按下则恢复正常。 第2题 基于单片机的电子秒表 本设计以MCS-51系列单片机为核心,采用常用电子器件设计,一个电源开关,两个按键,三位数码管显示,打开电源开关后显示8,每秒循环左移一位,即□□8—>□8□—>8□□—>□□8—>…,按A键开始计时,实时显示所经历的时间,按B键停止计时并显示从开始到当前时刻的时间,要求精确到0.1秒,量程为0~99.9秒。 要求按键输入采用中断方式,按键A接INT0,按键B接INT1。 第3题 采用单片机和DAC设计波形发生器 任务要求:1 利用单片机和DAC0832产生锯齿波、三角波、正弦波等波形 完成DAC与运放的连接,输出可供示波器显示。3 用按键改变波型的种类,波形的幅值与频率。 第4题 基于单片机的精确时钟 本设计以单片机为核心,采用常用电子器件设计,一个电源开关,1个按键负责设置时间和开始走时,1个按键负责循环递增时间,16位数码管显示,可实时显示年,月,日,时,分,秒,百分秒,要求精确到0.01秒。具有整点播放音乐,并根据时针输出相应次数的嘟嘟声,最后一声较尖锐,为准确整点时间。 要求按键输入采用中断方式,按键A接INT0,按键B接INT1.第5题 智能温控器 本设计以单片机为核心,采用常用电子器件设计,一个电源开关,两个控制温度设定按键(增大 / 减小),四位数码管分别显示设定温度和实际温度,量程为0~99度,打开电源开关后设定温度值初始化为26度。按键输入采用中断方式,两个按键分别接INT0和INT1.采用铂电阻(Pt100)温度传感器进行温度测量,模数转换采用ADC0809.单片机根据设定温度S和实测温度P控制继电器R的动作,死区设为2度: 当P<=S-1时,控制R接通电加热回路; 当P>S+1时,控制R断开电加热回路; 当S-1 第6题 电子密码锁 任务要求: 1、密码锁由4X4键盘和4位数码管组成。 2、当输入密码时,只显示“8.”,当密码位数输入完毕按下确认键时,对输入的密码与设定的密码进行比较,若密码正确,则门开,此处用LED发光二极管亮一秒钟做为提示。若密码不正确,则可以从新输入密码。如连续三次输入错误,则禁止输入。 第7题 抢答器 任务要求: 1、有一主持人和8个参赛队。 2、当主持人按下抢答按键,参赛队在10秒钟内可以抢答。如超过10秒则不能抢答。如抢答成功,则显示抢答的队号。 3、如抢答成功必需在60秒内回答完成。如超过时间则抢答无效,且显示无效指示。如在60秒内回答完成(抢答队再次按下抢答按键表示回答完成)则抢答正确成功,且显示有效。 4、当主持人按下复位按键时,系统回到初始状态。 第8题 篮球比赛计分器 任务要求: 1、能显示2个队的当前比分; 2、根据各自得分情况进行加1、2、3分; 3、显示当前进攻队的进攻时间倒计; 4、计时归零时候鸣响。 第9题 班级投票显示器 任务要求: 1、设计一个投票系统,具有计票显示功能; 2、可实现6人同时进行投票,累计票数在显示器上显示; 3、主持人使用一个按键开关控制开始投票,终止投票和清零; 4、投票开始后每人能且仅能投一次票,多投无效; 第10题 基于单片机的直流电机调速系统 本设计以系列单片机为核心,采用常用电子器件设计,一个启动开关,1个停止开关,1个正向开关,1个反向开关,8位拨码开关负责设置占空比,进行脉冲宽度调制,可实现电动机的正转,反转,刹车,滑行,4种状态,并可根据占空比调节转速。 第11题 基于单片机的锅炉报警系统 本设计以单片机为核心,采用常用电子器件设计,采用蜂鸣器输出声音报警,LED输出红灯报警,并可根据指示灯确定哪个参量越限,6位数码管显示越限参量值,可对锅炉的水位上下限,炉膛温度上下限,蒸汽压力上下限,6个极限值进行报警。 第12题 步进电机控制 任务要求:1 完成单片机与功率驱动电路及小功率步进电机的连接 控制步进电机的转动方向、转动速度及转过指定的角度。3 通过按键改变电机的转向、转速等参数。 单片机实训室安全规章制度 1、学生(学员)进入教室应服从实习指导教师的安排,按指定位置就坐上课。 2、进入教室应换鞋或带好鞋套,并保持室内安静及卫生。 3、操作带电设备时应注意安全,穿好绝缘鞋。 4、不得将与教学无关的东西带入教室。不做与教学无关的事。教室内禁止吃东西,不得将水杯放在操作台及设备上。 5、严禁私自将外来软件带入教室上机运行,一经发现除没收软件外,视情节轻重给予一定的处罚。 6、不得随意开关电源及重启设备,发现异常时应及时与带班老师联系。若因不遵守操作规程而造成设备损坏时,除适当赔偿外,还将视情节轻重给予教育或处分。 7、下课前每位同学(学员)应正常关闭设备,并做好本机位卫生工作。值日生应认真做好教室的卫生工作,离开时应关闭总电源,关好门窗。 8、实验结束后,由辅导教师检查仪器设备有无损坏等情况,认真如实填写使用记录并签字。 9、外来培训人员,需经实验室管理人员批准,并事先安排好时间,学习以 上规章制度后方可进入,并遵守以上管理制度,听从本室工作人指导。 单片机实训室操作规程 1、实训人员要树立“安全第一”的思想,严格遵守安全操作规程。 2、实验人员在实验前,要做好实验预习、并写好预习报告,方可进行实验,接线前先熟悉实验台上各单元、元器件的功能及其接线位置,特别要熟知各单片机引线及接线位置。 3、实验前认真检查电源、线路、设备是否正常,防止事故的发生。 4、实验时,严格按照的实验步骤逐一进行操作,确认一切正常后,由老师检查正确后方可进行通电实验。实验始终,板上要保持整洁,不可随意放置杂物,特别是导电的工具和导线等,以免发生短路等故障。 5、实验时使用到的由外部交流电源供电的仪器(如检测仪器、示波器等),其外壳应有可靠接地。实验中出现异常现象,应立即断电,排除故障后方可继续实验。 6、本实验装置上的直流电源及各信号源原则上仅供实验使用。一般不外接负载或电路。如作它用,要注意使用的负载不能超出本电源或信号源允许的范围。实验完毕后,及时关闭实验桌和仪器设备的电源,将仪器设备和元气件整理好整齐的摆放在实验桌上,并填好学生实验登记表。. 苏州经贸职业技术学院 实训项目1 报警器控制 一、项目要求 调研实际报警器的使用,设计一个应用开关控制报警器发声报警。 二、项目实践技能目标 1.通过项目的训练,锻炼理论联系实际的能力,熟练掌握单片机控制系统,掌握单片机的定时器的技术等知识。 2.掌握C语言或汇编语言。掌握软件延时或定时器延时程序的设计。 3.根据设计要求,在PROTUES开发平台上,完成硬件系统的电路组装,完成系统软件设计要求,并提交程序设计框图和程序清单;完成系统软硬件的综合调试,实现设计要求。 4.通过该项目的训练,提高学生的实际动手操作能力,养成学生的工程道德观念,建立工程敬业精神和团队合作精神。 三、参考电路 苏州经贸职业技术学院 实训项目2 简易音乐播放器设计 一、项目要求 1、用一个按键实现选定播放的音乐段,在播放的过程中可用此按键暂停; 2、用另一个按键选择待播放的几段音乐中的一段; 3、选择的曲目可以在数码管上显示。 二、项目实践技能目标 1、通过该项目的训练巩固单片机定时器技术、中断技术的应用; 2、学会C语言中二维数组的使用,学习音乐索引和节拍的设计,学习通过每个高脉冲或低脉冲的延时形成某种频率的声音输出方法,学习控制每个不同频率声音输出的时间长短形成节拍的方法,学习高低音的方法等。 3、根据设计要求,在PROTUES开发平台上,完成硬件系统的电路组装,完成系统软件设计要求,并提交程序设计框图和程序清单;完成系统软硬件的综合调试,实现设计要求。 4、通过该项目的训练,提高学生的实际动手操作能力,养成学生的工程道德观念,建立工程敬业精神和团队合作精神。 三、参考电路 四、思考题 苏州经贸职业技术学院 设计一个音乐门铃。 实训项目3 单片机之间双向通信 一、项目要求 两片单片机工作于串口模式1,整个系统实现双机双向通信; 工作任务: 1.甲机的K1按键可通过串口分别控制乙机的LED1点亮,LED2点亮,LED1和LED2全亮或全灭.2.乙机按键可向甲机发送数字,甲机接收上午数字显示在其P0端口的数码管上。 应用软件完成硬件电路的设计并实现电气意义;完成软件设计;并实现仿真调试或实物调试。 二、项目实践技能目标 1.通过实际项目,来理解和掌握串行通信基本知识,串行口及应用技术等知识。2.根据设计要求,在PROTUES开发平台上,完成硬件系统的电路组装,完成系统软件设计要求,并提交程序设计框图和程序清单;完成系统软硬件的综合调试,实现设计要求。 3.通过该项目的训练,提高学生的实际动手操作能力,养成学生的工程道德观念,建立工程敬业精神和团队合作精神。 4.核心技能教学目标:培养学生的对于通信的概念理解和掌握,在教学中注意引导学生自己提出问题,分析问题,培养他们独立解决问题的能力,培养学生融合课程间知识的相关联系能力,以及外语能力和再学习能力,并培养学生质疑精神。 5.考核标准:单片机串行通信基本知识;串行口及应用技术的基本知识30%;硬件连接及PROTUES使用10%;软件设计20%;系统调试20%;回答问题10%;创新能力(在原有基础上有能力拓展)10%。 三、参考电路 苏州经贸职业技术学院 四、思考题 1.如何实现双工通信?试编写通讯程序。 2.如何利用中断方式实现串行通讯?试编写通讯程序。 实训项目4 8*8LED点阵屏显示数据 一、项目要求 8*8LED点阵屏循环显示数字0~9; 刷新过程由定时器中断完成。 二、项目实践技能目标 1.通过项目的训练,掌握点阵屏的结构以及与单片机的接口技术;掌握点阵屏形成的字符编码。 2.根据设计要求,在PROTUES开发平台上,完成硬件系统的电路组装,完成系统软件设计要求,并提交程序设计框图和程序清单;完成系统软硬件的综合调试,实现设计要求。 苏州经贸职业技术学院 3.通过该项目的训练,提高学生的实际动手操作能力,养成学生的工程道德观念,建立工程敬业精神和团队合作精神。 三、基础知识点 LED显示屏是将发光二极管按行按列布置的,驱动时也就按行按列驱动。在扫描驱动方式下可以按行扫描按列控制,当然也可以按列扫描按行控制。LED显示屏现多采用多块8X8点阵显示单元拼接而成。8X8点阵LED结构如图其等效电路如图所示,8X8点阵LED结构图 从图中可以看出,8X8点阵共需要64个发光二极管组成,且每个发光二极管是放置在行线和列线的交叉点上。要实现显示图形或字体,只需考虑其显示方式,通过编程控制各显示点对应LED阳极和阴极端的电平,就可以有效的控制各显示点的亮灭。当采用按行扫描按列控制的驱动方式时,LED显示屏8行的同名列共用一套列驱动器。行驱动器一行的行线连接到电源的一端,列驱动器一列的列线连接到电源的另一端。应用时还应在各条行线或列线上接上限流电阻。扫描中控制电路将行线的1到 8轮流接通高电位,使连接到各该行的全部LED器件接通正电源,但具体那一个LED导通,还要看它的负电源是否接通,这就是列控制的任务了。当对应的某一列置0电平,则相应的二极管就亮;反之则不亮。例如:如果想使屏幕左上角LED点亮,左下角LED熄灭的话,在扫描到第一行时,第 8X8点阵LED等效电路图 一列的电位就应该为低,而扫描到第八行时第一列的电位就应该为高。这样行线上一行一行的轮流导通,列线上进行通断控制,实现了行扫描列控制的驱动方式。 0x00,0x3C,0x66,0x42,0x42,0x66,0x3C,0x00 显示0 0x00,0x08,0x38,0x08,0x08,0x88,0x3E,0x00 显示1 0x00,0x3C,0x42,0x04,0x08,0x32,0x7E,0x00 显示2 0x00,0x3C,0x42,0x1C,0x02,0x42,0x3C,0x00 显示3 0x00,0x0C,0x14,0x24,0x44,0x3C,0x0C,0x00 显示4 0x00,0x7E,0x40,0x7C,0x02,0x42,0x3C,0x00 显示5 0x00,0x3C,0x40,0x7C,0x42,0x42,0x3C,0x00 显示6 0x00,0x7E,0x44,0x08,0x10,0x10,0x10,0x00 显示7 0x00,0x3C,0x42,0x24,0x5C,0x42,0x3C,0x00 显示8 苏州经贸职业技术学院 0x00,0x38,0x46,0x42,0x3E,0x06,0x3C,0x00 显示9 四、参考电路 五、思考题 1.完整显示一个汉字需要几个8*8LED点阵屏?汉字的编码怎样形成?试编写汉字显示程序。 实训项目5 ADC0809 实现输出PWM波形 一、项目要求 调节ADC0809(ADC0808)芯片的0通道输入的可变电阻器,从而实现控制输出脉冲的占空比变化(0%~100%),从而实现脉冲宽度调制(PWM)。 二、项目实践技能目标 1.通过项目的训练,理解数据采集技术; 2.学会A/D转换器的结构和原理,及与单片机的接口技术,掌握软件设计技术。3.巩固单片机基础知识点。 苏州经贸职业技术学院 4.根据设计要求,在PROTUES开发平台上,完成硬件系统的电路组装,完成系统软件设计要求,并提交程序设计框图和程序清单;完成系统软硬件的综合调试,实现设计要求。 三、参考电路 4.思考题 对于代码中两个if语句,如果去掉这几句语句,观察一下示波器的输出波形,读者思考两个if语句有什么作用?如果不用中断子程序提供时钟信号,如何实现该功能? 实训项目6 数字波形信号的合成技术 一、项目要求 利用数字波形信号的合成技术来生成正弦波。 二、程序设计思路和实现过程 数字波形合成技术是一个斜升波的合成过程,它根据已设定的输出波形参数,先由CPU算出输出波形数据并存入ROM中,再将输出波形在采样点的ROM中的数字值依次通过D/A转换器转换为模拟量输出。要采用数字波形合成技术产生工频正弦信号,可预 苏州经贸职业技术学院 先将一个周期的正弦信号分成K个点,经计算求得各点的幅值并数字量化后存于RAM(或程序的数组)中。若需输出波形时,按照一定的频率从RAM中取出每点的量化值送D/A,D/A就可恢复原来一个周期的完整正弦波信号,经过连续的循环即可得到连续的正弦信号输出。 工频信号的输出频率可由式fout=fc/K确定,其中fc为采样(取点)频率,K为一周期所分割的点数。本设计中为了使相位设置方便,把正弦波每周期分成了180个点,所以K=180,那么在K不变的情况下,可以通过改变采样频率fc,就可改变输出频率值。程序设计过程类似于锯齿波的产生设计过程,关键是每点的D/A值的确定。 三、项目实践技能目标 1.通过项目的训练,理解数据采集技术; 2.学会D/A转换器的结构和原理,及与单片机的接口技术,掌握软件设计技术。3.巩固单片机基础知识点。 4.根据设计要求,在PROTUES开发平台上,完成硬件系统的电路组装,完成系统软件设计要求,并提交程序设计框图和程序清单;完成系统软硬件的综合调试,实现设计要求。 三、参考电路 RP110k1U119XTAL1P0.0/AD0P0.1/AD1P0.2/AD2P0.3/AD3P0.4/AD4P0.5/AD5P0.6/AD6P0.7/AD7P2.0/A8P2.1/A9P2.2/A10P2.3/A11P2.4/A12P2.5/A13P2.6/A14P2.7/A15P3.0/RXDP3.1/TXDP3.2/INT0P3.3/INT1P3.4/T0P3.5/T1P3.6/WRP3.7/RD*********617S1S2S1123D34D25D16D07VREF8910D0D1D2D3D4D5D6D72019***3121123456789R4RV11k100%+12ABVREFCD18XTAL29RSTU210kS2D4D5D6D7238R51k293031PSENALEEA12345678P1.0/T2P1.1/T2EXP1.2P1.3P1.4P1.5P1.6P1.7AT89C52CSVCCWR1ILE(BY1/BY2)GNDWR2DI3XFERDI2DI4DI1DI5DI0DI6VREFDI7RFBIOUT2GNDIOUT1DAC0832R2-1215kR315k4U3:A1TL0824R17.5k658U3:B7TL082+12 图7-1 数字波形信号的合成技术仿真电路图 苏州经贸职业技术学院 图7-2 输出的三角波和正弦波信号 四、思考题 (1)对于代码中提供的正弦信号sine_tab[256] 数组是如何确定的?如果要频率提高一倍,如何重新确定数组? (2)修改程序,使之能输出三角波。 (3)程序对应的仿真电路图如图7-1所示;相应的运行结果如图7-2所示。 实训项目7 利用LCD1602设计的可调式电子钟 一、项目要求 利用单片机的定时器控制时钟运行,运行过程中的误差,通过K1~K4键进行调节; K1键用来选择调节时/分,K2键与K3键用于增减当前的小时或分钟,调整完成后按下K4键确定,电子钟继续运行; 利用LCD1602显示电子日历与时钟。 二、项目实践技能目标 1.通过项目的训练,理解LCD1602芯片的结构和原理,及与单片机的接口技术,掌握 苏州经贸职业技术学院 LCD忙检测、初始化、设置位置、写命令、写数据函数等的软件设计。2.掌握利用单片机的定时器实现时钟功能。 3.根据设计要求,在PROTUES开发平台上,完成硬件系统的电路组装,完成系统软件设计要求,并提交程序设计框图和程序清单;完成系统软硬件的综合调试,实现设计要求。 4.通过该项目的训练,提高学生的实际动手操作能力,养成学生的工程道德观念,建立工程敬业精神和团队合作精神。 三、参考电路 五、思考题 1.利用时钟芯片DS1302实现可调式电子表,完成软硬件的设计。 实训项目8 16*16点阵屏设计 一、项目要求 利用单片机控制实现16*16点阵屏的汉字滚动显示 二、项目实践技能目标 1、巩固8*8点阵屏的知识点,学习实现一个汉字需要4片8*8点阵屏的硬件知识点,以及实现汉字点阵的数组知识。 2、掌握单片机扩展原理,加强芯片的认知能力、以及使用能力。 苏州经贸职业技术学院 3、掌握软件设计的技巧和方法。 4、根据设计要求,在PROTUES开发平台上,完成硬件系统的电路组装,完成系统软件设计要求,并提交程序设计框图和程序清单;完成系统软硬件的综合调试,实现设计要求。 5、通过该项目的训练,提高学生的实际动手操作能力,养成学生的工程道德观念,建立工程敬业精神和团队合作精神。 三、参考电路 苏州经贸职业技术学院 四、思考题 实现多个汉字滚动显示,怎样完成? 实训项目9 计算器的设计 一、项目要求 利用单片机控制系统实现单行液晶显示的计算器。 二、项目实践技能目标 1、巩固单片机的硬件系统知识,熟练掌握单片机的指令系统以及软件设计方法。 2、练习并行扩展存储单元的原理 3、根据设计要求,在PROTUES开发平台上,完成硬件系统的电路组装,完成系统软件设计要求,并提交程序设计框图和程序清单;完成系统软硬件的综合调试,实现设计要求。 4、通过该项目的训练,提高学生的实际动手操作能力,养成学生的工程道德观念,建立工程敬业精神和团队合作精神。 苏州经贸职业技术学院 三、参考电路 四、思考题 1、重新修改代码,使计算器实现保留两位小数精度的数值计算 2、设计一部电子秤第二篇:单片机实训
第三篇:单片机实训题目
第四篇:单片机实训操作规程
第五篇:单片机实训教案