- 打卡等级:偶尔看看III
- 打卡总天数:55
- 最近打卡:2026-07-04 22:38:22
已绑定手机
中级会员
- 积分
- 216
|
朋友送来1个大数码管显示板,板上有1只74LS164和2只74LS247,74LS164驱动2只74LS247,而每只74LS247驱动1只共阳数码管,2只数码管的型号是:TYS1230SRA,单个尺寸47mmX69mm。原以为该数码管是5V供电的,但5V点不亮,发现共阳极端与集成电路供电端不连通,而采用较粗的电源线,经试验至少6V才可以点亮,要达到正常亮度需8~9V供电,电路原理图见附图,需要说明的是54247/74247、54LS247、74LS247、74LS47等引脚功能相同,只是驱动能力有差别。该数码管显示板用普通51单片机可以驱动,手头刚好有免费申请的擎天柱Ai8051U转89C52-DIP40核心板,由于该板只需2根信号线,何不实验一下。
由于没有串口方式0 的实例参考,只得参考Ai8051.PDF文档中的第19章串口知识,逐个配置寄存器,这里注意,使用8bit模式,好多寄存器不支持位操作,例如串口功能脚切换寄存器P_SW1的地址是A2H,按普通51单片机的规定,寄存器地址不是8的倍数就不能位寻址,想选择串口1的RXD/P36,TXD/P37,不能“S1_S1 = 0; S1_S0 = 1;” ,只能 “P_SW1 |= (~(1<<7)) | (1<<6); ”,尤其在使用官方实例的时候,用Keil文件编译出现错误,需要查一下官方文档是不是出现类似的错误。
本例用串口1的RXD/P36,TXD/P37驱动两只大数码管作0~99s计时器,没有用定时器,只是采用了阻塞延时,程序如下:
#define MAIN_Fosc 12000000UL
#include "Ai8051U.h"
//#include <intrins.h>
#define INT8U unsigned char
#define INT16U unsigned int
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
//串口发送数据,低位在前,经串口向74HC164发送0x17,输出端Q0~Q7=0001 0111
//硬件接法:74HC164输出端与十位的74HC247对应关系Q2/D1,Q1/C1,Q0/B1,Q3/A1,
//与个位的74HC247对应关系Q6/D2,Q5/C2,Q4/B2,Q7/A2
//要发送十位的1,要送D1C1B1A1数据0001,即74HC164要输出Q0Q1Q2Q3=0001,即1
//要发送个位的2,要送D2C2B2A2数据0010,即74HC164要输出Q4Q5Q6Q7=1000,即8
//可得出如下0~9对应的数据表
code INT8U tab[] = { 0,1,8,9,4, 5,12,13,2,3};
INT8U Buf[2]; //显示缓冲,Buf[1]十位,Buf[0]个位
//74HC164引脚定义
//sbit DAT = P3^0; //串行数据线
//sbit CLK = P3^1; //串行时钟线
void delay_ms(u8 ms); //本地函数声明
//-----------------------------------------------------------------
// 延时
//-----------------------------------------------------------------
void delay_ms(u8 ms)
{
u16 i;
do{
i = MAIN_Fosc / 6000;
while(--i);
}while(--ms);
}
//-----------------------------------------------------------------
// 主程序
//-----------------------------------------------------------------
void main(void)
{
INT8U value = 0,temp=0;
WTST = 0; //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
EAXSFR(); //扩展寄存器(XFR)访问使能
CKCON = 0; //提高访问XRAM速度
P0M1 = 0x00; P0M0 = 0x00; //设置为准双向口
P1M1 = 0x00; P1M0 = 0x00; //设置为准双向口
P2M1 = 0x00; P2M0 = 0x00; //设置为准双向口
P3M1 = 0x00; P3M0 = 0x00; //设置为准双向口
P4M1 = 0x00; P4M0 = 0x00; //设置为准双向口
P5M1 = 0x00; P5M0 = 0x00; //设置为准双向口
P6M1 = 0x00; P6M0 = 0x00; //设置为准双向口
P7M1 = 0x00; P7M0 = 0x00; //设置为准双向口
SCON= 0x00; //串口1方式0,同步移位串行方式SM1=SM0=0
//S1_S1 = 0; S1_S0 = 1; //配置串口1引脚RXD/P36,TXD/P37
P_SW1 |= (~(1<<7)) | (1<<6); //8bit不支持此位操作
//UART_M0x6 = 0; //波特率不加倍,为FOSC/12
AUXR &= ~(1 << 5); //波特率不加倍,为FOSC/12
//DORD = 1; //先发送/接收数据的低位(LSB)
USARTCR1 |= (1<<6); //先发送/接收数据的低位(LSB)
//SMOD = 0; //串口1各个模式波特率不加倍
PCON &= ~(1 << 7); //串口1各个模式波特率不加倍
// 关闭串口1中断(轮询收发用,需中断则打开下方注释)
ES = 0;
TI = 1; //允许发送
while(1)
{
Buf[1] = value % 10; //个位数码
Buf[0] = value / 10; //十位数码
temp = ( tab[Buf[0]] << 4) | tab[Buf[1]];
SBUF = temp; //发送数据
//SBUF = 0x17; //发送数据,测试用
while(TI ==0 ); //等待发送完成
TI = 0; //清除标志位
delay_ms(250); //延时250ms
delay_ms(250); //延时250ms
delay_ms(250); //延时250ms
delay_ms(250); //延时250ms
if(++value == 100) //数据加1,满100清0
value = 0;
}
}
C:\\Users\\Administrator\\Desktop
希望能对采用该硬件的朋友有所帮助。
|
|