16×16的点阵,直接用单片机IO口,让点阵显示字符左右或上下滚动,程序应该怎么写呀

16×16的点阵,直接用单片机IO口,让点阵显示字符左右或上下滚动,程序应该怎么写呀,第1张

你这个单片机是带I2C接口的

那个SMBus就是,我用这个系列的单片机写过,模拟的还没有借口直接来的好。 我的空间里面有我调好的一篇247519442

你说的全部是0xff也是正常的,因为外部存储一般都是高电平为空,也就是说你的数据没有写进去

我给你一个模拟的看看

#include<reg51.h>

#include <Intrins.h>

#define uchar unsigned char

#define uint unsigned int

sbit pcf8563_scl=P0^5//时钟频率

sbit pcf8563_sda=P0^4//串行数据传输脚

bit busy=0

uchar sg//时高位

uchar sd//时低位

uchar fg//分高位

uchar fd//分低位

uchar mg//秒高位

uchar md//秒低位

uchar hou=0

uchar min=0

uchar sec=0

uchar subadd//地址

uchar dat//数据

uchar number

void start_pcf8563()//开始数据

void send_pcf8563_byte()//发送

void stop_pcf8563()//结束数据

void receive_pcf8563_byte()//接收

void spit_time()//分别计算时、分、秒的各位数字

void spit_time()//分别计算时、分、秒的各位数字

{

sg=(int)hou/10

sd=(int)hou%10

fg=(int)min/10

fd=(int)min%10

mg=(int)sec/10

md=(int)sec%10

}

void Send_pcf8563_byte(uchar bb) //向PCF8563发送一个字节

{

uchar aa

pcf8563_scl=0

for(aa=0aa<8aa++)

{

if((bb&0x80)==0x80)

{

pcf8563_sda=1

}

else

{

pcf8563_sda=0

}

pcf8563_scl=1

pcf8563_scl=0

bb=bb<<1

}

_nop_()

_nop_()

pcf8563_sda=1

pcf8563_scl=1

busy=0

if(pcf8563_sda)

{

busy=1

}

else

{

_nop_()

_nop_()

pcf8563_scl=0

busy=0

}

}

void write_pcf8563(uchar subadd,uchar dat)// 向PCF8563对应地址写数据

{

start_pcf8563()

Send_pcf8563_byte(0xa2)

if(!busy)

{

Send_pcf8563_byte(subadd)

if(!busy)

{

Send_pcf8563_byte(dat)

}

}

stop_pcf8563()

}

void read_pcf8563() //读当时的时,分,钞

{

start_pcf8563()

Send_pcf8563_byte(0xa2)

if(!busy)

{

Send_pcf8563_byte(0x02)

if(!busy)

{

start_pcf8563()

Send_pcf8563_byte(0xa3)

receive_pcf8563_byte()

sec=number&0x7f

start_pcf8563()

Send_pcf8563_byte(0xa3)

receive_pcf8563_byte()

min=number&0x7f

start_pcf8563()

Send_pcf8563_byte(0xa3)

receive_pcf8563_byte()

hou=number&0x3f

}

}

stop_pcf8563()

}

void receive_pcf8563_byte() //从PCF8563接受一个字节

{uchar cc

pcf8563_sda=1

number=0

for(cc=0cc<8cc++)

{

number<<=1

pcf8563_scl=0

pcf8563_scl=1

_nop_()

_nop_()

number= number|pcf8563_sda

}

pcf8563_scl=0

_nop_()

_nop_()

}

void start_pcf8563() //开启PCF8563IIC

{

pcf8563_sda=1

pcf8563_scl=1

pcf8563_sda=0//SCL为高,SDA执行一个下跳

pcf8563_scl=0//SCL为低,嵌住数据线

}

void stop_pcf8563() //关闭PCF8563IIC

{

pcf8563_sda=0

pcf8563_scl=1

pcf8563_sda=1//SCL为高,SDA执行一个上跳

pcf8563_scl=0//SCL为低,嵌住数据线

}

void main(void)

{

write_pcf8563(0x02,sec) //写钞

write_pcf8563(0x03,min) //写分

write_pcf8563(0x04,hou) //写时

while(1)

{

read_pcf8563()//读当前时间

spit_time() //切换时间,为显示做准备

}

}

如果还是不行,你把你的代码给我看看,看我能不能看出来

很简单/*16*16点阵屏的显示*/

#include <reg51.h>

#include <intrins.h>

#define DATAOUT P2 //指定P2口做为输出

sbit DATA=DATAOUT^0 //列数据输出位

sbit SCLH=DATAOUT^1 //列扫描时钟位

sbit SCLT=DATAOUT^2 //列数据锁存位

sbit AB=DATAOUT^4 //行数据输出位

sbit SCK=DATAOUT^5 //行扫描时钟位

unsigned char lhj[32]//32字节RAM做为16*16点阵屏显示缓存

void display()//做为点阵扫描函数,将显示缓存的数据输出到点阵屏

void displayS(unsigned int timer)//指定时间扫描显示

