标题:
这个单片机点阵的段选和位选是啥意思,整不明白位选为啥还取反了
[打印本页]
作者:
liangsheng0212
时间:
2020-4-14 19:50
标题:
这个单片机点阵的段选和位选是啥意思,整不明白位选为啥还取反了
代码:
/**************************************************************************************
* LED点阵--显示汉字实验 *
实现现象:下载程序后,按照光盘内操作视频接线,LED点阵显示汉字
注意事项:必须将74HC595模块的JP595短接片短接,否则不会出现现象
***************************************************************************************/
#include "reg51.h" //此文件中定义了单片机的一些特殊功能寄存器
#include "intrins.h"
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
//--定义使用的IO口--//
sbit SRCLK=P3^6;
sbit RCLK=P3^5;
sbit SER=P3^4;
//定义LED点阵的位选,也就是类似于数码管的位选,因为要对其动态扫描操作
//数组前16位和后16位数据正好是相反的,也就是说先让第3个595输出低电平,然后再让第4个595输出低电平
u8 code ledwei[]=
{
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
};
u8 code ledduan1[]=
{
/*-- 文字: 普 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x40,0x44,0x54,0x64,0x45,0x7E,0x44,0x44,0x44,0x7E,0x45,0x64,0x54,0x44,0x40,0x00,
0x00,0x00,0x00,0xFF,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0xFF,0x00,0x00,0x00,0x00,
};
u8 code ledduan2[]=
{
/*-- 文字: 中 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0xFF,0x10,0x10,0x10,0x10,0xF0,0x00,0x00,0x00,
0x00,0x00,0x0F,0x04,0x04,0x04,0x04,0xFF,0x04,0x04,0x04,0x04,0x0F,0x00,0x00,0x00,
};
/*******************************************************************************
* 函 数 名 : delay
* 函数功能 : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)
{
while(i--);
}
/*******************************************************************************
* 函 数 名 : Hc595SendByte(u8 dat1,u8 dat2,u8 dat3,u8 dat4)
* 函数功能 : 通过595发送四个字节的数据
* 输 入 : dat1:第4个595输出数值
* * dat2: 第3个595输出数值
* * dat3:第2个595输出数值
* * dat4:第1个595输出数值
* 输 出 : 无
*******************************************************************************/
void Hc595SendByte(u8 dat1,u8 dat2,u8 dat3,u8 dat4)
{
u8 a;
SRCLK = 1;
RCLK = 1;
for(a=0;a<8;a++) //发送8位数
{
SER = dat1 >> 7; //从最高位开始发送
dat1 <<= 1;
SRCLK = 0; //发送时序
_nop_();
_nop_();
SRCLK = 1;
}
for(a=0;a<8;a++) //发送8位数
{
SER = dat2 >> 7; //从最高位开始发送
dat2 <<= 1;
SRCLK = 0; //发送时序
_nop_();
_nop_();
SRCLK = 1;
}
for(a=0;a<8;a++) //发送8位数
{
SER = dat3 >> 7; //从最高位开始发送
dat3 <<= 1;
SRCLK = 0; //发送时序
_nop_();
_nop_();
SRCLK = 1;
}
for(a=0;a<8;a++) //发送8位数
{
SER = dat4 >> 7; //从最高位开始发送
dat4 <<= 1;
SRCLK = 0; //发送时序
_nop_();
_nop_();
SRCLK = 1;
}
RCLK = 0;
_nop_();
_nop_();
RCLK = 1;
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
u8 i;
while(1)
{
for(i=0;i<16;i++)
{
Hc595SendByte(~ledwei[i+16],~ledwei[i],ledduan1[16+i],ledduan1[i]);
delay(10);
}
}
}
复制代码
作者:
群样儿
时间:
2020-4-14 22:35
比如你要控制8个数码管,依次是1、2…… 8。你要选择控制哪个数码管(比如第1个),这就是位选,位有选择位置的意思。
然后呢,你要让第1个数码管显示源“1”。你就要控制第一个数码管的“a、b……g”也就是让b、c=0,a、d、e、f、g=1(或者b、c=1,a、d、e、f、g=0),这就是段选,即选择数码管的哪一笔段。
作者:
hulilanyua
时间:
2020-4-14 23:22
新手,总结一点自已的经验,就拿共阳数码管来说,有2种排列,a-dp和dp-a,“0”的段码分别是0x03和0xC0,“1”的段码分别是0x9F和0xF9,这就是段选。如果有2 个共阳数码管,动态扫描显示下管脚都并联在一起,不位选的情况下2 个共阳数码管显示相同的数据,这就是位选。
作者:
消逝的青盏
时间:
2020-4-20 16:56
位选就是选择点阵哪一列输出,相当于选择数码管哪一位
作者:
消逝的青盏
时间:
2020-4-20 17:51
位选就是选择点阵的某一列输出,相当于数码管位选
段选就是当你选择这一列的时候控制哪些LED灯点亮,相当于数码管段选
由于是动态扫描显示,所以由视觉残留效应,显示的字符像是静态的
至于位选取反,不懂你说的是在位选数组定义还是在主函数中
如果是在位选数组里,比如你要依次选择八位 输出数据为
0111 1111 //0x7f
1011 1111 // 0xbf
1101 1111 //0xdf
1110 1111 //0xef
1111 0111 //0xf7 从这里开始后四个数据就相当于前四个数据取反了
1111 1011 //0xfb
1111 1101 //0xfd
1111 1110 //0xfe
如果你想要问的是在主函数调用中,
位选若要选择最低位,按照位选数组中定义为0x01 即0000 0001
在实际电路中位选为低电平有效,故而要取反 即1111 1110
这么写大概是为了方便读代码吧
新手自己理解,希望对你有帮助
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1