这是一个8位数码管动态扫描显示电路:
LIBRARY IEEE;
USE IEEESTD_LOGIC_1164ALL;
USE IEEESTD_LOGIC_UNSIGNEDALL;
ENTITY SCAN_LED IS
PORT ( CLK : IN STD_LOGIC;
SG : OUT STD_LOGIC_VECTOR(6 DOWNTO 0);--段控制信号输出
BT : OUT STD_LOGIC_VECTOR(3 DOWNTO 0) );--位控制信号输出
END;
ARCHITECTURE one OF SCAN_LED IS
SIGNAL CNT8 : STD_LOGIC_VECTOR(2 DOWNTO 0);
SIGNAL A : INTEGER RANGE 0 TO 15;
BEGIN
P1:process(CNT8)
BEGIN
CASE CNT8 IS
WHEN "000" => BT <= "0000" ; A <= 0 ;
WHEN "001" => BT <= "0001" ; A <= 6 ;
WHEN "010" => BT <= "0010" ; A <= 6 ;
WHEN "011" => BT <= "0011" ; A <= 2 ;
WHEN "100" => BT <= "0100" ; A <= 3 ;
WHEN "101" => BT <= "0101" ; A <= 0 ;
WHEN "110" => BT <= "0110" ; A <= 0 ;
WHEN "111" => BT <= "0111" ; A <= 7 ;
WHEN OTHERS => NULL ;
END CASE ;
END PROCESS P1;
P2:process(CNT8) --当时钟上升沿来到时进行加1,是一个模8的计数器。作用是产生扫描时钟----
BEGIN
IF CLK'EVENT AND CLK = '1' THEN CNT8 <= CNT8 + 1;
END IF;
END PROCESS P2 ;
P3:process(A) ----译码电路-----
BEGIN
CASE A IS
WHEN 0 => SG <= "0111111"; WHEN 1 => SG <= "0000110";
WHEN 2 => SG <= "1011011"; WHEN 3 => SG <= "1001111";
WHEN 4 => SG <= "1100110"; WHEN 5 => SG <= "1101101";
WHEN 6 => SG <= "1111101"; WHEN 7 => SG <= "0000111";
WHEN 8 => SG <= "1111111"; WHEN 9 => SG <= "1101111";
--WHEN 10=> SG <= "1110111"; WHEN 11 => SG <= "1111100";
-- WHEN 12=> SG <= "0111001"; WHEN 13 => SG <= "1011110";
-- WHEN 14=> SG <= "1111001"; WHEN 15 => SG <= "1110001";
WHEN OTHERS => NULL ;
END CASE ;
END PROCESS P3;
END;
8个数码管分别由位选BT0-BT2控制。如果希望在8个数码管显示希望的数据,就必须使得8个数码管分别被单独选通;同时有段信号输入口加上希望在该对应数码管上显示的数据,于是随着选通信号的变化(加上人眼的视觉残留效果),实现了数码管动态扫描显示的目的。
此例中显示的是:70032660
CLK EQU P10 ;定义端口P10在该程序中用CLK表示
HEIPING:MOV R0,#40 ;r0=40 BLACK子程序入口参数
LCALL BLACK ;调用BLACK
LP: MOV R6,#0 ;r6=0
MOV R3,#16 ;r3=16决定BEGIN子程序执行次数
MOV A,#0 ;a=0
BEGIN: MOV DPTR,#MyZiKu ;dptr=MYZIKU(首地址)
MOVC A,@A+DPTR ;a=欲显示字符的字形码
LCALL SHOW ;调用SHOW程序(显示)
LCALL DELAY ;调用DELAY程序(延时)
INC R6 ;r6加1
MOV A,R6 ;a=r6
DJNZ R3,BEGIN ;r3减1不为0转移到BEGIN
;BEGIN这一段程序的作用是在LED上每隔DELAY程序设定的时间按顺序显示0~F 循环16次
LJMP LP ;转移到LP执行
;延时程序 r0 r1 r2决定延时时间
DELAY: MOV R0,#0FFH ;r0=255
DLP: MOV R1,#0FFH ;r1=255
DLP1: MOV R2,#04H ;r2=4
DJNZ R2,$ ;r2减1不为0仍在该行再次执行
DJNZ R1,DLP1 ;r1减1不为0转到DLP1
DJNZ R0,DLP ;r0减1不为0转到DLP
RET ;退出
;显示程序 该程序将循环8次显示一个字符
SHOW: MOV R0,#8 ;r0=8
SLP: CLR CLK ;P10输出低电平
RRC A ;将存放在A中欲显示的字符码右移一位(最低位存入C)
MOV A_B,C ;A_B(未见到你程序中定义 应是个端口)=C
SETB CLK ;P10输出高电平
DJNZ R0,SLP ;r0减1不为0转到SLP 继续输出字形码
RET
;该程序循环40次 P10输出40个脉冲 同时端口A_B持续输出低电平
BLACK: CLR CLK ;P10输出低电平
CLR A_B ;A_B(未见到你程序中定义 应是个端口)输出低电平
SETB CLK ;P10输出高电平
DJNZ R0,BLACK ;r0减1不为0转到BLACK
RET
;0~F的字形码
MYZIKU:
DB 77H,06H,0B3H,97H,0C6H ;"0,1,2,3,4"
DB 0D5H,0F5H,07H,0F7H,0D7H ;"5,6,7,8,9"
DB 0E7H,0F4H,71H,0B6H,0F1H,0E1H ;"A,B,C,D,E,F"
0101 0000 1289 1488 R4H5 Q533
你把GPIOA->ODR=(GPIOA->ODR&~GPIO_Pin_7) 这句改成 GPIOA->ODR=(GPIOA->ODR&(~GPIO_Pin_7) )试试,也许是这个问题,建议你还是别玩数码管了,STM32是那么高级货,直接玩彩屏吧
#define u8 unsigned char
#define u16 unsigned int
u8 code table[] = {
0xc0,0xf9,0xa4,0xb0, 0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83, 0xc6,0xa1,0x86,0x8e,
};
void delay(u16 t)
{
u16 i;
for(;t>0; t--)
for(i=100; i>0; i--);
}
void main(void)
{
u8 num = 0;
while(1) {
P1 = table[num];
delay(1000);
num++;
if(num>9)
num = 0;
}
}
library ieee;
use ieeestd_logic_1164all;
use ieeestd_logic_arithall;
use ieeestd_logic_unsignedall;
entity ymq is
port
(
num:in std_logic_vector(3 downto 0);
dout:out std_logic_vector(6 downto 0)
);
end ymq;
architecture a1 of ymq is
begin
with num select
dout<="1111110" when "0000",
"0110000" when "0001",
"1101101" when "0010",
"1111001" when "0011",
"0110011" when "0100",
"1011011" when "0101",
"1011111" when "0110",
"1110000" when "0111",
"1111111" when "1000",
"1111011" when "1001",
"0000000" when others;
end a1;
以上就是关于VHDL的数码管驱动原理全部的内容,包括:VHDL的数码管驱动原理、74HC164驱动数码管循环显示0~F的汇编程序求注释、最近做一个STM32驱动595显示数码管的程序,感觉程序没问题,可就显示不对(不是段码问题),求大侠帮忙等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)