void displaymove(unsigned char *lp,unsigned char c,unsigned char timer)//显示汉字内容的移动效果,LP指向要显示第一个字的首地址,C表示显示字的个数,

//timer是移动的速度

void displaymovetb(unsigned char din,unsigned char *lp,unsigned char timer)

//上下移动内容,din:1为向下,0为向上,lp指向要移入的内容,timer为移动速度

void delay(unsigned int a)//延时子函数

code unsigned char lin[32]={0x04,0x20,0x04,0x20,0xff,0xfe,0x04,0x20,//汉字"英"的点阵数据。汉字点阵数据,可用汉字库点阵生成软件获得

0x01,0x00,0x1f,0xf0,0x11,0x10,0x11,0x10,

0x11,0x10,0xff,0xfe,0x01,0x00,0x02,0x80,

0x04,0x40,0x08,0x30,0x10,0x1c,0x20,0x08}

code unsigned char yang[32]={//达

0x00,0x00,0x40,0x80,0x30,0x80,0x10,0x80,

0x0f,0xfc,0x00,0x80,0x00,0x80,0xe0,0x80,

0x21,0x40,0x21,0x20,0x22,0x18,0x24,0x0c,

0x28,0x08,0x50,0x02,0x8f,0xfc,0x00,0x00}

code unsigned char dian[32]={//通

0x40,0x00,0x27,0xf8,0x20,0x90,0x00,0x60,

0x07,0xf8,0x04,0x48,0xe7,0xf8,0x24,0x48,

0x24,0x48,0x27,0xf8,0x24,0x48,0x24,0x68,

0x24,0x50,0x50,0x00,0x8f,0xfe,0x00,0x00}

code unsigned char zi[32]={//讯

0x40,0x00,0x27,0xf8,0x31,0x08,0x21,0x08,

0x01,0x08,0xf1,0x08,0x17,0xe8,0x11,0x08,

0x11,0x08,0x11,0x08,0x11,0x08,0x11,0x0a,

0x15,0x0a,0x19,0x0a,0x11,0x04,0x00,0x00}

code unsigned char LY[32]={//图案数据

0x00,0x00,0x30,0x00,0x30,0x20,0x30,0x30,

0x30,0x18,0x30,0x0C,0x30,0x06,0x3F,0x7F,

0x3F,0x7F,0x00,0x06,0x00,0x0C,0x00,0x18,

0x00,0x30,0x00,0x20,0x00,0x00,0x00,0x00}

void main(void) //主入口函数

{

unsigned char i=0,j=0

for(i=0i<32i++)

lhj[i]=LY[i]//将图案数据复制到显示缓存

while(1){

displayS(2) //显示图案约2秒

displaymove(lin,4,7)//将从"英"开始的四个汉字从右向左移动

displayS(1) //等持约1秒

displaymovetb(1,0,10) //将点阵上显示的内容向下以10的速度移出,补上0,即清空显示屏

displayS(1) //等待1秒

displaymovetb(0,lin,10) //达"达"字以10的速度向上移动

displaymovetb(0,yang,10) //将"通"字以10的速度向上移动

displaymovetb(0,dian,10) //将"讯"字以10的速度向上移动

displaymovetb(0,zi,10) //将"子"字以10的速度向上移动

displaymovetb(0,0,10) //以10的速度向上清空

displayS(1) //等待1秒

displaymovetb(1,LY,10) //将"图案"以10的速度向下移动

}

}

void display()//显示

{

unsigned char i,ia,j,tmp //定义变量

DATAOUT=0XFF //置位高电平做准备

AB=0 //将行数据位清0,准备移位

for(i=0i<16i++){ //循环输出16行数据

SCK=0 //为行移位做准备

SCLT=0 //为列锁存做准备

for(ia=2ia>0){ //每行16个点,循环位移两个字节

ia-- //循环两次

tmp=~lhj[i*2+ia] //读取点阵数据做输出,这里用到ia目的是先读取点阵数据的第二位字节,因一行16个点由两个字节组成,

//电路中的移位寄存器最后一位对应最后一列,所以要先输出一行中的第二个字节数据

for(j=0j<8j++){ //循环两次,每次移一个字节,

SCLH=0 //为列移位做准备

DATA=tmp&0x01 //将数据低位做输出,由电路图可知,移位寄存器的最后一位对应最后一列,因此先移最后一位

tmp>>=1 //将数据缓冲右移一位,为下次输出做准备

SCLH=1 //将DATA上的数据移入寄存器

} //移入单字节结束

} //移入两个字节结束

DATAOUT|=0X24 //此句可以用以下两句来理解,如果不将两句合为一句,将出现拖影现像

//SCK=1 //SCK拉高,行数据移位,相应行拉低,三极管导通输出电量到相应行点阵管阳极(共阳)

//SCLT=1 //SCLT拉高,将数据锁存输出到相应列的点阵发光管显示,显示一行后将保持到下一行显示开始

AB=1 //行数据位只在第一行时为0,其它时候都为1,当将这个0移入寄存器后,从第一位开始一直移位最后一位,

//移位的过程,AB就必需是1,这是因为不能同时有两个及两个以上0的出现,否则显示出乱

}

j=64

while(j--) //每一行的显示,保持了两字节的移位时间,因此,最后一行的显示,也要加入保持时间,补尝显示的亮度

SCK=0 //

SCK=1 //将最后一行数据移出

}

