LED数码管段码生成

LED数码管段码计算器


前言

最近在复习单片机的知识,写编写LED数码管的驱动时,嫌计算太麻烦,就做了个WinForm项目

正文

原理

这里的LED数码管指的是8段数码管
在这里插入图片描述

我们可以看到每个LED数码管都是由7条线和一个点组成的,它们实际上都是LED灯(发光二极管),驱动一个LED数码管,就是点亮相应的LED灯。

LED数码管有两种连接方式,分别是共阴(cathode)、共阳(anode)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0h71s77V-1594570307669)(https://i.loli.net/2020/07/12/6Wy48hnYNjQxsDZ.png)]

不难看出,若用共阳的连接方式,则向对应的管脚输入低电平,该led灯就会被点亮;相反,若使用共阳的连接方式,则需要向对应的管脚输入高电平,才能点亮led灯。

要使LED数码管显示数字“0”,则需要点亮a、b、c、d、e、f,若规定dp位为高位,a位为低位并且使用共阴的连接方式,那么此时的段码就是0011 1111,hex码为0x3f。若使用共阳的连接方式那么bin码就是1100 0000,hex码0xc0。可以看出,共阳的段码取反就是共阴了。

编程

UI长这样

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DUAcUpZY-1594570307672)(https://i.loli.net/2020/07/12/bPIzqJj4oYdcyeR.png)]

PS:不要吐槽我待合格的美术,谢谢

数码管呢,是自己写的用户控件,其实就是8个PictureBox(name分别是a、b、c、d、e、f、g、h),背景色什么的设置一下不就行了对吧(~ ̄▽ ̄)~,咳咳,这个控件类里面呢,有定义一个SegmentCode类,当然了,这个类也是我自己写的

 	public class SegmentCode
    {
		//这个是段码,我用字典存储它,用a,b,c,d,e,f,g,h来做键,0与1做值
        public Dictionary<char, int> dic = new Dictionary<char, int>();
		//这个枚举变量存储的是连接方式        
		public Ode ode;

        public SegmentCode()
        {
            ode = Ode.anode;	//默认共阳连接
            for(int i = 0; i < 8; i++)
            {
				//初始化字典,默认都为熄灭状态,97是'a'的ASCII码
                dic[(char)(97 + i)] = 0;
            }
        }

		//这个方法看下文详解
        public String getCode()
        {
            Int32 date = 0x00;
            for (int i = 7; i >= 0; i--)
            {
                date <<= 1;
                date |= dic[(char)(97 + i)];
            }

            if (ode.Equals(Ode.anode))
            {
                date = ~date; 
            }
            String s = Convert.ToString(date, 16);
			if(s.Length < 2)
			{
				return s.PadLeft(2,'0');
			}
            return s.Substring(s.Length - 2, 2);
        }
    }
    public enum Ode
    {
        anode,
        cathode
    }

如何从字典转为hex码呢?由于我太菜了,所以想了很久,最后在学习EEPROM-IIC总线通讯,编写AT24C02的驱动时,发现了这个函数:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b3AG3a8b-1594570307673)(https://i.loli.net/2020/07/12/pBArFRSiVoU8ht2.png)]

从中得到启发,解决了这个从字典转为hex的难题(笑)

来看看这个方法如何把字典转为hex码

假设现在遍历字典的结果是:

a:1
b:1
c:0
d:1

e:1
f:1
g:0
h:1

  1. 当i= =7时,date左移一位赋值给自身,最高位移出,最低位补0。即date==0000 0000

  2. date按位或dic[‘h’] PS:104是’h’的ASCII码

    date---|0000 0000

    dic[h]-|0000 0001

    result-|0000 0001

  3. 此时date==0000 0001

  4. 当i–,i= =6时,date左移位赋值,即date==0000 0010

  5. date按位或dic[‘g’] PS:103是’g’的ASCII码

    date---|0000 0010

    dic[g]-|0000 0000

    result-|0000 0010

  6. 此时date==0000 0010

  7. 同理,在循环结束时date==1011 1011

  8. 此时的date是共阴连接的bin码,如果是共阳连接,就对date取反赋值

	String s = Convert.ToString(date, 16)
  1. 这句就是把date转为16进制格式的字符串
	return s.Substring(s.Length - 2, 2);
  1. 如果是共阳连接,输出的结果可能前面有一大堆f,那是因为int32不是8位的,它占4个字节,即32位,所以取反之后,date==1111 1111 1111 1111 1111 1111 0100 0100,所以在正常结果之前会有6个f多出来,我们只需要倒数两位数字就行了
	return s.PadLeft(2,'0');
  1. 如果位数不够两位,就补0

因为懒,我就把8个PictureBox的单击事件全写一个了,无非是改变颜色,改变状态,另外两个就是获取hex码的方法和设置连接方式,没啥好说的。

		SegmentCode seg = new SegmentCode();
        Ode ode = Ode.anode;

    	private void ClickProce(object sender,EventArgs e)
       	{
			//sender实际上就是PictureBox本Box
            PictureBox pbox = sender as PictureBox;
            if (pbox.BackColor.Equals(SystemColors.ControlDark))
            {
                pbox.BackColor = Color.Red;
				//pbox.Name.ToCharArray()[0]实际上就是PictureBox的Name了(即a、b、c、d、e、f、g、h)
                this.seg.dic[pbox.Name.ToCharArray()[0]] = 1;
            }
            else
            {
                pbox.BackColor = SystemColors.ControlDark;
                this.seg.dic[pbox.Name.ToCharArray()[0]] = 0;
            }
        }
		
		public String getHexCode()
        {
            seg.ode = this.ode;
            return seg.getCode();
        }

        public void SetOde(Ode ode)
        {
            this.ode = ode;
        }

接下来就是控件使用了

		private void calc_Click(object sender, EventArgs e)
        {
            if(this.cathode.Checked)
            {
                this.led1.SetOde(Ode.cathode);
            }
            else if(this.anode.Checked)
            {
                this.led1.SetOde(Ode.anode);
            }
            this.date.Text = "HexCode: " + this.led1.getHexCode();
        }

看看效果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eZawMQOY-1594570307676)(https://i.loli.net/2020/07/12/FJNIgGOES8HxZvm.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tXKPM3jp-1594570307678)(https://i.loli.net/2020/07/13/32SzipAJB1UoWM5.png)]

Github

Click me

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

正崽不emo

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

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

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

打赏作者

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

抵扣说明:

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

余额充值