共2条
1/1 1 跳转至页
max7219 知道max7219的各路大侠帮帮忙!
问
这几天在忙毕业设计,需要做一显示模块,我用max7219做,听说比较方便。
我在网上找到了关于max7219的文章,文章中附带了7219与单片机的接口电路图与用汇编写的源代码。
文章中7219与单片机的之间用三根线相连接。
单片机 7219
P1^2 -> din
P1^3 -> clk
P1^4 -> load
源代码如下:
ORG 0000H
ajmp start
org 00a0h
start: MOV SP,#50H
LCALL MAX0 ;调用初始化7219函数
LOOP: LCALL DISP ;调用显示函数
SJMP LOOP
MAX0: MOV A,#0BH ;设置扫描位数
MOV R2,#07H ;显示8位
LCALL YW
MOV A,#0AH ;设置亮度
MOV R2,#05H
LCALL YW
MOV A,#09H ;设置译码格式
MOV R2,#0FFH ;设置BCD码
LCALL YW
MOV A,#0CH ;设置正常工作
MOV R2,#01H
LCALL YW
RET
DISP: MOV R0,#40H ;要显示的数据存储地址
MOV R1,#01H ;数码管的地址寄存器01h~08h
MOV R3,#08H
LOOP1: MOV A,@R0
MOV R2,A
MOV A,R1
LCALL YW
INC R0
INC R1
DJNZ R3,LOOP1
RET
YW: LCALL SEND ;调用发送函数,一位一位的从din送入7219
MOV A,R2
LCALL SEND
CLR P1.4 ;load 信号上升沿对其锁存
NOP
NOP
SETB P1.4
RET
SEND: MOV R4,#08H ;对其字节向左循环移8位
LOOP2: CLR P1.3 ;clk上升沿对每一位数据锁存
RLC A
MOV P1.2,C
NOP
NOP
NOP
SETB P1.3
DJNZ R4,LOOP2
RET
以上的程序我调试后成功了,证明程序的流程是正确的。而当我按照上面汇编的思想来用c语言编写时麻烦就来了。
以下是我的C源代码:恳请大家帮忙看看我是哪儿出了错。
#include<intrins.h>
#include<reg52.h>
sbit bytesend_din=P1^2;
sbit byteclk_clk=P1^3;
sbit byteload_load=P1^4;
void sendbyte(unsigned char value_send)
{
unsigned char cycal=0x80;
while(cycal>=0x01) //将一个字节八个位按从高到低依次送出。
{
byteclk_clk=0; //clk上升沿对每位数据锁存
if(value_send&cycal==0x00)
bytesend_din=0;
else
bytesend_din=1;
_nop_();
_nop_();
_nop_();
byteclk_clk=1;
_nop_();
cycal=cycal>>1;
}
}
void valuesend(unsigned char address,unsigned char value)
{
sendbyte(address); //先送地址
sendbyte(value); //再送数据
byteload_load=0; //load上升沿对16位数据锁存
_nop_();
_nop_();
_nop_();
byteload_load=1;
}
void initial7219()
{
valuesend(0x0b,0x06); //扫描位数的设置
valuesend(0x0a,0x05); //亮度的设置
valuesend(0x09,0xff); //译码的设置,BCD码
valuesend(0x0c,0x01); //设置正常工作
}
void disp7219()
{
unsigned char i;
for(i=0x00;i<=0x06;i++)
valuesend(i+1,i);
}
void main()
{
initial7219(); //初始化7219
do
{
disp7219(); //显示函数
}while(1);
}
汇编是正确的,但按它写的C语言就出错了。显示结果是所有数码管全部高亮,无论我初始化时设置了多少位,也无论我也设置了亮度都无济于事。
请大家帮帮忙,利用你们的经验看看哪儿有问题。谢谢!
答 1: 好像是SPI的时序有点问题,数据发送是下降沿写入void sendbyte(unsigned char value_send)
{
unsigned char cycal=0x80;
while(cycal>=0x01) //将一个字节八个位按从高到低依次送出。
{
byteclk_clk=1; //clk上升沿对每位数据锁存
if(value_send&cycal==0x00)
bytesend_din=0;
else
bytesend_din=1;
_nop_();
_nop_();
_nop_();
byteclk_clk=0; //
_nop_();
cycal=cycal>>1;
}
}
答 2: RE:问题已经解决了,请教了一位研究生,将循环移位输出程序的 判断中的
if(value_send&cycal==0x00)改写为 if((value_send&cycal)==0x00)
我也不知为何原先写的出了错,反正加了括号后就对了,呵呵,谢谢楼上的大侠啊!
答 3: 优先级很重要呀!!!!!!!!!!!!!!!!!!!!!! 答 4: re以前我从网上找一个现成的x5645的SPI的源程序,也是改动了一个类似代码才能用的。网上一些源码大多是有错的,现成的东东,能直接用的也不多。 答 5: 我习惯if(!(value_send&cycal))以减少出错机会
我在网上找到了关于max7219的文章,文章中附带了7219与单片机的接口电路图与用汇编写的源代码。
文章中7219与单片机的之间用三根线相连接。
单片机 7219
P1^2 -> din
P1^3 -> clk
P1^4 -> load
源代码如下:
ORG 0000H
ajmp start
org 00a0h
start: MOV SP,#50H
LCALL MAX0 ;调用初始化7219函数
LOOP: LCALL DISP ;调用显示函数
SJMP LOOP
MAX0: MOV A,#0BH ;设置扫描位数
MOV R2,#07H ;显示8位
LCALL YW
MOV A,#0AH ;设置亮度
MOV R2,#05H
LCALL YW
MOV A,#09H ;设置译码格式
MOV R2,#0FFH ;设置BCD码
LCALL YW
MOV A,#0CH ;设置正常工作
MOV R2,#01H
LCALL YW
RET
DISP: MOV R0,#40H ;要显示的数据存储地址
MOV R1,#01H ;数码管的地址寄存器01h~08h
MOV R3,#08H
LOOP1: MOV A,@R0
MOV R2,A
MOV A,R1
LCALL YW
INC R0
INC R1
DJNZ R3,LOOP1
RET
YW: LCALL SEND ;调用发送函数,一位一位的从din送入7219
MOV A,R2
LCALL SEND
CLR P1.4 ;load 信号上升沿对其锁存
NOP
NOP
SETB P1.4
RET
SEND: MOV R4,#08H ;对其字节向左循环移8位
LOOP2: CLR P1.3 ;clk上升沿对每一位数据锁存
RLC A
MOV P1.2,C
NOP
NOP
NOP
SETB P1.3
DJNZ R4,LOOP2
RET
以上的程序我调试后成功了,证明程序的流程是正确的。而当我按照上面汇编的思想来用c语言编写时麻烦就来了。
以下是我的C源代码:恳请大家帮忙看看我是哪儿出了错。
#include<intrins.h>
#include<reg52.h>
sbit bytesend_din=P1^2;
sbit byteclk_clk=P1^3;
sbit byteload_load=P1^4;
void sendbyte(unsigned char value_send)
{
unsigned char cycal=0x80;
while(cycal>=0x01) //将一个字节八个位按从高到低依次送出。
{
byteclk_clk=0; //clk上升沿对每位数据锁存
if(value_send&cycal==0x00)
bytesend_din=0;
else
bytesend_din=1;
_nop_();
_nop_();
_nop_();
byteclk_clk=1;
_nop_();
cycal=cycal>>1;
}
}
void valuesend(unsigned char address,unsigned char value)
{
sendbyte(address); //先送地址
sendbyte(value); //再送数据
byteload_load=0; //load上升沿对16位数据锁存
_nop_();
_nop_();
_nop_();
byteload_load=1;
}
void initial7219()
{
valuesend(0x0b,0x06); //扫描位数的设置
valuesend(0x0a,0x05); //亮度的设置
valuesend(0x09,0xff); //译码的设置,BCD码
valuesend(0x0c,0x01); //设置正常工作
}
void disp7219()
{
unsigned char i;
for(i=0x00;i<=0x06;i++)
valuesend(i+1,i);
}
void main()
{
initial7219(); //初始化7219
do
{
disp7219(); //显示函数
}while(1);
}
汇编是正确的,但按它写的C语言就出错了。显示结果是所有数码管全部高亮,无论我初始化时设置了多少位,也无论我也设置了亮度都无济于事。
请大家帮帮忙,利用你们的经验看看哪儿有问题。谢谢!
答 1: 好像是SPI的时序有点问题,数据发送是下降沿写入void sendbyte(unsigned char value_send)
{
unsigned char cycal=0x80;
while(cycal>=0x01) //将一个字节八个位按从高到低依次送出。
{
byteclk_clk=1; //clk上升沿对每位数据锁存
if(value_send&cycal==0x00)
bytesend_din=0;
else
bytesend_din=1;
_nop_();
_nop_();
_nop_();
byteclk_clk=0; //
_nop_();
cycal=cycal>>1;
}
}
答 2: RE:问题已经解决了,请教了一位研究生,将循环移位输出程序的 判断中的
if(value_send&cycal==0x00)改写为 if((value_send&cycal)==0x00)
我也不知为何原先写的出了错,反正加了括号后就对了,呵呵,谢谢楼上的大侠啊!
答 3: 优先级很重要呀!!!!!!!!!!!!!!!!!!!!!! 答 4: re以前我从网上找一个现成的x5645的SPI的源程序,也是改动了一个类似代码才能用的。网上一些源码大多是有错的,现成的东东,能直接用的也不多。 答 5: 我习惯if(!(value_send&cycal))以减少出错机会
共2条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
与电子爱好者谈读图四被打赏50分 | |
与电子爱好者谈读图二被打赏50分 | |
【FRDM-MCXN947评测】Core1适配运行FreeRtos被打赏50分 | |
【FRDM-MCXN947评测】双核调试被打赏50分 | |
【CPKCORRA8D1B评测】---移植CoreMark被打赏50分 | |
【CPKCORRA8D1B评测】---打开硬件定时器被打赏50分 | |
【FRDM-MCXA156评测】4、CAN loopback模式测试被打赏50分 | |
【CPKcorRA8D1评测】--搭建初始环境被打赏50分 | |
【FRDM-MCXA156评测】3、使用FlexIO模拟UART被打赏50分 | |
【FRDM-MCXA156评测】2、rt-thread MCXA156 BSP制作被打赏50分 |