蓝桥杯单片机竞赛需要记住的寄存器与C语言模块代码(20种必背模块)总结

1. 需要记住的寄存器总结

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2. 需要记住的20种必背功能模块代码

//****************存储模块****************************//
void write_eeprom(unsigned char add,unsigned char val)
{  
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_SendByte(val);
	IIC_WaitAck();
	IIC_Stop();
}

write_eeprom(0,juli);
delay(10);
//在主函数里初始化读取  
juli=read_eeprom(0);

//读存储值
unsigned char read_eeprom(unsigned char add)
{  
	unsigned char temp;
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	
	IIC_Start();
	IIC_SendByte(0xa1);
	temp=IIC_RecByte();
	IIC_Ack(0);
	IIC_Stop();
	return temp;
}
//****************读ADC模块****************************//
unsigned char adc_pcf8591(unsigned char a)
{  unsigned char ad;
	 IIC_Start();
	 IIC_SendByte(0x90);
	 IIC_WaitAck();
	 IIC_SendByte(a);
	 IIC_WaitAck();
  
	 IIC_Start();
	 IIC_SendByte(0x91);
	 IIC_WaitAck();
	 ad=IIC_RecByte();//从总线上读数据
	IIC_Ack(0);  //应答
	 IIC_Stop();
	return ad;
}
//****************读ADC模块****************************//
//****************读DAC输出模块****************************//
void dac_pcf8591(unsigned char dat)
{
	i2c_start();
	i2c_sendbyte(0x90);
	i2c_waitack();
	i2c_sendbyte(0x40);  //DAC输出模式
	i2c_waitack();
	
	i2c_sendbyte(dat);
	i2c_waitack();
	i2c_stop();
}
//****************读DAC输出模块****************************//
//****************读时间模块****************************//
//---DS1302写入和读取时分秒的地址 ---//
//---秒分时日月周年-------//
uchar code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d}; 
uchar code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};

//---DS1302时钟初始化为2013年1月1日星期二12点00分00秒 ---//
uchar TIME[7] = {0, 0, 0x12, 0x01, 0x01, 0x02, 0x13};


unsigned char time_table[]={0x00,0x30,0x08};//必须要加0x00
unsigned char write[]={0x80,0x82,0x84};
unsigned char read[]={0x81,0x83,0x85};

void Ds1302_init()
{  
	unsigned char n;
	//Ds1302_Single_Byte_Write(0x8e,0x01); //可以省略
	for(n=0;n<2;n++)
	Ds1302_Single_Byte_Write(write[n],time_table[n]);
	//Ds1302_Single_Byte_Write(0x8e,0x00);
}

void read_time()
{  
	unsigned char i;
	for(i=0;i<2;i++)
	time_table[i]=Ds1302_Single_Byte_Read(read[i]);	
}
//****************读时间模块****************************//
//****************读温度模块****************************//
unsigned char read_18b20_data()
{
	unsigned char low,high,da;
	//温度转换命令
	Init_DS18B20();
	Write_DS18B20(0xcc);//跳过ROM操作
	Write_DS18B20(0x44);//温度转换命令
	Delay_OneWire(200);
	//发送温度转换
	Init_DS18B20();
	Write_DS18B20(0xcc);//跳过ROM操作
	Write_DS18B20(0xbe);//发送读取温度命令
	
	//读温度
	low=Read_DS18B20();
	high=Read_DS18B20();
	
	da=(low>>4)|(high<<4);
	return da;
}

//温度只需要读取,无需换算(为两位数)
buf[4]=temp/10;
buf[5]=temp%10;
//****************读温度模块****************************//
//****************数码管显示模块****************************//
//段选                                                 //--     //C
uchar duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff,0xc6};
//位选
uchar Disp_sbuf[]={10,10,11,10,10,11,10,10};
//一、显示第一种(首选第一种)
uchar Disp_i;
void Display()
 {
    P2=((P2&0X1F)|0XE0);
	P0=0XFF;
	P2&=0X1F;

	P0=1<<Disp_i;
	P2=((P2&0X1F)|0XC0);
	P2&=0X1F;

	P0=Disp_tab[Disp_sbuf[Disp_i]];
	P2=((P2&0X1F)|0Xe0);
	P2&=0X1F;

	if( ++Disp_i == 8 )
	{
	   Disp_i = 0;
	}
 }
//二、显示第二种
code duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};
uchar wei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

