秒表暂停与定时器不冲突

        作为一个初学者第一次做项目就把目光放在了不需要什么传感器的数码管上,上手后才发现还是有点难度的,首先数码管与单片机直连需要消耗的资源太多,所以选择了用74HC138作为段选器选择哪一位数码管亮,用74HC595芯片作为数码管的位选选择其段码。

 

管脚号管脚名称作用
1 ~ 7,15Q1~Q7,Q15输出端
8GED电源地
9Q7S级联输出,与下一个595 DS段连接
10MR清除移位寄存器数据(低电平有效),一般不用
11SHCP此引脚上升沿时,移位寄存器后移,接收新数据
12STCP上升沿时数据放进存储寄存器
13OE使能控制(低电平有效)
14DS数据写入端
16VCC供电端

138译码器,就是把 3 种输入状态翻译成 8 种输出状态。从图所能看出来的74HC138 有 1~6 一共是 6 个输入引脚, 4,5,6 是使能引脚。Y0 到 Y7 为输出引脚。

引脚定义 

引脚号引脚名称作用
1,2,3A0,A1,A2输入引脚
4,5E1,E2使能引脚(低电平有效)
6E3使能引脚(高电平有效)
7,9 ~ 15Y0 ~ Y7输出引脚
8GND电源地
16VCC电源

 电路图如下所示

         OK接下来是段选时间!! 当我们要选择第七位时 转换成二进制是0111,A0 = 0111&0x01取最后一位给A0,A1 = 0111 & 0x01 >> 1将第二位送给A1引脚 A2 = 0111 & 0x03 >> 2;将第三位送到A2引脚 可以定义一个子函数专门用来处理段选的数据 nod为选择的段位

void SHUMAGUAN_DUANXUAN_MOD(u8 nod)
{
     SEG_A0=  nod&0x01;
	 SEG_A1= (nod&0x02)>>1;
	 SEG_A2= (nod&0x04)>>2;
}

         段选搞定了后就要向这个位发送数据啦,在介绍74HC595芯片里了解到想要向寄存器中写入数据要先写入移位寄存器。所以在写入数据后需要手动给SHCP一个上升沿写入一位给一次

	for(i=0;i<8;i++)            
	{
		SEG_DATA = (dat>>i)&0x01;
		SEG_SCK=0;
		Delay10us();
		SEG_SCK=1;
	}

        经过8次循环数据已经完整的写入移位寄存器 现在需要将移位寄存器的值放入到存储器中手动给STCP引脚一个上升沿。这就是完整的写数据步骤。

        以下是我的程序段:定义了一个数组用来存放每一位的段码值需要改变数据时 只要更新数组里的值就可以。

u8 SEG8_Code[] ={
        0xFC, // 0
        0x60, // 1
        0xDA, // 2
        0xF2, // 3
        0x66, // 4
        0xB6, // 5
        0xBE, // 6
        0xE0, // 7
        0xFE, // 8
        0xF6, // 9
        0xEE, // A
        0x3E, // b
        0x9C, // C
        0x7A, // d
        0x9E, // E
        0x8E, // F
    };

		//断码显示数组
u8 SEG8_DispArray[8] ={0xFC,0xFC,0x02,0xFC,0xFC,0x02,0xFC,0xFC};

//初始化
void LEDseg_init(void)		     
{
  P3M1 &= 0xCB;	P3M0 |= 0x34;	       //数据口推挽输出
	P4M1 &= 0xEE;	P4M0 &= 0xEE;	       //段选口双向输入
	P5M1 &= 0xDF;	P5M0 &= 0xDF;	       //P5.5双向输入
	
	SEG_A0=1;			               
	SEG_A1=1;			               
	SEG_A2=1;			              
	SEG_LCLK=1;			             
	SEG_SCK=0;			             
	SEG_DATA=0;			             
}

//段选 7 = 0111;
void SHUMAGUAN_DUANXUAN_MOD(u8 nod)
{
   SEG_A0=  nod&0x01;
	 SEG_A1= (nod&0x02)>>1;
	 SEG_A2= (nod&0x04)>>2;
}

//写数据 将数据以移位的方式写入DS引脚 DS(数据引脚) SCK引脚上升沿时接收新数据
void SHUMAGUAN_WRITE_MOD(u8 nod)
{
	u8 dat,i;
	
	dat = SEG8_DispArray[nod];  
	for(i=0;i<8;i++)            
	{
		SEG_DATA = (dat>>i)&0x01;
		SEG_SCK=0;
		Delay10us();
		SEG_SCK=1;
	}
  SHUMAGUAN_DUANXUAN_MOD(nod);    
}

//更新数组里的数据
void SHUMAGUAN_Updata_MOD(u8 nod,u8 dat,u8 dp)
{
	EA = 0;
	SEG8_DispArray[nod] = SEG8_Code[dat] | dp;
	EA = 1;
}

//数据存储到存储器中上升沿有效
void CUNFANG(void)
{
	SEG_LCLK=1;
	Delay10us();
	SEG_LCLK=0;
}


//驱动数码管步骤 :写数据 (SCK引脚上升沿有效) 存储数据 (RCK上升沿有效)
void LEDseg_loop(void)
{
	SHUMAGUAN_WRITE_MOD(ledseg_nod);      
	CUNFANG();                   
	ledseg_nod++;
	if(ledseg_nod == 8)ledseg_nod = 0;  
}	

        数码管解决了按键直接一套消抖小连招送上,上电测试后发现消抖会用到延时函数,占用CPU按下按键时定时器时停止工作装态的,后面试了外部中断去掉抖动的延时发现按键不灵敏了,后来看江科大的视频发现可以使用一个定时器来扫描这些函数具体的实现过程是,定义一个定时器,定时器不断地扫描数码管,按键,如果按键有按下它当前的状态一定是高电平,它过去的状态一定是低电平所以只需要增加一个条件判断就可以去掉delay函数

 

 unsigned char key_read(void)
 {
	unsigned char temp = 0;
	 temp = key_flag;
	 return temp;
 }
 
//按下哪个按键
u8 buttons_scan(void)
{

	unsigned char keynum;
	
		keynum = 0;
	if(BUTTON1_P37 == BUTTON_PRESSED )
	{
		keynum = 1;
	}
	if(BUTTON2_P36 == BUTTON_PRESSED)
	{
		keynum = 2;
	}
	return keynum;
	
}

//按键按下判断
void button_loop(void)
{
	static unsigned char  last_state =0, now_state =0;
	
	last_state = now_state;
	now_state = buttons_scan();
	
	if(now_state == 0 && last_state == 1)
		key_flag = 1;
	if(now_state == 0 && last_state == 2)
		key_flag = 2;
}

         最后再用定时器不断调用 unsigned char key_read(void)函数就完美解决占用CPU资源的问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值