电子工艺课存档 proteus和C语言

开学初装了Proteus 8 Professional和Keil uVision4

电子工艺课存档 proteus和C语言电子工艺课存档 proteus和C语言电子工艺课存档 proteus和C语言

   

2020-06-17安装vspdpro-jie.exe

1.串口调试助手直接运行,无需安装。
2.Virtual Serial Port Driver,先运行vspdpro安装,完成安装后,将vspdpro-jie.exe复制到安装目录,C:Program FilesEltima SoftwareVirtual Serial Port Driver Pro 9.0,运行vspdpro-jie.exe

 

C:Program FilesEltima SoftwareVirtual Serial Port Driver Pro 9.0

 

以下是全部程序,从入门到入门

花样流水灯

电子工艺课存档 proteus和C语言 

电子工艺课存档 proteus和C语言

/* Main.c file generated by New Project wizard
 *
 * Created:   周四 4月 2 2020
 * Processor: AT89C52
 * Compiler:  Keil for 8051
 */

#include <reg51.h>
#include <stdio.h>
#include < intrins.h>

void delay(void) //延迟函数,当程序输出一个电信号后,CPU做无意义运算,让这个状态维持一段时间(约0.5毫秒),
    //人眼就能感受到LED灯被点亮了
{
   unsigned int i,j;

   for(i=0;i<10;i++)
      for(j=0;j<5000;j++)
      {
     }

 }

void main(void)
 { 
   // Write your code here
   unsigned char a,b;
    signed int i;
    a=1;
    b=1;
    while (1)
    {
        for(i=0; i<16; i++) 
        {
            P1=a;//P1在安装好的keil目录的reg51.h被定义好,是单片机P1端口(共8个)的数据寄存器,
                    //即给它赋值就代表了让P1.0-P.7输出(1,高电平,0,低电平),以驱动外接的LED灯被点亮
            P2=b;
            delay();
            a=_crol_(a,1);//定义在intrins.h里的标准C函数,使得a无符号 字符型变量(8位二进制数)循环左移,
            //然后当把a赋值给P1后,使得P1口每一位(P.0-P1.7)逐次输出一个1(5v高电平)
            b=_crol_(b,1);
        }

        b=_cror_(b,1);
        for(i=0; i<15; i++)//流水灯都往右
        {
            P1=a;
            P2=b;
            delay();
            a=_crol_(a,1);
            b=_cror_(b,1);
        }

        for(i=0; i<15; i++)//流水灯都往左
        {
            P1=a;
            P2=b;
            delay();
            a=_cror_(a,1);
            b=_crol_(b,1);
        }

        a=_cror_(a,1);
        for(i=0; i<15; i++)//流水灯相对而行
        {
            P1=a;
            P2=b;
            delay();
            a=_cror_(a,1);
            b=_cror_(b,1);
        }

        for(i=0; i<16; i++) 
        {
            P1=a;
            P2=b;
            delay();
            a=_crol_(a,2);
            b=_crol_(b,2);
        }
   }
}

View Code

流水灯都往左,流水灯都往右,流水灯相对而行,流水灯相向而行

 

按钮控制流水灯花样

电子工艺课存档 proteus和C语言 

电子工艺课存档 proteus和C语言

/* Main.c file generated by New Project wizard
 *
 * Created:   周三 4月 22 2020
 * Processor: AT89C52
 * Compiler:  Keil for 8051
 */

/*
    按button0, 流水灯下移;按button1,流水灯上移;
    按button2,流水灯双灯下移;按button3,流水灯双灯上移;
    按button4, 流水灯双灯下移两格;按button5,流水灯双灯上移两格;
    按button6, 流水灯三灯下移;按button7,流水灯四灯间隔闪烁;
*/
#include<reg52.h>             //库文件
#include<intrins.h>
#define uchar unsigned char//宏定义无符号字符型
#define uint unsigned int  //宏定义无符号整型
/********************************************************************
                            初始定义
*********************************************************************/
uchar a,b,c,d;       //定义字符型变量
uchar flag;
sbit BY0=P2^0; //定义按键的输入端(为单片机P2口的P2.0按键)
sbit BY1=P2^1; //定义按键的输入端(为单片机P2口的P2.1按键)
sbit BY2=P2^2;
sbit BY3=P2^3;
sbit BY4=P2^4;
sbit BY5=P2^5;
sbit BY6=P2^6;
sbit BY7=P2^7;
/********************************************************************
                            延时函数
*********************************************************************/
void delay10ms(void) //延时程序
{
uchar i,j;
for(i=20;i>0;i--)
for(j=248;j>0;j--);
}

