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

📄 波形发生器.c

📁 这是本人参加电子设计竞赛过程中编写的几个单片机程序
💻 C
📖 第 1 页 / 共 3 页
字号:
 	second_row = 0;
 	M_key = KEY;
 	if(M_key != 0xff)  //如果有连续两次按键按下,认为有有效按键按下。消除按键抖动
   	{
    	if(first_getkey == 0)
     	{
   			first_getkey = 1;	
   		}
  		else    //当有有效按键按下时,进一步识别是哪一个按键
   		{
   			if(keyon == 0)  //防止按键冲突,当还有未释放的按键时不对其它按键动作响应   
   			{
      			first_row = 0;         //扫描第一行按键
      			second_row = 1;
         		M_key = KEY;
         		if(M_key != 0xff)
           		{
            		switch(M_key) 
            		{
            	 		case 0xfe:
                   			keynum = 0x01;
               				break;
            			case 0xfd:
                       		keynum = 0x02;
                 			break;
               			case 0xfb:
                 		    keynum = 0x03;
                 			break;
               			case 0xf7:
                      		keynum = 0x04;
                 			break;
               			case 0xef:
                 			keynum = 0x05;
                 			break;
               			case 0xdf:
                 			keynum = 0x06;
                			break;
               			case 0xbf:
                			keynum = 0x07;
                 			break;
              	 		case 0x7f:
                 			keynum = 0x08;
                 			break;
              		}
           		}
         		else
           		{
            		second_row = 0;     //扫描第二行按键
            		first_row = 1;
            		M_key = KEY;
            		switch(M_key)
              		{
               			case 0xfe:
                			keynum = 0x09;
                			break;
               			case 0xfd:
                 			keynum = 0x0a;
                 			break;
               			case 0xfb:
                 			keynum = 0x0b;
                 			break;
               			case 0xf7:
                 			keynum = 0x0c;
                 			break;
               			case 0xef:
                 			keynum = 0x0d;
                 			break;
               			case 0xdf:
                 			keynum = 0x0e;
                 			break;
               			case 0xbf:
                 			keynum = 0x0f;
                 			break;
               			case 0x7f:
                 			keynum = 0x10;
                 			break;
              		}
           		}
				getkey = 1; //获得有效按键数值
                keyon = 1;  //防止按键冲突,当获得有效按键时将其置1
        	} 
     	} 
   	}
 	else
   	{
    		first_getkey = 0;
    		keyon = 0;     //防止按键冲突,当所有的按键都释放时将其清0
    }
}

/***************************************************
			数码管显示函数
原型:   void leddisp(void);
功能:  每次调用轮流显示一位数码管

****************************************************/
void leddisp(void)
{
	switch(lednum)  //选择需要显示的数码位
 	{
  		case 0:
    		LED1 = segtab[led[0]];
     		break;
  		case 1:
     		LED2 = segtab[led[1]];
     		break;
 		case 2:
     		LED3 = segtab[led[2]];
     		break;
 		case 3:
     		LED4 = segtab[led[3]];
     		break;
 		case 4:
     		LED5 = segtab[led[4]];
     		break;
 		case 5:
     		LED6 = segtab[led[5]];
     		break;
 		case 6:
     		LED7 = segtab[led[6]];
     		break;
		case 7:
     		LED8 = segtab[led[7]];
     		break;
  	}

	if(lednum == 0) //更新需要现实的数码位
 	{
		lednum = 7;
 	}
 	else
 	{
		lednum = lednum-1;
	}
}  

void lcdlon_off(uchar D)
{
	lcdlCommand = D;
	_nop_();
}

void setlstartx(uchar D)
{
	lcdlCommand = D;
	_nop_();
}

void setlstarty(uchar D)
{
	lcdlCommand = D;
	_nop_();
}

void setlstartline(uchar D)
{
	lcdlCommand = D;
	_nop_();
}

void lcdron_off(uchar D)
{
	lcdrCommand = D;
	_nop_();
}

void setrstartx(uchar D)
{
	lcdrCommand = D;
	_nop_();
}

void setrstarty(uchar D)
{
	lcdrCommand = D;
	_nop_();
}

void setrstartline(uchar D)
{
	lcdrCommand = D;
	_nop_();
}

void lcdlwrite(uchar D) 
{
	lcdDl = D;
	_nop_();
}

void lcdrwrite(uchar D) 
{
	lcdDr = D;
	_nop_();
}


