⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 file11.c

📁 单片机学习系统附的实验源代码
💻 C
字号:
// 该信号源可以产生 多种波形,包括:占空比为1:1的方波,频率可调节(1 -- 50 Hz)
// 调制波,载波频率为1k,备调制频率   (1 --  50 Hz)
// 高频信号 :  高电平 5V, 低电平  0V   频率 500K;
// 按键key3 选择 输出波形方式 1 ->载波(LED3亮,LED1指示输出)  
//                            2 -> 非载波(LED2亮,LED1指示输出);
// 按键key2 选择 输出频率  
// 按键key1 启动\停止

#include <8051.h>

#define uchar unsigned char
#define uint unsigned int

#define key1  P3_3    //键盘定义
#define key2  P3_4
#define key3  P3_5

#define segdata  P0   //数据 输出
#define sege  P2_7    //显示 选中
#define segb  P2_6    //位 选
#define segd  P2_5    //段 选

uchar keyb();
// 这里定义的是数码管对应的字符字根

code uchar  disbuf_u[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
                        0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,
                        0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,
                        0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e};
// ***************************************************************************
// 12M下的频率码表,每个数据分为三个字节,
// 第一个字节,定时器初值高8位
// 第二个字节,定时器初值低8位
// 第三个字节,倍数
// 用这三个信息来确定一个输出频率值
                              //1HZ   ,   
code uchar fretab12[] ={0,0,0,11,219,16};

code uchar freq12M[]={  0,0,0,    //起头,无效码
                        11,219,16,//频率1
						11,218,8,//频率2
						38,250,6,//频率3
						11,217,4,//频率4
						60,173,4,//频率5
						38,249,3,//频率6
						69,249,3,//频率7
						11,214,2,//频率8
						38,247,2,//频率9
						60,170,2,//频率10
						78,108,2,//频率11
						93,56,2,//频率12
						105,189,2,//频率13
						116,120,2,//频率14
						125,197,2,//频率15
						11,209,1,//频率16
						26,46,1,//频率17
						38,242,1,//频率18
						50,94,1,//频率19
						60,165,1,//频率20
						69,242,1,//频率21
						78,103,1,//频率22
						86,31,1,//频率23
						93,51,1,//频率24
						99,181,1,//频率25
						105,184,1,//频率26
						111,72,1,//频率27
						116,115,1,//频率28
						121,67,1,//频率29
						125,192,1,//频率30
						129,243,1,//频率31
						133,227,1,//频率32
						137,150,1,//频率33
						141,18,1,//频率34
						144,90,1,//频率35
						147,116,1,//频率36
						150,98,1,//频率37
						153,42,1,//频率38
						155,204,1,//频率39
						158,77,1,//频率40
						160,175,1,//频率41
						162,244,1,//频率42
						165,30,1,//频率43
						167,46,1,//频率44
						169,39,1,//频率45
						171,10,1,//频率46
						172,217,1,//频率47
						174,148,1,//频率48
						176,61,1,//频率49
						177,213,1};//频率50
						
code uchar freq6M[]={   0,0,0,//无效
						3,251,31,//频率1
						11,218,16,//频率2
						19,64,11,//频率3
						11,217,8,//频率4
						32,198,7,//频率5
						38,249,6,//频率6
						32,196,5,//频率7
						11,214,4,//频率8
						38,247,4,//频率9
						60,170,4,//频率10
						19,58,3,//频率11
						38,245,3,//频率12
						55,166,3,//频率13
						69,246,3,//频率14
						82,92,3,//频率15
						11,209,2,//频率16
						26,46,2,//频率17
						38,242,2,//频率18
						50,94,2,//频率19
						60,165,2,//频率20
						69,242,2,//频率21
						78,103,2,//频率22
						86,31,2,//频率23
						93,51,2,//频率24
						99,181,2,//频率25
						105,184,2,//频率26
						111,72,2,//频率27
						116,115,2,//频率28
						121,67,2,//频率29
						125,192,2,//频率30
						3,230,1,//频率31
						11,198,1,//频率32
						19,44,1,//频率33
						26,36,1,//频率34
						32,180,1,//频率35
						38,232,1,//频率36
						44,196,1,//频率37
						50,84,1,//频率38
						55,152,1,//频率39
						60,154,1,//频率40
						65,94,1,//频率41
						69,232,1,//频率42
						74,60,1,//频率43
						78,92,1,//频率44
						82,78,1,//频率45
						86,20,1,//频率46
						89,178,1,//频率47
						93,40,1,//频率48
						96,122,1,//频率49
						99,170,1//频率50
}; //最后面一个逗号去掉

struct botout {
      uchar outh;    //定时器常数 THO
      uchar outl;    //定时器常数 TLO
      uchar count;   //需要输出的次数
};

struct botout  fcout;   //这个是每个数据点的数据结构

static uint counts;     //需要计数的次数  
uchar fre;              //用户设置的频率,不大于50  
uchar flag;             //波形选择 = 1调制波,否则方波           
uchar start;            //启动/停止标志