void delay(void) //延迟函数,当程序输出一个电信号后,CPU做无意义运算,让这个状态维持一段时间(约0.5毫秒),
    //人眼就能感受到LED灯被点亮了
{
   unsigned int i,j;

   for(i=0;i<10;i++)
      for(j=0;j<5000;j++)
      {
     }
 }
/********************************************************************
                           按键判断函数
*********************************************************************/
void key1() //按键判断程序
{
    unsigned int k;
    if(P2!=0xFF)//是否有键按下,进一步通过区分P2的8位二进制数值来判断哪个键按下了
    {
        delay10ms(); //延时,软件去干扰,机械按键在按下和松开时,状态进入稳定前会有微小的不稳定抖动态,重复判断,确定按键的状态
        if(BY0==0)    flag=0;
        else if(BY1==0)    flag=1;
        else if(BY2==0)    flag=2;
        else if(BY3==0)    flag=3;
        else if(BY4==0)    flag=4;
        else if(BY5==0)    flag=5;
        else if(BY6==0)    flag=6;
        else flag=7;
    }
}
void key() //按键判断程序
{
    unsigned int i,j=1;
    if(P2!=0XFF){//判断是否有键按下 没有键被按下时全部为‘1’
        for(i=0;i<=7;i++){
            if((P2&j)==0){//单片机P2口的P2.i按键被按下 为‘0'
                delay10ms(); //延时,软件,机械按键在按下和松开时,状态进入稳定前会有微小的不稳定抖动态,重复判断,确定按键的状态
                if((P2&j)==0){//确认按键按下
                    flag=i;//flag用于标识最近一次按下的键
                }
                while((P2&j)==0);//按键锁定
                return ;
            }
            j*=2;
        }
    }
}
/********************************************************************
                            主函数
*********************************************************************/
void main()
{

    a=0xFE, b=0xFC, c=0xF8, d=0xAA;
    flag=-1;
    while(1)
    {
        key(); //调用按键判断函数
        switch(flag)
        {
            case 0:        P0=a;    delay();        a=_crol_(a,1);    break;
            case 1:        P0=a;    delay();        a=_cror_(a,1);    break;
            case 2:        P0=b;    delay();        b=_crol_(b,1);    break;
            case 3:        P0=b;    delay();        b=_cror_(b,1);    break;
            case 4:        P0=b;    delay();        b=_crol_(b,2);    break;
            case 5:        P0=b;    delay();        b=_cror_(b,2);    break;
            case 6:        P0=c;    delay();        c=_crol_(c,1);    break;
            case 7:        P0=d;    delay();        d=_cror_(d,1);    break;
            default:     break;
        }
    }
}

/********************************************************************
                              结束
*********************************************************************/

View Code

按button0, 流水灯下移;按button1,流水灯上移;
按button2,流水灯双灯下移;按button3,流水灯双灯上移;
按button4, 流水灯双灯下移两格;按button5,流水灯双灯上移两格;
按button6, 流水灯三灯下移;按button7,流水灯四灯间隔闪烁;

 

外部中断控制流水灯花样

电子工艺课存档 proteus和C语言 

电子工艺课存档 proteus和C语言

/* Main.c file generated by New Project wizard
 *
 * Created:   周三 5月 6 2020
 * Processor: AT89C52
 * Compiler:  Keil for 8051
 */

#include <reg51.h>
#define uint unsigned int
#define uchar unsigned char
//花样显示,23个状态
uchar tab[ ]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
                     0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0XFE,0XFF,
                     0xAA,0x55,0xAA,0x55,0xAA,0x55,0xFF};
//中断显示,10个状态,0号中断
uchar tab1[ ]={0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00};

//中断显示,10个状态,2号中断,中断一次切换中断显示
uchar tab2[ ]={0x3C,0xC3,0x3C,0xC3,0x3C,0xC3,0x3C,0xC3,0x3C,0xC3};
uchar tab3[ ]={0x5A,0xA5,0x5A,0xA5,0x5A,0xA5,0x5A,0xA5,0x5A,0xA5};
uchar tab4[ ]={0xF0,0x0F,0xF0,0x0F,0xAA,0x55,0xAA,0x55,0x00,0xFF};

uint count=-1;

//ms延时程序
void delay_ms(uint x) 
{
   uint t; 
   while(x--) 
      for(t = 0; t < 120; t++);
}

void  intrp0(  )  interrupt  0
{
    uchar i;
    for(i=0;i<10;i++)
    {
      P0=tab1[i];
      delay_ms(300);
    } 
}