/**********************************************************
			LCD清屏
原型:  void clear_lcd(void);
功能: 将LCD清屏

**********************************************************/
void clear_lcd(void)
{
	uchar i,j;
	
	for(i=0;i<8;i++)//左边8行
	{
		setlstartx(strat_xaddr + i);
		for(j=0;j<64;j++)//左边64列   8*8
		{
			setlstarty(strat_yaddr+j);
			_nop_();
			_nop_();
			_nop_();
			_nop_();
			_nop_();
			_nop_();
			_nop_();
			_nop_();
			lcdlwrite(0x00);//清除
		}
		_nop_();
	}

	for(i=0;i<8;i++)//清除右边
	{
		setrstartx(strat_xaddr + i);
		for(j=0;j<64;j++)
		{
			setrstarty(strat_yaddr+j);
			_nop_();
			_nop_();
			_nop_();
			_nop_();
			_nop_();
			_nop_();
			_nop_();
			_nop_();
			lcdrwrite(0x00);
		}
		_nop_();
	}
}

/************************************************************************************
			LCD初始化
原型:  void initial_lcd(void);
功能: 将LCD初始化显示"National University of defence technology's ASIC R&D Center"

************************************************************************************/
void initial_lcd(void)
{
	
	setlstartline(strat_dispaddr);//设置显示初始行
	setrstartline(strat_dispaddr);
	lcdlon_off(0x3F);//LCD两屏都打开
 	lcdron_off(0x3F);  
}


/*******************************************************************
                    延时函数               
函数原型: void  delay(uchar time_nop);  
功能:       延时time_nop个nop
  
********************************************************************/
void  delay(uchar time_nop)
{
	uchar i;
	for(i=0;i<time_nop;i++)
	{
		_nop_();	
	}
}
/*******************************************************************
                     起动总线函数               
函数原型: void  Start_I2c();  
功能:       启动I2C总线,即发送I2C起始条件.
  
********************************************************************/
void Start_I2c(void)
{
  sda = 1;   /* SDA=1发送起始条件的数据信号*/
  delay(2);
  scl = 1;
  delay(6);    /*SCL=1起始条件建立时间大于4.7us,延时*/
 
  sda = 0;   /*SDA=0发送起始信号*/
  delay(6);    /* 起始条件锁定时间大于4μs*/
     
  scl = 0;   /*SCL=0钳住I2C总线,准备发送或接收数据 */
  delay(2);
}




/*******************************************************************
                      结束总线函数               
函数原型: void  Stop_I2c();  
功能:       结束I2C总线,即发送I2C结束条件.
  
********************************************************************/
void Stop_I2c(void)
{
  sda = 0;  /*SDA=0发送结束条件的数据信号*/
  delay(2);   /*发送结束条件的时钟信号*/
  
  scl = 1;  /*SCL=1结束条件建立时间大于4μs*/
  delay(6);
  sda = 1;  /*SDA=1发送I2C总线结束信号*/
  delay(6);
}




/*******************************************************************
                 字节数据传送函数               
函数原型: uchar  SendByte(uchar c); 
功能:  将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
     此状态位进行操作. 发送数据正常返回1 ,发送失败返回0。
********************************************************************/
uchar  SendByte(uchar c)
{
 uchar BitCnt, ack;

 for(BitCnt=0;BitCnt<8;BitCnt++)  /*要传送的数据长度为8位*/
    {
     if((c<<BitCnt)&0x80)
     	sda = 1;   /*SDA=1判断发送位 从高位开始传输 */ 
     else  
     	sda = 0; //SDA=0               
     delay(2);
     scl = 1;               /*SCL=1置时钟线为高,通知被控器开始接收数据位*/ 
     delay(6);               /*保证时钟高电平周期大于4μs   */     
     scl = 0; //SCL=0
    }
    delay(2);
    sda = 1;        //SDA=1 8位发送完后释放数据线,准备接收应答位
    delay(2);  
    scl = 1;  //SCL=1
    delay(4);
    if(sda == 1)
    	ack=0;  //SDA==1   未收到
    else 
    	ack=1;        /*判断是否接收到应答信号*/
    scl = 0;  //SCL=0
    delay(2);
    
    return(ack);		
}






/*******************************************************************
                 字节数据接受函数               
函数原型: uchar  RcvByte();
功能:  用来接收从器件传来的数据,并判断总线错误(不发应答信号)
  
********************************************************************/	
uchar  RcvByte(void)
{
	uchar retc;
  	uchar BitCnt;
  
  	retc=0; 
  	for(BitCnt=0;BitCnt<8;BitCnt++)
  	{
  		delay(2);          
        scl = 0;       /*SCL=0置时钟线为低,准备接收数据位*/
        
        delay(6);         /*时钟低电平周期大于4.7μs*/
       
        scl = 1;       /*SCL=1置时钟线为高使数据线上数据有效*/
        delay(9);
        retc=retc<<1;
        if(sda == 1)
        	retc=retc+1; /*SDA==1读数据位,接收的数据位放入retc中 */
        delay(2); 
	}
  	scl = 0;    //SCL=0
  	delay(2);
  	return(retc);
}