void displayS(unsigned int timer) //指定时间扫描显示

{

unsigned char i

while(timer--){ //当timer=1时,大约1秒时间

i=130

while(i--)

display()

}

}

void displaymove(unsigned char *lp,unsigned char c,unsigned char timer)//显示汉字内容的移动效果,LP指向要显示第一个字的首地址,C表示显示字的个数,

//timer是移动的速度

{

unsigned char i=0,j=0,ia=0

unsigned int tmp=0,timerc=0

unsigned char tmp2[16]

c*=2 //因一个汉字由32字节组成,而移位显示,要分开半个汉字16字节处理,因此将这里乘以2

for(i=0i<16i++)

tmp2[1]=0 //将缓冲区清0,

while(c){ //循环处理

if(lp!=0){ //当lp指向的地址为0时,直接用组缓冲0补上,效果是将当前显示的内容移出

tmp=c%2 //取余,目的是为了判断处理汉字的前半部份还是后半部份

for(i=0i<16i++){

tmp2[i]=lp[i*2+tmp] //取半个汉字点阵数据,16字节

}

if(tmp) //当tmp为1时,表时一个字数组处理完成,将地址转到下一个字

lp+=32

}

//--------------

tmp=8 //变量再次利用

while(tmp){ //循环8次,是将下一个字的前半部份的字节数据移入显示缓冲

ia=0 //做为点阵数组的元素

for(i=0i<16i++){//移动是16行同时移,因此要处理16个字节

lhj[ia]<<=1 //移当前显示缓冲的前半行字节

if(lhj[ia+1]&0x80) //判断后半行字节的高位是否为1,是移入前半行字节低位,否则不处理

lhj[ia]++

ia++

lhj[ia]<<=1 //移当前显示缓冲的后半行字节

if(tmp2[i]&0x80) //判断下一个要显示汉字的前半行字节的高位是否为1,是移入,否则不处理

lhj[ia]++

ia++

tmp2[i]<<=1 //下一个要显示汉字的半行字节向高位移一位,准备下一次取位

}

tmp--

timerc=timer //处理完16行,调用显示函数更新点阵

while(timerc--) //循环做为处理的速度,即移动的速度

display()

}

//----------

c-- //移完一半,进入下一半或下一个汉字,直到结束

}

}

void displaymovetb(unsigned char din,unsigned char *lp,unsigned char timer)

//上下移动内容,din:1为向下,0为向上,lp指向要移入的内容,timer为移动速度

{

unsigned char i=0,j=0,ia=0

unsigned int tmp=0,timerc=0

if(din){ //判断移动方向,向下

ia=32 //要移入第一个汉字的数组元素

i=16 //行索引

while(i--){ //逐行处理

j=30

while(j){

j--

lhj[j+2]=lhj[j] //将上一行的内容复制到下一行,每两行内容相隔四个字节,复制15行

}

if(lp==0){ //最后一行的处理,判断移入的内容是否为空,是用0移入

lhj[0]=0

lhj[1]=0

}

else{ //否则,取字数组处理

ia--

lhj[1]=lp[ia]

ia--

lhj[0]=lp[ia]

}

timerc=timer //处理完16行,调用显示函数更新点阵

while(timerc--) //循环做为处理的速度,即移动的速度

display()

}

}

else{ //移动方向,向上

ia=0 //向上移动,移入汉字从低位开始

for(i=0i<16i++){ //处理16行

for(j=0j<30j++) //将下一行的内容复制到上一行,每两行内容相隔四个字节,复制15行

lhj[j]=lhj[j+2]

if(lp==0){ //最后一行的处理,判断移入的内容是否为空,是用0移入

lhj[30]=0

lhj[31]=0

}

else{ //否则,取字数组处理

lhj[30]=lp[ia]

lhj[31]=lp[ia+1]

ia+=2

}

timerc=timer //处理完16行,调用显示函数更新点阵

while(timerc--) //循环做为处理的速度,即移动的速度

display()

}

}

}

void delay(unsigned int a) //延时

{

while(a--)

}

有字模软件修改你想要显示的字,程序要字模改动别告诉我你不懂

以简单的8X8点阵为例,它共由64个发光二极管组成,且每个发光二极管是放置在行线和列线的交叉点上,当对应的某一行置1电平,某一列置0电平,则相应的二极管就亮如要将第一个点点亮,则9脚接高电平13脚接低电平,则第一个点就亮了

如果要将第一行点亮,则第9脚要接高电平,而(13、3、4、10、6、11、15、16)这些引脚接低电平,那么第一行就会点亮如要将第一列点亮,则第13脚接低电平,而(9、14、8、12、1、7、2、5)接高电平,那么第一列就会点亮.


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/7792557.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-09
下一篇 2023-04-09

发表评论

登录后才能评论

评论列表(0条)

保存