void  intrp2(  )  interrupt  2
{
    uchar i;
    count=(count+1)%3;
    if(count==0)
    {
        for(i=0;i<10;i++)
        {
          P1=tab2[i];
          delay_ms(300);
        }
    }
    else if(count==1)
    {
        for(i=0;i<10;i++)
        {
          P1=tab3[i];
          delay_ms(300);
        }
    }
    else
    {
        for(i=0;i<10;i++)
        {
          P1=tab4[i];
          delay_ms(300);
        }
    }
}


void main(   )
{
    IT0=1;
    EX0=1;
    EA=1;
    IT1=1;
    EX1=1;
    while(1)
        {
            uchar  x;
            for(x=0;x<23;x++)
            {
                P0=tab[x];
                P1=tab[x];
                delay_ms(500);
            }
      }
}

View Code

 

流水灯正常运行,外部中断0触发时P0口显示花样,外部中断1触发时P1口显示花样

 

定时器实现方波

电子工艺课存档 proteus和C语言电子工艺课存档 proteus和C语言 电子工艺课存档 proteus和C语言 

电子工艺课存档 proteus和C语言

/* Main.c file generated by New Project wizard
 *
 * Created:   周三 5月 20 2020
 * Processor: AT89C52
 * Compiler:  Keil for 8051
 */


#include <reg51.h>
sbit P2_0=P2^0;
void timer0 (void) interrupt 1 {
   P2_0 = !P2_0;         //P2.0取反
   TH0 = 55536/256;             //计数初值重装载
   TL0 = 55536%256;
}
void main (void) {
   TMOD = 0x01;             //T0定时方式1
   P2_0=0;
   TH0=55536/256;                 //预置计数初值  定时10ms
   TL0=55536%256;
   EA=1; 
   ET0=1; 
   TR0=1;
   while(1);
}

View Code

 

 

 电子琴

电子工艺课存档 proteus和C语言 

电子工艺课存档 proteus和C语言

/* Main.c file generated by New Project wizard
 *
 * Created:   周三 5月 20 2020
 * Processor: AT89C52
 * Compiler:  Keil for 8051
 */

#include<reg52.h>             //库文件
#include<intrins.h>
#define uchar unsigned char//宏定义无符号字符型
#define uint unsigned int  //宏定义无符号整型
/********************************************************************
                            初始定义
*********************************************************************/

unsigned int T[8]={63628,63835,64021,64103,64260,64400,64524,64580};//低1-低7和中1 音符的频率所对应的T值
unsigned int T_value;
unsigned int count=0;//中断服务程序运行的次数,确保一次按键只响一声
sbit BY0=P1^0; //定义按键的输入端(为单片机P1口的P1.0按键)
sbit BY1=P1^1; //定义按键的输入端(为单片机P1口的P1.1按键)
sbit BY2=P1^2;
sbit BY3=P1^3;
sbit BY4=P1^4;
sbit BY5=P1^5;
sbit BY6=P1^6;
sbit BY7=P1^7;
sbit P2_0=P2^0;
/********************************************************************
                            延时函数
*********************************************************************/
void delay10ms(void) //延时程序
{
uchar i,j;
for(i=20;i>0;i--)
for(j=248;j>0;j--);
}
/********************************************************************
                           中断函数
*********************************************************************/
void timer(void) interrupt 1//定时计数器T0 中端号为1
{
    P2_0=!P2_0;
    TH0=T_value/256;
    TL0=T_value%256;
    count++;
    if(count==2) {
        count=0;
        ET0=0;
        TR0=0;
    }
}

/********************************************************************
                            主函数
*********************************************************************/
void main()
{
    TMOD=0x01; //T0定时方式1
    EA=1;
    P0=0xFF;//灯初始状态为全关
    while(1)
    {
        P0=0xFF;
        if(P1!=0)//是否有键按下,进一步通过区分P1的8位二进制数值来判断哪个键按下了
        {
            delay10ms(); //延时,软件去干扰,机械按键在按下和松开时,状态进入稳定前会有微小的不稳定抖动态,重复判断,确定按键的状态
            while(BY0==0) {
                P0=0xFE;//1111 1110
                T_value=T[0];
                ET0=1;//开T0中断
                TR0=1;//启动定时器0
            }
            while(BY1==0) {
                P0=0xFD;//1111 1101
                T_value=T[1];
                ET0=1;
                TR0=1;
            }
            while(BY2==0) {
                P0=0xFB;//1111 1011
                T_value=T[2];
                ET0=1;
                TR0=1;
            }
            while(BY3==0) {
                P0=0xF7;//1111 0111
                T_value=T[3];
                ET0=1;
                TR0=1;
            }
            while(BY4==0) {
                P0=0xEF;//1110 1111
                T_value=T[4];
                ET0=1;
                TR0=1;
            }
            while(BY5==0) {
                P0=0xDF;//1101 1111
                T_value=T[5];
                ET0=1;
                TR0=1;
            }
            while(BY6==0) {
                P0=0xBF;//1011 1111
                T_value=T[6];
                ET0=1;
                TR0=1;
            }
            while(BY7==0) {
                P0=0x7F;//0111 1111
                T_value=T[7];
                ET0=1;
                TR0=1;
            }
        }
    }
}