/********************************************************************
                     应答子函数
原型:  void Ack_I2c(bit a);
 
功能:主控器进行应答信号,(可以是应答或非应答信号)
********************************************************************/
void Ack_I2c(uchar a)
{
	if(a==0)
  		sda = 0;     /*SDA=0  应答信号 */
  	else 
  		sda = 1;   //SDA=1    非应答信号
  	delay(4);    
  	scl = 1;  //SCL=1

    delay(4);             /*时钟低电平周期大于4μs*/
    
 	scl = 0;                /*SCL=0清时钟线,钳住I2C总线以便继续接收*/
    delay(2);
        
}






/*******************************************************************
                    向无子地址器件发送字节数据函数               
函数原型: uchar  ISendByte(uchar sla,uchar c);  
功能:     从启动总线到发送地址,数据,结束总线的全过程,从器件地址sla.
           如果返回1表示操作成功,否则操作有误。
注意:    使用前必须已结束总线。
********************************************************************/
uchar ISendByte(uchar sla,uchar c)
{
   uchar ack;
	
   Start_I2c();                    /*启动总线*/
   ack = SendByte(sla);            /*发送器件地址*/
     if(ack==0)return(0);
   ack = SendByte(c);               /*发送数据*/
     if(ack==0)return(0);
   Stop_I2c();                 /*结束总线*/ 
   return(1);
}




/*******************************************************************
                    向有子地址器件发送多字节数据函数               
函数原型: uchar  ISendStr(uchar sla,uchar suba,uchar *s,uchar no);  
功能:     从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件
          地址sla,子地址suba,发送内容是s指向的内容,发送no个字节。
           如果返回1表示操作成功,否则操作有误。
注意:    使用前必须已结束总线。
********************************************************************/
uchar ISendStr(uchar sla,uchar suba,uchar *s,uchar no)
{
   uchar i,ack;

   Start_I2c();                     /*启动总线*/
 
   ack = SendByte(sla);             /*发送器件地址*/
   if(ack==0)return(0);
   
   ack = SendByte(suba);            /*发送器件子地址*/
   if(ack==0)return(0);

   for(i=0;i<no;i++)
    {   
     	ack = SendByte(*s);         /*发送数据*/
        if(ack==0)return(0);
        s++;
    } 

   Stop_I2c();                 /*结束总线*/ 
   return(1);
}






/*******************************************************************
                    向无子地址器件读字节数据函数               
函数原型: uchar  IRcvByte(uchar sla,uchar *c);  
功能:     从启动总线到发送地址,读数据,结束总线的全过程,从器件地
          址sla,返回值在c.
           如果返回1表示操作成功,否则操作有误。
注意:    使用前必须已结束总线。
********************************************************************/
uchar IRcvByte(uchar sla,uchar *c)
{
   uchar ack;

   Start_I2c();                /*启动总线*/
   ack = SendByte(sla + 1);      /*发送器件地址  +1 代表读 */
   if(ack==0)return(0);
   *c = RcvByte();             /*读取数据*/
   Ack_I2c(1);               /*发送非就答位*/
   Stop_I2c();                  /*结束总线*/ 
   return(1);
}



/*******************************************************************
                    向有子地址器件读取多字节数据函数               
函数原型: uchar  ISendStr(uchar sla,uchar suba,uchar *s,uchar no);  
功能:     从启动总线到发送地址,子地址,读数据,结束总线的全过程,从器件
          地址sla,子地址suba,读出的内容放入s指向的存储区,读no个字节。
           如果返回1表示操作成功,否则操作有误。
注意:    使用前必须已结束总线。
********************************************************************/
uchar IRcvStr(uchar sla,uchar suba,uchar *s,uchar no)
{
   uchar i, ack;

   Start_I2c();               /*启动总线*/
  
   ack = SendByte(sla);            /*发送器件地址*/
   if(ack==0)return(0);
   
   ack = SendByte(suba);            /*发送器件子地址*/
   if(ack==0)return(0);

   Start_I2c();
   ack = SendByte(sla + 1);       // +1 代表读
   if(ack==0)return(0);

   for(i=0;i<no-1;i++)
    {   
     *s=RcvByte();               /*发送数据*/
      Ack_I2c(0);                /*发送就答位*/  
     s++;
    } 
   *s=RcvByte();
    Ack_I2c(1);                 /*发送非应位*/
    
    Stop_I2c();                    /*结束总线*/ 
    return(1);
}

/**************************************************************************
                     写函数                				                  *
函数原型: void  write_24lc16b(uint adrress, uchar *data, uchar number); *
功能:       向24lc16b以address地址开始的单元写number个数据,number从1到16 *
  
**************************************************************************/

⌨️ 快捷键说明

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