void display(uchar adr,uchar dat)
{ 
	uchar i=255;
	P2=P2&0x1f|0xc0;
	P0=wei[adr];
	P2=P2&0x1f|0Xe0;
	P0=duan[dat];
	while(i--);		
	P0=0xff;
	P2&=0x1f;
}

//定时器0
//显示函数放这里面
void time0()
{
	TMOD|=0X01;
	TH0=(65536-2000)/256;
	TL0=(65536-2000)%256;
	ET0=1;
	TR0=1;
	EA=1;
}

void time() interrupt 1
{
	TH0=(65536-2000)/256;
	TL0=(65536-2000)%256;
	display();
}
//****************数码管显示模块****************************//
//****************独立按键检测模块****************************//
Uchar R, key_value;
Void key ()
{
if((P3&0X0F)!=0X0F) 
	{
		delay(10); //10ms
		if((P3&0X0F)!=0X0F)
		{
		  	R=1;
			switch(P3&0X0F)
			{
			  case 0x0d: key_value=2;break;
			  case 0x0b: key_value=3;break;
			  case 0x07: key_value=4;break;
			}				
		}
	}	
 if(R==1)
 {
	R=0;
	return  key_value;
 }
	return 0xff;
}
//****************独立按键检测模块****************************//
//****************矩阵键盘检测模块****************************//
uchar key_re=0;
uchar key_press;
uchar key_value;
uchar key_1()
{
	static uchar col;
	P3=0xf0;P42=1;P44=1;
    if((P3!=0xf0)||(P42!=1)||(P44!=1)) 
        key_press++;
	else
		key_press = 0;    
    if(key_press == 3)
    {
			key_press = 0;
			key_re = 1;			
	//		if(P44 == 0)			col = 1;
			if(P42 == 0)			col = 0;
			if((P3 & 0x20) == 0)	col = 1;
			if((P3 & 0x10) == 0)	col = 2;
					
			P3 = 0x0F; P42 = 0; P44 = 0;
			if((P3&0x01) == 0)	key_value = (col+6);
			if((P3&0x02) == 0)	key_value = (col+3);
			if((P3&0x04) == 0)	key_value = (col+0);
			if((P3&0x08) == 0)	key_value = (col+9);
    } 	
    if(key_re == 1)
    {
        key_re = 0;
        return key_value;
    }    
    return 0xff;   
}
//****************矩阵键盘检测模块****************************//
//****************温度记录器模块****************************//
//温度记录器  间隔采集
uchar time[4]={1,5,30,60};//温度采集间隔可选值

void DisplayTime()
{
 static uchar CountNum,flag;
 uchar second=	Timevalue[0];//读取时间
 uint NowTime=Timevalue[1]*60+Timevalue[0];
 if(second-CountNum!=0)  //间隔闪烁
 {
		CountNum=second;
   
		flag++;
		flag%=2;
 }
 if((NowTime-FirstTime)!=0)//达到需要的时间
 {
    if((NowTime-FirstTime)%time[WidthNumIndex]==0)
    {
		FirstTime=NowTime;
		if(SaveTemp(Tempvalue)==1)//存储数据并判断是否存满
      	{
        MenNum=2;//数据存满 显示温度
        LEDcontrol(1);//开启LED
      	}
    }
 }
 if(flag)//间隔闪烁
 {
	DisplayBit(2,10);
	DisplayBit(5,10);
 }
	 DisplayBit(0,Timevalue[2]/16);
	 DisplayBit(1,Timevalue[2]%16);
	 DisplayBit(3,Timevalue[1]/16);
	 DisplayBit(4,Timevalue[1]%16);
	 DisplayBit(6,second/16);
	 DisplayBit(7,second%16);
}
//****************温度记录器模块****************************//
//****************模拟风扇控制系统****************************//
//模拟风扇控制系统  调占空比
uchar pwm_h=10;
uchar pwm_l=10; 
uchar pwm=0;    
void time1() interrupt 3  //一定是3
{ 
	if(pwm_flag==1)
	{ pwm++;
		if(pwm==pwm_h-pwm_count)
	     P04=1;
		if(pwm==pwm_l)
		{P04=0;
			pwm=0;
		}
	}
}
//****************模拟风扇控制系统****************************//
//****************LED控制模块****************************//
#define led1 0xfe
#define led2 0xfd
#define led3 0xfb
#define led_off 0xff
void tishi_led()
{
	 if(a==1)
	 { 
		P2=P2&0X1F|0X80;
		P0=led_off&led;
		P2&=0X1F;
	 }
	 if(a==0)
	 { 
		P2=P2&0X1F|0X80;
		P0=led_off;
		P2&=0X1F;
	 }
}
//****************LED控制模块****************************//
//****************模拟智能灌溉系统****************************//
//难点:手动模式切换提示音
#define buzz_open 0x40
#define relay_open 0x10
#define br_off 0x00
uchar buzz=buzz_open,relay=br_off;
if(moshi==1)
{      
		if(b1==0)
		{
			if(AD<yuzhi)
			{ 		
				P2=P2&0X1F|0XA0;
				P0=relay|buzz;//前者是继电器  或者 蜂蜜器
				P2&=0X1F;
				b1=1;b2=0;
			 }
	   } 
		if(b2==0)
		{
			if(AD>yuzhi)
			{
				P2=P2&0X1F|0XA0;
				P0=relay|br_off;
				P2&=0X1F;
				b1=0;b2=1;
			 }
		}
}
//****************模拟智能灌溉系统****************************//
//****************温度采集与控制装置****************************//
//难点:1.LED在不同模式下闪烁频率不同 2.修改温度上下限
//清除
	if(KeyValue==11)
	{ 
		for(i=0;i<4;i++)
		buf[i]=0;
		i=0;
	}
	if(MenNum&&(KeyValue<=9)) 
	{  //if(status)//不能删
//		{
//		  status=0;
			MenNum=2;
//		}		  	  
	 buf[i++]=KeyValue;//位置不能变
		i%=4;	
	
	  }		
	 }		