/********************************************************************
                              结束
*********************************************************************/

View Code

 8个音符较少,可弹奏粉刷匠和小毛驴

 unsigned int T[8]={63628,63835,64021,64103,64260,64400,64524,64580};//低1-低7和中1 音符的频率所对应的T值

 

用8255实现数码管60秒计时

电子工艺课存档 proteus和C语言 

电子工艺课存档 proteus和C语言

/* Main.c file generated by New Project wizard
 *
 * Created:   周三 6月 3 2020
 * Processor: AT89C52
 * Compiler:  Keil for 8051
 */

#include <reg51.h>
#include <intrins.h>
#include <absacc.h>
#define uint unsigned int
#define uchar unsigned char

//P0.5和P0.6决定A0和A1,决定选择的寄存器组
#define portA 0X00 
#define portB 0x20
#define portC 0x40
#define Cont  0x60

sbit P1_0=P1^0;
sbit P1_1=P1^1;
uint ten=0;
uint one=0;
uint count=0;//计数满20次为1s
uchar table[]={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};//共阴数码管段码表
//工作方式1最大计时65.536ms,我们要计算一秒,则计时20次50ms较好,
//要计算的机器周期数=50ms/1μs=50000,计数初值=2^16-50000=15536

//中断函数定时计数器T0 中端号为1
void timer0(void) interrupt 1
{
    TH0=15536/256;
    TL0=15536%256;
    count++;
    if(count==20)
    {
        count=0;
        one++;
    }
    if(one==10)
    {
        one=0;
        ten++;
        if(ten==6) 
        {
            ten=0;
        }
    }
}

void show()
{
    PBYTE[portA]=table[ten];
    PBYTE[portB]=table[one];
}

void main(void)
{
    PBYTE[Cont]=0x81;//将控制字写入8255的控制口地址 1000 0001
    TMOD=0x01;//T0定时方式1
    EA=1;
    TH0=15536/256;
    TL0=15536%256;
    ET0=1;//开T0中断
    TR0=1;//启动计时器
    while(1)
    {
        show();
        if(P1_0==0)//P1.0处按键按下,计时暂停,或者是P1==255-1
        {
            TR0=0;//关闭定时器0
        }
        if(P1_1==0)//P1.1处按键按下,计时重置
        {
            ten=0;
            one=0;
            TR0=1;
        }
   }
 }

View Code

 

 

串行口通信

要使用串口调试助手和vspdpro

电子工艺课存档 proteus和C语言 

电子工艺课存档 proteus和C语言电子工艺课存档 proteus和C语言 

电子工艺课存档 proteus和C语言

/* Main.c file generated by New Project wizard
 *
 * Created:   周三 6月 17 2020
 * Processor: AT89C52
 * Compiler:  Keil for 8051
 */

#include <reg51.h>
#include <stdio.h>
unsigned char table[]={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};//共阴数码管段码表
unsigned char mystr[]={0x68,0x65,0x6c,0x6c,0x6f};//hello
unsigned int num = 9;
sbit P2_0 = P2^0;
unsigned int i;

//延时函数
void delay_ms(unsigned int x){
    unsigned int t;
    while(x--)
        for(t=0;t<120;t++);
}


//串行口初始化
void csh()    
{
    SCON=0x50;//设置串行口工作方式,SM0=0,SM1=1,REN=1,TI=RI=0
    PCON=0;      //波特率不加倍
    TH1=0xFD; //波特率设定为9600,计数初值查表可得,晶振频率为11.0592MHz
    TL1=0XFD;
    TMOD=0X20;//T1工作于方式2定时方式
    TR1=1;      //启动T1
} 

//按键判断函数
void key() {
    num = 0;
    if(P1==255-1) {//P1.0按下,下面类似
        num = 1;
    }
    else if(P1==255-2) {
        num = 2;
    }
    else if(P1==255-4) {
        num = 3;
    }
    else if(P1==255-8) {
        num = 4;
    }
    else if(P1==255-16) {
        num = 5;
    }
    else if(P1==255-32) {
        num = 6;
    }
    else if(P1==255-64) {
        num = 7;
    }
    else if(P1==255-128) {
        num = 8;
    }
    if(num != 0) {
        P0=table[num];
        SBUF = num+0x30;
        while(!TI);
        TI = 0;
    }    
}

