MAX7221的参考资料,我待补充:
先上代码
#include <reg51.h>
#include <intrins.h>
sbit DIN = P2^0; //数据串出引脚
sbit CS = P2^1; //片选端
sbit CLK = P2^2; //移位时钟端
// 延时函数
void delayms(unsigned int x){
unsigned char i;
while(x--) for(i = 0;i < 120;i++);
}
void write_data(unsigned char addr,unsigned char dat)
{
unsigned char i;
CS = 0; // 拉低CS选中芯片 先写地址,片选置低,串行数据加载到移位寄存器
for(i = 0;i < 8;i++) //传输地址
{
CLK = 0; //时钟上升沿数据移入内部移位寄存器
addr <<= 1; //待发送的地址,每次左移一次,高位在前发送,
DIN = CY; //数据移位后,如果有溢出,则可以从进位位CY中获得溢出的数据位
CLK = 1; // 拉高时钟线,写入数据
_nop_(); //延迟1Us
_nop_();
CLK = 0; //下降沿时数据从DOUT移出
}
for(i = 0;i < 8;i++) // 传输数据
{
CLK = 0;
dat <<= 1; //发送数据
DIN = CY;
CLK = 1;
_nop_();
_nop_();
CLK = 0;
}
CS = 1; //CS上升沿,数据锁存
}
//初始化函数
void init_max7221(void)
{
write_data(0x09,0xff); //解码模式选择 8个位分别控制8个LED是否解码,'1'为BCD解码,'0'为不解码
write_data(0x0a,0x07); //初始亮度设置 0-15设置1-16档亮度
write_data(0x0b,0x07); //扫描方式选择 0-7 设置扫描1-8个LED(通俗就是控制数码管的位)
write_data(0x0c,0x01); //工作模式选择 1:正常工作 0:掉电模式(开关)
write_data(0x0f,0x00); //测试模式开关 1:测试模式 0:正常工作
}
void main(void)
{
int i,j;
init_max7221(); // 初始化
for(i=0;i<8;i++) write_data(i+1,i),delayms(500);
delayms(2000);
while(1)
{
// write_data(1,8);
// write_data(2,9);
// write_data(3,10); //"-"
// write_data(4,11); //"E"
// write_data(5,12); //"H"
// write_data(7,13); //"L"
// write_data(8,14); //"P"
// write_data(8,15); //全灭 我只是一个一个试的,一起显示出现乱码
}
}
形成现象的
以上两图可以看出:
1、MAX7221是可以动态可变的(可能需要加上初始化最后一句)
2、MAX7221串口的使用想象(一组数据从U2流到U3,相差一帧)(我一帧一帧快进的)
3、显示现象“——”的值为10
4、MAX7221还要一直运行着,要不没显示;(因为它是串口寄存器);如果不运行,最后一个不会消失,就像上图一样;
如何让数码管的小数点亮引出的问题,探索:
问题在初始化配置的问题:探索后做过形成现象,显示修改后的代码
//初始化函数
void init_max7221(void)
{
write_data(0x09,0xf0); //解码模式选择 8个位分别控制8个LED是否解码,'1'为BCD解码,'0'为不解码 低4位不解码
write_data(0x0a,0x0f); //初始亮度设置 0-15设置1-16档亮度 15
write_data(0x0b,0x03); //扫描方式选择 0-7 设置扫描1-8个LED(通俗就是控制数码管的位) 扫描前4个
write_data(0x0c,0x01); //工作模式选择 1:正常工作 0:掉电模式(开关)
write_data(0x0f,0x00); //测试模式开关 1:测试模式 0:正常工作
}
void main(void)
{
int i,j;
init_max7221(); // 初始化
while(1);
}
有改动,亮度15,扫描3,低4位不解码
对应现象:
初始化的现象,我进入while(1);(CC共阴数码管,下面都是)
和上面有点改动,把原来断开的都连上了,(测试电平-高电平)也去掉;全部解码(代码也改了)
对解码、扫描、亮度和对应的段码的相关探索,修改后的代码,只显示修改的代码
//初始化函数
void init_max7221(void)
{
// write_data(0x09,0xf0); //解码模式选择 8个位分别控制8个LED是否解码,'1'为BCD解码,'0'为不解码 低四位不解码
write_data(0x09,0x00); //解码模式选择 8个位分别控制8个LED是否解码,'1'为BCD解码,'0'为不解码 低四位不解码
write_data(0x0a,0x0f); //初始亮度设置 0-15设置1-16档亮度 最亮
// write_data(0x0b,0x03); //扫描方式选择 0-7 设置扫描1-8个LED(通俗就是控制数码管的位)
write_data(0x0b,0x07); //扫描方式选择 0-7 设置扫描1-8个LED(通俗就是控制数码管的位)
write_data(0x0c,0x01); //工作模式选择 1:正常工作 0:掉电模式(开关)(长时间不用还可以关着)
write_data(0x0f,0x00); //测试模式开关 1:测试模式 0:正常工作 (主要是可以闪烁变化)
//地址上没有0x00和0x0d,为啥呢,没找到,也不太清除;资料上写了
}
void main(void)
{
init_max7221(); // 初始化
while(1)
{
write_data(1,0x01); // 地址位选,数据段选
write_data(2,0x02);
write_data(3,0x04); //"-"
write_data(4,0x08); //"E"
write_data(5,0x10); //"H"
write_data(6,0x20); //"L"
write_data(7,0x40); //"P"
write_data(8,0x80); //全灭
}
}
全不解码,扫描8位
推算出MAX7221的信息:不是按上面推算的,我是一个一个试的:
段位(高电平) | 对应数字 | 对应上图的第几个(左到右) |
---|---|---|
A | 0x40 | 7 |
B | 0x20 | 6 |
C | 0x10 | 5 |
D | 0x08 | 4 |
E | 0x04 | 3 |
F | 0x02 | 2 |
G | 0x01 | 1 |
DP | 0x80 | 8 |
解码和不解码的区别
//相同部分已去掉,只显示修改的部分
//初始化函数
void init_max7221(void)
{
// write_data(0x09,0x00); //解码模式选择 8个位分别控制8个LED是否解码,'1'为BCD解码,'0'为不解码 低四位不解码
write_data(0x09,0xf0); //解码模式选择 8个位分别控制8个LED是否解码,'1'为BCD解码,'0'为不解码 低四位不解码
write_data(0x0a,0x07); //初始亮度设置 0-15设置1-16档亮度 最亮
write_data(0x0b,0x07); //扫描方式选择 0-7 设置扫描1-8个LED(通俗就是控制数码管的位)
write_data(0x0c,0x01); //工作模式选择 1:正常工作 0:掉电模式(开关)(长时间不用还可以关着)
write_data(0x0f,0x00); //测试模式开关 1:测试模式 0:正常工作 (主要是可以闪烁变化)
//地址上没有0x00和0x0d,为啥呢,没找到,也不太清除;资料上写了
}
void main(void)
{
int i,j;
init_max7221(); // 初始化
while(1)
{
for(i=0;i<8;i++) write_data(i+1,DSY_CODE[i]); // 验证低四位不解码的现象
}
}
和上面对比会发现,不解码会按照我们写的段码显示;解码会按照MAX7221内部的默认的段码显示(0),最后一个是不解码的写在了最高位,而默认的就低7个位的段码,叠加而成的。
最后送自己一个Π(3.141592……)
几个寄存器的合用,扫描,亮度,解码,小数点等操作
#include <reg51.h>
#include <intrins.h>
sbit DIN = P2^0; //数据串出引脚
sbit CS = P2^1; //片选端
sbit CLK = P2^2; //移位时钟端
unsigned char code DSY_CODE[]={0xf9,0x30,0x33,0x30,0x5b,0x7b,0x4f,0xff};
// 3. 1 4 1 5 9 2 8.
// 延时函数
void delayms(unsigned int x){
unsigned char i;
while(x--) for(i = 0;i < 120;i++);
}
void write_data(unsigned char addr,unsigned char dat){
unsigned char i;
CS = 0; // 拉低CS选中芯片 先写地址,片选置低,串行数据加载到移位寄存器
for(i = 0;i < 8;i++){
CLK = 0,addr <<= 1,DIN = CY,CLK = 1; // 拉高时钟线,写入数据
_nop_(),_nop_(),CLK = 0; //下降沿时数据从DOUT移出
}
for(i = 0;i < 8;i++){
CLK = 0,dat <<= 1,DIN = CY,CLK = 1;
_nop_(),_nop_(),CLK = 0;
}
CS = 1; //CS上升沿,数据锁存
}
//初始化函数
void init_max7221(void)
{
write_data(0x09,0x00); //解码模式选择 8个位分别控制8个LED是否解码,'1'为BCD解码,'0'为不解码 低四位不解码
write_data(0x0a,0x07); //初始亮度设置 0-15设置1-16档亮度 最亮
write_data(0x0b,0x05); //扫描方式选择 0-7 设置扫描1-8个LED(通俗就是控制数码管的位)
write_data(0x0c,0x01); //工作模式选择 1:正常工作 0:掉电模式(开关)(长时间不用还可以关着)
write_data(0x0f,0x00); //测试模式开关 1:测试模式 0:正常工作 (主要是可以闪烁变化)
//地址上没有0x00和0x0d,为啥呢,没找到,也不太清除;资料上写了
}
void main(void)
{
int i;
init_max7221(); // 初始化
while(1)
{
for(i=0;i<8;i++) write_data(i+1,DSY_CODE[i]); // 验证低四位不解码的现象
}
}