//不同频率闪烁
void timer_1() interrupt 1
{
	static uchar i=0,flag;
	TH0=(65536-10000)/256;  // 10ms
	TL0=(65536-10000)%256;
 	i++;
	switch(way)
	{	case 0:
				if(i==80)
				{ 
					i=0;
					flag++;
					flag%=2;
				 	if(flag) led_control(control,1);
					else led_control(control,0);	
				};break;
		case 1:
				if(i==40)
				{ 
					i=0;
					flag++;
					flag%=2;
				 	if(flag) led_control(control,1);
					else led_control(control,0);		
				};break;
		case 2:
				if(i==20)
				{ 
					i=0;
					flag++;
					flag%=2;
					 if(flag)
					led_control(control,1);
					else
					led_control(control,0);	
				};break;				
	}				 
}

//l当MAX<MIN时其L2一直亮
//LED控制
void  led_control(uchar a,uchar b)
{
	if(a&b)
	{
		P2=P2&0X1F|0X80;
		P0=0Xfc;     //低位前两位灯亮  or ~0x03
		P2&=0x1f;
	}
	else if(a&b==0)
	{
		P2=P2&0X1F|0X80;
		P0=0Xfd;
		P2&=0x1f;
	}
	else if(a==0&b)
	{
		 P2=P2&0X1F|0X80;
		 P0=~0X01;
		 P2&=0x1f;
	}
	else
	{
		 P2=P2&0X1F|0X80;
		 P0=0xff;
		 P2&=0x1f;
	}
}
//****************温度采集与控制装置****************************//
//****************超声波模块****************************//
//1.定时器0 
uchar wei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
uchar duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
void Init()
{
	P2=P2&0x1f|0x80;
	P2=P2&0x1f|0xa0;
	P0=0x00;
	P2&=0x1f;
}

void DisplayBit(uchar adr,uchar dat)
{
	uchar i=200;
	P2=P2&0x1f|0xc0;
	P0=wei[adr];
	P2&=0x1f;
	
	P2=P2&0x1f|0xe0;
	P0=duan[dat];
	while(i--);
	P0=0xff;
	P2&=0x1f;
}

void delay_8us()
{
	uchar i;
	_nop_();
	_nop_();
	i=21;
	while(i--);
}

uint StartCheck()
{
	uchar i;
	uint distance,time;
	for(i=0;i<8;i++)
	{
	  P10=1;
	  delay_8us();
	  P10=0;
	  delay_8us();
	}
	TR0=1;
	while(P11==1&&(TF0==0));
	TR0=0;
	if(TF0)
	{
	  TF0=0;
	  distance=4000;
	}
	else
	{
	  time=TH0;
	  time<<=8;
	  time|=TL0;
	  distance=(uint)(time*0.017);//us *1000000 =s *340m/s *100cm
	  TH0=0;
	  TL0=0;
	}
	return distance;
}

