
为什么要用plc呢?用plc不加外围器件直接来控制88点阵效果肯定不好,可以说是根本就不行,因为88点阵的控制类似于8位数码管循环扫描,用plc的触点输出,速度慢了看不出完整的图来,速度快触点又受不了(继电器输出的肯定不行,触点是有寿命的,晶体管的不清楚)再有PLC的输出方式又决定了它不可能刷新的很快。如果非要用plc控制,下面就是:
点阵的控制类似于循环扫描法点亮数码管,单片机如何控制,plc就用一样的方式,控制点阵单片机不加外围器件要用2组输出口(因为点阵有16跟线啊)。首先要找到点阵16个脚作用,哪些是控制行的,哪些是控制列的,并分清方向(二极管单向导通)然后把控制行的接在一组开关量输出上(8点),控制列的接在一组开关量输出上(8点),点阵每一个点(一个发光二极管)的电路是:1、电源正2、经过一组输出触点中的一个3、进点阵某管脚(看极性)经过发光二极管从某管脚出来4、再连另一组触点中一个5、到电源负。说白了PLC输出点就是2组开关而已。一般plc的触点都有一端连成一个公共点(如西门子的L1~Ln,三菱貌似是COM),行和列的公共点分别接电源的正和负就行了。只不过要注意点阵的供电,别直接用PLC的电源,注意加限流电阻(呵呵,一般不会范这个错误的)。
感觉还是用其他器件如单片机或专用芯片控制点阵,plc只是给它提供要显示的数据比较好。
啰嗦了点,不知你能不能明白。可以在网上找plc控制数码管的相关资料对比,相通的。
//这里显示数字,字母的话,定义每个字母的代码就可以了,汉字够呛,1616点阵还可以,88不是很好。
#include<reg51h>
#include<intrinsh>
#define uchar unsigned char
#define uint unsigned int
uchar code Table_of_Digits[]=
{
0x00,0x3e,0x41,0x41,0x41,0x3e,0x00,0x00, //0
0x00,0x00,0x00,0x21,0x7f,0x01,0x00,0x00, //1
0x00,0x27,0x45,0x45,0x45,0x39,0x00,0x00, //2
0x00,0x22,0x49,0x49,0x49,0x36,0x00,0x00, //3
0x00,0x0c,0x14,0x24,0x7f,0x04,0x00,0x00, //4
0x00,0x72,0x51,0x51,0x51,0x4e,0x00,0x00, //5
0x00,0x3e,0x49,0x49,0x49,0x26,0x00,0x00, //6
0x00,0x40,0x40,0x40,0x4f,0x70,0x00,0x00, //7
0x00,0x36,0x49,0x49,0x49,0x36,0x00,0x00, //8
0x00,0x32,0x49,0x49,0x49,0x3e,0x00,0x00, //9
0xff,0x81,0x81,0x81,0x81,0x81,0x81,0xff
};
uchar code xdat[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
uchar code ydat[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
uchar i=0,j=0,t=0,Num_Index,key,xi,yi;
//主程序
void main()
{
P1=0x80;
Num_Index=0; //从0 开始显示
TMOD=0x01; //T0 方式0
TH0=(65536-2000)/256; //2ms 定时
TL0=(65536-2000)%256;
IE=0x82;
key=0;
xi=0;
yi=0;
EX0=1;
IT0=1;
TR0=1; //启动T0
while(1);
}
//T0 中断函数
void ext_int0() interrupt 0
{
key++;
key&=0x03;
}
void LED_Screen_Display() interrupt 1
{
TH0=(65536-2000)/256; //2ms 定时
TL0=(65536-2000)%256;
switch(key)
{
case 0:
P0=0xff; //输出位码和段码
P0=~Table_of_Digits[Num_Index8+i];
P1=_crol_(P1,1);
if(++i==8) i=0; //每屏一个数字由8 个字节构成
if(++t==250) //每个数字刷新显示一段时间
{
t=0;
if(++Num_Index==10) Num_Index=0; //显示下一个数字
}
break;
case 1:
P0=~xdat[xi];
P1=0xff;
P1=ydat[yi];
if(++t==250) //每个数字刷新显示一段时间
{
t=0;
yi++;
if(yi>7){yi=0;xi++;}
if(xi>7)xi=0;
}
break;
case 2:
P0=0xff; //输出位码和段码
P0=~Table_of_Digits[80+j];
if(j==0)P1=0x80;
P1=_crol_(P1,1);
if(++j==8) j=0; //每屏一个数字由8 个字节构成
break;
default:
key=0;
i=0;
j=0;#include<reg51h>
#include<intrinsh>
#define uchar unsigned char
#define uint unsigned int
uchar code Table_of_Digits[]=
{
0x00,0x3e,0x41,0x41,0x41,0x3e,0x00,0x00, //0
0x00,0x00,0x00,0x21,0x7f,0x01,0x00,0x00, //1
0x00,0x27,0x45,0x45,0x45,0x39,0x00,0x00, //2
0x00,0x22,0x49,0x49,0x49,0x36,0x00,0x00, //3
0x00,0x0c,0x14,0x24,0x7f,0x04,0x00,0x00, //4
0x00,0x72,0x51,0x51,0x51,0x4e,0x00,0x00, //5
0x00,0x3e,0x49,0x49,0x49,0x26,0x00,0x00, //6
0x00,0x40,0x40,0x40,0x4f,0x70,0x00,0x00, //7
0x00,0x36,0x49,0x49,0x49,0x36,0x00,0x00, //8
0x00,0x32,0x49,0x49,0x49,0x3e,0x00,0x00, //9
0xff,0x81,0x81,0x81,0x81,0x81,0x81,0xff
};
uchar code xdat[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
uchar code ydat[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
uchar i=0,j=0,t=0,Num_Index,key,xi,yi;
//主程序
void main()
{
P1=0x80;
Num_Index=0; //从0 开始显示
TMOD=0x01; //T0 方式0
TH0=(65536-2000)/256; //2ms 定时
TL0=(65536-2000)%256;
IE=0x82;
key=0;
xi=0;
yi=0;
EX0=1;
IT0=1;
TR0=1; //启动T0
while(1);
}
//T0 中断函数
void ext_int0() interrupt 0
{
key++;
key&=0x03;
}
void LED_Screen_Display() interrupt 1
{
TH0=(65536-2000)/256; //2ms 定时
TL0=(65536-2000)%256;
switch(key)
{
case 0:
P0=0xff; //输出位码和段码
P0=~Table_of_Digits[Num_Index8+i];
P1=_crol_(P1,1);
if(++i==8) i=0; //每屏一个数字由8 个字节构成
if(++t==250) //每个数字刷新显示一段时间
{
t=0;
if(++Num_Index==10) Num_Index=0; //显示下一个数字
}
break;
case 1:
P0=~xdat[xi];
P1=0xff;
P1=ydat[yi];
if(++t==250) //每个数字刷新显示一段时间
{
t=0;
yi++;
if(yi>7){yi=0;xi++;}
if(xi>7)xi=0;
}
break;
case 2:
P0=0xff; //输出位码和段码
P0=~Table_of_Digits[80+j];
if(j==0)P1=0x80;
P1=_crol_(P1,1);
if(++j==8) j=0; //每屏一个数字由8 个字节构成
break;
default:
key=0;
i=0;
j=0;
t=0;
xi=0;
yi=0;
Num_Index=0;
P0=0xff;
P1=0x80;
break;
}
}
t=0;
xi=0;
yi=0;
Num_Index=0;
P0=0xff;
P1=0x80;
break;
}
}
在8X8 LED 点阵上显示柱形,让其先从左到右平滑移动1次,其次从右到左
平滑移动1次,再次从上到下平滑移动1次,最后从下到上平滑移动次,
如此循环下去。
LED显示原理:显示某一个点时,列值设为1,行值设为0即可
算法其实很简单,在不同时间片打入字模不同就可以实现
以下是伪代码
//
while(1)
{
for{打入字模}
delay(人眼可以识别的时间,不要太小,会出现鬼影)
}
library IEEE;
use IEEESTD_LOGIC_1164ALL;
use IEEESTD_LOGIC_ARITHALL;
use IEEESTD_LOGIC_UNSIGNEDALL;
ENTITY seg70 IS
PORT (
clk : IN std_logic; --clk 50MHZ
rst : IN std_logic; --REST
dataout : OUT std_logic_vector(7 DOWNTO 0); --各段数据输出
en : OUT std_logic_vector(7 DOWNTO 0)); --COM使能输出
END seg70;
ARCHITECTURE arch OF seg70 IS
signal cnt_scan : std_logic_vector(15 downto 0 ); --计数器分频用
signal data4 : std_logic_vector(2 downto 0);
signal dataout_xhdl1 : std_logic_vector(7 downto 0);
signal en_xhdl : std_logic_vector(7 downto 0);
begin
dataout<=dataout_xhdl1;
en<=en_xhdl;
process(clk,rst)
begin
if(rst='0')then
cnt_scan<="0000000000000000";
elsif(clk'event and clk='1')then
cnt_scan<=cnt_scan+1; --计数器累加
end if;
end process;
process(cnt_scan(15 downto 13)) --计数器分频
begin
case cnt_scan(15 downto 13) is --这里有8种状态,一个状态的时间间隔是一样的。
when"000"=> en_xhdl<="11111110"; --每一次轮流选择一排点阵灯
when"001"=> en_xhdl<="11111101";
when"010"=> en_xhdl<="11111011";
when"011"=> en_xhdl<="11110111";
when"100"=> en_xhdl<="11101111";
when"101"=> en_xhdl<="11011111";
when"110"=> en_xhdl<="10111111";
when"111"=> en_xhdl<="01111111";
when others=> en_xhdl<="11111110";
end case;
end process;
process(en_xhdl)
begin
case en_xhdl is --每一选择一排灯,同时还要给点阵的数据端口送数据
when "11111110"=> data4<="000";
when "11111101"=> data4<="001";
when "11111011"=> data4<="010";
when "11110111"=> data4<="011";
when "11101111"=> data4<="100";
when "11011111"=> data4<="101";
when "10111111"=> data4<="110";
when "01111111"=> data4<="111";
when others => data4<="111";
end case;
end process;
process(data4)
begin
case data4 is
--给点阵的数据端口送数据
--点阵数据口对应的管脚为1时,那个点不会亮。
--当点阵数据口对应的管脚为0时,那个点会亮。
--下面是一个汉字“正”的点阵码,就是利用点阵的亮和不亮形成对比显示出来的。
WHEN "000" =>
dataout_xhdl1 <= "11111111"; --第一行
WHEN "001" =>
dataout_xhdl1 <= "00000000";
WHEN "010" =>
dataout_xhdl1 <= "11101011";
WHEN "011" =>
dataout_xhdl1 <= "10001011";
WHEN "100" =>
dataout_xhdl1 <= "11101011";
WHEN "101" =>
dataout_xhdl1 <= "11101111";
WHEN "110" =>
dataout_xhdl1 <= "10000001";
WHEN "111" =>
dataout_xhdl1 <= "11111111"; --第八行
WHEN OTHERS =>
dataout_xhdl1 <= "00000011";
END CASE;
END PROCESS;
end arch;
88 LED显示正字
你根据这个来改成0-F显示啊,程序看懂就行。再加个状态机,就可以顺序循环显示了
点阵原理就是一个LED的两端都接IO,当正极为1,负极为0时点亮相应的LED。
下面是8×8的LED点阵程序,参考一下吧
#include<reg51h>
#define uchar unsigned char
#define uint unsigned int
uchar code TAB[]={
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0x00,0x82,0xFE,0x82,0x80,0xC0,0x00,0x00,
0x00,0x7C,0x82,0x82,0x82,0x7C,0x00,0x00,
0x02,0x0E,0x72,0x80,0x70,0x0E,0x02,0x00,
0x00,0x82,0xFE,0x92,0xBA,0x82,0xC6,0x00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00
};
/delay(uint t)
{
uint a,b;
for(a=0;a<t;a++)
for(b=0;b<110;b++);
} /
void main(void)
{
uint i,j,xx;
uchar bittemp=0x01;
while(1)
{
for(i=0;i<40;i++)
{
for(xx=0;xx<500;xx++)
{
bittemp=0x80;
for(j=0;j<8;j++)
{
P2=0x00; //消隐
P0= ~TAB[i+8-j];
P2 = bittemp;
bittemp >>= 1;
}
}
}
}
}
以上就是关于PLC怎么控制8*8LED点阵显示全部的内容,包括:PLC怎么控制8*8LED点阵显示、单片机8x 8点阵程序,hc6800——es v2.0,显示字母和汉字、单片机led点阵显示屏8*8左移怎么调等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)