void showString(){
    for(i=0;i<5;i++){
        SBUF=mystr[i];
        while(!TI);
        TI=0;
    }
}

void main()
{
        csh();      //串行口初始化
        while(1) {
            while(RI) {
                RI=0;
                P0=table[SBUF-0x30];
            }
            while(P1!=255) {
                delay_ms(10);
                key();
            }
            if(!P2_0){
                P2_0 = 1;
                delay_ms(10);
                showString();
            }
        }
}

View Code

 

 

单片机异步串行通讯

通过矩阵键盘,8位数码管,8255,74ls373等器件,完成单片机之间的串口通讯。将两个单片机的串行口连接,进行异步串行通讯。两个单片机能够通过按键,8位数码管,设置输出数据(10个数字和A-F字符组成的字符串,最多输入8个)和显示接收到的数据(最多8个),通过设置发送键(可使用外部中断),发送。  (100分)

电子工艺课存档 proteus和C语言 

电子工艺课存档 proteus和C语言

/* Main.c file generated by New Project wizard
 *
 * Created:   周三 7月 1 2020
 * Processor: AT89C52
 * Compiler:  Keil for 8051
 */

#include <reg51.h>
extern void delay_ms(unsigned int n);
extern void Scan_Key(void);
void disp(void);//显示收到的字符
void receive(void);
unsigned char ptr,m;
unsigned int tno=0,rno=0;//发送和接收时的第几个数码管
sbit P3_2=P3^2;//发送键
unsigned char table[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71 };//共阴极字型码
unsigned char sel[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位选
unsigned char  data tdisbuf[8]={0};
unsigned char  data rdisbuf[8]={0};

void delay_ms(unsigned int n)              //延时
{ 
    unsigned int i,j;
      for(i=0;i<n;i++)
      {
        for(j=0;j<80;j++); 
    }
}

void intrr0(void) interrupt 0        //判断P3.2是否按下,如按下就发送字符串
{
    unsigned int i,j;
    //串行口发送
    for(i=0;i<8;i++){
        SBUF=tdisbuf[i];
        delay_ms(2);
    }
    tno=0;//重置,以便下次发送从头开始
    for(j=0;j<8;j++){
        tdisbuf[i]=0;
    }
}

void intrr4(void) interrupt 4        //判断串行口是否发送或接收完数据
{
    if(TI==1)      //若发送完数据
    {
        TI=0;      //发送完数据,清TI
    }
    if(RI==1)      //若接收到数据
    {
        RI=0;      //清RI
        receive();
    }
}

void receive(void)         //把接收到数据的数据送给rdisbuf数组
{
    unsigned char i;
    rdisbuf[rno]=SBUF;
    rno=(rno+1)%8;
}

void disp(void)         //把rdisbuf数组内的字符显示在数码管上
{
    unsigned char i,j;
    P2=0XFF;  //关闭所示数码管显示
    for(i=0;i<8;i++)
        {
            j=rdisbuf[i];
            P2=sel[i];  //得到位选
            P0=table[j];    //送段码
            delay_ms(2);
            P2=0XFF;        
        }
}

void csh()        //初始化串口
{
    SM0=0;    SM1=1;    REN=1;
    TI=0;    RI=0;//以上两行可用SCON=0x50替换
    PCON=0;  //波特率不加倍
    TH1=0xFD;    TL1=0XFD;//波特率设定为9600
    TMOD=0X20;//T1工作于方式2定时方式
    EA=1;    //开总中断
    ES=1;    //开串行通信中断
    TR1=1;  //启动T1
}


unsigned char Check_Key()
{
    unsigned char i;
    P1=0xF0;     //送全0,向各行送低电平  
       i=P1;        //取P1口值     
    i=i&0xF0; //屏蔽掉低四位,作为列值
      if(i==0xF0)  //判断是否有键按下  
         return 0;
    else  
         return 0xff;
}


void Scan_Key(void)                     // 键盘扫描程序 
{
    char a1,i;
    bit FLAG0=0;
    a1=0xfe;                                 //列扫描初值,送1个“0”
    ptr=0;                                      //第ptr个按钮,A-F时为10-16
    if(Check_Key()==0)
        return;
    for(i=0;i<4;i++)                      //键盘4个扫描列
    {
        P1=a1;
         delay_ms(10);
          m=P1;
          switch(m&0xf0)                    //取行的高4位,检测哪一行有按键被按下
          { 
            case 0xe0:  ptr=i*4;        //第一行被按否?
            FLAG0=1;                    //表示有按键
            break;                  
             case 0xd0:  ptr=i*4+1;      //第二行被按否?
            FLAG0=1;
            break;
             case 0xb0:  ptr=i*4+2;        //第三行被按否?
            FLAG0=1;
            break;
            case 0x70:  ptr=i*4+3;      //第四行被按否?
            FLAG0=1;
            break;
            default:  break;
        }
           if( FLAG0 ) 
         {                                
            if(tno<8)
            {
                tdisbuf[tno]=ptr;    //第tno个数码管            
                while((P1&0xf0)==0xe0);
                while((P1&0xf0)==0xd0);
                while((P1&0xf0)==0xb0);
                while((P1&0xf0)==0x70);
                tno=tno+1;
                return;
            }
        }
        a1=a1<<1|0x01; 
    }
}


 void main(void)
{ 
    EX0=1;//开外部中断0
    csh();
    while(1)
    { 
        Scan_Key();                            //扫描键盘
        disp();
    }                 
}

View Code

注:两个单片机程序一样

unsigned char table[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71 };//共阴极字型码
unsigned char sel[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位选

 

为了上面这个综合设计打过的草稿,参考了一堆程序,大部分来源于河南理工大学的mooc,单片机原理与应用实例仿真

电子工艺课存档 proteus和C语言

 

 

双机通信

 电子工艺课存档 proteus和C语言

电子工艺课存档 proteus和C语言

//单片机甲的程序
#include <reg51.h>
void delay_ms(unsigned int x)  
{ unsigned int t;
   while(x--)
     for(t=0;t<120;t++);
}
//初始化串行口
void csh()
    {
    SM0=0;    SM1=1;    REN=1;
    TI=0;    RI=0;
    PCON=0;
    TH1=0xF3;    TL1=0XF3;
    TMOD=0X20;
    EA=1;    ET1=0;
    ES=1;    TR1=1;
    }

void main()
    {
    char c=0;
    csh();
    while(1)
        {
        P0=c;
        SBUF=c;
        while(!TI);
        TI=0;
        delay_ms(600);
        c++;
        if (c>9)
        c=0;
        }
}

void intrr() interrupt 4
    {
    char temp;
    temp=SBUF;
    P2=temp;
    RI=0;
    }

View Code

 

 注:这是单片机甲的程序,乙的程序只在main函数的发送9-0处不同

 

电子钟

电子工艺课存档 proteus和C语言 

电子工艺课存档 proteus和C语言

#include "reg51.h"
#include "stdio.h"
#define uint unsigned int
#define uchar unsigned char
uchar  data second=0,minute=0,hour=0;
uchar  data disbuf[6]={0};

uchar bdata FLAG=0;
sbit H_M=FLAG^1;   //小时  分钟切换标志位  启动后默认为分钟设置状态
sbit P1_0=P1^0;   //增1键
sbit P3_2=P3^2;   //小时,分钟切换键
//定义共阴段码 0-9
uchar code table[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//计数变量
uchar data count=0;

//定时器0的中断服务程序   50ms
void  timer0(void) interrupt 1 using 1
{TH0=-50000/256;
 TL0=-50000%256;
 count++;
 if(count==20)
     {count=0;
       second++;
           if(second==60)
               {second=0;
                minute++;
                    if(minute==60)
                       {minute=0;
                        hour++;
                          if(hour==24)
                              {hour=0;}
                        }
                }
     }
  return;
 }

 //延时程序
void dlms(void)
{uchar i;
 for(i=2000;i>0;i--){}
}

//外部中断0的中断服务程序
void int0(void) interrupt 0 using 2
{ 
    while(!P3_2)  //等待按键弹起
    { 
            dlms();
    }
  dlms( );   
  if(P3_2)     //按键弹起 
     H_M=!H_M;
 }

//显示程序
void disp(void)
{uchar i,j;
 uchar bdata sel;
 disbuf[0]=second%10;
 disbuf[1]=second/10;
 disbuf[2]=minute%10;
 disbuf[3]=minute/10;
 disbuf[4]=hour%10;
 disbuf[5]=hour/10;
 P2=0XFF;  //关闭所示数码管显示
 sel=0x01;
 for(i=0;i<6;i++)
  {j=disbuf[i];
   P2=(sel^0xff);  //得到位选
   P0=table[j];    //送段码
   dlms();
   P2=0XFF;        
   sel=sel<<1;    //位选左移1位
  }
}

//加1处理程序 
void increa(void)
{if(H_M)   //H_M为1  表示小时设置
   {hour++;
    if(hour==24)
        {hour=0;
         disbuf[4]=0;
         disbuf[5]=0;
         }
    }
  else   //H_M为0  表示分钟设置
    {minute++;
      if(minute==60)
        {minute=0;
         disbuf[2]=0;
         disbuf[3]=0;
         }
     }
 }

int  main( )
 {
     TCON=0x01;
   TMOD=0x01;
   TH0=-50000/256;
   TL0=-50000%256;
   EA=1;
   ET0=1;
   EX0=1;
   TR0=1;

  while(1)
   {disp();
    if(!P1_0)
    {while(!P1_0)
        dlms();
     if(P1_0)
       increa();
     }
   }
}

View Code

 

 

动态显示数码管(人眼的暂存效应)

  电子工艺课存档 proteus和C语言 

电子工艺课存档 proteus和C语言

#include <reg51.h>
#define uchar unsigned char
#define uint  unsigned int
uchar code ledD[6]={0x06,0x5b,0x4f,0x66,0x6d,0x7d};//段码
uchar code ledW[6]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};//位选
//延时函数
void delay_ms(uint x)
{
  uint t;
  while(x--)
    for(t=0;t<120;t++);
}
//主程序
void main( )
{
  uchar i;
  while(1)
  {
   for(i=0;i<6;i++)
   {
    P0=ledD[i];
      P2=ledW[i];
      delay_ms(2);         //参数大于50时能清晰看到数码管一个一个点亮
      P2=0xff;    
   }
  }
}

View Code

 

 

串口方式1

电子工艺课存档 proteus和C语言 

电子工艺课存档 proteus和C语言

#include <reg52.h>
//串行口初始化
void csh()      //中断方式串行口初始化
{
    SCON=0x50;//设置串行口工作方式,SM0=0,SM1=1,REN=1,TI=RI=0
    PCON=0;      //波特率不加倍
    TH1=0xF4; //波特率设定为2400
    TL1=0XF4;
    TMOD=0X20;//T1工作于方式2定时方式
    ES=1;      //开中断
    EA=1; 
    TR1=1;      //启动T1
} 
void main()
{
        csh();      //串行口初始化
        P2=0Xff;  //设P2为输入端口
        SBUF=P2;
        while(1);
}
void intrr() interrupt 4   //串行通信中断函数
{
    if(TI==1)      //若发送完数据
    {
        TI=0;      //发送完数据,清TI
        SBUF=P2;  //将开关的状态读入并从串行口发送出去
    }
    if(RI==1)      //若接收到数据
    {
        RI=0;      //清RI
        P0=SBUF;  //将接收到的数据显示在LED上
    }
}

View Code

 

 

单片机7例子

老师发的优秀例子,仅供学习之用,不可转载

电子工艺课存档 proteus和C语言

#include<reg52.h>

#include <stdio.h>

#define uchar unsigned char

#define uint unsigned int  



uchar table[]={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};

uchar a;

uchar str[7] = "Hello !";



void delay_ms(uint x)

{

   uchar t;

   while(x --)

      for(t = 0; t < 120; t ++);

}



void csh()

{

   SCON = 0x50;

   PCON = 0;

   TH1 = 0xFD;  

   TL1 = 0xFD;

   TMOD = 0x20;

   ES = 1;

   EA = 1;

   TR1 = 1;

}



uint Key()

{

   uint k;

   k = 0;

   if(P1 != 0xff)

      {

 delay_ms(10);

 switch(P1)

 {

    case 0xfe:k = 1;

       break;

    case 0xfd: k = 2;

       break;

    case 0xfb: k = 3;

       break;

    case 0xf7: k = 4;

       break;

    case 0xef: k = 5;

       break;

    case 0xdf: k = 6;

       break;

    case 0xbf: k = 7;

       break;

    case 0x7f: k = 8;

       break;

}

    while(P1 != 0xff);

}

else if(P2 != 0xff)

{

   delay_ms(10);

    if(P2 == 0xfe)

       k = 9;

}

return k;

}



void main()

{

   uint i;

   csh();

   P0 = 0x00;

   while(1)

   {

      if(TI == 0)  

      {

 uint K = Key();

 if(K >0 & K< 9 )

    {

       SBUF = (K + 0x30);

       while(!TI);

  TI = 0;

    }

    else if(K ==9)

       for(i = 0; i < 7; i ++)

       {

  SBUF = str[i];

  while(!TI);

  TI = 0;

       }



 }

   }

}



void intrr() interrupt 4

{

   if(RI == 1)

   {  

      RI = 0;

      P0 = table[SBUF-0x30];



    }

 }

View Code

 

 

单片机7例子3

老师发的优秀例子,仅供学习之用,不可转载

电子工艺课存档 proteus和C语言

#include <reg51.h>

#include <stdio.h>



#define uchar unsigned char

#define uint  unsigned int

uchar buf;

sbit BY0=P1^0;

sbit BY1=P1^1;

sbit BY2=P1^2;

sbit BY3=P1^3;

sbit BY4=P1^4;

sbit BY5=P1^5;

sbit BY6=P1^6;

sbit BY7=P1^7;

sbit BY8=P2^0;//这是控制向pc机发送一个字符串

unsigned char string[]="hello world!";  //向pc机发送hello world!

unsigned char tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//数码管0-9

unsigned int m,n;

void delay10ms(void) //延时程序

{

unsigned char i,j;

for(i=20;i>0;i--)

for(j=248;j>0;j--);

}

void csh()

{

      SCON=0x50;

      PCON=0;

      TH1=0xFD;

      TL1=0xFD;

      TMOD=0x20;

      ES=1;

      EA=1;

      TR1=1;

 }

 void sendString()

 {

      for(m=0;m<12;m++)

      {

 SBUF=string[m];

 while(!TI) ;

    TI=0;

 }

 }

 void key() //按键判断程序

{



       if(P1 != 0xff)

       {

  delay10ms();

  if(BY0==0)  {SBUF=1+0x30;while(!TI) ;TI=0;while(!BY0) ;}

  if(BY1==0)  {SBUF=2+0x30;while(!TI) ;TI=0;while(!BY1) ;}

  if(BY2==0)  {SBUF=3+0x30;while(!TI) ;TI=0;while(!BY2) ;}

  if(BY3==0)  {SBUF=4+0x30;while(!TI) ;TI=0;while(!BY3) ;}

  if(BY4==0)  {SBUF=5+0x30;while(!TI) ;TI=0;while(!BY4) ;}

  if(BY5==0)  {SBUF=6+0x30;while(!TI) ;TI=0;while(!BY5) ;}

  if(BY6==0)  {SBUF=7+0x30;while(!TI) ;TI=0;while(!BY6) ;}

  if(BY7==0)  {SBUF=8+0x30;while(!TI) ;TI=0;while(!BY7) ;}

       }

    if(BY8==0)

    {

       delay10ms();

       if(BY8==0)  {sendString(); while(!BY8) ;}

       }

}

void main(void)

{

    csh();

    while(1) key();         

}

void serial() interrupt 4

{

if(RI==1){

RI=0;

P0=tab[SBUF-0x30];

 }

}

View Code

 

矩阵式键盘

电子工艺课存档 proteus和C语言 

电子工艺课存档 proteus和C语言

#include <reg51.h>
extern void Delay(unsigned int n);
extern void Scan_Key(void);
unsigned char ptr,m;
unsigned char tab[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,
0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71 };//共阴极字型码

void main(void)
{ 
 P2=0x0;    
 while(1)
     { 
    Scan_Key();                            //扫描键盘
    }                 
}
void Delay(unsigned int n)              //延时
{ 
    unsigned int i,j;
      for(i=0;i<n;i++)
      {
        for(j=0;j<80;j++); 
    }
}

void Scan_Key(void)                     // 键盘扫描程序 
{
    char a1,i;
    bit FLAG0=0;
    a1=0xfe;                               //列扫描初值
    ptr=0;                                  
    for(i=0;i<4;i++)                      //键盘4个扫描列
    {     P3=a1;
         Delay(10);
          m=P3;
          switch(m&0xf0)                    //取行的高4位,检测哪一行有按键被按下
          { 
            case 0xe0:  ptr=i*4;        //第一行被按否?    如有则是tab[i*4]键
            FLAG0=1;                    //表示有按键
            break;                  
             case 0xd0:  ptr=i*4+1;      //第二行被按否?    如有则是tab[i*4+1]键
            FLAG0=1;
            break;
             case 0xb0:  ptr=i*4+2;        //第三行被按否?    如有则是tab[i*4+2]键
            FLAG0=1;
            break;
            case 0x70:  ptr=i*4+3;      //第四行被按否?如有则是tab[i*4+3]键
            FLAG0=1;
            break;
            default:  break;
        }
           if( FLAG0 ) 
         {                                
            P2=tab[ptr];       //将键盘编码转换成显示编码
         
        }
        a1=a1<<1|0x01 ; 
        }
}



unsigned char Check_Key()
{
    unsigned char i;
    P3=0xF0;     //送全0,向各行送低电平  改了原来是0x00
       i=P3;        //取P3口值     
    i=i&0xF0; //屏蔽掉低四位,作为列值
      if(i==0xF0)  //判断是否有键按下  
         return 0;
    else  
         return 0xff;
}

View Code

 

原文链接: https://www.cnblogs.com/jie-74/p/13303567.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    电子工艺课存档 proteus和C语言

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/366849

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月2日 下午4:58
下一篇 2023年3月2日 下午5:00

相关推荐