void Timerinit()
{
	TMOD|=0x01;
	TH0=0;
	TL0=0;
	TR0=0;
	TF0=0;
}
uint dis;
void main()
{
	uchar i=0;
	Init();
	Timerinit();
	while(1)
	{
	  dis=StartCheck();
	}
}

//2.定时器1
void time1()
{
	TMOD|=0X10;
	TH1=0;
	TL1=0;
	TR1=0;
}

void friger_t()   //振荡
{
uchar r=0;
	for(;r<8;r++)
	{
   Delay8us();//8US最好
   P10=~P10;
	}
}

//第一种“测距”核心代码
uint receive_distance()  
{
	uint distance;
	friger_t();	
	TR1=1;      //开始计数
	while((P11==1)&&TF1==0);  //正常接收返回低电平P11=0,溢出时返回TF1=1
	TR1=0;      //关闭计数
	if(TF1)
	{
	 TF1=0;
	 distance=150;
	}
	 else
	 {
	 distance=(uint)(8<<TH1)+TL1;
	 distance=distance*0.17*1.08; 
	 }
	 TH1=0;
	 TL1=0;
	return distance;
}

int main()   //主函数调用超声波模块
{
   int_1();
	time1();
	while(1)
	{
	if(flag==1)     //最好10MS读一次
	{
		flag=0;
		dis_juli=receive_distance();   //读距离
	}
		display1();
	}
}

//超声波的显示格式
DisplayBit(1,dis/1000);
DisplayBit(2,dis%1000/100);
DisplayBit(3,dis%100/10);
DisplayBit(4,dis%10);
  
//第二种“测距”核心代码
void trigSig()  
{  
    unsigned char i;  
    for(i=0;i<8;i++)  
    {  
        delayus();  //这个延时要保证P10保持在40Khz的情况下震荡  
        P10=~P10;   
    }  
}  

//接收并处理函数如下:(这里采用的是定时器1)
unsigned int recevieSig()  
{  
    unsigned int distance;  
    TH1=0;  
    TL1=0;     //初始化计数               
    trigSig();     //发送信号  
    TR1=1;     //开启定时器计数  
    while(P11==1&&TF1==0); //当P11=0或者计数计满时跳出   
    TR1=0;     //停止计数  
    if(TF1)     //表示计数计满 达到软件限定最远距离  
    {  
        distance =150;    
        TF1=0;  
    }  
    else  
    {  
        distance = (unsigned int)(TH1<<8)+TL1;  
        distance = distance *0.017*1.085;   //单位cm  
    }    
    return distance;  
}  
//****************超声波模块****************************//
//****************读电位器值(光敏电阻)模块****************************//
Temp = PCF8591_ADC_Read();
Temp = Temp * 0.0195 * 100;   
Disp_sbuf[5] = Temp / 100;
Disp_sbuf[6] = Temp % 100 / 10;
Disp_sbuf[7] = Temp % 10;
if(Temp > 100)
{
	P0=0Xfe;
	P2=((P2&0X1F)|0X80);	      
	P2&=0X1F;   
}
else
{
   P0=0Xfd;
   P2=((P2&0X1F)|0X80);
   P2&=0X1F;
}

//通过调adc控制LED的亮度
if(PCF85091_read_flag)
		{ 	PCF85091_read_flag=0;
			PCF85091_read_val = PCF85091_read(0x03);					 //1-4四个亮度		 0-255
	   		PCF85091_read_val = PCF85091_read_val/255*5;
		if((PCF85091_read_val >= 0)&&(PCF85091_read_val < 1.25))
	   {   	  
		  	LED_level_index =5;
	   }
 	   else if((PCF85091_read_val >= 1.25)&&(PCF85091_read_val < 2.5))
	   {  	  
		  	LED_level_index =10;
	   }
 	   if((PCF85091_read_val >= 2.5)&&(PCF85091_read_val < 3.75))
	   {	  
		  	LED_level_index =15;
	   }
 	   if((PCF85091_read_val >= 3.75)&&(PCF85091_read_val <= 5))
	   {  
		 	 LED_level_index =20;
	   }
	 }
	 