// 下面是定时器T0的中断服务程序
void ClockIrqHandler (void) interrupt 1{
  TL0 = fcout.outl;
  TH0 = fcout.outh;
  
  if(counts)  counts --;     //如果没到定时时间,定时倍数减少一
  else 
  {
     if(start == 1)         //这是启动/停止标志
     {
           if(flag == 1)    //这个是调制/非调制标志
          {
            TR1 = ~TR1,P1_0 = ~TR1;  //输出调制波
           
           }  
           else  P1_0 = ~P1_0,TR1 = 0;         //输出方波
           
      }else TR1=0,P1_0 = 1;          //停止输出波形
      counts = fcout.count;          //重新送倍数 
   }
  
}


// 定时器T1中断服务程序 

void TIMER1() interrupt 3{

  TL1 = -1000%256;
  TH1 = -1000/256;
  P1_0 = ~P1_0;  //p1.0输出
  
}
//*****************************************************************************

// 频率设置函数
void setfre(uchar fre)
{
     uchar f;
     f = fre*3;
     fcout.outh = freq6M[f];          //根据给定频率值,查表求定时器高低初值和倍数
     fcout.outl = freq6M[f+1] ; 
     fcout.count = freq6M[f+2];       
}
//下面是延时程序。具体的延时时间不能通过表面程序看出,(为什么?)
//如果我们需要一个精密的延时程序,那么我们可以采用内嵌汇编代码的方式
void delay(uint ysz)
{
	while(ysz--){};
}

//这里是显示子程序,入口参数为
// disseg  -> 位选 可选范围 0-7 一共8个数码管
// disdata -> 段选 可选范围 0-31 一个32个字符
//  段选 0-15  16个字符 为 "0"->"F"
//  段选 16-31 16个字符 为 "0."->"F."

void display(uchar disseg,uchar disdata)
{
    unsigned char dataf;

     dataf = 1;
     while(disseg)
     {
         dataf <<= 1;
         disseg--;
      }
      sege = 0;
	  segdata = dataf;             //这里首先把要显示的数据放到数据总线
	  segb = 1;                    //这里给出一个脉冲,数据送往位选端
	  segb = 0;
	  
      segdata = disbuf_u[disdata];
      segd = 1;                    //这里给出一个脉冲,数据送往段选端
      segd = 0;
      
      delay(10);
      
      segdata = 255;
      segd = 1;                    //这里给出一个脉冲,数据送往段选端
      segd = 0;     
}

// 键盘程序,返回的结果是读得键盘对应的数据
uchar keyb()
{
    uchar key,keytmp;

    key1 = 1;   //将输出线拉高
    key2 = 1;
    key3 = 1;

    key = P3 ;  //读回来
    key = key & 0x38;           //获得键盘结果
    if(key == 56 ) return 0;   //如果用户没有按键返回 0  
    else
     { 
       keytmp = key;    
       delay(100);              //判断是不是干扰
       key = P3;
       key = key & 0x38;
       if (key != keytmp ) return 0;  //是干扰,返回 0
          else                        //不是干扰,等待用户释放按键
            {                
                  do{ 
                      key1 = 1;       //输出拉高
                      key2 = 1;
                      key3 = 1;
                    key = P3 & 0x38;  //读回来
                    P1_0 = ~P1_0;     //如果用户不释放,闪烁 p1.0 
                   }while(key != 56 );   //等待用户释放 
                    P1_0 = 1;             //用户释放以后,清除p1.0指示灯
                   switch(keytmp)
                      {
                         case 24: return 1;//返回用户按键结果
                         case 40: return 2;
                         case 48: return 3;
                       }         
                  
             }

   
      }
    
    return 0;  
    
}

void main()
{

    uchar key;
    P1 = 255;             //关闭LED显示
    P0 = 0;               //关闭数码显示
    P2 = 255;             //
    P3_7 = 0;             //关闭蜂鸣器
    counts = 0;    
    flag = 1 ;             //调制波输出
    fre = 1;              // 初始化输出1HZ频率
    start = 1;

   TL0 = 255; //初值
   TH0 = 255; //初值
   
   
   TL1 = -1000%256;
   TH1 = -1000/256;


   TMOD = 1;               // 定时器工作在方式0
   ET0=1;                  // 允许定时器T0中断
   EA =1;                  // 中断总允许
   ET1 = 1;                // 允许定时器1中断
   
   setfre(fre);
   TR0=1;                  //开启定时器
   while(1)
   {    
        key = keyb();          //取得键盘
        if(key == 1)           //用户按启动/停止功能键盘   
        {  
            start = ~start;   
        }else if(key == 2)     //用户按频率选择功能键
        {
            if(fre>49) fre = 1;
            else fre++;
            setfre(fre);       //设置频率值
        }else if(key == 3)     //用户按输出标志键
        {
            flag = ~flag;
            if(flag==1) P1_2 = 1,P1_3=0;
            else P1_2 = 0,P1_3 = 1;
        }

        if(flag==1) P1_2 = 1,P1_3=0;//显示标志位
        else P1_2 = 0,P1_3 = 1;

        display(0,fre%10);        //显示个位
            
        if(fre/10 !=0 )            //如果十位 = 0,不显示
        {      
            display(1,fre/10); 
        }    
   } 

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -