|
本帖最后由 duocool 于 2018-5-22 08:54 编辑
先上最终效果,感觉还是可以的,不过要是想完美,得像卖得挺火的那种木壳钟一样,平常像块木头,显示的时候才透出来,不过没找到合适的外壳。
最近想用arduino-esp8266网上抓点东西下来玩,先试了试OLED模块,网上0.9寸的多,怕小买了1.3寸的,倒是搞定了显示,不过感觉还是小,不够用。
还有种办法是用电子纸模块,淘宝上也有现成的,不过2,3百的价钱感觉性价比不高。后来决定用下面这种Max7219 8段数码管模块
这种模块从5块多到10多块,样子都差不多,都宣称三线驱动,支持级联,有例程。有焊的也有没焊接口的,我省事买了7块多的焊了的,后的发觉要级联还是得焊,还不如买没焊接口的,自己接线还能紧凑点。
然后就是填级联这个坑了。最省力的应该是用LedControl这个库了,论坛里也有用这个库max7219 级联LED点阵的例子。不过不管怎么试,都是报错,好象这个库是不支持esp8266的。问卖家要到例程,arduino的例程只有单个模块的,这个样子,没用什么库,感觉就是别的单片机的c代码直接移值过来的。
[mw_shl_code=bash,true]/*******************************************************************************
* Software Author: HQ
* Creation Date: 2015-2-10
* Software History: 2015-3-10
* Version: 2.0
* Sales address: http://qifeidz.taobao.com/
********************************************************************************/
//模块引脚定义
int CLK = 2;
int CS = 1;
int DIN = 0; //这里定义了那三个脚
void setup() {
// put your setup code here, to run once:
pinMode(CLK,OUTPUT);
pinMode(CS,OUTPUT);
pinMode(DIN,OUTPUT); //让三个脚都是输出状态
}
void loop() {
// put your main code here, to run repeatedly:
Delay_xms(50);
Init_MAX7219();
Delay_xms(2000);
Write_Max7219(0x0f, 0x00); //显示测试:1;测试结束,正常显示:0
Write_Max7219(1,8);
Write_Max7219(2,7);
Write_Max7219(3,6);
Write_Max7219(4,5);
Write_Max7219(5,4);
Write_Max7219(6,3);
Write_Max7219(7,2);
Write_Max7219(8,1);
while(1);
}
void Delay_xms(unsigned int x)
{
unsigned int i,j;
for(i=0;i<x;i++)
for(j=0;j<112;j++);
}
//--------------------------------------------
//功能:向MAX7219(U3)写入字节
//入口参数:DATA
//出口参数:无
//说明:
void Write_Max7219_byte(unsigned char DATA)
{
unsigned char i;
digitalWrite(CS,LOW);
for(i=8;i>=1;i--)
{
digitalWrite(CLK,LOW);
if(DATA&0X80)
digitalWrite(DIN,HIGH);
else
digitalWrite(DIN,LOW);
DATA<<=1;
digitalWrite(CLK,HIGH);
}
}
//-------------------------------------------
//功能:向MAX7219写入数据
//入口参数:address、dat
//出口参数:无
//说明:
void Write_Max7219(unsigned char address,unsigned char dat)
{
digitalWrite(CS,LOW);
Write_Max7219_byte(address); //写入地址,即数码管编号
Write_Max7219_byte(dat); //写入数据,即数码管显示数字
digitalWrite(CS,HIGH);
}
void Init_MAX7219(void)
{
Write_Max7219(0x09, 0xff); //译码方式:BCD码
Write_Max7219(0x0a, 0x03); //亮度
Write_Max7219(0x0b, 0x07); //扫描界限;4个数码管显示
Write_Max7219(0x0c, 0x01); //掉电模式:0,普通模式:1
Write_Max7219(0x0f, 0x01); //显示测试:1;测试结束,正常显示:0
}[/mw_shl_code]
试了下,可以用。级联怎么解决呢,网上反复找,这里有篇写的http://www.geek-workshop.com/for ... p;highlight=max7219控制led点阵的,试着小改用了用,显示还是乱的,不行。又搜到这个贴http://lib.csdn.net/article/embeddeddevelopment/63594 MAX7219多级联串行控制多个点阵/数码管的详解 用的是c语言,都不是写给arduino用的,不过我一看注释那么熟,有些部分简直和卖家给的例程一模一样,可以肯定他们都有一个共同的祖先。仔细研究后,发现级联的关键是写后面的模块就得把它前面的模块写空。像这样
[mw_shl_code=bash,true]/*第二片MAX7219的写入数据*/
void Write_Max7219_2(uchar add2,uchar dat2)
{
Max7219_pinCS=0;
Write_Max7219_byte(add2);
Write_Max7219_byte(dat2);
Max7219_pinCLK=1;
Write_Max7219_byte(0x00); //片1写入空
Write_Max7219_byte(0x00);
Max7219_pinCS=1;
}
/*第三片MAX7219的写入数据*/
void Write_Max7219_3(uchar add3,uchar dat3)
{
Max7219_pinCS=0;
Write_Max7219_byte(add3);
Write_Max7219_byte(dat3);
Max7219_pinCLK=1;
Write_Max7219_byte(0x00); //片1写入空
Write_Max7219_byte(0x00);
Write_Max7219_byte(0x00); //片2写入空
Write_Max7219_byte(0x00);
Max7219_pinCS=1;
}[/mw_shl_code]
我的代码如下: 定义了一个总的片数,然后用循环把初始化数码管模块和写每片的数据都统一起来了,这样不管是写一片,还是8片,代码都是一样的长度(好象max7219最多就支持8片),还自定义了一个DP参数,解决了卖家例程没写的小数点有无的问题。卖家例程是在loop中初始化模块的,这样显示感觉有闪烁,我移到setup中初始化,闪烁就没了
[mw_shl_code=bash,true]//模块引脚定义
int CLK = D6;
int CS = D7;
int DIN = D8; //这里定义了那三个脚
int PIECENUM = 4;//数码管片数
void setup() {
// put your setup code here, to run once:
pinMode(CLK, OUTPUT);
pinMode(CS, OUTPUT);
pinMode(DIN, OUTPUT); //让三个脚都是输出状态
Delay_xms(50);
Init_MAX7219(PIECENUM);
Delay_xms(2000);
}
void loop() {
// put your main code here, to run repeatedly:
Write_Max7219(1, 0x0f, 0x00, 0); //显示测试:1;测试结束,正常显示:0
for (int i = 1; i <= 5; i++) {
Write_Mynum(1, i, i + 1, 1);
}
//Write_Mynum(1, 7, '_', 0);
// Write_Mynum(1, 8, '_', 0);
for (int i = 1; i <= 8; i++) {
Write_Mynum(2, i, 2, 0);
}
for (int i = 1; i <= 8; i++) {
Write_Mynum(3, i, 3, 0);
}
for (int i = 1; i <= 8; i++) {
Write_Mynum(4, i, 8 - i, 1);
}
while (1);
}
void Delay_xms(unsigned int x)
{
unsigned int i, j;
for (i = 0; i < x; i++)
for (j = 0; j < 112; j++);
}
//切换地址,方便写
void Write_Mynum(int pnum, unsigned char address, unsigned char dat , int dp) {
Write_Max7219(pnum, 9 - address, dat, dp);
}
//--------------------------------------------
//功能:向MAX7219写入字节
//入口参数:DATA,dp显示小数点与否
void Write_Max7219_byte(unsigned char DATA, int dp)
{
unsigned char i;
digitalWrite(CS, LOW);
for (i = 8; i >= 1; i--)
{
digitalWrite(CLK, LOW);
if (i == 8 && dp == 1)
digitalWrite(DIN, HIGH);
else {
if (DATA & 0X80)
digitalWrite(DIN, HIGH);
else
digitalWrite(DIN, LOW);
}
DATA <<= 1;
digitalWrite(CLK, HIGH);
}
}
//-------------------------------------------
//功能:向MAX7219写入数据
//入口参数:pnum数码管片序号,address,dat,dp显示小数点与否
void Write_Max7219(int pnum, unsigned char address, unsigned char dat, int dp)
{
digitalWrite(CS, LOW);
Write_Max7219_byte(address, 0); //写入地址,即数码管编号
Write_Max7219_byte(dat, dp); //写入数据,即数码管显示数字
if (pnum > 1) {
digitalWrite(CLK, HIGH);
for (int i = 1; i < pnum; i++) {
Write_Max7219_byte(0X00, 0);
Write_Max7219_byte(0X00, 0);
}
}
digitalWrite(CS, HIGH);
}
//Max7219初始化
void Init_MAX7219(int pienum)
{
for (int i = 1 ; i <= pienum ; i++) {
Write_Max7219(i, 0x09, 0xff, 0); //译码方式:BCD码
Write_Max7219(i, 0x0a, 0x03, 0); //参数3:亮度
Write_Max7219(i, 0x0b, 0x07, 0); //扫描界限;参数3:8个数码管显示
Write_Max7219(i, 0x0c, 0x01, 0); //掉电模式:参数3:0,普通模式:1
Write_Max7219(i, 0x0f, 0x01, 0); //显示测试:参数3:1;测试结束,正常显示:0
}
}
[/mw_shl_code]
|
|