void time0() interrupt 1
{
	static uint q;
	TH0=(65536-1000)/256;
	TL0=(65536-1000)%256;
	j++;
	t++;
	q++;
  	display();
	if(q>=200)
	{
		q=0;
		PCF85091_read_flag =1;
	}
	if(key_value)
	{
		display1();
		key_value=0;
	}
	if(t==50){led_flag=1;}
	if(j >=20)  j=0;
	if(j <= LED_level_index)     
	{
	   P2=P2&0X1F|0X80;P0 =led_temp; P2&=0X1F;
	}
	else
	{
		 P2=P2&0X1F|0X80; P0 =0xff; P2&=0X1F;
	} 
}
//****************读电位器值(光敏电阻)模块****************************//
//****************几种按键控制模块总结****************************//
//一、一直按按键显示,不按不显示
void jiance_key()
{
	 key_return1 = key();
	  switch(key_return1)
	  {
			case 1:		LED_level_flag =1;    break;
			case 2:		
						{ 
						LED_level_flag =0;
						buf[0]=buf[1]=buf[2]=buf[3]=buf[4]=buf[5]=buf[6]=buf[7]=10; 					
						}break;	  
	  }
}

//二、两种一直按才执行的按键
//1. 第一种
uchar key()	
{															  
	key_press=0xff;
	if(P30==0) key_press=0x77;
	switch(key_state)   
	{
		case 0:if(key_press!=0xff){	key_state =1;break; }				//真的按下,还没有松开
	 	case 1:
		 	if(key_press!=0xff)
		 	{
		 		switch(key_press)
			{
				case 0x77: key_return =1;  break;
			}
				key_state =2;
			}
			else 
			{
				key_state =0;
				break;	 
			}
		case 2:
			if(key_press == 0xff)
			{
			key_state =0;
			key_return =2;
			break;
			}
	}
	return key_return;
}

//第二种 时间超短(比赛用)
uchar key_scan()
{
 	keypress=0xff;
	if(P30==0)keypress=0x66;
	switch(keypress)
		{ 
		case 0x66:return 0;break;
		case 0xff:return 1;break;
    	}
}

//三、长按键(按一段时间才执行)
if(P30==0)  
 {
	delay(300); //多延长点时间就可以实现
	if(P30==0)
	{
		R=1;
		key_value=1;	 
	}
	while(!P30);
 }
 //****************几种按键控制模块总结****************************//
//****************串口模块总结****************************//
//一、串口发送数据
void send_data(uchar c)   //发送单个字符
{
	SBUF=c;
	while(!TI);
	TI=0;
}

void sedn_str(uchar str[],uchar len)  //发送字符串
{
	uchar i=0;
	for(;i<len;i++)
	{
		send_data(str[i]);	
	}
}

void send_temp()    //发送温度
{
	sedn_str("temp:",5);
	send_data('0'+temp/10);
	send_data('0'+temp%10);
	send_data('\r');
	send_data('\n');
}

void uart_int()
{
	SCON=0X50;  //选择模式一
	AUXR=0X00;
	TMOD|=0X20;
	PCON=0X80;//加这一句波特率变翻倍变为19200,没有这一句为4800
	TH1=0XFD;
	TL1=0XFD;
	TR1=1;
}
//二、串口接收数据
void uart_int()
{
	SCON=0X50;
	TMOD|=0X20;
	AUXR=0X00;
	PCON=0X80;//¼ÓÕâÒ»¾äÖ®ºó²¨ÌØÂÊ·­±¶Îª19200£¬È¥µôÖ®ºóΪ4800
	TH1=0XFD;
	TL1=0XFD;
	TR1=1;
	//加上中断就可以在中断里接收了
	ES=1;
	EA=1;
}
//接收数字用HEX模式,字符用文本模式
void recive_data() interrupt 4
{
	if(RI)
	{
		RI=0;
		flag=SBUF;
	}
}
//****************串口模块总结****************************//
//****************ds1302写时间总结****************************//
//ds1302写时间
//DS1302写小时
void WriteHour(uchar Hour)
{
	Hour %= 24;
	Ds1302_Single_Byte_Write(ds1302_hr_addr,((Hour / 10) << 4) | (Hour % 10));	
}

//DS1302写分钟
void WriteMinute(uchar Minute)
{
	Minute %= 60;
	Ds1302_Single_Byte_Write(ds1302_min_addr,((Minute / 10) << 4) | (Minute % 10));
}

//DS1302写秒
void WriteSecond(uchar Second)
{
	uchar dat;
	Second %= 60;
	dat = (Ds1302_Single_Byte_Read(ds1302_sec_addr) & 0x80) | ((uchar)(((Second / 10) << 4) | (Second % 10)));	
	Ds1302_Single_Byte_Write(ds1302_sec_addr,dat);
}
//****************ds1302写时间总结****************************//
//****************频率信号输入总结****************************//
//频率信号输入
void time1()   //定时模式
{
	TMOD&=0X0F;
	AUXR&=0XBF;
	TH1=0XFC;
	TL1=0X66;
	ET1=1;
	TR1=1;
	EA=1;
}

void time0() //计数模式
{
	TMOD|=0X05;
	AUXR&=0X7F;  //选择12分频
	TH0=0x00;
	TL0=0x00;
	TF0=0;
	TR0=1;
}

int main()
{
	int_1();
	time0();
	time1();	
	while(1)
	{
	display1();
	}
}

void time_zd() interrupt 3
{
	static uint time=0;
	if(++time==1000)
	{
		TR0=0;
		time=0;
		fre=TH0*256+TL0;
		TH0=0;
		TL0=0;
		TR0=1;
	}
	display();
}
//****************频率信号输入总结****************************//
//****************外部中断总结****************************//
//外部中断
-----S5-INT0----
-----S4-INT1----

Void int()
{
	EX0 = 1;
    IT0 = 1;  //边沿触发方式(下降沿)
    EX1 = 1;
    IT1 = 1;  //边沿触发方式(下降沿)      
	EA = 1;  //开启总中断
}

void isr_intr_0(void) interrupt 0
{
	P2 = ((P2&0x1f)|0x80);
    LED1 = ~LED1;    
	P2 = P2&0x1f;
}
                        
void isr_intr_1(void) interrupt 2
{
	P2 = ((P2&0x1f)|0x80);
    LED2 = ~LED2;    
	P2 = P2&0x1f;
}
//****************外部中断总结****************************//

3. 蓝桥杯单片机竞赛各种必背练习模块及代码汇总

   汇总文件地址自取

🤞🤞🤞

以上代码需根据具体代码场景调整(例如变量和函数名称),如有错误请及时提出, 创作不易,请伸出您发财的小手,打赏下博主,谢谢。

🤞🤞🤞

  • 18
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,以下是使用 Verilog 语言实现的入串出移位寄存器模块代码: ```verilog module shift_register( input wire clk, input wire reset, input wire serial_in, output reg serial_out, output reg[7:0] parallel_out ); reg[7:0] data; always @(posedge clk or negedge reset) begin if(!reset) begin data <= 8'b0; end else begin data <= {data[6:0], serial_in}; end end assign parallel_out = data; assign serial_out = data[7]; endmodule ``` 该模块有五个输入输出端口: - `clk`:时钟信号,用于控制寄存器的移位。 - `reset`:复位信号,用于将寄存器清零。 - `serial_in`:串行输入信号,用于接收输入数据。 - `serial_out`:串行输出信号,用于输出寄存器中的最高位数据。 - `parallel_out`:并行输出信号,用于输出寄存器中的所有数据。 在时钟信号的上升沿触发时,将数据向左移动一位,同时将串行输入的数据放在最低位。在复位信号为低电平时,将寄存器中的所有数据清零。 以下是使用 Verilog 语言实现的测试代码: ```verilog module test_shift_register; reg clk, reset, serial_in; wire serial_out; wire[7:0] parallel_out; shift_register dut( .clk(clk), .reset(reset), .serial_in(serial_in), .serial_out(serial_out), .parallel_out(parallel_out) ); initial begin clk = 0; reset = 1; serial_in = 0; #10 reset = 0; end always #5 clk = ~clk; initial begin $monitor("serial_out=%b parallel_out=%b", serial_out, parallel_out); #100 serial_in = 1; #100 serial_in = 0; #100 serial_in = 1; #100 serial_in = 0; #100 $finish; end endmodule ``` 在测试代码中,我们通过生成时钟信号和输入数据信号来对寄存器进行测试,并使用 `$monitor` 内置函数实时显示寄存器的输出结果。 首先将复位信号置为高电平,然后等待一段时间后将其置为低电平,表示开始测试。随后,每隔一定时间就向寄存器中输入一个比特位,最后等待一段时间后结束测试。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时空旅行者 陈俊松

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值